defun
Major Section: MISCELLANEOUS
Common Lisp's defun
function does not easily allow one to pass extra
arguments such as ``hints''. ACL2 therefore supports a peculiar new
declaration (see declare) designed explicitly for passing additional
arguments to defun
via a keyword-like syntax. This declaration can
also be used with defmacro
, but only for xargs
keyword :GUARD
;
so we restrict attention below to use of xargs
in defun
events.
The following declaration is nonsensical but does illustrate all of the
xargs
keywords for defun
(which are the members of the list
*xargs-keywords*
).
(declare (xargs :guard (symbolp x) :guard-hints (("Goal" :in-theory (theory batch1))) :guard-debug t :hints (("Goal" :in-theory (theory batch1))) :measure (- i j) :ruler-extenders :basic :mode :logic :non-executable t :normalize nil :otf-flg t :stobjs ($s) :verify-guards t :split-types t :well-founded-relation my-wfr)) General Form: (xargs :key1 val1 ... :keyn valn)where the keywords and their respective values are as shown below. Note that once ``inside'' the xargs form, the ``extra arguments'' to
defun
are
passed exactly as though they were keyword arguments.:
GUARD
Value
is a term involving only the formals of the function being defined.
The actual guard used for the definition is the conjunction of all the
guards and types (see declare) declared.
:GUARD-HINTS
Value
: hints (see hints), to be used during the guard verification
proofs as opposed to the termination proofs of the defun
.
:GUARD-DEBUG
Value
: nil
by default, else directs ACL2 to decorate each guard proof
obligation with hypotheses indicating its sources. See guard-debug.
:
HINTS
Value: hints (see hints), to be used during the termination proofs as
opposed to the guard verification proofs of the defun
.
:MEASURE
Value
is a term involving only the formals of the function being defined.
This term is indicates what is getting smaller in the recursion. The
well-founded relation with which successive measures are compared is
o<
. Also allowed is a special case, (:? v1 ... vk)
, where
(v1 ... vk)
enumerates a subset of the formal parameters such that some
valid measure involves only those formal parameters. However, this special
case is only allowed for definitions that are redundant
(see redundant-events) or are executed when skipping proofs
(see skip-proofs). Another special case is :MEASURE nil
, which is
treated the same as if :MEASURE
is omitted.
:RULER-EXTENDERS
For recursive definitions (possibly mutually recursive), value
controls
termination analysis and the resulting stored induction scheme.
See ruler-extenders for a discussion of legal values and their effects.
:MODE
Value
is :
program
or :
logic
, indicating the
defun
mode of the function introduced. See defun-mode. If
unspecified, the defun
mode defaults to the default defun
mode of
the current world. To convert a function from :
program
mode
to :
logic
mode, see verify-termination.
:NON-EXECUTABLE
Value
is normally t
or nil
(the default). Rather than stating
:non-executable t
directly, which requires :
logic
mode and that
the definitional body has a certain form, we suggest using the macro
defun-nx
or defund-nx
; see defun-nx. A third value of
:non-executable
for advanced users is :program
, which is generated by
expansion of defproxy
forms; see defproxy. For another way to deal with
non-executability, see non-exec.
:NORMALIZE
Value is a flag telling defun
whether to propagate if
tests
upward. Since the default is to do so, the value supplied is only of
interest when it is nil
.
(See defun).
:
OTF-FLG
Value is a flag indicating ``onward through the fog''
(see otf-flg).
:STOBJS
Value
is either a single stobj
name or a true list of stobj names
(see stobj and see defstobj, and perhaps see defabsstobj). Every stobj
name among the formals of the function must be listed, if the corresponding
actual is to be treated as a stobj. That is, if a function uses a stobj name
as a formal parameter but the name is not declared among the :stobjs
then
the corresponding argument is treated as ordinary. The only exception to
this rule is state
: whether you include it or not, state
is always
treated as a single-threaded object. This declaration has two effects. One
is to enforce the syntactic restrictions on single-threaded objects. The
other is to strengthen the guard
of the function being defined so that
it includes conjuncts specifying that each declared single-threaded object
argument satisfies the recognizer for the corresponding single-threaded
object.
:
VERIFY-GUARDS
Value
is t
or nil
, indicating whether or not guards are to
be verified upon completion of the termination proof. This flag should only
be t
if the :mode
is unspecified but the default defun
mode is
:
logic
, or else the :mode
is :
logic
.
:
SPLIT-TYPES
Value
is t
or nil
, indicating whether or not types are to
be proved from the guards. The default is nil
, indicating that
type declarations (see declare) contribute to the guards. If the value
is t
, then instead, the expressions corresponding to the type
declarations (see type-spec) are conjoined into a ``split-type expression,''
and guard verification insists that this term is implied by the specified
:guard
. Suppose for example that a definition has the following
declare
form.
(declare (xargs :guard (p x y) :split-types t) (type integer x) (type (satisfies good-bar-p) y))Then for guard verification,
(p x y)
is assumed, and in addition to the
usual proof obligations derived from the body of the definition, guard
verification requires a proof that (p x y)
implies both (integerp x)
and (good-bar-p y)
. See community book
demos/split-types-examples.lisp
for small examples.:
WELL-FOUNDED-RELATION
Value
is a function symbol that is known to be a well-founded relation in
the sense that a rule of class :
well-founded-relation
has been
proved about it. See well-founded-relation.