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)))))))