mv-let supporting speculative and parallel execution
Major Section: PARALLEL-PROGRAMMING
This documentation topic relates to the experimental extension of ACL2 supporting parallel execution and proof; see parallelism.
Example Form:
(defun pfib-with-step-count (x)
  (declare (xargs :mode :program))
  (if (or (zp x) (< x 33))
      (fib-with-step-count x)
    (spec-mv-let
     (a cnt1)
     (pfib-with-step-count (- x 1))
     (mv-let (b cnt2)
             (pfib-with-step-count (- x 2))
             (if t
                 (mv (+ a b)
                     (+ 1 cnt1 cnt2))
               (mv "speculative result is always needed"
                   -1))))))
General Form:
(spec-mv-let
 (v1 ... vn)  ; bind distinct variables
 <spec>       ; evaluate speculatively; return n values
 (mv-let      ; or, use mv?-let if k=1 below
  (w1 ... wk) ; bind distinct variables
  <eager>     ; evaluate eagerly
  (if <test>  ; use results from <spec> if true
      <typical-case> ; may mention v1 ... vn
    <abort-case>)))  ; does not mention v1 ... vn
Our design of spec-mv-let is guided by its use in ACL2 source code to
parallelize part of ACL2's proof process, in the experimental parallel
extension of ACL2.  The user can think of spec-mv-let as a speculative
version of mv-let.  (In ordinary ACL2, the semantics agree with this
description but without speculative or parallel execution.)
Evaluation of the above general form proceeds as suggested by the comments.
First, <spec> is executed speculatively.  Control then passes immediately
to the mv-let call, without waiting for the result of evaluating
<spec>.  The variables (w1 ... wk) are bound to the result of
evaluating <eager>, and then <test> is evaluated.  If the value of
<test> is true, then the values of (v1 ... vn) are needed, and
<typical-case> blocks until they are available.  If the value of
<test> is false, then the values of (v1 ... vn) are not needed, and
the evaluation of <spec> may be aborted.
The calls to mv-let and to if displayed above in the General Form are
an essential part of the design of spec-mv-let, and are thus required.
The following definition of fib-with-step-count completes the example
above:
(defun fib-with-step-count (x)
(declare (xargs :mode :program))
(cond ((<= x 0)
       (mv 0 1))
      ((= x 1) (mv 1 1))
      (t (mv-let (a cnt1)
                 (fib-with-step-count (- x 1))
                 (mv-let (b cnt2)
                         (fib-with-step-count (- x 2))
                         (mv (+ a b)
                             (+ 1 cnt1 cnt2)))))))
 
 