Major Section: EVENTS

Examples: (defun app (x y) (if (consp x) (cons (car x) (app (cdr x) y)) y))where(defun fact (n) (declare (xargs :guard (and (integerp n) (>= n 0)))) (if (zp n) 1 (* n (fact (1- n)))))

General Form: (defun fn (var1 ... varn) doc-string dcl ... dcl body),

`fn`

is the symbol you wish to define and is a new symbolic name
(see name), `(var1 ... varn)`

is its list of formal parameters
(see name), and `body`

is its body. The definitional axiom is logically
admissible provided certain restrictions are met. These are sketched below.
Note that ACL2 does not support the use of `lambda-list`

keywords (such as
`&optional`

) in the formals list of functions. We do support some such
keywords in macros and often you can achieve the desired syntax by defining a
macro in addition to the general version of your function. See defmacro.
The documentation string, `doc-string`

, is optional; for a
description of its form, see doc-string.

The *declarations* (see declare), `dcl`

, are also optional. If more
than one `dcl`

form appears, they are effectively grouped together as one.
Perhaps the most commonly used ACL2 specific declaration is of the form
`(declare (xargs :guard g :measure m))`

. This declaration in the `defun`

of some function `fn`

has the effect of making the ``guard'' for
`fn`

be the term `g`

and the ``measure'' be the term `m`

. The notion
of ``measure'' is crucial to ACL2's definitional principle. The notion of
``guard'' is not, and is discussed elsewhere; see verify-guards and
see set-verify-guards-eagerness. Note that the `:measure`

is ignored in
`:`

`program`

mode; see defun-mode.

We now briefly discuss the ACL2 definitional principle, using the following definition form which is offered as a more or less generic example.

(defun fn (x y) (declare (xargs :guard (g x y) :measure (m x y))) (if (test x y) (stop x y) (step (fn (d x) y))))Note that in our generic example,

`fn`

has just two arguments, `x`

and
`y`

, the guard and measure terms involve both of them, and the body is
a simple case split on `(test x y)`

leading to a ``non-recursive'' branch,
`(stop x y)`

, and a ``recursive'' branch. In the recursive branch, `fn`

is called after ``decrementing'' `x`

to `(d x)`

and some step function is
applied to the result. Of course, this generic example is quite specific in
form but is intended to illustrate the more general case.Provided this definition is admissible under the logic, as outlined below, it adds the following axiom to the logic.

Defining Axiom: (fn x y) = (if (test x y) (stop x y) (step (fn (d x) y)))Note that the guard of

`fn`

has no bearing on this logical axiom.
This defining axiom is actually implemented in the ACL2 system by a
`:`

`definition`

rule, namely

(equal (fn x y) (if (test a b) (stop a b) (step (fn (d a) b)))).See definition for a discussion of how definition rules are applied. Roughly speaking, the rule causes certain instances of

`(fn x y)`

to be replaced by
the corresponding instances of the body above. This is called ``opening up''
`(fn x y)`

. The instances of `(fn x y)`

opened are chosen primarily by
heuristics which determine that the recursive calls of `fn`

in the opened
body (after simplification) are more desirable than the unopened call of
`fn`

.
This discussion has assumed that the definition of `fn`

was admissible.
Exactly what does that mean? First, `fn`

must be a previously
unaxiomatized function symbol (however, see ld-redefinition-action).
Second, the formal parameters must be distinct variable names. Third, the
guard, measure, and body should all be terms and should mention no free
variables except the formal parameters. Thus, for example, body may not
contain references to ``global'' or ``special'' variables; ACL2 constants or
additional formals should be used instead.

The final conditions on admissibility concern the termination of the
recursion. Roughly put, all applications of `fn`

must terminate. In
particular, there must exist a binary relation, `rel`

, and some unary
predicate `mp`

such that `rel`

is well-founded on objects satisfying
`mp`

, the measure term `m`

must always produce something satisfying
`mp`

, and the measure term must decrease according to `rel`

in each
recursive call, under the hypothesis that all the tests governing the call
are satisfied. By the meaning of well-foundedness, we know there are no
infinitely descending chains of successively `rel`

-smaller `mp`

-objects.
Thus, the recursion must terminate.

The only primitive well-founded relation in ACL2 is `o<`

(see o<), which
is known to be well-founded on the `o-p`

s (see o-p). For the proof of
well-foundedness, see proof-of-well-foundedness. However it is possible to
add new well-founded relations. For details, see well-founded-relation. We
discuss later how to specify which well-founded relation is selected by
`defun`

and in the present discussion we assume, without loss of
generality, that it is `o<`

on the `o-p`

s.

For example, for our generic definition of `fn`

above, with measure term
`(m x y)`

, two theorems must be proved. The first establishes that `m`

produces an ordinal:

(o-p (m x y)).The second shows that

`m`

decreases in the (only) recursive call of `fn`

:
(implies (not (test x y)) (o< (m (d x) y) (m x y))).Observe that in the latter formula we must show that the ``

`m`

-size'' of
`(d x)`

and `y`

is ``smaller than'' the `m`

-size of `x`

and `y`

,
provided the test, `(test x y)`

, in the body fails, thus leading to the
recursive call `(fn (d x) y)`

.
See o< for a discussion of this notion of ``smaller than.'' It should be
noted that the most commonly used ordinals are the natural numbers and that
on natural numbers, `o<`

is just the familiar ``less than'' relation
(`<`

). Thus, it is very common to use a measure `m`

that returns a
nonnegative integer, for then `(o-p (m x y))`

becomes a simple conjecture
about the type of `m`

and the second formula above becomes a conjecture
about the less-than relationship of nonnegative integer arithmetic.

The most commonly used measure function is `acl2-count`

, which computes a
nonnegative integer size for all ACL2 objects. See acl2-count.

Probably the most common recursive scheme in Lisp programming is when
some formal is supposed to be a list and in the recursive call it is replaced
by its `cdr`

. For example, `(test x y)`

might be simply `(atom x)`

and `(d x)`

might be `(cdr x)`

. In that case, `(acl2-count x)`

is a
suitable measure because the `acl2-count`

of a `cons`

is strictly
larger than the `acl2-count`

s of its `car`

and `cdr`

. Thus,
``recursion by `car`

'' and ``recursion by `cdr`

'' are trivially
admitted if `acl2-count`

is used as the measure and the definition
protects every recursive call by a test insuring that the decremented
argument is a `consp`

. Similarly, ``recursion by `1-`

'' in which a
positive integer formal is decremented by one in recursion, is also trivially
admissible. See built-in-clause to extend the class of trivially admissible
recursive schemes.

We now turn to the question of which well-founded relation `defun`

uses.
It should first be observed that `defun`

must actually select both a
relation (e.g., `o<`

) and a domain predicate (e.g., `o-p`

) on which
that relation is known to be well-founded. But, as noted elsewhere
(see well-founded-relation), every known well-founded relation has a unique
domain predicate associated with it and so it suffices to identify simply the
relation here.

The `xargs`

field of a `declare`

permits the explicit specification
of any known well-founded relation with the keyword
`:`

`well-founded-relation`

. An example is given below. If the
`xargs`

for a `defun`

specifies a well-founded relation, that relation
and its associated domain predicate are used in generating the termination
conditions for the definition.

If no `:`

`well-founded-relation`

is specified, `defun`

uses the
`:`

`well-founded-relation`

specified in the `acl2-defaults-table`

.
See set-well-founded-relation to see how to set the default well-founded
relation (and, implicitly, its domain predicate). The initial default
well-founded relation is `o<`

(with domain predicate `o-p`

).

This completes the brief sketch of the ACL2 definitional principle. Optionally, see ruler-extenders for a more detailed discussion of the termination analysis and resulting proof obligations for admissibility, as well as a discussion of the relation to how ACL2 stores induction schemes.

On very rare occasions ACL2 will seem to "hang" when processing a
definition, especially if there are many subexpressions of the body whose
function symbol is `if`

(or which macroexpand to such an expression). In
those cases you may wish to supply the following to `xargs`

:
`:normalize nil`

. This is an advanced feature that turns off ACL2's usual
propagation upward of `if`

tests.

The following example illustrates all of the available declarations and most hint keywords, but is completely nonsensical. For documentation, see xargs and see hints.

(defun example (x y z a b c i j) (declare (ignore a b c) (type integer i j) (xargs :guard (symbolp x) :measure (- i j) :ruler-extenders :basic :well-founded-relation my-wfr :hints (("Goal" :do-not-induct t :do-not '(generalize fertilize) :expand ((assoc x a) (member y z)) :restrict ((<-trans ((x x) (y (foo x))))) :hands-off (length binary-append) :in-theory (set-difference-theories (current-theory :here) '(assoc)) :induct (and (nth n a) (nth n b)) :use ((:instance assoc-of-append (x a) (y b) (z c)) (:functional-instance (:instance p-f (x a) (y b)) (p consp) (f assoc))))) :guard-hints (("Subgoal *1/3'" :use ((:instance assoc-of-append (x a) (y b) (z c))))) :mode :logic :normalize nil :verify-guards nil :non-executable t :otf-flg t)) (example-body x y z i j))