Execute a call in the ACL2 logic instead of raw Lisp
The name ``
Logically,
General Forms: (ec-call (fn term1 ... termk)) (ec-call (fn term1 ... termk) :dfs-in 'dfs-in :dfs-out dfs-out)
where
Semantically,
(1) Guard verification generates no proof obligations from the guard of
fn for this call. Indeed, guards need not have been verified forfn .(2) During evaluation, after the arguments of
fn are evaluated as usual, the executable-counterpart offn is called, rather than its submitted version (see evaluation). That is, the call offn is made on its evaluated arguments as though this call is being made in the ACL2 top-level loop, rather than in raw Lisp. In particular, the guard offn is checked, at least by default (see set-guard-checking).
The use of
(defun f1 (x) (declare (xargs :guard t)) (ec-call (nth t x)))
This definition is admitted, but evaluation of
(defun f1 (x) (declare (xargs :guard t)) (with-guard-checking nil (ec-call (nth t x))))
Note that in the term
Technical Remark (probably best ignored). During evaluation of a
call of defconst or defpkg in raw Lisp, a form
Here is another small example. We define
ACL2 !>(defun foo (x y) (declare (xargs :guard (consp y))) (if (consp x) (cons (car x) (ec-call (foo (cdr x) (cdr y)))) (car y))) The admission of FOO is trivial, using the relation O< (which is known to be well-founded on the domain recognized by O-P) and the measure (ACL2-COUNT X). We could deduce no constraints on the type of FOO. Computing the guard conjecture for FOO.... The guard conjecture for FOO is trivial to prove. FOO is compliant with Common Lisp. Summary Form: ( DEFUN FOO ...) Rules: NIL Warnings: None Time: 0.00 seconds (prove: 0.00, print: 0.00, other: 0.00) FOO ACL2 !>(foo '(2 3 4 5) '(6 7)) ACL2 Error in TOP-LEVEL: The guard for the function call (FOO X Y), which is (CONSP Y), is violated by the arguments in the call (FOO '(4 5) NIL). To debug see :DOC print-gv, see :DOC trace, and see :DOC wet. See :DOC set-guard-checking for information about suppressing this check with (set-guard-checking :none), as recommended for new users. ACL2 !>
The error above arises because eventually,
ACL2 !>(trace$ foo) ((FOO)) ACL2 !>(foo '(2 3 4 5) '(6 7)) 1> (ACL2_*1*_ACL2::FOO (2 3 4 5) (6 7)) 2> (FOO (2 3 4 5) (6 7)) 3> (ACL2_*1*_ACL2::FOO (3 4 5) (7)) 4> (FOO (3 4 5) (7)) 5> (ACL2_*1*_ACL2::FOO (4 5) NIL) ACL2 Error in TOP-LEVEL: The guard for the function call (FOO X Y), which is (CONSP Y), is violated by the arguments in the call (FOO '(4 5) NIL). To debug see :DOC print-gv, see :DOC trace, and see :DOC wet. See :DOC set-guard-checking for information about suppressing this check with (set-guard-checking :none), as recommended for new users. ACL2 !>
If we turn off guard errors then we can see the trace as above, but where we avoid calling the raw Lisp function when the guard fails to hold.
ACL2 !>:set-guard-checking nil Masking guard violations but still checking guards except for self- recursive calls. To avoid guard checking entirely, :SET-GUARD-CHECKING :NONE. See :DOC set-guard-checking. ACL2 >(foo '(2 3 4 5) '(6 7)) 1> (ACL2_*1*_ACL2::FOO (2 3 4 5) (6 7)) 2> (FOO (2 3 4 5) (6 7)) 3> (ACL2_*1*_ACL2::FOO (3 4 5) (7)) 4> (FOO (3 4 5) (7)) 5> (ACL2_*1*_ACL2::FOO (4 5) NIL) 6> (ACL2_*1*_ACL2::FOO (5) NIL) 7> (ACL2_*1*_ACL2::FOO NIL NIL) <7 (ACL2_*1*_ACL2::FOO NIL) <6 (ACL2_*1*_ACL2::FOO (5)) <5 (ACL2_*1*_ACL2::FOO (4 5)) <4 (FOO (3 4 5)) <3 (ACL2_*1*_ACL2::FOO (3 4 5)) <2 (FOO (2 3 4 5)) <1 (ACL2_*1*_ACL2::FOO (2 3 4 5)) (2 3 4 5) ACL2 >
Note on Inlining. Although in general, the form
(encapsulate () (defun foo () nil) (defun bar () t) (defmacro mac () nil) (add-macro-alias mac foo) (local (add-macro-alias mac bar)) (defun h () (ec-call (mac))) (defthm bad (h)))
Consider what would happen if this were legal, where
We conclude with a discussion of the second General Form:
(ec-call (fn term1 ... termk) :dfs-in 'dfs-in :dfs-out 'dfs-out)
Note that either or both keyword arguments may be omitted, and if both are included then they can be given in either order.
See df for background on dfs. Here is an example.
ACL2 !>(ec-call (binary-df+ (df1) (df1)) :dfs-in '(t t) :dfs-out '(t)) #d2.0 ACL2 !>
The keyword arguments indicate, respectively,
The next example illustrates the use of
(defun g (x) (mv (df+ (df1) (to-df x)) (- x 1)))
The use of
ACL2 !>(ec-call (g 3) :dfs-out '(t nil)) (#d4.0 2) ACL2 !>
Returning to the second General Form, notice that
When there are no df inputs (respectively, outputs) of the call, then