This is acl2-doc-emacs.info, produced by makeinfo version 4.13 from
acl2-doc-emacs.texinfo.

This is documentation for ACL2 Version 6.3
Copyright (C) 2013  University of Texas at Austin

This program is free software; you can redistribute it and/or modify
it under the terms of Version 2 of the GNU General Public License as
published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

Written by:  Matt Kaufmann and J Strother Moore
Department of Computer Sciences
University of Texas at Austin
Austin, TX 78712-1188 U.S.A.

INFO-DIR-SECTION Math
START-INFO-DIR-ENTRY
* acl2: (acl2-doc-emacs). Applicative Common Lisp
END-INFO-DIR-ENTRY


File: acl2-doc-emacs.info,  Node: ORACLE-APPLY,  Next: ORACLE-APPLY-RAW,  Prev: OR,  Up: ACL2-BUILT-INS

ORACLE-APPLY    call a function argument on the given list of arguments

Oracle-apply evaluates its first argument to produce an ACL2 function
symbol, FN, and then applies FN to the value of the second argument,
which should be a true list whose length is the number of inputs for FN.
The return value is of the form (mv call-result state).

     Examples:
     (oracle-apply 'cons '(3 4) state) = (mv '(3 . 4) <state>)
     (oracle-apply (car '(floor foo)) (list (+ 6 7) 5) state) = (mv 2 <state>)

Also see *note ORACLE-FUNCALL:: for a related utility.

Note that calls of oracle-funcall and oracle-apply return two values:
the result of the function application, and a modified state.

Oracle-apply is defined in :logic mode, and in fact is guard-verified.
However, you will not be able to prove much about this function,
because it is defined in the logic using the acl2-oracle field of the
ACL2 state.  The behavior described above -- i.e., making a function
call -- takes place when the third argument is the ACL2 state, so
during proofs (when that can never happen), a term (oracle-apply 'fn
'...) will not simplify using a call of fn.

The guard for (oracle-apply fn args state) is the term
(oracle-apply-guard fn args state), which says the following: fn and
args must satisfy symbolp and true-listp, respectively; fn must be a
known function symbol other than return-last that is not untouchable
(see *note PUSH-UNTOUCHABLE::) and has no stobj arguments (not even
state); and the length of args must equal the arity of fn (see *note
SIGNATURE::).  The requirement that fn be a known function symbol may
be a bit onerous for guard verification, but this is easily overcome by
using ec-call, for example as follows.

     (defun f (x state)
       (declare (xargs :stobjs state))
       (ec-call (oracle-apply 'car (list x) state)))

This use of ec-call will, however, cause the guard of oracle-apply to
be checked at runtime.

If the guard for oracle-apply fails to hold but there is no guard
violation because guard-checking is suppressed (see *note
SET-GUARD-CHECKING::), then the value returned is computed using its
logical definition -- which, as mentioned above, uses the ACL2 oracle
-- and hence the value computed is unpredictable (indeed, the function
argument will not actually be called).

The value returned by oracle-apply is always a single value obtained by
calling the executable counterpart of its function argument, as we now
explain.  Consider a form (oracle-apply fn args state) that evaluates to
(mv VAL state'), where fn evaluates to the function symbol F.  If F
returns multiple values, then VAL is the first value computed by the
call of F on the value of args.  More precisely, oracle-apply actually
invokes the executable counterpart of F; thus, if args is the
expression (list x1 ... xk), then VAL is the same as (first) value
returned by evaluating (ec-call (F x1 x2 ... xk)).  See *note EC-CALL::.

(Remark.  If you identify a need for a version of oracle-apply to return
multiple values, we can perhaps provide such a utility; feel free to
contact the ACL2 implementors to request it.)

A subtlety is that the evaluation takes place in so-called "safe mode",
which avoids raw Lisp errors due to calls of :program mode functions.
The use of safe mode is unlikely to be noticed if the value of the
first argument of oracle-apply is a :logic mode function symbol.
However, for :program mode functions with side effects due to special
raw Lisp code, as may be the case for built-in functions or for custom
functions defined with active trust tags (see *note DEFTTAG::), use of
the following function may be preferable:

See *note ORACLE-APPLY-RAW:: for a much less restrictive version of
oracle-apply, which avoids safe mode and (for example) can apply a
function that has a definition in the host Lisp but not in the ACL2
world.


File: acl2-doc-emacs.info,  Node: ORACLE-APPLY-RAW,  Next: ORACLE-FUNCALL,  Prev: ORACLE-APPLY,  Up: ACL2-BUILT-INS

ORACLE-APPLY-RAW    call a function argument on the given list of arguments, no restrictions

See *note ORACLE-APPLY::, as we assume familiarity with that function.
Oracle-apply-raw is a variant of oracle-apply that is untouchable, and
hence requires a trust tag to remove the untouchability (see *note
DEFTTAG:: and see *note REMOVE-UNTOUCHABLE::).  Unlike oracle-apply,
oracle-apply-raw simply calls the raw Lisp function funcall to compute
the result, without restriction: the specified :guard is t, the
function itself is applied (not its executable counterpart), there is
no restriction for untouchable functions or return-last, and safe mode
is not used.  Thus, in general, oracle-apply-raw can be dangerous to
use: any manner of error can occur!

As is the case for oracle-apply, the function symbol oracle-apply-raw
is defined in :logic mode and is guard-verified.  Oracle-apply-raw is
logically defined to be oracle-apply; more precisely:

     (oracle-apply-raw fn args state)
     = {logical definition}
     (ec-call (oracle-apply fn args state))


File: acl2-doc-emacs.info,  Node: ORACLE-FUNCALL,  Next: PAIRLIS,  Prev: ORACLE-APPLY-RAW,  Up: ACL2-BUILT-INS

ORACLE-FUNCALL    call a function argument on the remaining arguments

Oracle-funcall evaluates its first argument to produce an ACL2 function
symbol, and then applies that function symbol to the values of the rest
of the arguments.  The return value is of the form (mv call-result
state).

     Examples:
     (oracle-funcall 'cons 3 4) ==> (mv '(3 . 4) <state>)
     (oracle-funcall (car '(floor foo bar)) (+ 6 7) 5) ==> (mv 2 <state>)

Oracle-funcall is a macro; each of its calls macroexpands to a call of
the related utility oracle-apply that takes the ACL2 state as an
argument, as follows:

     (oracle-funcall fn x1 x2 .. xk)

macroexpands to

     (oracle-apply fn (list x1 x2 .. xk) state)

Note that calls of oracle-funcall and oracle-apply return two values:
the result of the function application, and a modified state.

See *note ORACLE-APPLY:: for details, including information about
guards.


File: acl2-doc-emacs.info,  Node: PAIRLIS,  Next: PAIRLIS$,  Prev: ORACLE-FUNCALL,  Up: ACL2-BUILT-INS

PAIRLIS    See *note PAIRLIS$::

The Common Lisp language allows its pairlis function to construct an
alist in any order!  So we have to define our own version: See *note
PAIRLIS$::.


File: acl2-doc-emacs.info,  Node: PAIRLIS$,  Next: PEEK-CHAR$,  Prev: PAIRLIS,  Up: ACL2-BUILT-INS

PAIRLIS$    zipper together two lists

The Common Lisp language allows its pairlis function to construct an
alist in any order!  So we have to define our own version, pairlis$.
It returns the list of pairs obtained by consing together successive
respective members of the given lists until the first list runs out.
(Hence in particular, if the second argument is nil then each element
of the first argument is paired with nil.)

The guard for pairlis$ requires that its arguments are true lists.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: PEEK-CHAR$,  Next: PKG-IMPORTS,  Prev: PAIRLIS$,  Up: ACL2-BUILT-INS

PEEK-CHAR$    See *note IO::.


File: acl2-doc-emacs.info,  Node: PKG-IMPORTS,  Next: PKG-WITNESS,  Prev: PEEK-CHAR$,  Up: ACL2-BUILT-INS

PKG-IMPORTS    list of symbols imported into a given package

Completion Axiom (completion-of-pkg-imports):

     (equal (pkg-imports x)
            (if (stringp x)
                (pkg-imports x)
              nil))

Guard for (pkg-imports x):

     (stringp x)

(Pkg-imports pkg) returns a duplicate-free list of all symbols imported
into pkg, which should be the name of a package known to ACL2.  For
example, suppose "MY-PKG" was created by

     (defpkg "MY-PKG" '(ACL2::ABC LISP::CAR)).

Then (pkg-imports "MY-PKG") equals the list (ACL2::ABC LISP::CAR).

If pkg is not a string, then (pkg-imports pkg) is nil.  If pkg is a
string but not the name of a package known to ACL2, then the value of
the form (pkg-imports pkg) is unspecified, and it evaluation will fail
to yield a value.  By "the symbols imported into pkg" we mean the
symbols imported into pkg by the defpkg event that introduced pkg.
There are no imports for built-in packages except for the "ACL2"
package, which imports the symbols in the list value of the constant
*common-lisp-symbols-from-main-lisp-package*.  In particular, this is
the case for the "COMMON-LISP" package.  Users familiar with Common
Lisp may find this surprising, since in actual Common Lisp
implementations it is often the case that many symbols in that package
are imported from other packages.  However, ACL2 treats all symbols in
the constant *common-lisp-symbols-from-main-lisp-package* as having a
symbol-package-name of "COMMON-LISP", as though they were not imported.
ACL2 admits a symbol imported into in the "COMMON-LISP" package only if
it belongs to that list: any attempt to read any other symbol imported
into the "COMMON-LISP" package, or to produce such a symbol with
intern$ or intern-in-package-of-symbol, will cause an error.

The following axioms formalize properties of pkg-imports discussed above
(use :pe to view them).

     symbol-package-name-intern-in-package-of-symbol
     intern-in-package-of-symbol-is-identity
     symbol-listp-pkg-imports
     no-duplicatesp-pkg-imports
     completion-of-pkg-imports


File: acl2-doc-emacs.info,  Node: PKG-WITNESS,  Next: PLUSP,  Prev: PKG-IMPORTS,  Up: ACL2-BUILT-INS

PKG-WITNESS    return a specific symbol in the indicated package

For any string pkg that names a package currently known to ACL2,
(pkg-witness pkg) is a symbol in that package whose symbol-name is the
value of constant *pkg-witness-name*.  Logically, this is the case even
if the package is not currently known to ACL2.  However, if pkg-witness
is called on a string that is not the name of a package known to ACL2,
a hard Lisp error will result.

(Pkg-witness pkg) has a guard of (and (stringp pkg) (not (equal pkg
""))).  If pkg is not a string, then (pkg-witness pkg) is equal to
(pkg-witness "ACL2")


File: acl2-doc-emacs.info,  Node: PLUSP,  Next: POSITION,  Prev: PKG-WITNESS,  Up: ACL2-BUILT-INS

PLUSP    test whether a number is positive

(Plusp x) is true if and only if x > 0.

The guard of plusp requires its argument to be a rational (real, in
ACL2(r)) number.

Plusp is a Common Lisp function.  See any Common Lisp documentation for
more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: POSITION,  Next: POSITION-EQ,  Prev: PLUSP,  Up: ACL2-BUILT-INS

POSITION    position of an item in a string or a list

     General Forms:
     (position x seq)
     (position x seq :test 'eql)   ; same as above (eql as equality test)
     (position x seq :test 'eq)    ; same, but eq is equality test
     (position x seq :test 'equal) ; same, but equal is equality test

(Position x seq) is the least index (zero-based) of the element x in
the string or list seq, if x is an element of seq.  Otherwise (position
x seq) is nil.  The optional keyword, :TEST, has no effect logically,
but provides the test (default eql) used for comparing x with items of
seq.

The guard for a call of position depends on the test.  In all cases,
the second argument must satisfy stringp or true-listp.  If the test is
eql, then either the first argument must be suitable for eql (see *note
EQLABLEP::) or the second argument must satisfy eqlable-listp.  If the
test is eq, then either the first argument must be a symbol or the
second argument must satisfy symbol-listp.

See *note EQUALITY-VARIANTS:: for a discussion of the relation between
position and its variants:

     (position-eq x seq) is equivalent to (position x seq :test 'eq);

     (position-equal x seq) is equivalent to (position x seq :test
     'equal).


In particular, reasoning about any of these primitives reduces to
reasoning about the function position-equal.

Position is defined by Common Lisp.  See any Common Lisp documentation
for more information.


File: acl2-doc-emacs.info,  Node: POSITION-EQ,  Next: POSITION-EQUAL,  Prev: POSITION,  Up: ACL2-BUILT-INS

POSITION-EQ    See *note POSITION::.


File: acl2-doc-emacs.info,  Node: POSITION-EQUAL,  Next: POSP,  Prev: POSITION-EQ,  Up: ACL2-BUILT-INS

POSITION-EQUAL    See *note POSITION::.


File: acl2-doc-emacs.info,  Node: POSP,  Next: PPROGN,  Prev: POSITION-EQUAL,  Up: ACL2-BUILT-INS

POSP    a recognizer for the positive integers

(posp x) is logically equivalent to (not (zp x)) (see *note ZP::) and
also   to (and (natp x) (not (equal x 0))).  We recommend the community
book   books/ordinals/natp-posp for reasoning about posp and natp.  This
 book is included by community books books/arithmetic/top and
books/arithmetic/top-with-meta.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: PPROGN,  Next: PRINC$,  Prev: POSP,  Up: ACL2-BUILT-INS

PPROGN    evaluate a sequence of forms that return state

     Example Form:
     (pprogn
      (cond ((or (equal (car l) #\) (equal (car l) slash-char))
             (princ$ #\ channel state))
            (t state))
      (princ$ (car l) channel state)
      (mv (cdr l) state))

The convention for pprogn usage is to give it a non-empty sequence of
forms, each of which (except possibly for the last) returns state (see
*note STATE::) as its only value.  The state returned by each but the
last is passed on to the next.  The value or values of the last form
are returned as the value of the pprogn.

If you are using single-threaded objects you may wish to define an
analogue of this function for your own stobj.

General Form:

     (PPROGN form1
             form2
             ...
             formk
             result-form)

This general form is equivalent, via macro expansion, to:

     (LET ((STATE form1))
          (LET ((STATE form2))
               ...
               (LET ((STATE formk))
                    result-form)))


File: acl2-doc-emacs.info,  Node: PRINC$,  Next: PRINT-OBJECT$,  Prev: PPROGN,  Up: ACL2-BUILT-INS

PRINC$    print an atom

Use princ$ to do basic printing of atoms (i.e., other than cons pairs).
In particular, princ$ prints a string without the surrounding
double-quotes and without escaping double-quote characters within the
string.  Note that princ$ is sensitive to the print-base, print-radix,
and print-case; see *note SET-PRINT-BASE::, see *note
SET-PRINT-RADIX::, and see *note SET-PRINT-CASE::.  Princ$ returns
state.

     Examples:
     ACL2 !>(princ$ "Howdy ho" (standard-co state) state)
     Howdy ho<state>
     ACL2 !>(pprogn (princ$ "Howdy ho" (standard-co state) state)
                    (newline (standard-co state) state))
     Howdy ho
     <state>
     ACL2 !>(princ$ "ab\"cd" *standard-co* state)
     ab"cd<state>
     ACL2 !>
     ACL2 !>(princ$ 17 *standard-co* state)
     17<state>
     ACL2 !>(set-print-base 16 state)
     <state>
     ACL2 !>(princ$ 17 *standard-co* state)
     11<state>
     ACL2 !>(set-print-radix t state)
     <state>
     ACL2 !>(princ$ 17 *standard-co* state)
     #x11<state>
     ACL2 !>(princ$ 'xyz *standard-co* state)
     XYZ<state>
     ACL2 !>(set-print-case :downcase state)
     <state>
     ACL2 !>(princ$ 'xyz *standard-co* state)
     xyz<state>
     ACL2 !>

The guard for (princ$ x channel state) is essentially as follows; see
*note IO:: for an explanation of guards of certain built-in functions
that take state, such as princ$.

     (and (or (acl2-numberp x)
              (characterp x)
              (stringp x)
              (symbolp x))
          (state-p1 state-state)
          (symbolp channel)
          (open-output-channel-p1 channel :character state-state))

See *note FMT:: for more sophisticated printing routines, and see *note
IO:: for general information about input and output.


File: acl2-doc-emacs.info,  Node: PRINT-OBJECT$,  Next: PROG2$,  Prev: PRINC$,  Up: ACL2-BUILT-INS

PRINT-OBJECT$    See *note IO::.


File: acl2-doc-emacs.info,  Node: PROG2$,  Next: PROGN$,  Prev: PRINT-OBJECT$,  Up: ACL2-BUILT-INS

PROG2$    execute two forms and return the value of the second one

See *note HARD-ERROR::, see *note ILLEGAL::, and see *note CW:: for
examples of functions to call in the first argument of prog2$.  Also
see *note PROGN$:: for an extension of prog2$ that handles than two
arguments.

Semantically, (Prog2$ x y) equals y; the value of x is ignored.
However, x is first evaluated for side effect.  Since the ACL2
programming language is applicative, there can be no logical impact of
evaluating x.  However, x may involve a call of a function such as
hard-error or illegal, which can cause so-called "hard errors", or a
call of cw to perform output.

Here is a simple, contrived example using hard-error.  The intention is
to check at run-time that the input is appropriate before calling
function bar.

     (defun foo-a (x)
       (declare (xargs :guard (consp x)))
       (prog2$
        (or (good-car-p (car x))
            (hard-error 'foo-a
                        "Bad value for x: ~p0"
                        (list (cons #\0 x))))
        (bar x)))

The following similar function uses illegal instead of hard-error.
Since illegal has a guard of nil, guard verification would guarantee
that the call of illegal below will never be made (at least when guard
checking is on; see *note SET-GUARD-CHECKING::).

     (defun foo-b (x)
       (declare (xargs :guard (and (consp x) (good-car-p (car x)))))
       (prog2$
        (or (good-car-p (car x))
            (illegal 'foo-b
                     "Bad value for x: ~p0"
                     (list (cons #\0 x))))
        (bar x)))

We conclude with a simple example using cw from the ACL2 sources.

     (defun print-terms (terms iff-flg wrld)

     ; Print untranslations of the given terms with respect to iff-flg, following
     ; each with a newline.

     ; We use cw instead of the fmt functions because we want to be able to use this
     ; function in print-type-alist-segments (used in brkpt1), which does not return
     ; state.

       (if (endp terms)
           terms
         (prog2$
          (cw "~q0" (untranslate (car terms) iff-flg wrld))
          (print-terms (cdr terms) iff-flg wrld))))


File: acl2-doc-emacs.info,  Node: PROGN$,  Next: PROOFS-CO,  Prev: PROG2$,  Up: ACL2-BUILT-INS

PROGN$    execute a sequence of forms and return the value of the last one

This macro expands to a corresponding nest of calls of prog2$; see
*note PROG2$::.  The examples below show how this works: the first case
below is typical, but we conclude with two special cases.

     ACL2 !>:trans1 (progn$ (f1 x) (f2 x) (f3 x))
      (PROG2$ (F1 X) (PROG2$ (F2 X) (F3 X)))
     ACL2 !>:trans1 (progn$ (f1 x) (f2 x))
      (PROG2$ (F1 X) (F2 X))
     ACL2 !>:trans1 (progn$ (f1 x))
      (F1 X)
     ACL2 !>:trans1 (progn$)
      NIL
     ACL2 !>


File: acl2-doc-emacs.info,  Node: PROOFS-CO,  Next: PROPER-CONSP,  Prev: PROGN$,  Up: ACL2-BUILT-INS

PROOFS-CO    the proofs character output channel

Proofs-co is an ld special (see *note LD::).  The accessor is
(proofs-co state) and the updater is (set-proofs-co val state).
Proofs-co must be an open character output channel.  It is to this
channel that defun, defthm, and the other event commands print their
commentary.

"Proofs-co" stands for "proofs character output." The initial value of
proofs-co is the same as the value of *standard-co* (see *note
*STANDARD-CO*::).


File: acl2-doc-emacs.info,  Node: PROPER-CONSP,  Next: PSEUDO-TERMP,  Prev: PROOFS-CO,  Up: ACL2-BUILT-INS

PROPER-CONSP    recognizer for proper (null-terminated) non-empty lists

Proper-consp is the function that checks whether its argument is a
non-empty list that ends in nil.  Also see *note TRUE-LISTP::.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: PSEUDO-TERMP,  Next: PUT-ASSOC,  Prev: PROPER-CONSP,  Up: ACL2-BUILT-INS

PSEUDO-TERMP    a predicate for recognizing term-like s-expressions

     Example Forms:
     (pseudo-termp '(car (cons x 'nil)))      ; has value t
     (pseudo-termp '(car x y z))              ; also has value t!
     (pseudo-termp '(delta (h x)))            ; has value t
     (pseudo-termp '(delta (h x) . 7))        ; has value nil (not a true-listp)
     (pseudo-termp '((lambda (x) (car x)) b)) ; has value t
     (pseudo-termp '(if x y 123))             ; has value nil (123 is not quoted)
     (pseudo-termp '(if x y '123))            ; has value t

If x is the quotation of a term, then (pseudo-termp x) is t.  However,
if x is not the quotation of a term it is not necessarily the case that
(pseudo-termp x) is nil.

See *note TERM:: for a discussion of the various meanings of the word
"term" in ACL2.  In its most strict sense, a term is either a legal
variable symbol, a quoted constant, or the application of an n-ary
function symbol or closed lambda-expression to n terms.  By "legal
variable symbol" we exclude constant symbols, such as t, nil, and
*ts-rational*.  By "quoted constants" we include 't (aka (quote t)),
'nil, '31, etc., and exclude constant names such as t, nil and
*ts-rational*, unquoted constants such as 31 or 1/2, and ill-formed
quote expressions such as (quote 3 4).  By "closed lambda expression"
we exclude expressions, such as (lambda (x) (cons x y)), containing
free variables in their bodies.  Terms typed by the user are translated
into strict terms for internal use in ACL2.

The predicate termp checks this strict sense of "term" with respect to
a given ACL2 logical world; See *note WORLD::.  Many ACL2 functions,
such as the rewriter, require certain of their arguments to satisfy
termp.  However, as of this writing, termp is in :program mode and thus
cannot be used effectively in conjectures to be proved.  Furthermore,
if regarded simply from the perspective of an effective guard for a
term-processing function, termp checks many irrelevant things.  (Does
it really matter that the variable symbols encountered never start and
end with an asterisk?)  For these reasons, we have introduced the
notion of a "pseudo-term" and embodied it in the predicate
pseudo-termp, which is easier to check, does not require the logical
world as input, has :logic mode, and is often perfectly suitable as a
guard on term-processing functions.

A pseudo-termp is either a symbol, a true list of length 2 beginning
with the word quote, the application of an n-ary pseudo-lambda
expression to a true list of n pseudo-terms, or the application of a
symbol to a true list of n pseudo-termps.  By an "n-ary pseudo-lambda
expression" we mean an expression of the form (lambda (v1 ... vn)
pterm), where the vi are symbols (but not necessarily distinct legal
variable symbols) and pterm is a pseudo-termp.

Metafunctions may use pseudo-termp as a guard.


File: acl2-doc-emacs.info,  Node: PUT-ASSOC,  Next: PUT-ASSOC-EQ,  Prev: PSEUDO-TERMP,  Up: ACL2-BUILT-INS

PUT-ASSOC    modify an association list by associating a value with a key

     General Forms:
     (put-assoc name val alist)
     (put-assoc name val alist :test 'eql)   ; same as above (eql as equality test)
     (put-assoc name val alist :test 'eq)    ; same, but eq is equality test
     (put-assoc name val alist :test 'equal) ; same, but equal is equality test

(Put-assoc name val alist) returns an alist that is the same as the list
alist, except that the first pair in alist with a car of name is
replaced by (cons name val), if there is one.  If there is no such
pair, then (cons name val) is added at the end.  Note that the order of
the keys occurring in alist is unchanged (though a new key may be
added).

The guard for a call of put-assoc depends on the test.  In all cases,
the last argument must satisfy alistp.  If the test is eql, then either
the first argument must be suitable for eql (see *note EQLABLEP::) or
the last argument must satisfy eqlable-alistp.  If the test is eq, then
either the first argument must be a symbol or the last argument must
satisfy symbol-alistp.

See *note EQUALITY-VARIANTS:: for a discussion of the relation between
put-assoc and its variants:

     (put-assoc-eq name val alist) is equivalent to (put-assoc name val
     alist :test 'eq);

     (put-assoc-equal name val alist) is equivalent to (put-assoc name
     val alist :test 'equal).


In particular, reasoning about any of these primitives reduces to
reasoning about the function put-assoc-equal.


File: acl2-doc-emacs.info,  Node: PUT-ASSOC-EQ,  Next: PUT-ASSOC-EQL,  Prev: PUT-ASSOC,  Up: ACL2-BUILT-INS

PUT-ASSOC-EQ    See *note PUT-ASSOC::.


File: acl2-doc-emacs.info,  Node: PUT-ASSOC-EQL,  Next: PUT-ASSOC-EQUAL,  Prev: PUT-ASSOC-EQ,  Up: ACL2-BUILT-INS

PUT-ASSOC-EQL    See *note PUT-ASSOC::.


File: acl2-doc-emacs.info,  Node: PUT-ASSOC-EQUAL,  Next: PUTPROP,  Prev: PUT-ASSOC-EQL,  Up: ACL2-BUILT-INS

PUT-ASSOC-EQUAL    See *note PUT-ASSOC::.


File: acl2-doc-emacs.info,  Node: PUTPROP,  Next: QUOTE,  Prev: PUT-ASSOC-EQUAL,  Up: ACL2-BUILT-INS

PUTPROP    update fast property lists

     General form:
     (putprop symbol key value world-alist)

See community book books/misc/getprop.lisp for an example that
illustrates the use of ACL2 utilities getprop and putprop to take
advantage of under-the-hood Lisp (hashed) property lists.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: QUOTE,  Next: R-EQLABLE-ALISTP,  Prev: PUTPROP,  Up: ACL2-BUILT-INS

QUOTE    create a constant

The form (quote x) evaluates to x.  See any Common Lisp documentation.


File: acl2-doc-emacs.info,  Node: R-EQLABLE-ALISTP,  Next: R-SYMBOL-ALISTP,  Prev: QUOTE,  Up: ACL2-BUILT-INS

R-EQLABLE-ALISTP    recognizer for a true list of pairs whose cdrs are suitable for eql

The predicate r-eqlable-alistp tests whether its argument is a
true-listp of consp objects whose cdrs all satisfy eqlablep.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: R-SYMBOL-ALISTP,  Next: RANDOM$,  Prev: R-EQLABLE-ALISTP,  Up: ACL2-BUILT-INS

R-SYMBOL-ALISTP    recognizer for association lists with symbols as values

(R-symbol-alistp x) is true if and only if x is a list of pairs of the
form (cons key val) where val is a symbolp.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: RANDOM$,  Next: RASSOC,  Prev: R-SYMBOL-ALISTP,  Up: ACL2-BUILT-INS

RANDOM$    obtain a random value

     Example:
     (random$ 10 state) ==> (mv 7 <state>)

(Random$ limit state), where limit is a positive integer, returns a
random non-negative integer together with a new state.  Logically, it
simply returns the first element of a list that is a field of the ACL2
state, called the acl2-oracle, together with the new state resulting
from removing that element from that list.  (Except, if that element is
not in range as specified above, then 0 is returned.)  However, random$
actually invokes a Common Lisp function to choose the integer returned.
Quoting from the Common Lisp HyperSpec(TM),
`http://www.lispworks.com/documentation/HyperSpec/Front': "An
approximately uniform choice distribution is used...  each of the
possible results occurs with (approximate) probability 1/limit."

Consider enabling rules natp-random$ and random$-linear if you want to
reason about random$.


File: acl2-doc-emacs.info,  Node: RASSOC,  Next: RASSOC-EQ,  Prev: RANDOM$,  Up: ACL2-BUILT-INS

RASSOC    look up value in association list

     General Forms:
     (rassoc x alist)
     (rassoc x alist :test 'eql)   ; same as above (eql as equality test)
     (rassoc x alist :test 'eq)    ; same, but eq is equality test
     (rassoc x alist :test 'equal) ; same, but equal is equality test

(Rassoc x alist) is the first member of alist whose cdr is x, or nil if
no such member exists.  (rassoc x alist) is thus similar to (assoc x
alist), the difference being that it looks for the first pair in the
given alist whose cdr, rather than car, is eql to x.  See *note
ASSOC::.  The optional keyword, :TEST, has no effect logically, but
provides the test (default eql) used for comparing x with the cdrs of
successive elements of lst.

The guard for a call of rassoc depends on the test.  In all cases, the
second argument must satisfy alistp.  If the test is eql, then either
the first argument must be suitable for eql (see *note EQLABLEP::) or
the second argument must satisfy r-eqlable-alistp.  If the test is eq,
then either the first argument must be a symbol or the second argument
must satisfy r-symbol-alistp.

See *note EQUALITY-VARIANTS:: for a discussion of the relation between
rassoc and its variants:

     (rassoc-eq x lst) is equivalent to (rassoc x lst :test 'eq);

     (rassoc-equal x lst) is equivalent to (rassoc x lst :test 'equal).


In particular, reasoning about any of these primitives reduces to
reasoning about the function rassoc-equal.

Rassoc is defined by Common Lisp.  See any Common Lisp documentation for
more information.


File: acl2-doc-emacs.info,  Node: RASSOC-EQ,  Next: RASSOC-EQUAL,  Prev: RASSOC,  Up: ACL2-BUILT-INS

RASSOC-EQ    See *note RASSOC::.


File: acl2-doc-emacs.info,  Node: RASSOC-EQUAL,  Next: RATIONAL-LISTP,  Prev: RASSOC-EQ,  Up: ACL2-BUILT-INS

RASSOC-EQUAL    See *note RASSOC::.


File: acl2-doc-emacs.info,  Node: RATIONAL-LISTP,  Next: RATIONALP,  Prev: RASSOC-EQUAL,  Up: ACL2-BUILT-INS

RATIONAL-LISTP    recognizer for a true list of rational numbers

The predicate rational-listp tests whether its argument is a true list
of rational numbers.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: RATIONALP,  Next: READ-BYTE$,  Prev: RATIONAL-LISTP,  Up: ACL2-BUILT-INS

RATIONALP    recognizer for rational numbers (ratios and integers)

(rationalp x) is true if and only if x is an rational number.


File: acl2-doc-emacs.info,  Node: READ-BYTE$,  Next: READ-CHAR$,  Prev: RATIONALP,  Up: ACL2-BUILT-INS

READ-BYTE$    See *note IO::.


File: acl2-doc-emacs.info,  Node: READ-CHAR$,  Next: READ-OBJECT,  Prev: READ-BYTE$,  Up: ACL2-BUILT-INS

READ-CHAR$    See *note IO::.


File: acl2-doc-emacs.info,  Node: READ-OBJECT,  Next: READ-RUN-TIME,  Prev: READ-CHAR$,  Up: ACL2-BUILT-INS

READ-OBJECT    See *note IO::.


File: acl2-doc-emacs.info,  Node: READ-RUN-TIME,  Next: REAL/RATIONALP,  Prev: READ-OBJECT,  Up: ACL2-BUILT-INS

READ-RUN-TIME    read elapsed runtime

By default, (read-run-time state) returns (mv runtime state), where
runtime is the elapsed runtime in seconds since the start of the
current ACL2 session and state is the resulting ACL2 state.  But
read-run-time can be made to return elapsed realtime (wall clock time)
instead; see *note GET-INTERNAL-TIME::.

The logical definition probably won't concern many users, but for
completeness, we say a word about it here.  That definition uses the
function read-acl2-oracle, which modifies state by popping the value to
return from its acl2-oracle field.


File: acl2-doc-emacs.info,  Node: REAL/RATIONALP,  Next: REALFIX,  Prev: READ-RUN-TIME,  Up: ACL2-BUILT-INS

REAL/RATIONALP    recognizer for rational numbers (including real number in ACL2(r))

For most ACL2 users, this is a macro abbreviating rationalp.  In
ACL2(r) (see *note REAL::), this macro abbreviates the predicate realp,
which holds for real numbers as well (including rationals).  Most ACL2
users can ignore this macro and use rationalp instead, but many
community books use real/rationalp so that these books will be suitable
for ACL2(r) as well.


File: acl2-doc-emacs.info,  Node: REALFIX,  Next: REALPART,  Prev: REAL/RATIONALP,  Up: ACL2-BUILT-INS

REALFIX    coerce to a real number

Realfix simply returns any real number argument unchanged, returning 0
on a non-real argument.  Also see *note NFIX::, see *note IFIX::, see
*note RFIX::, and see *note FIX:: for analogous functions that coerce
to a natural number, an integer, a rational, and a number, respectively.

Realfix has a guard of t.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: REALPART,  Next: REM,  Prev: REALFIX,  Up: ACL2-BUILT-INS

REALPART    real part of a complex number

Completion Axiom (completion-of-realpart):

     (equal (realpart x)
            (if (acl2-numberp x)
                (realpart x)
              0))

Guard for (realpart x):

     (acl2-numberp x)


File: acl2-doc-emacs.info,  Node: REM,  Next: REMOVE,  Prev: REALPART,  Up: ACL2-BUILT-INS

REM    remainder using truncate

     ACL2 !>(rem 14 3)
     2
     ACL2 !>(rem -14 3)
     -2
     ACL2 !>(rem 14 -3)
     2
     ACL2 !>(rem -14 -3)
     -2
     ACL2 !>(rem -15 -3)
     0
     ACL2 !>

(Rem i j) is that number k for which (* j (truncate i j)) added to k
equals i.

The guard for (rem i j) requires that i and j are rational (real, in
ACL2(r)) numbers and j is non-zero.

Rem is a Common Lisp function.  See any Common Lisp documentation for
more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: REMOVE,  Next: REMOVE-DUPLICATES,  Prev: REM,  Up: ACL2-BUILT-INS

REMOVE    remove all occurrences

     General Forms:
     (remove x lst)
     (remove x lst :test 'eql)   ; same as above (eql as equality test)
     (remove x lst :test 'eq)    ; same, but eq is equality test
     (remove x lst :test 'equal) ; same, but equal is equality test

(Remove x lst) is equal to lst if x is not a member of lst, else is the
result of removing all occurrences of x from lst.  The optional
keyword, :TEST, has no effect logically, but provides the test (default
eql) used for comparing x with successive elements of lst.

Also see *note REMOVE1::.

The guard for a call of remove depends on the test.  In all cases, the
second argument must satisfy true-listp.  If the test is eql, then
either the first argument must be suitable for eql (see *note
EQLABLEP::) or the second argument must satisfy eqlable-listp.  If the
test is eq, then either the first argument must be a symbol or the
second argument must satisfy symbol-listp.

See *note EQUALITY-VARIANTS:: for a discussion of the relation between
remove and its variants:

     (remove-eq x lst) is equivalent to (remove x lst :test 'eq);

     (remove-equal x lst) is equivalent to (remove x lst :test 'equal).


In particular, reasoning about any of these primitives reduces to
reasoning about the function remove-equal.

Remove is defined by Common Lisp.  See any Common Lisp documentation for
more information.


File: acl2-doc-emacs.info,  Node: REMOVE-DUPLICATES,  Next: REMOVE-DUPLICATES-EQ,  Prev: REMOVE,  Up: ACL2-BUILT-INS

REMOVE-DUPLICATES    remove duplicates from a string or a list

     General Forms:
     (remove-duplicates x)
     (remove-duplicates x :test 'eql)   ; same as above (eql as equality test)
     (remove-duplicates x :test 'eq)    ; same, but eq is equality test
     (remove-duplicates x :test 'equal) ; same, but equal is equality test

(Remove-duplicates x) returns the result of deleting duplicate elements
from the beginning of the list or string x.  For example,
(remove-duplicates '(1 2 3 2 4)) is equal to '(1 3 2 4).  The optional
keyword, :TEST, has no effect logically, but provides the test (default
eql) used for comparing x with successive elements of lst.

The guard for a call of remove-duplicates depends on the test.  In all
cases, the argument must satisfy stringp or true-listp.  If the test is
eql, then the argument must satisfy either stringp or eqlable-listp.
If the test is eq, then the argument must satisfy symbol-listp.

The relation between remove-duplicates and its variants is related to
the usual pattern for equality variants; see *note EQUALITY-VARIANTS::.
However, the possibility of a string argument changes the usual pattern
a bit.  As one might expect:

     (remove-duplicates-eq lst) is equivalent to (remove-duplicates lst
     :test 'eq).


However, remove-duplicates-equal is defined without consideration of
strings, for backward compatibility with versions of ACL2 through
Version_4.2.  The macro remove-duplicates-logic has been introduced to
model the behavior of remove-duplicates even on strings; use :pe if you
wish to see its definition.  So we can say the following.

     (remove-duplicates-logic lst) is equivalent to (remove-duplicates
     lst :test 'equal); and

     (remove-duplicates-logic lst) is equal to (remove-duplicates-equal
     lst) when lst is not a string.


In particular, when the argument is not a string, reasoning about any of
these primitives reduces to reasoning about the function
remove-duplicates-equal.

Remove-duplicates is defined by Common Lisp.  See any Common Lisp
documentation for more information.


File: acl2-doc-emacs.info,  Node: REMOVE-DUPLICATES-EQ,  Next: REMOVE-DUPLICATES-EQUAL,  Prev: REMOVE-DUPLICATES,  Up: ACL2-BUILT-INS

REMOVE-DUPLICATES-EQ    See *note REMOVE-DUPLICATES::.


File: acl2-doc-emacs.info,  Node: REMOVE-DUPLICATES-EQUAL,  Next: REMOVE-EQ,  Prev: REMOVE-DUPLICATES-EQ,  Up: ACL2-BUILT-INS

REMOVE-DUPLICATES-EQUAL    See *note REMOVE-DUPLICATES::.


File: acl2-doc-emacs.info,  Node: REMOVE-EQ,  Next: REMOVE-EQUAL,  Prev: REMOVE-DUPLICATES-EQUAL,  Up: ACL2-BUILT-INS

REMOVE-EQ    See *note REMOVE::.


File: acl2-doc-emacs.info,  Node: REMOVE-EQUAL,  Next: REMOVE1,  Prev: REMOVE-EQ,  Up: ACL2-BUILT-INS

REMOVE-EQUAL    See *note REMOVE::.


File: acl2-doc-emacs.info,  Node: REMOVE1,  Next: REMOVE1-EQ,  Prev: REMOVE-EQUAL,  Up: ACL2-BUILT-INS

REMOVE1    remove first occurrences, testing using eql

     General Forms:
     (remove1 x lst)
     (remove1 x lst :test 'eql)   ; same as above (eql as equality test)
     (remove1 x lst :test 'eq)    ; same, but eq is equality test
     (remove1 x lst :test 'equal) ; same, but equal is equality test

(Remove1 x lst) is equal to lst if x is not a member of lst, else is
the result of removing the first occurrences of x from lst.  The
optional keyword, :TEST, has no effect logically, but provides the test
(default eql) used for comparing x with successive elements of lst.

Also see *note REMOVE::.

The guard for a call of remove1 depends on the test.  In all cases, the
second argument must satisfy true-listp.  If the test is eql, then
either the first argument must be suitable for eql (see *note
EQLABLEP::) or the second argument must satisfy eqlable-listp.  If the
test is eq, then either the first argument must be a symbol or the
second argument must satisfy symbol-listp.

See *note EQUALITY-VARIANTS:: for a discussion of the relation between
remove1 and its variants:

     (remove1-eq x lst) is equivalent to (remove1 x lst :test 'eq);

     (remove1-equal x lst) is equivalent to (remove1 x lst :test
     'equal).


In particular, reasoning about any of these primitives reduces to
reasoning about the function remove1-equal.


File: acl2-doc-emacs.info,  Node: REMOVE1-EQ,  Next: REMOVE1-EQUAL,  Prev: REMOVE1,  Up: ACL2-BUILT-INS

REMOVE1-EQ    See *note REMOVE1::.


File: acl2-doc-emacs.info,  Node: REMOVE1-EQUAL,  Next: REST,  Prev: REMOVE1-EQ,  Up: ACL2-BUILT-INS

REMOVE1-EQUAL    See *note REMOVE1::.


File: acl2-doc-emacs.info,  Node: REST,  Next: RETURN-LAST,  Prev: REMOVE1-EQUAL,  Up: ACL2-BUILT-INS

REST    rest (cdr) of the list

In the logic, rest is just a macro for cdr.

Rest is a Common Lisp function.  See any Common Lisp documentation for
more information.


File: acl2-doc-emacs.info,  Node: RETURN-LAST,  Next: REVAPPEND,  Prev: REST,  Up: ACL2-BUILT-INS

RETURN-LAST    return the last argument, perhaps with side effects

Return-last is an ACL2 function that returns its last argument.  It is
used to implement common utilities such as prog2$ and time$.  For most
users, this may already be more than one needs to know about
return-last; for example, ACL2 tends to avoid printing calls of
return-last in its output, printing calls of prog2$ or time$ (or other
such utilities) instead.

If you encounter a call of return-last during a proof, then you may find
it most useful to consider return-last simply as a function defined by
the following equation.

     (equal (return-last x y z) z)

It may also be useful to know that unlike other ACL2 functions,
return-last can take a multiple value as its last argument, in which
case this multiple value is returned.  The following contrived
definition illustrates this point.

     ACL2 !>(defun foo (fn x y z)
              (return-last fn x (mv y z)))

     Since FOO is non-recursive, its admission is trivial.  We observe that
     the type of FOO is described by the theorem
     (AND (CONSP (FOO FN X Y Z)) (TRUE-LISTP (FOO FN X Y Z))).  We used
     primitive type reasoning.

     (FOO * * * *) => (MV * *).

     Summary
     Form:  ( DEFUN FOO ...)
     Rules: ((:FAKE-RUNE-FOR-TYPE-SET NIL))
     Time:  0.01 seconds (prove: 0.00, print: 0.00, other: 0.01)
      FOO
     ACL2 !>(foo 'bar 3 4 5)
     (4 5)
     ACL2 !>(mv-let (a b)
                    (foo 'bar 3 4 5)
                    (cons b a))
     (5 . 4)
     ACL2 !>

Most readers would be well served to avoid reading the rest of this
documentation of return-last.  For reference, however, below we document
it in some detail.  We include some discussion of its evaluation, in
particular its behavior in raw Lisp, because we expect that most who
read further are working with raw Lisp code (and trust tags).

Return-last is an ACL2 function that can arise from macroexpansion of
certain utilities that return their last argument, which may be a
multiple value.  Consider for example the simplest of these, prog2$:

     ACL2 !>:trans1 (prog2$ (cw "Some CW printing...~%") (+ 3 4))
      (RETURN-LAST 'PROGN
                   (CW "Some CW printing...~%")
                   (+ 3 4))
     ACL2 !>

Notice that a call of prog2$ macroexpands to a call of return-last in
which the first argument is (quote progn).  Although return-last is a
function in the ACL2 world, it is implemented "under the hood" as a
macro in raw Lisp, as the following log (continuing the example above)
illustrates.

     ACL2 !>:q

     Exiting the ACL2 read-eval-print loop.  To re-enter, execute (LP).
     ? [RAW LISP] (macroexpand-1 '(RETURN-LAST 'PROGN
                                                (CW "Some CW printing...~%")
                                                (+ 3 4)))
     (PROGN (LET ((*AOKP* T)) (CW "SOME CW PRINTING...~%")) (+ 3 4))
     T
     ? [RAW LISP]

Thus, the original prog2$ call generates a corresponding call of progn
in raw Lisp, which in turn causes evaluation of each argument and
returns whatever is returned by evaluation of the last (second)
argument.

(Remark for those who use defattach.  The binding of *aokp* to t is
always included for the second argument as shown except when the first
argument is of the form (QUOTE M) where M is a macro, or (less
important) when the first argument is a symbol or a cons whose car is
QUOTE.  This binding allows ACL2 to use attachments in the second
argument of return-last (hence, in the first argument of prog2$), even
in contexts such as proofs in which attachments are normally not
allowed.  Those who use the experimental HONS version of ACL2 (see
*note HONS-AND-MEMOIZATION::) will see an additional binding in the
above single-step macroexpansion, which allows the storing of memoized
results even when that would otherwise be prevented because of the use
of attachments.)

In general, a form (return-last (quote F) X Y) macroexpands to (F X Y),
where F is defined in raw Lisp to return its last argument.  The case
that F is progn is a bit misleading, because it is so simple.  More
commonly, macroexpansion produces a call of a macro defined in raw Lisp
that may produce side effects.  Consider for example the ACL2 utility
with-guard-checking, which is intended to change the guard-checking
mode to the indicated value (see *note WITH-GUARD-CHECKING::).

     ACL2 !>(with-guard-checking :none (car 3)) ; no guard violation
     NIL
     ACL2 !>:trans1 (with-guard-checking :none (car 3))
      (WITH-GUARD-CHECKING1 (CHK-WITH-GUARD-CHECKING-ARG :NONE)
                            (CAR 3))
     ACL2 !>:trans1 (WITH-GUARD-CHECKING1 (CHK-WITH-GUARD-CHECKING-ARG :NONE)
                                          (CAR 3))
      (RETURN-LAST 'WITH-GUARD-CHECKING1-RAW
                   (CHK-WITH-GUARD-CHECKING-ARG :NONE)
                   (CAR 3))
     ACL2 !>:q

     Exiting the ACL2 read-eval-print loop.  To re-enter, execute (LP).
     ? [RAW LISP] (macroexpand-1
                   '(RETURN-LAST 'WITH-GUARD-CHECKING1-RAW
                                  (CHK-WITH-GUARD-CHECKING-ARG :NONE)
                                  (CAR 3)))
     (WITH-GUARD-CHECKING1-RAW (CHK-WITH-GUARD-CHECKING-ARG :NONE) (CAR 3))
     T
     ? [RAW LISP] (pprint
                   (macroexpand-1
                    '(WITH-GUARD-CHECKING1-RAW
                      (CHK-WITH-GUARD-CHECKING-ARG :NONE)
                      (CAR 3))))

     (LET ((ACL2_GLOBAL_ACL2::GUARD-CHECKING-ON
            (CHK-WITH-GUARD-CHECKING-ARG :NONE)))
       (DECLARE (SPECIAL ACL2_GLOBAL_ACL2::GUARD-CHECKING-ON))
       (CAR 3))
     ? [RAW LISP]

The above raw Lisp code binds the state global variable
guard-checking-on to :none, as chk-with-guard-checking-arg is just the
identity function except for causing a hard error for an illegal input.

The intended use of return-last is that the second argument is evaluated
first in a normal manner, and then the third argument is evaluated in an
environment that may depend on the value of the second argument.  (For
example, the macro with-prover-time-limit macroexpands to a call of
return-last with a first argument of 'WITH-PROVER-TIME-LIMIT1-RAW, a
second argument that evaluates to a numeric time limit, and a third
argument that is evaluated in an environment where the theorem prover
is restricted to avoid running longer than that time limit.)  Although
this intended usage model is not strictly enforced, it is useful to
keep in mind in the following description of how calls of return-last
are handled by the ACL2 evaluator.

When a form is submitted in the top-level loop, it is handled by ACL2's
custom evaluator.  That evaluator is specified to respect the semantics
of the expression supplied to it: briefly put, if an expression E
evaluates to a value V, then the equality (equal E (quote V)) should be
a theorem.  Notice that this specification does not discuss the
side-effects that may occur when evaluating a call of return-last, so
we discuss that now.  Suppose that the ACL2 evaluator encounters the
call (return-last 'fn expr1 expr2).  First it evaluates expr1.  If this
evaluation succeeds without error, then it constructs an expression of
the form (fn *x* ev-form), where *x* is a Lisp variable bound to the
result of evaluating expr1 and ev-form is a call of the evaluator for
expr2.  (Those who want implementation details are invited to look at
function ev-rec-return-last in ACL2 source file translate.lisp.)  There
are exceptions if fn is progn, ec-call1-raw, with-guard-checking1-raw,
or mbe1-raw, but the main idea is the same: do a reasonable job
emulating the behavior of a raw-Lisp call of return-last.

The following log shows how a time$ call can generate a call of the
evaluator for the last argument of return-last (arguent expr2, above).
We use :trans1 to show single-step macroexpansions, which indicate how
a call of time$ expands to a call of return-last.  The implementation
actually binds the Lisp variable *RETURN-LAST-ARG3* to expr2 before
calling the ACL2 evaluator, ev-rec.

     ACL2 !>:trans1 (time$ (+ 3 4))
      (TIME$1 (LIST 0 NIL NIL NIL NIL)
              (+ 3 4))
     ACL2 !>:trans1 (TIME$1 (LIST 0 NIL NIL NIL NIL)
                            (+ 3 4))
      (RETURN-LAST 'TIME$1-RAW
                   (LIST 0 NIL NIL NIL NIL)
                   (+ 3 4))
     ACL2 !>(time$ (+ 3 4))
     ; (EV-REC *RETURN-LAST-ARG3* ...) took
     ; 0.00 seconds realtime, 0.00 seconds runtime
     ; (1,120 bytes allocated).
     7
     ACL2 !>

We now show how things can go wrong in other than the "intended use"
case described above.  In the example below, the macro mac-raw is
operating directly on the syntactic representation of its first
argument, which it obtains of course as the second argument of a
return-last call.  Again this "intended use" of return-last requires
that argument to be evaluated and then only its result is relevant; its
syntax is not supposed to matter.  We emphasize that only top-level
evaluation depends on this "intended use"; once evaluation is passed to
Lisp, the issue disappears.  We illustrate below how to use the
top-level utility to avoid this issue; see *note TOP-LEVEL::.  The
example uses the utility defmacro-last to "install" special handling of
the raw-Lisp macro mac-raw by return-last; later below we discuss
defmacro-last.

     ACL2 !>(defttag t)

     TTAG NOTE: Adding ttag :T from the top level loop.
      T
     ACL2 !>(progn!
              (set-raw-mode t)
              (defmacro mac-raw (x y)
                `(progn (print (quote ,(cadr x)))
                        (terpri) ; newline
                        ,y)))

     Summary
     Form:  ( PROGN! (SET-RAW-MODE T) ...)
     Rules: NIL
     Time:  0.01 seconds (prove: 0.00, print: 0.00, other: 0.01)
      NIL
     ACL2 !>(defmacro-last mac)
     [[ ... output omitted ... ]]
      RETURN-LAST-TABLE
     ACL2 !>(return-last 'mac-raw '3 nil)

     ***********************************************
     ************ ABORTING from raw Lisp ***********
     Error:  Fault during read of memory address #x120000300006
     ***********************************************

     If you didn't cause an explicit interrupt (Control-C),
     then the root cause may be call of a :program mode
     function that has the wrong guard specified, or even no
     guard specified (i.e., an implicit guard of t).
     See :DOC guards.

     To enable breaks into the debugger (also see :DOC acl2-customization):
     (SET-DEBUGGER-ENABLE T)
     ACL2 !>(top-level (return-last 'mac-raw '3 nil))

     3
     NIL
     ACL2 !>

We next describe how to extend the behavior of return-last.  This
requires an active trust tag (see *note DEFTTAG::), and is accomplished
by extending a table provided by ACL2, see *note RETURN-LAST-TABLE::.
Rather than using table events directly for this purpose, it is
probably more convenient to use a macro, defmacro-last.  We describe
the community book books/misc/profiling.lisp in order to illustrate how
this works.  The events in that book include the following, which are
described below.

     (defttag :profiling)

     (progn!
      (set-raw-mode t)
      (load (concatenate 'string (cbd) "profiling-raw.lsp")))

     (defmacro-last with-profiling)

The first event introduces a trust tag.  The second loads a file into
raw Lisp that defines a macro, with-profiling-raw, which can do
profiling for the form to be evaluated.  The third introduces an ACL2
macro with-profiling, whose calls expand into calls of the form
(return-last (quote with-profiling-raw) & &).  The third event also
extends return-last-table so that these calls will expand in raw Lisp
to calls of with-profiling-raw.

The example above illustrates the following methodology for introducing
a macro that returns its last argument but produces useful side-effects
with raw Lisp code.

     (1) Introduce a trust tag (see *note DEFTTAG::).

     (2) Using progn!, load into raw Lisp a file defining a macro,
     RAW-NAME, that takes two arguments, returning its last (second)
     argument but using the first argument to produce desired side
     effects during evaluation of that last argument.

     (3) Evaluate the form (defmacro-last NAME :raw RAW-NAME).  This
     will introduce NAME as an ACL2 macro that expands to a
     corresponding call of RAW-NAME (see (2) above) in raw Lisp.  The
     specification of keyword value of :raw as RAW-NAME may be omitted
     if RAW-NAME is the result of modifying the symbol NAME by
     suffixing the string "-RAW" to the symbol-name of NAME.

WARNING: Not every use of return-last can be soundly evaluated outside a
function body.  The reason is that ACL2's evaluator, ev-rec, recurs
through terms that are presented in the top-level loop, and handles
return-last calls in a special manner: basically, the call of ev-rec on
the form (return-last 'mac-raw x y) leads to evaluation of a macro call
of the form (mac-raw *return-last-arg2* (ev-rec ...)), where
*return-last-arg2* is a global variable bound to the result of
evaluating x with ev-rec.  Consider the following example.

     (defttag t)
     (set-raw-mode-on state)
     (defmacro mac-raw (str y) ; print message is an atom
      `(let ((result (consp ,y))
             (str ,str))
         (or result
             (prog2$ (fmx ,str ',y)
                     nil))))
     (set-raw-mode-off state)
     (defmacro-last mac)
     ; Horrible error:
     (mac "Not a cons: ~x0~%" 17)
     ; Works, but probably many would consider it awkward to use top-level:
     (top-level (mac "Not a cons: ~x0~%" 17))

In such cases we suggest supplying keyword :top-level-ok nil to the call
of defmacro-last, for example:

     (defmacro-last mac :top-level-ok nil)

Then any attempt to call mac at the top level, as opposed to inside a
function body, will cause a clean error before evaluation begins.

It is useful to explore what is done by defmacro-last.

     ACL2 !>:trans1 (defmacro-last with-profiling)
      (PROGN (DEFMACRO WITH-PROFILING (X Y)
                       (LIST 'RETURN-LAST
                             (LIST 'QUOTE 'WITH-PROFILING-RAW)
                             X Y))
             (TABLE RETURN-LAST-TABLE 'WITH-PROFILING-RAW
                    'WITH-PROFILING))
     ACL2 !>:trans1 (with-profiling '(assoc-eq fgetprop rewrite) (mini-proveall))
      (RETURN-LAST 'WITH-PROFILING-RAW
                   '(ASSOC-EQ FGETPROP REWRITE)
                   (MINI-PROVEALL))
     ACL2 !>:q

     Exiting the ACL2 read-eval-print loop.  To re-enter, execute (LP).
     ? [RAW LISP] (macroexpand-1
                   '(RETURN-LAST 'WITH-PROFILING-RAW
                                  '(ASSOC-EQ FGETPROP REWRITE)
                                  (MINI-PROVEALL)))
     (WITH-PROFILING-RAW '(ASSOC-EQ FGETPROP REWRITE) (MINI-PROVEALL))
     T
     ? [RAW LISP]

To understand the macro with-profiling-raw you could look at the
community book loaded above: books/misc/profiling-raw.lsp.

We mentioned above that ACL2 tends to print calls of prog2$ or time$
(or other such utilities) instead of calls of return-last.  Here we
elaborate that point.  ACL2's `untranslate' utility treats (return-last
(quote F) X Y) as (G X Y) if F corresponds to the symbol G in
return-last-table.  However, it is generally rare to encounter such a
term during a proof, since calls of return-last are generally expanded
away early during a proof.

Calls of return-last that occur in code -- forms submitted in the
top-level ACL2 loop, and definition bodies other than those marked as
non-executable (see *note DEFUN-NX::) -- have the following
restriction: if the first argument is of the form (quote F), then F
must be an entry in return-last-table.  There are however four
exceptions: the following symbols are considered to be keys of
return-last-table even if they are no longer associated with non-nil
values, say because of a table event with keyword :clear.

     * progn, associated with prog2$
     * mbe1-raw, associated with mbe1, a version of mbe
     * ec-call1-raw, associated with ec-call1 (a variant of ec-call)
     * with-guard-checking1-raw, associated with with-guard-checking1 (a
     variant of with-guard-checking)


Note that because of its special status, it is illegal to trace
return-last.

We conclude by warning that as a user, you take responsibility for not
compromising the soundness or error handling of ACL2 when you define a
macro in raw Lisp and especially when you install it as a key of
return-last-table, either directly or (more likely) using
defmacro-last.  In particular, be sure that you are defining a macro of
two arguments that always returns the value of its last argument,
returning the complete multiple value if that last argument evaluates
to a multiple value.

The following is correct, and illustrates care taken to return multiple
values.

     :q
     (defmacro my-time1-raw (val form)
       (declare (ignore val))
       `(let  ((start-time (get-internal-run-time))
               (result (multiple-value-list ,form))
               (end-time (get-internal-run-time)))
          (format t "Total time: ~s~%"
                  (float (/ (- end-time start-time)
                            internal-time-units-per-second)))
          (values-list result)))
     (lp)
     (defttag t)
     (defmacro-last my-time1)
     (defmacro my-time (form)
       `(my-time1 nil ,form))

Then for example:

     ACL2 !>(my-time (equal (make-list 1000000) (make-list 1000000)))
     Total time: 0.12
     T
     ACL2 !>

But if instead we provide the following more naive implementation, of
the above raw Lisp macro, the above evaluation can produce an error,
for example if the host Lisp is CCL.

     (defmacro my-time1-raw (val form)
         (declare (ignore val))
         `(let  ((start-time (get-internal-run-time))
                 (result ,form)
                 (end-time (get-internal-run-time)))
            (format t "Total time: ~s~%"
                    (float (/ (- end-time start-time)
                              internal-time-units-per-second)))
            result)) ; WRONG -- need multiple values returned!

Here is a second, similar example.  This time we'll start with the
error; can you spot it?

     (defttag t)
     (progn!
      (set-raw-mode t)
      (defmacro foo-raw (x y)
        `(prog1
             ,y
           (cw "Message showing argument 1: ~x0~%" ,x))))
     (defmacro-last foo)

We then can wind up with a hard Lisp error:

     ACL2 !>(foo 3 (mv 4 5))
     Message showing argument 1: 3

     ***********************************************
     ************ ABORTING from raw Lisp ***********
     Error:  value NIL is not of the expected type REAL.
     ***********************************************

     If you didn't cause an explicit interrupt (Control-C),
     then the root cause may be call of a :program mode
     function that has the wrong guard specified, or even no
     guard specified (i.e., an implicit guard of t).
     See :DOC guards.

     To enable breaks into the debugger (also see :DOC acl2-customization):
     (SET-DEBUGGER-ENABLE T)
     ACL2 !>

Here is a corrected version of the above macro.  The point here is that
prog1 returns a single value, while our-multiple-value-prog1 returns
all the values that are returned by its first argument.

     (progn!
      (set-raw-mode t)
      (defmacro foo-raw (x y)
        `(our-multiple-value-prog1 ;; better
          ,y
          (cw "Message showing argument 1: ~x0~%" ,x))))

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: REVAPPEND,  Next: REVERSE,  Prev: RETURN-LAST,  Up: ACL2-BUILT-INS

REVAPPEND    concatentate the reverse of one list to another

(Revappend x y) concatenates the reverse of the list x to y, which is
also typically a list.

The following theorem characterizes this English description.

     (equal (revappend x y)
            (append (reverse x) y))

Hint:  This lemma follows immediately from the definition of reverse
and the following lemma.

     (defthm revappend-append
       (equal (append (revappend x y) z)
              (revappend x (append y z))))

The guard for (revappend x y) requires that x is a true list.

Revappend is defined in Common Lisp.  See any Common Lisp documentation
for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: REVERSE,  Next: RFIX,  Prev: REVAPPEND,  Up: ACL2-BUILT-INS

REVERSE    reverse a list or string

(Reverse x) is the result of reversing the order of the elements of the
list or string x.

The guard for reverse requires that its argument is a true list or a
string.

Reverse is defined in Common Lisp.  See any Common Lisp documentation
for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: RFIX,  Next: ROUND,  Prev: REVERSE,  Up: ACL2-BUILT-INS

RFIX    coerce to a rational number

Rfix simply returns any rational number argument unchanged, returning 0
on a non-rational argument.  Also see *note NFIX::, see *note IFIX::,
see *note REALFIX::, and see *note FIX:: for analogous functions that
coerce to a natural number, an integer, a real, and a number,
respectively.

Rfix has a guard of t.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: ROUND,  Next: SEARCH,  Prev: RFIX,  Up: ACL2-BUILT-INS

ROUND    division returning an integer by rounding off

     Example Forms:
     ACL2 !>(round 14 3)
     5
     ACL2 !>(round -14 3)
     -5
     ACL2 !>(round 14 -3)
     -5
     ACL2 !>(round -14 -3)
     5
     ACL2 !>(round 13 3)
     4
     ACL2 !>(round -13 3)
     -4
     ACL2 !>(round 13 -3)
     -4
     ACL2 !>(round -13 -3)
     4
     ACL2 !>(round -15 -3)
     5
     ACL2 !>(round 15 -2)
     -8

(Round i j) is the result of taking the quotient of i and j and
rounding off to the nearest integer.  When the quotient is exactly
halfway between consecutive integers, it rounds to the even one.

The guard for (round i j) requires that i and j are rational (real, in
ACL2(r)) numbers and j is non-zero.

Round is a Common Lisp function.  See any Common Lisp documentation for
more information.  However, note that unlike Common Lisp, the ACL2 round
function returns only a single value,

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: SEARCH,  Next: SECOND,  Prev: ROUND,  Up: ACL2-BUILT-INS

SEARCH    search for a string or list in another string or list

     Example Forms:
     (search "cd" "Cdabcdefcde")                   ; = 4, index of first match
     (search "cd" "Cdabcdefcde" :test 'equal)      ; same as above
     (search "cd" "Cdabcdefcde" :from-end t)       ; = 8, index of last match
     (search "cd" "Cdabcdefcde" :start1 1)         ; = 1
     (search "cd" "Cdabcdefcde" :start2 5)         ; = 8
     (search "cd" "Cdabcdefcde" :test 'char-equal) ; = 0 (case-insensitive)
     (search "ac" "Cdabcdefcde")                   ; = nil
     (search '(a b) '(9 8 a b 7 6))                    ; = 2

     General Form:
     (search seq1 seq2 &key from-end test start1 start2 end1 end2)

Search indicates whether one string or list occurs as a (contiguous)
subsequence of another string or list, respectively.  It returns nil if
no such match is found; otherwise it returns the (zero-based) index of
the first match by default, but a non-nil value of keyword argument
:from-end causes it to return the last match.  The :test is equal by
default.  The other legal value for :test is char-equal, which can be
given only for two strings, in which case the match is case-insensitive.
Finally, values of :start1 and :end1 for the first sequence, and of
:start2 and :end2 for the second sequence, bound the portion of the
respective sequence used for deciding on a match, though the index
returned is always an index into the second sequence as a whole.

The guard for calls of search is given by a function, search-fn-guard,
which has the following requirements.

     o The two arguments much both satisfy true-listp or else must both
     be strings, which must consist of standard characters (see *note
     STANDARD-CHAR-P::) if the :test is char-equal.

     o The :test must evaluate to one of the symbols equal or
     char-equal, where the latter is only allowed if the (first) two
     arguments are strings.

     o The values of :start1, :start2, :end1, and :end2 must all be
     natural numbers, where if omitted they default to 0, 0, the length
     len1 of the first argument, and the length len2 of the second
     argument, respectively.

     o If start1 is the value of :start1, defaulting as described just
     above, and similarly for the other start and end keywords and for
     lengths len1 and len2 as described just above, then: start1 <=
     end1 <= len1 and start2 <= end2 <= len2.

Search is a Common Lisp function (actually, a macro in ACL2).  See any
Common Lisp documentation for more information.


File: acl2-doc-emacs.info,  Node: SECOND,  Next: SET-DIFFERENCE$,  Prev: SEARCH,  Up: ACL2-BUILT-INS

SECOND    second member of the list

See any Common Lisp documentation for details.


File: acl2-doc-emacs.info,  Node: SET-DIFFERENCE$,  Next: SET-DIFFERENCE-EQ,  Prev: SECOND,  Up: ACL2-BUILT-INS

SET-DIFFERENCE$    elements of one list that are not elements of another

     General Forms:
     (set-difference$ l1 l2)
     (set-difference$ l1 l2 :test 'eql)   ; same as above (eql as equality test)
     (set-difference$ l1 l2 :test 'eq)    ; same, but eq is equality test
     (set-difference$ l1 l2 :test 'equal) ; same, but equal is equality test

(Set-difference$ l1 l2) equals a list that contains the members of l1
that are not members of l2.  More precisely, the resulting list is the
same as one gets by deleting the members of l2 from l1, leaving the
remaining elements in the same order as in l1.  The optional keyword,
:TEST, has no effect logically, but provides the test (default eql)
used for comparing members of the two lists.

The guard for a call of set-difference$ depends on the test.  In all
cases, both arguments must satisfy true-listp.  If the test is eql,
then one of the arguments must satisfy eqlable-listp.  If the test is
eq, then one of the arguments must satisfy symbol-listp.

See *note EQUALITY-VARIANTS:: for a discussion of the relation between
set-difference$ and its variants:

     (set-difference-eq l1 l2) is equivalent to (set-difference$ l1 l2
     :test 'eq);

     (set-difference-equal l1 l2) is equivalent to (set-difference$ l1
     l2 :test 'equal).


In particular, reasoning about any of these primitives reduces to
reasoning about the function set-difference-equal.

Set-difference$ is similar to the Common Lisp primitive set-difference.
However, Common Lisp does not specify the order of elements in the
result of a call of set-difference.


File: acl2-doc-emacs.info,  Node: SET-DIFFERENCE-EQ,  Next: SET-DIFFERENCE-EQUAL,  Prev: SET-DIFFERENCE$,  Up: ACL2-BUILT-INS

SET-DIFFERENCE-EQ    See *note SET-DIFFERENCE$::.


File: acl2-doc-emacs.info,  Node: SET-DIFFERENCE-EQUAL,  Next: SETENV$,  Prev: SET-DIFFERENCE-EQ,  Up: ACL2-BUILT-INS

SET-DIFFERENCE-EQUAL    See *note SET-DIFFERENCE$::.


File: acl2-doc-emacs.info,  Node: SETENV$,  Next: SEVENTH,  Prev: SET-DIFFERENCE-EQUAL,  Up: ACL2-BUILT-INS

SETENV$    set an environment variable

(Setenv$ str val), where str and val are strings, sets the environment
variable str to have value val, for subsequent read by getenv$ (see
*note GETENV$::), and returns nil.  Or, if this operation is not
implemented for the host Common Lisp, an error will occur.

     Example:
     (setenv$ "FOO" "BAR")

It may be surprising that setenv$ returns nil; indeed, it neither takes
nor returns the ACL2 state.  The reason is that getenv$ takes
responsibility for trafficking in state; it is defined in the logic
using the function read-acl2-oracle, which (again, in the logic) does
modify state, by popping an entry from its acl2-oracle field.  getenv$.


File: acl2-doc-emacs.info,  Node: SEVENTH,  Next: SIGNED-BYTE-P,  Prev: SETENV$,  Up: ACL2-BUILT-INS

SEVENTH    seventh member of the list

See any Common Lisp documentation for details.


File: acl2-doc-emacs.info,  Node: SIGNED-BYTE-P,  Next: SIGNUM,  Prev: SEVENTH,  Up: ACL2-BUILT-INS

SIGNED-BYTE-P    recognizer for signed integers that fit in a specified bit width

(Signed-byte-p bits x) is T when bits is a positive integer and x is a
signed integer whose 2's complement representation fits in a bit-width
of bits, i.e., -2^(bits-1) <= x < 2^(bits-1).

Note that a type-spec of (signed-byte i) for a variable x in a
function's declare form translates to a guard condition of
(signed-byte-p i x).

The guard for signed-byte-p is T.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: SIGNUM,  Next: SIXTH,  Prev: SIGNED-BYTE-P,  Up: ACL2-BUILT-INS

SIGNUM    indicator for positive, negative, or zero

(Signum x) is 0 if x is 0, -1 if x is negative, and is 1 otherwise.

The guard for signum requires its argument to be rational (real, in
ACL2(r)) number.

Signum is a Common Lisp function.  See any Common Lisp documentation
for more information.

From "Common Lisp the Language" page 206, we see a definition of signum
in terms of abs.  As explained elsewhere (see *note ABS::), the guard
for abs requires its argument to be a rational (real, in ACL2(r))
number; hence, we make the same restriction for signum.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: SIXTH,  Next: STANDARD-CHAR-LISTP,  Prev: SIGNUM,  Up: ACL2-BUILT-INS

SIXTH    sixth member of the list

See any Common Lisp documentation for details.


File: acl2-doc-emacs.info,  Node: STANDARD-CHAR-LISTP,  Next: STANDARD-CHAR-P,  Prev: SIXTH,  Up: ACL2-BUILT-INS

STANDARD-CHAR-LISTP    recognizer for a true list of standard characters

(standard-char-listp x) is true if and only if x is a null-terminated
list all of whose members are standard characters.  See *note
STANDARD-CHAR-P::.

Standard-char-listp has a guard of t.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STANDARD-CHAR-P,  Next: STANDARD-CO,  Prev: STANDARD-CHAR-LISTP,  Up: ACL2-BUILT-INS

STANDARD-CHAR-P    recognizer for standard characters

(Standard-char-p x) is true if and only if x is a "standard" character,
i.e., a member of the list *standard-chars*.  This list includes
#\Newline and #\Space characters, as well as the usual punctuation and
alphanumeric characters.

Standard-char-p has a guard requiring its argument to be a character.

Standard-char-p is a Common Lisp function.  See any Common Lisp
documentation for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STANDARD-CO,  Next: STANDARD-OI,  Prev: STANDARD-CHAR-P,  Up: ACL2-BUILT-INS

STANDARD-CO    the character output channel to which ld prints

Standard-co is an ld special (see *note LD::).  The accessor is
(standard-co state) and the updater is (set-standard-co val state).
Standard-co must be an open character output channel.  It is to this
channel that ld prints the prompt, the form to be evaluated, and the
results.  The event commands such as defun, defthm, etc., which print
extensive commentary do not print to standard-co but rather to a
different channel, proofs-co, so that you may redirect this commentary
while still interacting via standard-co.  See *note PROOFS-CO::.

"Standard-co" stands for "standard character output." The initial value
of standard-co is the same as the value of *standard-co* (see *note
*STANDARD-CO*::).


File: acl2-doc-emacs.info,  Node: STANDARD-OI,  Next: STANDARD-STRING-ALISTP,  Prev: STANDARD-CO,  Up: ACL2-BUILT-INS

STANDARD-OI    the standard object input "channel"

Standard-oi is an ld special (see *note LD::).  The accessor is
(standard-oi state) and the updater is (set-standard-oi val state).
Standard-oi must be an open object input channel, a true list of
objects, or a list of objects whose last cdr is an open object input
channel.  It is from this source that ld takes the input forms to
process.  When ld is called, if the value specified for standard-oi is
a string or a list of objects whose last cdr is a string, then ld
treats the string as a file name and opens an object input channel from
that file, where the connected book directory (see *note CBD::) is used
to resolve relative pathnames.  The channel opened by ld is closed by
ld upon termination.

"Standard-oi" stands for "standard object input." The read-eval-print
loop in ld reads the objects in standard-oi and treats them as forms to
be evaluated.  The initial value of standard-oi is the same as the
value of *standard-oi* (see *note *STANDARD-OI*::).


File: acl2-doc-emacs.info,  Node: STANDARD-STRING-ALISTP,  Next: STATE-GLOBAL-LET*,  Prev: STANDARD-OI,  Up: ACL2-BUILT-INS

STANDARD-STRING-ALISTP    recognizer for association lists with standard strings as keys

(Standard-string-alistp x) is true if and only if x is a list of pairs
of the form (cons key val) where key is a string all of whose
characters are standard (see *note STANDARD-CHAR-P::).

Standard-string-alistp has a guard of t.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STATE-GLOBAL-LET*,  Next: STRING,  Prev: STANDARD-STRING-ALISTP,  Up: ACL2-BUILT-INS

STATE-GLOBAL-LET*    bind state global variables

See *note PROGRAMMING-WITH-STATE:: for requisite background on
programming with the ACL2 state.

     Example Forms:
     (state-global-let*
      ((inhibit-output-lst *valid-output-names*))
      (thm (equal x x)))

     (state-global-let*
      ((fmt-hard-right-margin 1000 set-fmt-hard-right-margin)
       (fmt-soft-right-margin 1000 set-fmt-soft-right-margin))
      (mini-proveall))

     General Form:
     (state-global-let* ((var1 form1) ; or (var1 form1 set-var1)
                         ...
                         (vark formk) ; or (vark formk set-vark)
                        )
                        body)

where: each vari is a variable; each formi is an expression whose value
is a single ordinary object (i.e. not multiple values, and not state or
any other stobj); set-vari, if supplied, is a function with signature
((set-vari * state) => state); and body is an expression that evaluates
to an error triple (see *note ERROR-TRIPLES::).  Each formi is
evaluated in order, starting with form1, and with each such binding the
state global variable vari is bound to the value of formi, sequentially
in the style of let*.  More precisely, then meaning of this form is to
set (in order) the global values of the indicated state global
variables vari to the values of formi using f-put-global, execute body,
restore the vari to their previous values (but see the discussion of
setters below), and return the triple produced by body (with its state
as modified by the restoration).  The restoration is guaranteed even in
the face of aborts.  The "bound" variables may initially be unbound in
state and restoration means to make them unbound again.

Still referring to the General Form above, let old-vali be the value of
state global variable vari at the time vari is about to be assigned the
value of formi.  If set-vari is not supplied, then as suggested above,
the following form is evaluated at the conclusion of the evaluation of
the state-global-let* form, whether or not an error has occurred:
(f-put-global 'vari 'old-vali state).  However, if set-vari is
supplied, then instead the form evaluated will be (set-vari 'old-vali
state).  This capability is particularly useful if vari is untouchable
(see *note PUSH-UNTOUCHABLE::), since the above call of f-put-global is
illegal.

Note that the scope of the bindings of a state-global-let* form is the
body of that form.  This may seem obvious, but to drive the point home,
let's consider the following example (see *note SET-PRINT-BASE:: and
see *note SET-PRINT-RADIX::).

     ACL2 !>(state-global-let* ((print-base 16 set-print-base)
                                (print-radix t set-print-radix))
                               (mv nil 10 state))
      10
     ACL2 !>

Why wasn't the result printed as #xA?  The reason is that the result was
printed after evaluation of the entire form had completed.  If you want
to see #xA, do the printing in the scope of the bindings, for example as
follows.

     ACL2 !>(state-global-let* ((print-base 16 set-print-base)
                                (print-radix t set-print-radix))
                               (pprogn (fms "~x0~%"
                                            (list (cons #0 10))
                                            *standard-co* state nil)
                                       (mv nil 10 state)))

     #xA
      10
     ACL2 !>


File: acl2-doc-emacs.info,  Node: STRING,  Next: STRING-APPEND,  Prev: STATE-GLOBAL-LET*,  Up: ACL2-BUILT-INS

STRING    coerce to a string

(String x) coerces x to a string.  If x is already a string, then it is
returned unchanged; if x is a symbol, then its symbol-name is returned;
and if x is a character, the corresponding one-character string is
returned.

The guard for string requires its argument to be a string, a symbol, or
a character.

String is a Common Lisp function.  See any Common Lisp documentation
for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STRING-APPEND,  Next: STRING-DOWNCASE,  Prev: STRING,  Up: ACL2-BUILT-INS

STRING-APPEND    concatenate two strings

String-append takes two arguments, which are both strings (if the guard
is to be met), and returns a string obtained by concatenating together
the characters in the first string followed by those in the second.
Also see *note CONCATENATE::, noting that the macro call

     (concatenate 'string str1 str2).

expands to the call

     (string-append str1 str2).

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STRING-DOWNCASE,  Next: STRING-EQUAL,  Prev: STRING-APPEND,  Up: ACL2-BUILT-INS

STRING-DOWNCASE    in a given string, turn upper-case characters into lower-case

For a string x, (string-downcase x) is the result of applying
char-downcase to each character in x.

The guard for string-downcase requires its argument to be a string
containing only standard characters.

String-downcase is a Common Lisp function.  See any Common Lisp
documentation for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STRING-EQUAL,  Next: STRING-LISTP,  Prev: STRING-DOWNCASE,  Up: ACL2-BUILT-INS

STRING-EQUAL    string equality without regard to case

For strings str1 and str2, (string-equal str1 str2) is true if and only
str1 and str2 are the same except perhaps for the cases of their
characters.

The guard on string-equal requires that its arguments are strings
consisting of standard characters (see *note STANDARD-CHAR-LISTP::).

String-equal is a Common Lisp function.  See any Common Lisp
documentation for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STRING-LISTP,  Next: STRING-UPCASE,  Prev: STRING-EQUAL,  Up: ACL2-BUILT-INS

STRING-LISTP    recognizer for a true list of strings

The predicate string-listp tests whether its argument is a true-listp
of strings.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STRING-UPCASE,  Next: STRING<,  Prev: STRING-LISTP,  Up: ACL2-BUILT-INS

STRING-UPCASE    in a given string, turn lower-case characters into upper-case

For a string x, (string-upcase x) is the result of applying char-upcase
to each character in x.

The guard for string-upcase requires its argument to be a string
containing only standard characters.

String-upcase is a Common Lisp function.  See any Common Lisp
documentation for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STRING<,  Next: STRING<=,  Prev: STRING-UPCASE,  Up: ACL2-BUILT-INS

STRING<    less-than test for strings

(String< str1 str2) is non-nil if and only if the string str1 precedes
the string str2 lexicographically, where character inequalities are
tested using char<.  When non-nil, (string< str1 str2) is the first
position (zero-based) at which the strings differ.  Here are some
examples.

     ACL2 !>(string< "abcd" "abu")
     2
     ACL2 !>(string< "abcd" "Abu")
     NIL
     ACL2 !>(string< "abc" "abcde")
     3
     ACL2 !>(string< "abcde" "abc")
     NIL

The guard for string< specifies that its arguments are strings.

String< is a Common Lisp function.  See any Common Lisp documentation
for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STRING<=,  Next: STRING>,  Prev: STRING<,  Up: ACL2-BUILT-INS

STRING<=    less-than-or-equal test for strings

(String<= str1 str2) is non-nil if and only if the string str1 precedes
the string str2 lexicographically or the strings are equal.  When
non-nil, (string<= str1 str2) is the first position (zero-based) at
which the strings differ, if they differ, and otherwise is their common
length.  See *note STRING<::.

The guard for string<= specifies that its arguments are strings.

String<= is a Common Lisp function.  See any Common Lisp documentation
for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STRING>,  Next: STRING>=,  Prev: STRING<=,  Up: ACL2-BUILT-INS

STRING>    greater-than test for strings

(String> str1 str2) is non-nil if and only if str2 precedes str1
lexicographically.  When non-nil, (string> str1 str2) is the first
position (zero-based) at which the strings differ.  See *note STRING<::.

String> is a Common Lisp function.  See any Common Lisp documentation
for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STRING>=,  Next: STRINGP,  Prev: STRING>,  Up: ACL2-BUILT-INS

STRING>=    less-than-or-equal test for strings

(String>= str1 str2) is non-nil if and only if the string str2 precedes
the string str1 lexicographically or the strings are equal.  When
non-nil, (string>= str1 str2) is the first position (zero-based) at
which the strings differ, if they differ, and otherwise is their common
length.  See *note STRING>::.

The guard for string>= specifies that its arguments are strings.

String>= is a Common Lisp function.  See any Common Lisp documentation
for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STRINGP,  Next: STRIP-CARS,  Prev: STRING>=,  Up: ACL2-BUILT-INS

STRINGP    recognizer for strings

(stringp x) is true if and only if x is a string.


File: acl2-doc-emacs.info,  Node: STRIP-CARS,  Next: STRIP-CDRS,  Prev: STRINGP,  Up: ACL2-BUILT-INS

STRIP-CARS    collect up all first components of pairs in a list

(strip-cars x) is the list obtained by walking through the list x and
collecting up all first components (cars).  This function is
implemented in a tail-recursive way, despite its logical definition.

(strip-cars x) has a guard of (alistp x).

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: STRIP-CDRS,  Next: SUBLIS,  Prev: STRIP-CARS,  Up: ACL2-BUILT-INS

STRIP-CDRS    collect up all second components of pairs in a list

(strip-cdrs x) has a guard of (alistp x), and returns the list obtained
by walking through the list x and collecting up all second components
(cdrs).  This function is implemented in a tail-recursive way, despite
its logical definition.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: SUBLIS,  Next: SUBSEQ,  Prev: STRIP-CDRS,  Up: ACL2-BUILT-INS

SUBLIS    substitute an alist into a tree

(Sublis alist tree) is obtained by replacing every leaf of tree with
the result of looking that leaf up in the association list alist.
However, a leaf is left unchanged if it is not found as a key in alist.

Leaves are looked up using the function assoc.  The guard for (sublis
alist tree) requires (eqlable-alistp alist).  This guard ensures that
the guard for assoc will be met for each lookup generated by sublis.

Sublis is defined in Common Lisp.  See any Common Lisp documentation
for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: SUBSEQ,  Next: SUBSETP,  Prev: SUBLIS,  Up: ACL2-BUILT-INS

SUBSEQ    subsequence of a string or list

For any natural numbers start and end, where start <= end <= (length
seq), (subseq seq start end) is the subsequence of seq from index start
up to, but not including, index end.  End may be nil, which which case
it is treated as though it is (length seq), i.e., we obtain the
subsequence of seq from index start all the way to the end.

The guard for (subseq seq start end) is that seq is a true list or a
string, start and end are integers (except, end may be nil, in which
case it is treated as (length seq) for the rest of this discussion),
and 0 <= start <= end <= (length seq).

Subseq is a Common Lisp function.  See any Common Lisp documentation
for more information.  Note:  In Common Lisp the third argument of
subseq is optional, but in ACL2 it is required, though it may be nil as
explained above.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: SUBSETP,  Next: SUBSETP-EQ,  Prev: SUBSEQ,  Up: ACL2-BUILT-INS

SUBSETP    test if every member of one list is a member of the other

     General Forms:
     (subsetp x y)
     (subsetp x y :test 'eql)   ; same as above (eql as equality test)
     (subsetp x y :test 'eq)    ; same, but eq is equality test
     (subsetp x y :test 'equal) ; same, but equal is equality test

(Subsetp x y) is true if and only if every member of the list x is a
member of the list y.  The optional keyword, :TEST, has no effect
logically, but provides the test (default eql) used for comparing
members of the two lists.

The guard for a call of subsetp depends on the test.  In all cases,
both arguments must satisfy true-listp.  If the test is eql, then one
of the arguments must satisfy eqlable-listp.  If the test is eq, then
one of the arguments must satisfy symbol-listp.

See *note EQUALITY-VARIANTS:: for a discussion of the relation between
subsetp and its variants:

     (subsetp-eq x lst) is equivalent to (subsetp x lst :test 'eq);

     (subsetp-equal x lst) is equivalent to (subsetp x lst :test
     'equal).


In particular, reasoning about any of these primitives reduces to
reasoning about the function subsetp-equal.

Subsetp is defined by Common Lisp.  See any Common Lisp documentation
for more information.


File: acl2-doc-emacs.info,  Node: SUBSETP-EQ,  Next: SUBSETP-EQUAL,  Prev: SUBSETP,  Up: ACL2-BUILT-INS

SUBSETP-EQ    See *note SUBSETP::.


File: acl2-doc-emacs.info,  Node: SUBSETP-EQUAL,  Next: SUBST,  Prev: SUBSETP-EQ,  Up: ACL2-BUILT-INS

SUBSETP-EQUAL    See *note SUBSETP::.


File: acl2-doc-emacs.info,  Node: SUBST,  Next: SUBSTITUTE,  Prev: SUBSETP-EQUAL,  Up: ACL2-BUILT-INS

SUBST    a single substitution into a tree

(Subst new old tree) is obtained by substituting new for every
occurence of old in the given tree.

Equality to old is determined using the function eql.  The guard for
(subst new old tree) requires (eqlablep old), which ensures that the
guard for eql will be met for each comparison generated by subst.

Subst is defined in Common Lisp.  See any Common Lisp documentation for
more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: SUBSTITUTE,  Next: SYMBOL-<,  Prev: SUBST,  Up: ACL2-BUILT-INS

SUBSTITUTE    substitute into a string or a list, using eql as test

(Substitute new old seq) is the result of replacing each occurrence of
old in seq, which is a list or a string, with new.

The guard for substitute requires that either seq is a string and new
is a character, or else:  seq is a true-listp such that either all of
its members are eqlablep or old is eqlablep.

Substitute is a Common Lisp function.  See any Common Lisp
documentation for more information.  Since ACL2 functions cannot take
keyword arguments (though macros can), the test used in substitute is
eql.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: SYMBOL-<,  Next: SYMBOL-ALISTP,  Prev: SUBSTITUTE,  Up: ACL2-BUILT-INS

SYMBOL-<    less-than test for symbols

(symbol-< x y) is non-nil if and only if either the symbol-name of the
symbol x lexicographially precedes the symbol-name of the symbol y (in
the sense of string<) or else the symbol-names are equal and the
symbol-package-name of x lexicographically precedes that of y (in the
same sense).  So for example, (symbol-< 'abcd 'abce) and (symbol-<
'acl2::abcd 'foo::abce) are true.

The guard for symbol specifies that its arguments are symbols.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: SYMBOL-ALISTP,  Next: SYMBOL-LISTP,  Prev: SYMBOL-<,  Up: ACL2-BUILT-INS

SYMBOL-ALISTP    recognizer for association lists with symbols as keys

(Symbol-alistp x) is true if and only if x is a list of pairs of the
form (cons key val) where key is a symbolp.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: SYMBOL-LISTP,  Next: SYMBOL-NAME,  Prev: SYMBOL-ALISTP,  Up: ACL2-BUILT-INS

SYMBOL-LISTP    recognizer for a true list of symbols

The predicate symbol-listp tests whether its argument is a true list of
symbols.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: SYMBOL-NAME,  Next: SYMBOL-PACKAGE-NAME,  Prev: SYMBOL-LISTP,  Up: ACL2-BUILT-INS

SYMBOL-NAME    the name of a symbol (a string)

Completion Axiom (completion-of-symbol-name):

     (equal (symbol-name x)
            (if (symbolp x)
                (symbol-name x)
              ""))

Guard for (symbol-name x):

     (symbolp x)


File: acl2-doc-emacs.info,  Node: SYMBOL-PACKAGE-NAME,  Next: SYMBOLP,  Prev: SYMBOL-NAME,  Up: ACL2-BUILT-INS

SYMBOL-PACKAGE-NAME    the name of the package of a symbol (a string)

WARNING: While symbol-package-name behaves properly on all ACL2 objects,
it may give surprising results when called in raw Lisp.  For more
details see *note PKG-IMPORTS::, in particular the discussion there of
the "COMMON-LISP" package.

Completion Axiom (completion-of-symbol-package-name):

     (equal (symbol-package-name x)
            (if (symbolp x)
                (symbol-package-name x)
              ""))

Guard for (symbol-package-name x):

     (symbolp x)

Note: Symbol-package-name may diverge from the name of the symbol's
package in raw Lisp, in the case that this package is the main Lisp
package.  For example, in GCL (symbol-package-name 'car) evaluates to
"COMMON-LISP" even though the actual package name for the symbol, car,
is "LISP".


File: acl2-doc-emacs.info,  Node: SYMBOLP,  Next: SYS-CALL,  Prev: SYMBOL-PACKAGE-NAME,  Up: ACL2-BUILT-INS

SYMBOLP    recognizer for symbols

(symbolp x) is true if and only if x is a symbol.


File: acl2-doc-emacs.info,  Node: SYS-CALL,  Next: SYS-CALL+,  Prev: SYMBOLP,  Up: ACL2-BUILT-INS

SYS-CALL    make a system call to the host operating system

     Example Forms:
     (sys-call "cp" '("foo.lisp" "foo-copied.lisp"))
     (prog2$ (sys-call "cp" '("foo.lisp" "foo-copied.lisp"))
             (sys-call-status state))

The first argument of sys-call is a command for the host operating
system, and the second argument is a list of strings that are the
arguments for that command.  In GCL and perhaps some other lisps, you
can put the arguments with the command; but this is not the case, for
example, in Allegro CL running on Linux.

For a related utility, see *note SYS-CALL+::.

The use of prog2$ above is optional, but illustrates a typical sort of
use when one wishes to get the return status.  See *note
SYS-CALL-STATUS::.

     General Form:
     (sys-call cmd args)

This function logically returns nil.  However, it makes the indicated
call to the host operating system, as described above, using a function
supplied "under the hood" by the underlying Lisp system.  On occasions
where one wishes to obtain the numeric status returned by the host
operating system (or more precisely, by the Lisp function under the
hood that passes the system call to the host operating system), one may
do so; see *note SYS-CALL-STATUS::.  The status value is the value
returned by that Lisp function, which may well be the same numeric
value returned by the host operating system for the underlying system
call.

Note that sys-call does not touch the ACL2 state; however,
sys-call-status updates the acl2-oracle field of the state.

Be careful if you use sys-call!  It can be used for example to overwrite
files, or worse!  We view a use of sys-call as a call to the operating
system that is made outside ACL2.  The following example from Bob Boyer
shows how to use sys-call to execute, in effect, arbitrary Lisp forms.
ACL2 provides a "trust tag" mechanism that requires execution of a
defttag form before you can use sys-call; see *note DEFTTAG::.  (Note:
The setting of the raw Lisp variable *features* below is just to
illustrate that any such mischief is possible.  Normally *features* is
a list with more than a few elements.)

     % cat foo
     print *0x85d2064=0x838E920
     detach
     q
     % acl2
     ... boilerplate deleted
     ACL2 !>(sys-call "gdb -p $PPID -w < foo >& /dev/null " nil)
     NIL
     ACL2 !>:q

     Exiting the ACL2 read-eval-print loop.  To re-enter, execute (LP).
     ACL2>*features*

     (:AKCL-SET-MV)

     ACL2>

Finally, we make a comment about output redirection, which also applies
to other related features that one may expect of a shell.  Sys-call
does not directly support output redirection.  If you want to run a
program, P, and redirect its output, one option is to create a wrapper
script, W to call instead.  Thus W might be a shell script containing
the line:

     P $* >& foo.out

For a different, more direct solution, see *note SYS-CALL+::.


File: acl2-doc-emacs.info,  Node: SYS-CALL+,  Next: SYS-CALL-STATUS,  Prev: SYS-CALL,  Up: ACL2-BUILT-INS

SYS-CALL+    make a system call to the host OS, returning status and output

     Example Form:
     ; The following returns (mv nil s state), where s is the standard output
     ; from the command: ls -l ./
     (sys-call+ "ls" '("-l" "./") state)

     General Form:
     (sys-call+ cmd args state)

where cmd is a command to the host operating system and args is a list
of strings.  Also see *note SYS-CALL::; but there are two differences
between sys-call and sys-call+.  First, the latter takes an extra
argument, state.  Second, while sys-call returns nil, sys-call+ returns
three values: a so-called error triple (see *note ERROR-TRIPLES::), (mv
erp val state).  While execution returns values as described just
below, further below we explain the logical return values.  In the
following, please keep in mind that the exact behavior depends on the
platform; the description is only a guide.  For example, on some
platforms erp might always be nil, even if in the error case, and val
might or might not include error output.  (For details, look at the
ACL2 source code for function system-call+, whose output is converted
by replacing an erp of nil by 0.)

     Erp is either nil or a non-zero integer.  Normally, nil indicates
     that the command ran without error, and otherwise erp is the exit
     status.

     Val is a string, typically the output generated by the call of cmd.

     State is an ACL2 state.

While the description above pertains to the values returned by executing
sys-call+, the logical values are as follows.  For a discussion of the
acl2-oracle field of an ACL2 state, see *note STATE::.

     Erp is the first element of the acl2-oracle of the input state if
     that element is a nonzero integer, and otherwise is nil.

     Val is the second element of the acl2-oracle of the input state if
     it is a string, else the empty string, "".

     State is the result of popping the acl2-oracle field twice from the
     input state.

Note that unlike sys-call, a call of sys-call+ has no effect on
subsequent calls of sys-call-status.

As is the case for sys-call, a trust tag is required to call sys-call+.
For discussion of this and more, see *note SYS-CALL::.


File: acl2-doc-emacs.info,  Node: SYS-CALL-STATUS,  Next: TAKE,  Prev: SYS-CALL+,  Up: ACL2-BUILT-INS

SYS-CALL-STATUS    exit status from the preceding system call

This function returns two values, (mv status state).  The first is the
status resulting from the most recent invocation of function sys-call;
see *note SYS-CALL::.  The second is the ACL2 state object, which is
also the input to this function.

The function sys-call makes a system call to the host operating system
using a function supplied "under the hood" by the underlying Lisp
system.  The status value is the value returned by that Lisp function,
which may well be the numeric value returned by the host operating
system for the underlying system call.  For more information, see *note
SYS-CALL::.


File: acl2-doc-emacs.info,  Node: TAKE,  Next: TENTH,  Prev: SYS-CALL-STATUS,  Up: ACL2-BUILT-INS

TAKE    initial segment of a list

For any natural number n not exceeding the length of l, (take n l)
collects the first n elements of the list l.

The following is a theorem (though it takes some effort, including
lemmas, to get ACL2 to prove it):

     (equal (length (take n l)) (nfix n))

If n is an integer greater than the length of l, then take pads the
list with the appropriate number of nil elements.  Thus, the following
is also a theorem.

     (implies (and (integerp n)
                   (true-listp l)
                   (<= (length l) n))
              (equal (take n l)
                     (append l (make-list (- n (length l))))))

For related functions, see *note NTHCDR:: and see *note BUTLAST::.

The guard for (take n l) is that n is a nonnegative integer and l is a
true list.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: TENTH,  Next: TERM-ORDER,  Prev: TAKE,  Up: ACL2-BUILT-INS

TENTH    tenth member of the list

See any Common Lisp documentation for details.


File: acl2-doc-emacs.info,  Node: TERM-ORDER,  Next: THE,  Prev: TENTH,  Up: ACL2-BUILT-INS

TERM-ORDER    the ordering relation on terms used by ACL2

ACL2 must occasionally choose which of two terms is syntactically
smaller.  The need for such a choice arises, for example, when using
equality hypotheses in conjectures (the smaller term is substituted for
the larger elsewhere in the formula), in stopping loops in permutative
rewrite rules (see *note LOOP-STOPPER::), and in choosing the order in
which to try to cancel the addends in linear arithmetic inequalities.
When this notion of syntactic size is needed, ACL2 uses "term order."
Popularly speaking, term order is just a lexicographic ordering on
terms.  But the situation is actually more complicated.

We define term order only with respect to terms in translated form.
See *note TRANS::.  Constants are viewed as built up by
_pseudo-function_ applications, as described at the end of this
documentation.

Term1 comes before term2 in the term order iff

     (a) the number of variable occurrences in term1 is less than that
     in term2, or

     (b) the numbers of variable occurrences in the two terms are equal
     but the number of function applications in term1 is less than that
     in term2, or

     (c) the numbers of variable occurrences in the two terms are
     equal, the numbers of functions applications in the two terms are
     equal, but pseudo-function application count for term1 is less
     than that for term2, or

     (d) the numbers of variable occurrences in the two terms are
     equal, the numbers of functions applications in the two terms are
     equal, the pseudo-function application counts for the two terms
     are equal, and term1 comes before term2 in a lexicographic
     ordering, lexorder, based their structure as Lisp objects: see
     *note LEXORDER::.

The function term-order, when applied to the translations of two ACL2
terms, returns t iff the first is "less than or equal" to the second in
the term order.

By "number of variable occurrences" we do not mean "number of distinct
variables" but "number of times a variable symbol is mentioned."  (Cons
x x) has two variable occurrences, not one.  Thus, perhaps
counterintuitively, a large term that contains only one variable
occurrence, e.g., (standard-char-p (car (reverse x))) comes before
(cons x x) in the term order.

Since constants contain no variable occurrences and non-constant
expressions must contain at least one variable occurrence, constants
come before non-constants in the term order, no matter how large the
constants.  For example, the list constant

     '(monday tuesday wednesday thursday friday)

comes before x in the term order.  Because term order is involved in the
control of permutative rewrite rules and used to shift smaller terms to
the left, a set of permutative rules designed to allow the permutation
of any two tips in a tree representing the nested application of some
function will always move the constants into the left-most tips.  Thus,

     (+ x 3 (car (reverse klst)) (dx i j)) ,

which in translated form is

     (binary-+ x
               (binary-+ '3
                         (binary-+ (dx i j)
                                   (car (reverse klst))))),

will be permuted under the built-in commutativity rules to

     (binary-+ '3
               (binary-+ x
                         (binary-+ (car (reverse klst))
                                   (dx i j))))

or

     (+ 3 x (car (reverse klst)) (dx i j)).

Two terms with the same numbers of variable occurrences and function
applications and the same pseudo-function application count are ordered
by lexicographic means, based on their structures.  See *note
LEXORDER::.  Thus, if two terms (member ...) and (reverse ...) contain
the same numbers of variable occurrences and function applications, and
no quoted constants, then the member term is first in the term order
because member comes before reverse in the term order (which is here
reduced to alphabetic ordering).

It remains to discuss the notion of _pseudo-function application count_.

Clearly, two constants are ordered using cases (c) and (d) of term
order, since they each contain 0 variable occurrences and no function
calls.  This raises the question "How many function applications are in
a constant?"  Because we regard the number of function applications as
a more fundamental measure of the size of a constant than lexicographic
considerations, we decided that for the purposes of term order,
constants would be seen as being built by primitive constructor
functions.  These constructor functions are not actually defined in
ACL2 but merely imagined for the purposes of term order.  We here use
suggestive names for these imagined functions, ignoring entirely the
prior use of these names within ACL2.  The imagined applications of
these functions are what we refer to as _pseudo-function_ applications.

The constant function z constructs 0.  Positive integers are
constructed from (z) by the successor function, s.  Thus 2 is (s (s
(z))) and contains three function applications.  100 contains one
hundred and one applications.  Negative integers are constructed from
their positive counterparts by -.  Thus, -2 is (- (s (s (z)))) and has
four applications.  Ratios are constructed by the dyadic function /.
Thus, -1/2 is

     (/ (- (s (z))) (s (s (z))))

and contains seven applications.  Complex rationals are similarly
constructed from rationals.  All character objects are considered
primitive and are constructed by constant functions of the same name.
Thus #\a and #\b both contain one application.  Strings are built from
the empty string, (o) by the "string-cons" function written cs.  Thus
"AB" is (cs (#\a) (cs (#\b) (o))) and contains five applications.
Symbols are obtained from strings by "packing" the symbol-name with the
unary function p.  Thus 'ab is

     (p (cs (#\a) (cs (#\b) (o))))

and has six applications.  Note that packages are here ignored and thus
'acl2::ab and 'my-package::ab each contain just six applications.
Finally, conses are built with cons, as usual.  So '(1 . 2) is (cons '1
'2) and contains six applications, since '1 contains two and '2
contains three.  This, for better or worse, answers the question "How
many function applications are in a constant?"

Finally, when we refer to the "pseudo-function application count", we
mean the number of pseudo-function applications as described above,
except that we bound this number by the constant
(fn-count-evg-max-val).  (This bound is important for efficiency, so
that constants that are very large cons structures do not cause
significant slowdown as ACL2 attempts to walk through them while
computing their pseudo-function application count.)


File: acl2-doc-emacs.info,  Node: THE,  Next: THIRD,  Prev: TERM-ORDER,  Up: ACL2-BUILT-INS

THE    run-time type check

(The typ val) checks that val satisfies the type specification typ (see
*note TYPE-SPEC::).  An error is caused if the check fails, and
otherwise, val is the value of this expression.  Here are some examples.

     (the integer 3)       ; returns 3
     (the (integer 0 6) 3) ; returns 3
     (the (integer 0 6) 7) ; causes an error (see below for exception)

See *note TYPE-SPEC:: for a discussion of the legal type specifications.

There is an exception to the rule that failure of the type-check causes
an error: there is no error when guard-checking has been turned off with
:set-guard-checking :NONE or (with-guard-checking :NONE ...).  See
*note SET-GUARD-CHECKING:: and see *note WITH-GUARD-CHECKING::.

The following remark is for those who verify guards for their functions
(see *note GUARD:: and see *note VERIFY-GUARDS::).  We remark that a
call of (the TYPE EXPR) in the body of a function definition generates
a guard proof obligation that the type, TYPE, holds for the value of the
expression, EXPR.  Consider the following example.

     (defun f (x)
       (declare (xargs :guard (p1 x)))
       (if (p2 x)
           (the integer x)
         17))

The guard proof obligation generated for the THE expression above is as
follows.

     (implies (and (p1 x) (p2 x))
              (let ((var x)) (integerp var)))

THE is defined in Common Lisp.  See any Common Lisp documentation for
more information.


File: acl2-doc-emacs.info,  Node: THIRD,  Next: TIME$,  Prev: THE,  Up: ACL2-BUILT-INS

THIRD    third member of the list

See any Common Lisp documentation for details.


File: acl2-doc-emacs.info,  Node: TIME$,  Next: TRUE-LIST-LISTP,  Prev: THIRD,  Up: ACL2-BUILT-INS

TIME$    time an evaluation

Semantically, (time$ x ...) equals x.  However, its evaluation may
write timing output to the trace output (which is usually the
terminal), as explained further below.

     Examples:

     ; Basic examples:

     (time$ (foo 3 4))
     (time$ (mini-proveall))
     (defun bar (x) (time$ (f x)))

     ; Custom examples, which use a custom timing message rather than a built-in
     ; message from Lisp:

     ; Report only if real time is at least 1/2 second (two equivalent forms).
     (time$ (foo) :mintime 1/2)
     (time$ (foo) :real-mintime 1/2)

     ; Report only if allocation is at least 1000 bytes (and if the Lisp supports
     ; :minalloc).
     (time$ (foo) :minalloc 1000)

     ; Report only if real time is at least 1/2 second and (if the Lisp supports
     ; :minalloc) allocation is at least 931 bytes.
     (time$ (foo) :real-mintime 1/2 :minalloc 931)

     ; Print "Hello Moon, Goodbye World" instead of any timing data.
     (time$ (foo)
            :msg "Hello ~s0, ~s1 World."
            :args (list "Moon" "Goodbye"))

     ; Print default custom timing message (same as omitting :mintime 0):
     (time$ (foo)
            :mintime 0)

     ; Print supplied custom timing message.
     (let ((bar ...))
       (time$ (foo)
              :msg "The execution of ~xf took ~st seconds of real ~
                    time and ~sc seconds of run time (cpu time), and ~
                    allocated ~sa bytes.  In an unrelated note, bar ~
                    currently has the value ~x0.~%"
              :args (list bar)))

     General Forms:
     (time$ form)
     (time$ form ; arguments below are optional
            :real-mintime  <rational number of seconds>
            :run-mintime   <rational number of seconds>
            :minalloc      <number of bytes>
            :msg           <fmt string>
            :args          <list of arguments for msg>
            )
     ; Note: :real-mintime can be replaced by :mintime

where form is processed as usual except that the host Common Lisp times
its evaluation.

The simplest form is (time$ x), which will call the time utility in the
underlying Lisp, and will print a small default message.  If you want to
see a message printed by the host Lisp, use (time$ x :mintime nil)
instead, which may provide detailed, implementation-specific data such
as the amounts of time spent in user and system mode, the gc time, the
number of page faults encountered, and so on.  Of you can create a
custom message, configured using the :msg and :args parameters.  Time$
can also be made to report timing information only conditionally: the
:real-mintime (or equivalently, :mintime), :run-mintime, and :minalloc
arguments can be used to avoid reporting timing information for
computations that take a small amount of time (perhaps as might be
expected in ordinary cases), but to draw the user's attention to
computations that take longer or allocate more memory than expected.

We next document the keyword arguments in some detail.

     Keyword arguments :real-mintime (or :mintime) and :run-mintime can
     be used to specify a minimum time threshold for time reporting.
     That is, no timing information will be printed if the execution of
     form takes less than the specified number of seconds of real
     (total) time or run (cpu) time, respectively.  Note that rational
     numbers like 1/2 may be used to specify a fractional amount of
     seconds.  It is an error to specify both :real-mintime and its
     synonym, :mintime.

     Keyword argument :minalloc is not supported on all Lisps.  When it
     is not supported, it is ignored.  But on supported Lisps,
     :minalloc can be used to specify a minimum memory allocation
     threshold.  If form results in fewer than this many bytes being
     allocated, then no timing information will be reported.

     Keyword argument :msg, when provided, should be a string accepted
     by the fmt family of functions (see *note FMT::), and it may refer
     to the elements of :args by their positions, just as for cw (see
     *note CW::).

The following directives allow you to report timing information using
the :msg string.  The examples at the top of this documentation topic
illustrate the use of these directives.

     ~xf -- the form that was executed

     ~sa -- the amount of memory allocated, in bytes (in supported
     Lisps)

     ~st -- the real time taken, in seconds

     ~sc -- the run time (cpu time) taken, in seconds


We turn now to an example that illustrates how time$ can be called in
function bodies.  Consider the following definition of the Fibonacci
function, followed by the definition of a function that times k calls of
this function.

     (defun fib (n)
       (if (zp n)
           1
         (if (= n 1)
             1
           (+ (fib (- n 1))
              (fib (- n 2))))))

     (defun time-fib (k)
       (if (zp k)
           nil
         (prog2$
          (time$ (fib k)
                 :mintime 1/2
                 :msg "(fib ~x0) took ~st seconds, ~sa bytes allocated.~%"
                 :args (list k))
          (time-fib (1- k)))))

The following log shows a sample execution of the function defined just
above.

     ACL2 !>(time-fib 36)
     (fib 36) took 3.19 seconds, 1280 bytes allocated.
     (fib 35) took 1.97 seconds, 1280 bytes allocated.
     (fib 34) took 1.21 seconds, 1280 bytes allocated.
     (fib 33) took 0.75 seconds, 1280 bytes allocated.
     NIL
     ACL2 !>

Notes:

(1) Common Lisp specifies that the time utility prints to "trace
output", and time$ follows this convention.  Thus, if you have opened a
trace file (see *note OPEN-TRACE-FILE::), then you can expect to find
the time$ output there.

(2) Unless the :msg argument is supplied, an explicit call of time$ in
the top-level loop will show that the form being timed is a call of the
ACL2 evaluator function ev-rec.  This is normal; the curious are
invited, at their own risk, to see *note RETURN-LAST:: for an
explanation.


File: acl2-doc-emacs.info,  Node: TRUE-LIST-LISTP,  Next: TRUE-LISTP,  Prev: TIME$,  Up: ACL2-BUILT-INS

TRUE-LIST-LISTP    recognizer for true (proper) lists of true lists

True-list-listp is the function that checks whether its argument is a
list that ends in, or equals, nil, and furthermore, all of its elements
have that property.  Also see *note TRUE-LISTP::.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: TRUE-LISTP,  Next: TRUNCATE,  Prev: TRUE-LIST-LISTP,  Up: ACL2-BUILT-INS

TRUE-LISTP    recognizer for proper (null-terminated) lists

True-listp is the function that checks whether its argument is a list
that ends in, or equals, nil.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: TRUNCATE,  Next: UNARY--,  Prev: TRUE-LISTP,  Up: ACL2-BUILT-INS

TRUNCATE    division returning an integer by truncating toward 0

     Example Forms:
     ACL2 !>(truncate 14 3)
     4
     ACL2 !>(truncate -14 3)
     -4
     ACL2 !>(truncate 14 -3)
     -4
     ACL2 !>(truncate -14 -3)
     4
     ACL2 !>(truncate -15 -3)
     5
     ACL2 !>(truncate 10/4 3/4)
     3

(Truncate i j) is the result of taking the quotient of i and j and
dropping the fraction.  For example, the quotient of -14 by 3 is -4
2/3, so dropping the fraction 2/3, we obtain a result for (truncate -14
3) of -4.

The guard for (truncate i j) requires that i and j are rational (real,
in ACL2(r)) numbers and j is non-zero.

Truncate is a Common Lisp function.  However, note that unlike Common
Lisp, the ACL2 truncate function returns only a single value,  Also see
*note NONNEGATIVE-INTEGER-QUOTIENT::, which is appropriate for integers
and may simplify reasoning, unless a suitable arithmetic library is
loaded, but be less efficient for evaluation on concrete objects.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: UNARY--,  Next: UNARY-/,  Prev: TRUNCATE,  Up: ACL2-BUILT-INS

UNARY-    arithmetic negation function

Completion Axiom (completion-of-unary-minus):

     (equal (unary-- x)
            (if (acl2-numberp x)
                (unary-- x)
              0))

Guard for (unary- x):

     (acl2-numberp x)

Notice that like all arithmetic functions, unary- treats non-numeric
inputs as 0.

Calls of the macro - on one argument expand to calls of unary-; see
*note -::.


File: acl2-doc-emacs.info,  Node: UNARY-/,  Next: UNION$,  Prev: UNARY--,  Up: ACL2-BUILT-INS

UNARY-/    reciprocal function

Completion Axiom (completion-of-unary-/):

     (equal (unary-/ x)
            (if (and (acl2-numberp x)
                     (not (equal x 0)))
                (unary-/ x)
              0))

Guard for (unary-/ x):

     (and (acl2-numberp x)
          (not (equal x 0)))

Notice that like all arithmetic functions, unary-/ treats non-numeric
inputs as 0.

Calls of the macro / on one argument expand to calls of unary-/; see
*note /::.


File: acl2-doc-emacs.info,  Node: UNION$,  Next: UNION-EQ,  Prev: UNARY-/,  Up: ACL2-BUILT-INS

UNION$    elements of one list that are not elements of another

     General Forms:
     (union$ l1 l2 ... lk)
     (union$ l1 l2 ... lk :test 'eql) ; same as above
     (union$ l1 l2 ... lk :test 'eq)    ; same, but eq is equality test
     (union$ l1 l2 ... lk :test 'equal) ; same, but equal is equality test

(Union$ x y) equals a list that contains both the members of x and the
members of y.  More precisely, the resulting list is the same as one
would get by first deleting the members of y from x, and then
concatenating the result to the front of y.  The optional keyword,
:TEST, has no effect logically, but provides the test (default eql)
used for comparing members of the two lists.

Union$ need not take exactly two arguments: (union$) is nil, (union$ x)
is x, (union$ x y z ... :test test) is (union$ x (union$ y z ... :test
test) :test test), and if :TEST is not supplied, then (union$ x y z
...) is (union$ x (union$ y z ...)).  For the discussion below we
restrict ourselves, then, to the cases (union$ x y) and (union$ x y
:test test).

The guard for a call of union$ (in the two cases just above) depends on
the test.  In all cases, both arguments must satisfy true-listp.  If
the test is eql, then one of the arguments must satisfy eqlable-listp.
If the test is eq, then one of the arguments must satisfy symbol-listp.

See *note EQUALITY-VARIANTS:: for a discussion of the relation between
union$ and its variants:

     (union-eq x lst) is equivalent to (union$ x lst :test 'eq);

     (union-equal x lst) is equivalent to (union$ x lst :test 'equal).


In particular, reasoning about any of these primitives reduces to
reasoning about the function union-equal.

Note that union-eq can take any number of arguments, in analogy to
union$; indeed, (union-eq ...) expands to (union$ ... :test 'eq).
However, union-equal is a function, not a macro, and takes exactly two
arguments.

Union$ is similar to the Common Lisp primitive union.  However, Common
Lisp does not specify the order of elements in the result of a call of
union.


File: acl2-doc-emacs.info,  Node: UNION-EQ,  Next: UNION-EQUAL,  Prev: UNION$,  Up: ACL2-BUILT-INS

UNION-EQ    See *note UNION$::.


File: acl2-doc-emacs.info,  Node: UNION-EQUAL,  Next: UNSIGNED-BYTE-P,  Prev: UNION-EQ,  Up: ACL2-BUILT-INS

UNION-EQUAL    See *note UNION$::.


File: acl2-doc-emacs.info,  Node: UNSIGNED-BYTE-P,  Next: UNTRANSLATE,  Prev: UNION-EQUAL,  Up: ACL2-BUILT-INS

UNSIGNED-BYTE-P    recognizer for natural numbers that fit in a specified bit width

(Unsigned-byte-p bits x) is T when bits is a positive integer and x is
a nonnegative integer that fits into a bit-width of bits, i.e., 0 <= x
< 2^bits.

Note that a type-spec of (unsigned-byte i) for a variable x in a
function's declare form translates to a guard condition of
(unsigned-byte-p i x).

The guard for unsigned-byte-p is T.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: UNTRANSLATE,  Next: UPDATE-NTH,  Prev: UNSIGNED-BYTE-P,  Up: ACL2-BUILT-INS

UNTRANSLATE    See *note USER-DEFINED-FUNCTIONS-TABLE::.


File: acl2-doc-emacs.info,  Node: UPDATE-NTH,  Next: UPPER-CASE-P,  Prev: UNTRANSLATE,  Up: ACL2-BUILT-INS

UPDATE-NTH    modify a list by putting the given value at the given position

(Update-nth key val l) returns a list that is the same as the list l,
except that the value at the 0-based position key (a natural number) is
val.

If key is an integer at least as large as the length of l, then l will
be padded with the appropriate number of nil elements, as illustrated
by the following example.

     ACL2 !>(update-nth 8 'z '(a b c d e))
     (A B C D E NIL NIL NIL Z)

We have the following theorem.

     (implies (and (true-listp l)
                   (integerp key)
                   (<= 0 key))
              (equal (length (update-nth key val l))
                     (if (< key (length l))
                         (length l)
                       (+ 1 key))))

The guard of update-nth requires that its first (position) argument is
a natural number and its last (list) argument is a true list.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: UPPER-CASE-P,  Next: WITH-LIVE-STATE,  Prev: UPDATE-NTH,  Up: ACL2-BUILT-INS

UPPER-CASE-P    recognizer for upper case characters

(Upper-case-p x) is true if and only if x is an upper case character,
i.e., a member of the list #\A, #\B, ..., #\Z.

The guard for upper-case-p requires its argument to be a standard
character (see *note STANDARD-CHAR-P::).

Upper-case-p is a Common Lisp function.  See any Common Lisp
documentation for more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: WITH-LIVE-STATE,  Next: WRITE-BYTE$,  Prev: UPPER-CASE-P,  Up: ACL2-BUILT-INS

WITH-LIVE-STATE    allow a reference to state in raw Lisp

The macro with-live-state is an advanced feature that very few users
will need (basically, only system hackers).  Indeed, it is untouchable;
see *note REMOVE-UNTOUCHABLE:: for how to enable calling
with-live-state in the ACL2 loop.

     Example Form:
     (with-live-state (assign y 3))

     General form:
     (with-live-state form)

where form is an arbitrary form with a free reference to the variable
state.

Logically, (with-live-state FORM) macroexpands to FORM.  However, in
raw Lisp it expands to:

     (let ((state *the-live-state*))
       FORM)

If a form that mentions the variable state might be executed in raw
Lisp -- that is, either outside the ACL2 loop or in raw mode (see *note
SET-RAW-MODE::) -- then the surrounding the form with with-live-state
as shown above can avoid potential warnings or (much less likely)
errors.  Note however that if state is lexically bound to a state other
than the usual "live" state, surprising behavior may occur when
evaluating a call of with-live-state in raw Lisp or raw mode (either
directly by evaluation or at compile time), because with-live-state will
override that lexical binding of state by a lexical binding of state to
the usual "live" state.


File: acl2-doc-emacs.info,  Node: WRITE-BYTE$,  Next: XOR,  Prev: WITH-LIVE-STATE,  Up: ACL2-BUILT-INS

WRITE-BYTE$    See *note IO::.


File: acl2-doc-emacs.info,  Node: XOR,  Next: ZEROP,  Prev: WRITE-BYTE$,  Up: ACL2-BUILT-INS

XOR    logical "exclusive or"

Xor is the ACL2 exclusive-or function.  (xor P Q) means that either P
or Q, but not both, is false (i.e., nil).

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: ZEROP,  Next: ZIP,  Prev: XOR,  Up: ACL2-BUILT-INS

ZEROP    test an acl2-number against 0

(zerop x) is t if x is 0 and is nil otherwise.  Thus, it is logically
equivalent to (equal x 0).

(Zerop x) has a guard requiring x to be numeric and can be expected to
execute more efficiently than (equal x 0) in properly guarded compiled
code.

In recursions down the natural numbers, (zp x) is preferred over (zerop
x) because the former coerces x to a natural and allows the termination
proof.  In recursions through the integers, (zip x) is preferred.  See
*note ZERO-TEST-IDIOMS::.

Zerop is a Common Lisp function.  See any Common Lisp documentation for
more information.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: ZIP,  Next: ZP,  Prev: ZEROP,  Up: ACL2-BUILT-INS

ZIP    testing an "integer" against 0

(Zip i) is logically equivalent to (equal (ifix i) 0) and is the
preferred termination test for recursion through the integers.  (Zip i)
returns t if i is 0 or not an integer; it returns nil otherwise.  Thus,

        i         (zip i)
        3         nil
        0         t
        -2        nil
        5/2       t
        #c(1 3)   t
        'abc      t

(Zip i) has a guard requiring i to be an integer.

For a discussion of the various idioms for testing against 0, see *note
ZERO-TEST-IDIOMS::.

Zip is typically used as the termination test in recursions through the
integers.  It has the advantage of "coercing" its argument to an
integer and hence allows the definition to be admitted without an
explicit type check in the body.  Guard verification allows zip to be
compiled as a direct =-comparision with 0.


File: acl2-doc-emacs.info,  Node: ZP,  Next: ZPF,  Prev: ZIP,  Up: ACL2-BUILT-INS

ZP    testing a "natural" against 0

(Zp n) is logically equivalent to (equal (nfix n) 0) and is the
preferred termination test for recursion down the natural numbers. (Zp
n) returns t if n is 0 or not a natural number; it returns nil
otherwise.  Thus, in the ACL2 logic (ignoring the issue of guards):

         n       (zp n)
        3         nil
        0         t
        -1        t
        5/2       t
        #c(1 3)   t
        'abc      t

(Zp n) has a guard requiring n to be a natural number.

For a discussion of the various idioms for testing against 0, see *note
ZERO-TEST-IDIOMS::.

Zp is typically used as the termination test in recursions down the
natural numbers.  It has the advantage of "coercing" its argument to a
natural and hence allows the definition to be admitted without an
explicit type check in the body.  Guard verification allows zp to be
compiled as a direct =-comparision with 0.


File: acl2-doc-emacs.info,  Node: ZPF,  Prev: ZP,  Up: ACL2-BUILT-INS

ZPF    testing a nonnegative fixnum against 0

Zpf is exactly the same as zp, except that zpf is intended for, and
faster for, fixnum arguments.  Its guard is specified with a type
declaration, (type (unsigned-byte 29) x).  (See *note DECLARE:: and see
*note TYPE-SPEC::.)  Also see *note ZP::.

To see the ACL2 definition of this function, see *note PF::.


File: acl2-doc-emacs.info,  Node: ACL2-USER,  Next: ARRAYS,  Prev: ACL2-BUILT-INS,  Up: PROGRAMMING

ACL2-USER    a package the ACL2 user may prefer

This package imports the standard Common Lisp symbols that ACL2
supports and also a few symbols from package "ACL2" that are commonly
used when interacting with ACL2.  You may prefer to select this as your
current package so as to avoid colliding with ACL2 system names.

This package imports the symbols listed in
*common-lisp-symbols-from-main-lisp-package*, which contains hundreds
of CLTL function and macro names including those supported by ACL2 such
as cons, car, and cdr.  It also imports the symbols in *acl2-exports*,
which contains a few symbols that are frequently used while interacting
with the ACL2 system, such as implies, defthm, and rewrite.  It imports
nothing else.

Thus, names such as alistp, member-equal, and type-set, which are
defined in the "ACL2" package are not present here.  If you find
yourself frequently colliding with names that are defined in "ACL2" you
might consider selecting "ACL2-USER" as your current package (see *note
IN-PACKAGE::).  If you select "ACL2-USER" as the current package, you
may then simply type member-equal to refer to acl2-user::member-equal,
which you may define as you see fit.  Of course, should you desire to
refer to the "ACL2" version of member-equal, you will have to use the
"ACL2::" prefix, e.g., acl2::member-equal.

If, while using "ACL2-USER" as the current package, you find that there
are symbols from "ACL2" that you wish we had imported into it (because
they are frequently used in interaction), please bring those symbols to
our attention.  For example, should union-theories and universal-theory
be imported?  Except for stabilizing on the "frequently used" names
from "ACL2", we intend never to define a symbol whose
symbol-package-name is "ACL2-USER".


File: acl2-doc-emacs.info,  Node: ARRAYS,  Next: COMPILATION,  Prev: ACL2-USER,  Up: PROGRAMMING

ARRAYS    an introduction to ACL2 arrays

Below we begin a detailed presentation of ACL2 arrays.  ACL2's
single-threaded objects (see *note STOBJ::) provide a similar
functionality that is generally more efficient when there are updates
(writes), but is also more restrictive.

* Menu:

* AREF1:: access the elements of a 1-dimensional array

* AREF2:: access the elements of a 2-dimensional array

* ARRAY1P:: recognize a 1-dimensional array

* ARRAY2P:: recognize a 2-dimensional array

* ARRAYS-EXAMPLE:: an example illustrating ACL2 arrays

* ASET1:: set the elements of a 1-dimensional array

* ASET2:: set the elements of a 2-dimensional array

* COMPRESS1:: remove irrelevant pairs from a 1-dimensional array

* COMPRESS2:: remove irrelevant pairs from a 2-dimensional array

* DEFAULT:: return the :default from the header of a 1- or 2-dimensional array

* DIMENSIONS:: return the :dimensions from the header of a 1- or 2-dimensional array

* FLUSH-COMPRESS:: flush the under-the-hood array for the given name

* HEADER:: return the header of a 1- or 2-dimensional array

* MAXIMUM-LENGTH:: return the :maximum-length from the header of an array

* SLOW-ARRAY-WARNING:: a warning or error issued when arrays are used inefficiently

See *note ARRAYS-EXAMPLE:: for a brief introduction illustrating the use
of ACL2 arrays.

ACL2 provides relatively efficient 1- and 2-dimensional arrays.  Arrays
are awkward to provide efficiently in an applicative language because
the programmer rightly expects to be able to "modify" an array object
with the effect of changing the behavior of the element accessing
function on that object.  This, of course, does not make any sense in
an applicative setting.  The element accessing function is, after all,
a function, and its behavior on a given object is immutable.  To
"modify" an array object in an applicative setting we must actually
produce a new array object.  Arranging for this to be done efficiently
is a challenge to the implementors of the language.  In addition, the
programmer accustomed to the von Neumann view of arrays must learn how
to use immutable applicative arrays efficiently.

In this note we explain 1-dimensional arrays.  In particular, we
explain briefly how to create, access, and "modify" them, how they are
implemented, and how to program with them.  2-dimensional arrays are
dealt with by analogy.

_The Logical Description of ACL2 Arrays_

An ACL2 1-dimensional array is an object that associates arbitrary
objects with certain integers, called "indices." Every array has a
dimension, dim, which is a positive integer.  The indices of an array
are the consecutive integers from 0 through dim-1.  To obtain the
object associated with the index i in an array a, one uses (aref1 name
a i).  Name is a symbol that is irrelevant to the semantics of aref1
but affects the speed with which it computes.  We will talk more about
array "names" later.  To produce a new array object that is like a but
which associates val with index i, one uses (aset1 name a i val).

An ACL2 1-dimensional array is actually an alist.  There is no special
ACL2 function for creating arrays; they are generally built with the
standard list processing functions list and cons.  However, there is a
special ACL2 function, called compress1, for speeding up access to the
elements of such an alist.  We discuss compress1 later.

One element of the alist must be the "header" of the array.  The header
of a 1-dimensional array with dimension dim is of the form:

     (:HEADER :DIMENSIONS (dim)
              :MAXIMUM-LENGTH max
              :DEFAULT obj ; optional
              :NAME name   ; optional
              :ORDER order ; optional values are < (the default), >, or :none/nil
              ).

Obj may be any object and is called the "default value" of the array.
Max must be an integer greater than dim.  Name must be a symbol.  The
:default and :name entries are optional; if :default is omitted, the
default value is nil.  The function header, when given a name and a 1-
or 2-dimensional array, returns the header of the array.  The functions
dimensions, maximum-length, and default are similar and return the
corresponding fields of the header of the array.  The role of the
:dimensions field is obvious: it specifies the legal indices into the
array.  The roles played by the :maximum-length and :default fields are
described below.

Aside from the header, the other elements of the alist must each be of
the form (i . val), where i is an integer and 0 <= i < dim, and val is
an arbitrary object.

The :order field of the header is ignored for 2-dimensional arrays.  For
1-dimensional arrays, it specifies the order of keys (i, above) when the
array is compressed as with compress1, as described below.  An :order
of :none or nil specifies no reordering of the alist by compress1, and
an order of > specifies reordering by compress1 so that keys are in
descending order.  Otherwise, the alist is reordered by compress1 so
that keys are in ascending order.

(Aref1 name a i) is guarded so that name must be a symbol, a must be an
array and i must be an index into a.  The value of (aref1 name a i) is
either (cdr (assoc i a)) or else is the default value of a, depending
on whether there is a pair in a whose car is i.  Note that name is
irrelevant to the value of an aref1 expression.  You might :pe aref1 to
see how simple the definition is.

(Aset1 name a i val) is guarded analogously to the aref1 expression.
The value of the aset1 expression is essentially (cons (cons i val) a).
Again, name is irrelevant.  Note (aset1 name a i val) is an array, a',
with the property that (aref1 name a' i) is val and, except for index
i, all other indices into a' produce the same value as in a.  Note also
that if a is viewed as an alist (which it is) the pair "binding" i to
its old value is in a' but "covered up" by the new pair.  Thus, the
length of an array grows by one when aset1 is done.

Because aset1 covers old values with new ones, an array produced by a
sequence of aset1 calls may have many irrelevant pairs in it.  The
function compress1 can remove these irrelevant pairs.  Thus, (compress1
name a) returns an array that is equivalent (vis-a-vis aref1) to a but
which may be shorter.  For technical reasons, the alist returned by
compress1 may also list the pairs in a different order than listed in a.

To prevent arrays from growing excessively long due to repeated aset1
operations, aset1 actually calls compress1 on the new alist whenever
the length of the new alist exceeds the :maximum-length entry, max, in
the header of the array.  See the definition of aset1 (for example by
using :pe).  This is primarily just a mechanism for freeing up cons
space consumed while doing aset1 operations.  Note however that this
compress1 call is replaced by a hard error if the header specifies an
:order of :none or nil.

This completes the logical description of 1-dimensional arrays.
2-dimensional arrays are analogous.  The :dimensions entry of the
header of a 2-dimensional array should be (dim1 dim2).  A pair of
indices, i and j, is legal iff 0 <= i < dim1 and 0 <= j < dim2.  The
:maximum-length must be greater than dim1*dim2.  Aref2, aset2, and
compress2 are like their counterparts but take an additional index
argument.  Finally, the pairs in a 2-dimensional array are of the form
((i . j) . val).

_The Implementation of ACL2 Arrays_

Very informally speaking, the function compress1 "creates" an ACL2
array that provides fast access, while the function aref1 "maintains"
fast access.  We now describe this informal idea more carefully.

Aref1 is essentially assoc.  If aref1 were implemented naively the time
taken to access an array element would be linear in the dimension of
the array and the number of "assignments" to it (the number of aset1
calls done to create the array from the initial alist).  This is
intolerable; arrays are "supposed" to provide constant-time access and
change.

The apparently irrelevant names associated with ACL2 arrays allow us to
provide constant-time access and change when arrays are used in
"conventional" ways.  The implementation of arrays makes it clear what
we mean by "conventional."

Recall that array names are symbols.  Behind the scenes, ACL2
associates two objects with each ACL2 array name.  The first object is
called the "semantic value" of the name and is an alist.  The second
object is called the "raw lisp array" and is a Common Lisp array.

When (compress1 name alist) builds a new alist, a', it sets the
semantic value of name to that new alist.  Furthermore, it creates a
Common Lisp array and writes into it all of the index/value pairs of
a', initializing unassigned indices with the default value.  This array
becomes the raw lisp array of name.  Compress1 then returns a', the
semantic value, as its result, as required by the definition of
compress1.

When (aref1 name a i) is invoked, aref1 first determines whether the
semantic value of name is a (i.e., is eq to the alist a).  If so, aref1
can determine the ith element of a by invoking Common Lisp's aref
function on the raw lisp array associated with name.  Note that no
linear search of the alist a is required; the operation is done in
constant time and involves retrieval of two global variables, an eq
test and jump, and a raw lisp array access.  In fact, an ACL2 array
access of this sort is about 5 times slower than a C array access.  On
the other hand, if name has no semantic value or if it is different
from a, then aref1 determines the answer by linear search of a as
suggested by the assoc-like definition of aref1.  Thus, aref1 always
returns the axiomatically specified result.  It returns in constant
time if the array being accessed is the current semantic value of the
name used.  The ramifications of this are discussed after we deal with
aset1.

When (aset1 name a i val) is invoked, aset1 does two conses to create
the new array.  Call that array a'.  It will be returned as the answer.
(In this discussion we ignore the case in which aset1 does a
compress1.)  However, before returning, aset1 determines if name's
semantic value is a.  If so, it makes the new semantic value of name be
a' and it smashes the raw lisp array of name with val at index i,
before returning a' as the result.  Thus, after doing an aset1 and
obtaining a new semantic value a', all aref1s on that new array will be
fast.  Any aref1s on the old semantic value, a, will be slow.

To understand the performance implications of this design, consider the
chronological sequence in which ACL2 (Common Lisp) evaluates
expressions:  basically inner-most first, left-to-right, call-by-value.
An array use, such as (aref1 name a i), is "fast" (constant-time) if
the alist supplied, a, is the value returned by the most recently
executed compress1 or aset1 on the name supplied.  In the functional
expression of "conventional" array processing, all uses of an array are
fast.

The :name field of the header of an array is completely irrelevant.
Our convention is to store in that field the symbol we mean to use as
the name of the raw lisp array.  But no ACL2 function inspects :name
and its primary value is that it allows the user, by inspecting the
semantic value of the array -- the alist -- to recall the name of the
raw array that probably holds that value.  We say "probably" since
there is no enforcement that the alist was compressed under the name in
the header or that all asets used that name.  Such enforcement would be
inefficient.

_Some Programming Examples_

In the following examples we will use ACL2 "global variables" to hold
several arrays.  See *note @: atsign, and see *note ASSIGN::.

Let the state global variable a be the 1-dimensional compressed array
of dimension 5 constructed below.

     ACL2 !>(assign a (compress1 'demo
                                 '((:header :dimensions (5)
                                            :maximum-length 15
                                            :default uninitialized
                                            :name demo)
                                   (0 . zero))))

Then (aref1 'demo (@ a) 0) is zero and (aref1 'demo (@ a) 1) is
uninitialized.

Now execute

     ACL2 !>(assign b (aset1 'demo (@ a) 1 'one))

Then (aref1 'demo (@ b) 0) is zero and (aref1 'demo (@ b) 1) is one.

All of the aref1s done so far have been "fast."

Note that we now have two array objects, one in the global variable a
and one in the global variable b.  B was obtained by assigning to a.
That assignment does not affect the alist a because this is an
applicative language.  Thus, (aref1 'demo (@ a) 1) must *still* be
uninitialized.  And if you execute that expression in ACL2 you will see
that indeed it is.  However, a rather ugly comment is printed, namely
that this array access is "slow."  The reason it is slow is that the
raw lisp array associated with the name demo is the array we are
calling b.  To access the elements of a, aref1 must now do a linear
search.  Any reference to a as an array is now "unconventional;" in a
conventional language like Ada or Common Lisp it would simply be
impossible to refer to the value of the array before the assignment
that produced our b.

Now let us define a function that counts how many times a given object,
x, occurs in an array.  For simplicity, we will pass in the name and
highest index of the array:

     ACL2 !>(defun cnt (name a i x)
              (declare (xargs :guard
                              (and (array1p name a)
                                   (integerp i)
                                   (>= i -1)
                                   (< i (car (dimensions name a))))
                              :mode :logic
                              :measure (nfix (+ 1 i))))
              (cond ((zp (1+ i)) 0) ; return 0 if i is at most -1
                    ((equal x (aref1 name a i))
                     (1+ (cnt name a (1- i) x)))
                    (t (cnt name a (1- i) x))))

To determine how many times zero appears in (@ b) we can execute:

     ACL2 !>(cnt 'demo (@ b) 4 'zero)

The answer is 1.  How many times does uninitialized appear in (@ b)?

     ACL2 !>(cnt 'demo (@ b) 4 'uninitialized)

The answer is 3, because positions 2, 3 and 4 of the array contain that
default value.

Now imagine that we want to assign 'two to index 2 and then count how
many times the 2nd element of the array occurs in the array.  This
specification is actually ambiguous.  In assigning to b we produce a
new array, which we might call c.  Do we mean to count the occurrences
in c of the 2nd element of b or the 2nd element of c?  That is, do we
count the occurrences of uninitialized or the occurrences of two?  If
we mean the former the correct answer is 2 (positions 3 and 4 are
uninitialized in c); if we mean the latter, the correct answer is 1
(there is only one occurrence of two in c).

Below are ACL2 renderings of the two meanings, which we call [former]
and [latter].  (Warning:  Our description of these examples, and of an
example [fast former] that follows, assumes that only one of these
three examples is actually executed; for example, they are not executed
in sequence.  See "A Word of Warning" below for more about this issue.)

     (cnt 'demo (aset1 'demo (@ b) 2 'two) 4 (aref1 'demo (@ b) 2))  ; [former]

     (let ((c (aset1 'demo (@ b) 2 'two)))                           ; [latter]
       (cnt 'demo c 4 (aref1 'demo c 2)))

Note that in [former] we create c in the second argument of the call to
cnt (although we do not give it a name) and then refer to b in the
fourth argument.  This is unconventional because the second reference
to b in [former] is no longer the semantic value of demo.  While ACL2
computes the correct answer, namely 2, the execution of the aref1
expression in [former] is done slowly.

A conventional rendering with the same meaning is

     (let ((x (aref1 'demo (@ b) 2)))                           ; [fast former]
       (cnt 'demo (aset1 'demo (@ b) 2 'two) 4 x))

which fetches the 2nd element of b before creating c by assignment.  It
is important to understand that [former] and [fast former] mean exactly
the same thing: both count the number of occurrences of uninitialized
in c.  Both are legal ACL2 and both compute the same answer, 2.
Indeed, we can symbolically transform [fast former] into [former]
merely by substituting the binding of x for x in the body of the let.
But [fast former] can be evaluated faster than [former] because all of
the references to demo use the then-current semantic value of demo,
which is b in the first line and c throughout the execution of the cnt
in the second line.  [Fast former] is the preferred form, both because
of its execution speed and its clarity.  If you were writing in a
conventional language you would have to write something like [fast
former] because there is no way to refer to the 2nd element of the old
value of b after smashing b unless it had been saved first.

We turn now to [latter].  It is both clear and efficient.  It creates c
by assignment to b and then it fetches the 2nd element of c, two, and
proceeds to count the number of occurrences in c.  The answer is 1.
[Latter] is a good example of typical ACL2 array manipulation: after
the assignment to b that creates c, c is used throughout.

It takes a while to get used to this because most of us have grown
accustomed to the peculiar semantics of arrays in conventional
languages.  For example, in raw lisp we might have written something
like the following, treating b as a "global variable":

     (cnt 'demo (aset 'demo b 2 'two) 4 (aref 'demo b 2))

which sort of resembles [former] but actually has the semantics of
[latter] because the b from which aref fetches the 2nd element is not
the same b used in the aset!  The array b is destroyed by the aset and
b henceforth refers to the array produced by the aset, as written more
clearly in [latter].

A Word of Warning:  Users must exercise care when experimenting with
[former], [latter] and [fast former].  Suppose you have just created b
with the assignment shown above,

     ACL2 !>(assign b (aset1 'demo (@ a) 1 'one))

If you then evaluate [former] in ACL2 it will complain that the aref1
is slow and compute the answer, as discussed.  Then suppose you
evaluate [latter] in ACL2.  From our discussion you might expect it to
execute fast -- i.e., issue no complaint.  But in fact you will find
that it complains repeatedly.  The problem is that the evaluation of
[former] changed the semantic value of demo so that it is no longer b.
To try the experiment correctly you must make b be the semantic value
of demo again before the next example is evaluated.  One way to do that
is to execute

     ACL2 !>(assign b (compress1 'demo (@ b)))

before each expression.  Because of issues like this it is often hard
to experiment with ACL2 arrays at the top-level.  We find it easier to
write functions that use arrays correctly and efficiently than to so
use them interactively.

This last assignment also illustrates a very common use of compress1.
While it was introduced as a means of removing irrelevant pairs from an
array built up by repeated assignments, it is actually most useful as a
way of insuring fast access to the elements of an array.

Many array processing tasks can be divided into two parts.  During the
first part the array is built.  During the second part the array is
used extensively but not modified.  If your programming task can be so
divided, it might be appropriate to construct the array entirely with
list processing, thereby saving the cost of maintaining the semantic
value of the name while few references are being made.  Once the alist
has stabilized, it might be worthwhile to treat it as an array by
calling compress1, thereby gaining constant time access to it.

ACL2's theorem prover uses this technique in connection with its
implementation of the notion of whether a rune is disabled or not.
Associated with every rune is a unique integer index, called its
"nume."  When each rule is stored, the corresponding nume is stored as
a component of the rule.  Theories are lists of runes and membership in
the "current theory" indicates that the corresponding rule is enabled.
But these lists are very long and membership is a linear-time
operation.  So just before a proof begins we map the list of runes in
the current theory into an alist that pairs the corresponding numes
with t.  Then we compress this alist into an array.  Thus, given a rule
we can obtain its nume (because it is a component) and then determine
in constant time whether it is enabled.  The array is never modified
during the proof, i.e., aset1 is never used in this example.  From the
logical perspective this code looks quite odd:  we have replaced a
linear-time membership test with an apparently linear-time assoc after
going to the trouble of mapping from a list of runes to an alist of
numes.  But because the alist of numes is an array, the "apparently
linear-time assoc" is more apparent than real; the operation is
constant-time.


File: acl2-doc-emacs.info,  Node: AREF1,  Next: AREF2,  Prev: ARRAYS,  Up: ARRAYS

AREF1    access the elements of a 1-dimensional array

     Example Form:
     (aref1 'delta1 a (+ i k))

     General Form:
     (aref1 name alist index)

where name is a symbol, alist is a 1-dimensional array and index is a
legal index into alist.  This function returns the value associated
with index in alist, or else the default value of the array.  See *note
ARRAYS:: for details.

This function executes in virtually constant time if alist is in fact
the "semantic value" associated with name (see *note ARRAYS::).  When
it is not, aref1 must do a linear search through alist.  In that case
the correct answer is returned but a *slow array* comment is printed to
the comment window.  See *note SLOW-ARRAY-WARNING::.


File: acl2-doc-emacs.info,  Node: AREF2,  Next: ARRAY1P,  Prev: AREF1,  Up: ARRAYS

AREF2    access the elements of a 2-dimensional array

     Example Form:
     (aref2 'delta1 a i j)

     General Form:
     (aref2 name alist i j)

where name is a symbol, alist is a 2-dimensional array and i and j are
legal indices into alist.  This function returns the value associated
with (i . j) in alist, or else the default value of the array.  See
*note ARRAYS:: for details.

This function executes in virtually constant time if alist is in fact
the "semantic value" associated with name (see *note ARRAYS::).  When
it is not, aref2 must do a linear search through alist.  In that case
the correct answer is returned but a *slow array* comment is printed to
the comment window.  See *note SLOW-ARRAY-WARNING::.


File: acl2-doc-emacs.info,  Node: ARRAY1P,  Next: ARRAY2P,  Prev: AREF2,  Up: ARRAYS

ARRAY1P    recognize a 1-dimensional array

     Example Form:
     (array1p 'delta1 a)

     General Form:
     (array1p name alist)

where name and alist are arbitrary objects.  This function returns t if
alist is a 1-dimensional ACL2 array.  Otherwise it returns nil.  The
function operates in constant time if alist is the semantic value of
name.  See *note ARRAYS::.


File: acl2-doc-emacs.info,  Node: ARRAY2P,  Next: ARRAYS-EXAMPLE,  Prev: ARRAY1P,  Up: ARRAYS

ARRAY2P    recognize a 2-dimensional array

     Example Form:
     (array2p 'delta1 a)

     General Form:
     (array2p name alist)

where name and alist are arbitrary objects.  This function returns t if
alist is a 2-dimensional ACL2 array.  Otherwise it returns nil.  The
function operates in constant time if alist is the semantic value of
name.  See *note ARRAYS::.


File: acl2-doc-emacs.info,  Node: ARRAYS-EXAMPLE,  Next: ASET1,  Prev: ARRAY2P,  Up: ARRAYS

ARRAYS-EXAMPLE    an example illustrating ACL2 arrays

The example below illustrates the use of ACL2 arrays.  It is not, of
course, a substitute for the detailed explanations provided elsewhere
(see *note ARRAYS::, including subtopics).

     ACL2 !>(defun defarray (name size initial-element)
              (compress1 name
                         (cons (list :HEADER
                                     :DIMENSIONS (list size)
                                     :MAXIMUM-LENGTH (1+ size)
                                     :DEFAULT initial-element
                                     :NAME name)
                               nil)))

     Since DEFARRAY is non-recursive, its admission is trivial.  We observe
     that the type of DEFARRAY is described by the theorem
     (AND (CONSP (DEFARRAY NAME SIZE INITIAL-ELEMENT))
          (TRUE-LISTP (DEFARRAY NAME SIZE INITIAL-ELEMENT))).
     We used the :type-prescription rule COMPRESS1.

     Summary
     Form:  ( DEFUN DEFARRAY ...)
     Rules: ((:TYPE-PRESCRIPTION COMPRESS1))
     Warnings:  None
     Time:  0.02 seconds (prove: 0.00, print: 0.02, other: 0.00)
      DEFARRAY
     ACL2 !>(assign my-ar (defarray 'a1 5 17))
      ((:HEADER :DIMENSIONS (5)
                :MAXIMUM-LENGTH 6 :DEFAULT 17 :NAME A1))
     ACL2 !>(aref1 'a1 (@ my-ar) 3)
     17
     ACL2 !>(aref1 'a1 (@ my-ar) 8)


     ACL2 Error in TOP-LEVEL:  The guard for the function symbol AREF1,
     which is
     (AND (ARRAY1P NAME L) (INTEGERP N) (>= N 0) (< N (CAR (DIMENSIONS NAME L)))),
     is violated by the arguments in the call (AREF1 'A1 '(#) 8).

     ACL2 !>(assign my-ar (aset1 'a1 (@ my-ar) 3 'xxx))
      ((3 . XXX)
       (:HEADER :DIMENSIONS (5)
                :MAXIMUM-LENGTH 6 :DEFAULT 17 :NAME A1))
     ACL2 !>(aref1 'a1 (@ my-ar) 3)
     XXX
     ACL2 !>(aset1 'a1 (@ my-ar) 3 'yyy) ; BAD: (@ my-ar) now points to
                                         ;      an old copy of the array!
     ((3 . YYY)
      (3 . XXX)
      (:HEADER :DIMENSIONS (5)
               :MAXIMUM-LENGTH 6 :DEFAULT 17 :NAME A1))
     ACL2 !>(aref1 'a1 (@ my-ar) 3) ; Because of "BAD" above, the array
                                    ; access is done using assoc rather
                                    ; than Lisp aref, hence is slower;
                                    ; but the answer is still correct,
                                    ; reflecting the value in (@ my-ar),
                                    ; which was not changed above.


     **********************************************************
     Slow Array Access!  A call of AREF1 on an array named
     A1 is being executed slowly.  See :DOC slow-array-warning
     **********************************************************

     XXX
     ACL2 !>


File: acl2-doc-emacs.info,  Node: ASET1,  Next: ASET2,  Prev: ARRAYS-EXAMPLE,  Up: ARRAYS

ASET1    set the elements of a 1-dimensional array

     Example Form:
     (aset1 'delta1 a (+ i k) 27)

     General Form:
     (aset1 name alist index val)

where name is a symbol, alist is a 1-dimensional array named name,
index is a legal index into alist, and val is an arbitrary object.  See
*note ARRAYS:: for details.  Roughly speaking this function "modifies"
alist so that the value associated with index is val.  More precisely,
it returns a new array, alist', of the same name and dimension as alist
that, under aref1, is everywhere equal to alist except at index where
the result is val.  That is, (aref1 name alist' i) is (aref1 name alist
i) for all legal indices i except index, where (aref1 name alist' i) is
val.

In order to "modify" alist, aset1 conses a new pair onto the front.  If
the length of the resulting alist exceeds the :maximum-length entry in
the array header, aset1 compresses the array as with compress1.

It is generally expected that the "semantic value" of name will be
alist (see *note ARRAYS::).  This function operates in virtually
constant time whether this condition is true or not (unless the
compress1 operation is required).  But the value returned by this
function cannot be used efficiently by subsequent aset1 operations
unless alist is the semantic value of name when aset1 is executed.
Thus, if the condition is not true, aset1 prints a *slow array* warning
to the comment window.  See *note SLOW-ARRAY-WARNING::.


File: acl2-doc-emacs.info,  Node: ASET2,  Next: COMPRESS1,  Prev: ASET1,  Up: ARRAYS

ASET2    set the elements of a 2-dimensional array

     Example Form:
     (aset2 'delta1 a i j 27)

     General Form:
     (aset2 name alist i j val)

where name is a symbol, alist is a 2-dimensional array named name, i
and j are legal indices into alist, and val is an arbitrary object.
See *note ARRAYS:: for details.  Roughly speaking this function
"modifies" alist so that the value associated with (i . j) is val.
More precisely, it returns a new array, alist', of the same name and
dimension as alist that, under aref2, is everywhere equal to alist
except at (i . j) where the result is val.  That is, (aref2 name alist'
x y) is (aref2 name alist x y) for all legal indices x y except i and j
where (aref2 name alist' i j) is val.

In order to "modify" alist, aset2 conses a new pair onto the front.  If
the length of the resulting alist exceeds the :maximum-length entry in
the array header, aset2 compresses the array as with compress2.

It is generally expected that the "semantic value" of name will be
alist (see *note ARRAYS::).  This function operates in virtually
constant time whether this condition is true or not (unless the
compress2 operation is required).  But the value returned by this
function cannot be used efficiently by subsequent aset2 operations
unless alist is the semantic value of name when aset2 is executed.
Thus, if the condition is not true, aset2 prints a *slow array* warning
to the comment window.  See *note SLOW-ARRAY-WARNING::.


File: acl2-doc-emacs.info,  Node: COMPRESS1,  Next: COMPRESS2,  Prev: ASET2,  Up: ARRAYS

COMPRESS1    remove irrelevant pairs from a 1-dimensional array

     Example Form:
     (compress1 'delta1 a)

     General Form:
     (compress1 name alist)

where name is a symbol and alist is a 1-dimensional array, generally
named name.  See *note ARRAYS:: for details.  Logically speaking, this
function removes irrelevant pairs from alist, possibly shortening it.
The function returns a new array, alist', with the same header
(including name and dimension) as alist, that, under aref1, is
everywhere equal to alist.  That is, (aref1 name alist' i) is (aref1
name alist i), for all legal indices i.  Alist' may be shorter than
alist and the non-irrelevant pairs may occur in a different order than
in alist.

Practically speaking, this function plays an important role in the
efficient implementation of aref1.  In addition to creating the new
array, alist', compress1 makes that array the "semantic value" of name
and allocates a raw lisp array to name.  For each legal index, i, that
raw lisp array contains (aref1 name alist' i) in slot i.  Thus,
subsequent aref1 operations can be executed in virtually constant time
provided they are given name and the alist' returned by the most
recently executed compress1 or aset1 on name.  See *note ARRAYS::.

In general, compress1 returns an alist whose cdr is an association list
whose keys are nonnegative integers in ascending order.  However, if the
header specifies an :order of > then the keys will occur in descending
order, and if the :order is :none or nil then the keys will not be
sorted, i.e., compress1 is logically the identity function (though it
still attaches an array under the hood).  Note however that a compress1
call is replaced by a hard error if the header specifies an :order of
:none or nil and the array's length exceeds the maximum-length field of
its header.


File: acl2-doc-emacs.info,  Node: COMPRESS2,  Next: DEFAULT,  Prev: COMPRESS1,  Up: ARRAYS

COMPRESS2    remove irrelevant pairs from a 2-dimensional array

     Example Form:
     (compress2 'delta1 a)

     General Form:
     (compress2 name alist)

where name is a symbol and alist is a 2-dimensional array, generally
named name.  See *note ARRAYS:: for details.  Logically speaking, this
function removes irrelevant pairs from alist, possibly shortening it.
The function returns a new array, alist', with the same header
(including name and dimension) as alist, that, under aref2, is
everywhere equal to alist.  That is, (aref2 name alist' i j) is (aref2
name alist i j), for all legal indices i and j.  Alist' may be shorter
than alist and the non-irrelevant pairs may occur in a different order
in alist' than in alist.

Practically speaking, this function plays an important role in the
efficient implementation of aref2.  In addition to creating the new
array, alist', compress2 makes that array the "semantic value" of name
and allocates a raw lisp array to name.  For all legal indices, i and
j, that raw lisp array contains (aref2 name alist' i j) in slot i,j.
Thus, subsequent aref2 operations can be executed in virtually constant
time provided they are given name and the alist' returned by the most
recently executed compress2 or aset2 on name.  See *note ARRAYS::.


File: acl2-doc-emacs.info,  Node: DEFAULT,  Next: DIMENSIONS,  Prev: COMPRESS2,  Up: ARRAYS

DEFAULT    return the :default from the header of a 1- or 2-dimensional array

     Example Form:
     (default 'delta1 a)

     General Form:
     (default name alist)

where name is an arbitrary object and alist is a 1- or 2-dimensional
array.  This function returns the contents of the :default field of the
header of alist.  When aref1 or aref2 is used to obtain a value for an
index (or index pair) not bound in alist, the default value is returned
instead.  Thus, the array alist may be thought of as having been
initialized with the default value.  default operates in virtually
constant time if alist is the semantic value of name.  See *note
ARRAYS::.


File: acl2-doc-emacs.info,  Node: DIMENSIONS,  Next: FLUSH-COMPRESS,  Prev: DEFAULT,  Up: ARRAYS

DIMENSIONS    return the :dimensions from the header of a 1- or 2-dimensional array

     Example Form:
     (dimensions 'delta1 a)

     General Form:
     (dimensions name alist)

where name is arbitrary and alist is a 1- or 2-dimensional array.  This
function returns the dimensions list of the array alist.  That list
will either be of the form (dim1) or (dim1 dim2), depending on whether
alist is a 1- or 2-dimensional array.  Dim1 and dim2 will be integers
and each exceed by 1 the maximum legal corresponding index.  Thus, if
dimensions returns, say, '(100) for an array a named 'delta1, then
(aref1 'delta1 a 99) is legal but (aref1 'delta1 a 100) violates the
guards on aref1.  Dimensions operates in virtually constant time if
alist is the semantic value of name.  See *note ARRAYS::.


File: acl2-doc-emacs.info,  Node: FLUSH-COMPRESS,  Next: HEADER,  Prev: DIMENSIONS,  Up: ARRAYS

FLUSH-COMPRESS    flush the under-the-hood array for the given name

     Example Form:
     (flush-compress 'my-array)

     General Form:
     (flush-compress name)

where name is a symbol.

Recall that (compress1 nm alist) associates an under-the-hood raw Lisp
one-dimensional array of name nm with the given association list,
alist, while (compress2 nm alist) is the analogous function for
two-dimensional arrays; see *note COMPRESS1:: and see *note
COMPRESS2::.  The only purpose of flush-compress, which always returns
nil, is to remove the association of any under-the-hood array with the
given name, thus eliminating slow array accesses (see *note
SLOW-ARRAY-WARNING::).  It is not necessary if the return values of
compress1 and compress2 are always used as the "current" copy of the
named array, and thus flush-compress should rarely, if ever, be needed
in user applications.

Nevertheless, we provide the following contrived example to show how
flush-compress can be used to good effect.  Comments have been added to
this log to provide explanation.

     ACL2 !>(assign a (compress1 'demo
                                 '((:header :dimensions (5)
                                            :maximum-length 15
                                            :default uninitialized
                                            :name demo)
                                   (0 . zero)
                                   (1 . one))))
      ((:HEADER :DIMENSIONS (5)
                :MAXIMUM-LENGTH
                15 :DEFAULT UNINITIALIZED :NAME DEMO)
       (0 . ZERO)
       (1 . ONE))
     ACL2 !>(aref1 'demo (@ a) 0)
     ZERO
     ; As expected, the above evaluation did not cause a slow array warning.  Now
     ; we associate a different under-the-hood array with the name 'demo.
     ACL2 !>(compress1 'demo
                       '((:header :dimensions (5)
                                  :maximum-length 15
                                  :default uninitialized
                                  :name demo)
                         (0 . zero)))
     ((:HEADER :DIMENSIONS (5)
               :MAXIMUM-LENGTH
               15 :DEFAULT UNINITIALIZED :NAME DEMO)
      (0 . ZERO))
     ; The following array access produces a slow array warning because (@ a) is
     ; no longer associated under-the-hood with the array name 'demo.
     ACL2 !>(aref1 'demo (@ a) 0)


     **********************************************************
     Slow Array Access!  A call of AREF1 on an array named
     DEMO is being executed slowly.  See :DOC slow-array-warning
     **********************************************************

     ZERO
     ; Now we associate under-the-hood, with array name 'demo, an alist equal to
     ; (@ a).
     ACL2 !>(compress1 'demo
                       '((:header :dimensions (5)
                                  :maximum-length 15
                                  :default uninitialized
                                  :name demo)
                         (0 . zero)
                         (1 . one)))
     ((:HEADER :DIMENSIONS (5)
               :MAXIMUM-LENGTH
               15 :DEFAULT UNINITIALIZED :NAME DEMO)
      (0 . ZERO)
      (1 . ONE))
     ; The following array access is still slow, because the under-the-hood array
     ; is merely associated with a copy of (@ a), not with the actual object
     ; (@ a).
     ACL2 !>(aref1 'demo (@ a) 0)


     **********************************************************
     Slow Array Access!  A call of AREF1 on an array named
     DEMO is being executed slowly.  See :DOC slow-array-warning
     **********************************************************

     ZERO
     ; So we might try to fix the problem by recompressing. But this doesn't
     ; work.  It would work, by the way, if we re-assign a:
     ; (assign a (compress1 'demo (@ a))).  That is why we usually will not need
     ; flush-compress.
     ACL2 !>(compress1 'demo (@ a))
     ((:HEADER :DIMENSIONS (5)
               :MAXIMUM-LENGTH
               15 :DEFAULT UNINITIALIZED :NAME DEMO)
      (0 . ZERO)
      (1 . ONE))
     ACL2 !>(aref1 'demo (@ a) 0)


     **********************************************************
     Slow Array Access!  A call of AREF1 on an array named
     DEMO is being executed slowly.  See :DOC slow-array-warning
     **********************************************************

     ZERO
     ; Finally, we eliminate the warning by calling flush-compress before we call
     ; compress1.  The call of flush-compress removes any under-the-hood
     ; association of an array with the name 'demo.  Then the subsequent call of
     ; compress1 associates the object (@ a) with that name.  (Technical point:
     ; compress1 always associates the indicated name with the value that it
     ; returns.  in this case, what compress1 returns is (@ a), because (@ a) is
     ; already, logically speaking, a compressed array1p (starts with a :header
     ; and the natural number keys are ordered).
     ACL2 !>(flush-compress 'demo)
     NIL
     ACL2 !>(compress1 'demo (@ a))
     ((:HEADER :DIMENSIONS (5)
               :MAXIMUM-LENGTH
               15 :DEFAULT UNINITIALIZED :NAME DEMO)
      (0 . ZERO)
      (1 . ONE))
     ACL2 !>(aref1 'demo (@ a) 0)
     ZERO
     ACL2 !>


File: acl2-doc-emacs.info,  Node: HEADER,  Next: MAXIMUM-LENGTH,  Prev: FLUSH-COMPRESS,  Up: ARRAYS

HEADER    return the header of a 1- or 2-dimensional array

     Example Form:
     (header 'delta1 a)

     General Form:
     (header name alist)

where name is arbitrary and alist is a 1- or 2-dimensional array.  This
function returns the header of the array alist.  The function operates
in virtually constant time if alist is the semantic value of name.  See
*note ARRAYS::.


File: acl2-doc-emacs.info,  Node: MAXIMUM-LENGTH,  Next: SLOW-ARRAY-WARNING,  Prev: HEADER,  Up: ARRAYS

MAXIMUM-LENGTH    return the :maximum-length from the header of an array

     Example Form:
     (maximum-length 'delta1 a)

     General Form:
     (maximum-length name alist)

where name is an arbitrary object and alist is a 1- or 2-dimensional
array.  This function returns the contents of the :maximum-length field
of the header of alist.  Whenever an aset1 or aset2 would cause the
length of the alist to exceed its maximum length, a compress1 or
compress2 is done automatically to remove irrelevant pairs from the
array.  Maximum-length operates in virtually constant time if alist is
the semantic value of name.  See *note ARRAYS::.


File: acl2-doc-emacs.info,  Node: SLOW-ARRAY-WARNING,  Prev: MAXIMUM-LENGTH,  Up: ARRAYS

SLOW-ARRAY-WARNING    a warning or error issued when arrays are used inefficiently

If you use ACL2 arrays you may sometimes see a *slow array* warning.
We explain below what that warning means and some likely "mistakes" it
may signify.

First, we note that you can control whether or not you get a warning
and, if so, whether or not a break (error from which you can continue;
see *note BREAK$::) ensues:

     (assign slow-array-action :warning) ; warn on slow array access (default)
     (assign slow-array-action :break)   ; warn as above, and then call break$
     (assign slow-array-action nil) ; do not warn or break on slow array access

If you are using ACL2 arrays, then you probably care about performance,
in which case it is probably best to avoid the nil setting.  Below we
assume the default behavior: a warning, but no break.

The discussion in the documentation for arrays defines what we mean by
the semantic value of a name.  As noted there, behind the scenes ACL2
maintains the invariant that with some names there is associated a pair
consisting of an ACL2 array alist, called the semantic value of the
name, and an equivalent raw lisp array.  Access to ACL2 array elements,
as in (aref1 name alist i), is executed in constant time when the array
alist is the semantic value of the name, because we can just use the
corresponding raw lisp array to obtain the answer.  Aset1 and compress1
modify the raw lisp array appropriately to maintain the invariant.

If aref1 is called on a name and alist, and the alist is not the
then-current semantic value of the name, the correct result is computed
but it requires linear time because the alist must be searched.  When
this happens, aref1 prints a *slow array* warning message to the
comment window.  Aset1 behaves similarly because the array it returns
will cause the *slow array* warning every time it is used.

From the purely logical perspective there is nothing "wrong" about such
use of arrays and it may be spurious to print a warning message.  But
because arrays are generally used to achieve efficiency, the *slow
array* warning often means the user's intentions are not being
realized.  Sometimes merely performance expectations are not met; but
the message may mean that the functional behavior of the program is
different than intended.

Here are some "mistakes" that might cause this behavior.  In the
following we suppose the message was printed by aset1 about an array
named name.  Suppose the alist supplied aset1 is alist.

(1) Compress1 was never called on name and alist.  That is, perhaps you
created an alist that is an array1p and then proceeded to access it
with aref1 but never gave ACL2 the chance to create a raw lisp array
for it.  After creating an alist that is intended for use as an array,
you must do (compress1 name alist) and pass the resulting alist' as the
array.

(2) Name is misspelled.  Perhaps the array was compressed under the
name 'delta-1 but accessed under 'delta1?

(3) An aset1 was done to modify alist, producing a new array, alist',
but you subsequently used alist as an array.  Inspect all (aset1 name
...) occurrences and make sure that the alist modified is never used
subsequently (either in that function or any other).  It is good
practice to adopt the following syntactic style.  Suppose the alist you
are manipulating is the value of the local variable alist.  Suppose at
some point in a function definition you wish to modify alist with
aset1.  Then write

     (let ((alist (aset1 name alist i val))) ...)

and make sure that the subsequent function body is entirely within the
scope of the let.  Any uses of alist subsequently will refer to the new
alist and it is impossible to refer to the old alist.  Note that if you
write

      (foo (let ((alist (aset1 name alist i val))) ...)  ; arg 1
           (bar alist))                                  ; arg 2

you have broken the rules, because in arg 1 you have modified alist but
in arg 2 you refer to the old value.  An appropriate rewriting is to
lift the let out:

      (let ((alist (aset1 name alist alist i val)))
        (foo ...                                         ; arg 1
             (bar alist)))                               ; arg 2

Of course, this may not mean the same thing.

(4) A function which takes alist as an argument and modifies it with
aset1 fails to return the modified version.  This is really the same as
(3) above, but focuses on function interfaces.  If a function takes an
array alist as an argument and the function uses aset1 (or a
subfunction uses aset1, etc.), then the function probably "ought" to
return the result produced by aset1.  The reasoning is as follows.  If
the array is passed into the function, then the caller is holding the
array.  After the function modifies it, the caller's version of the
array is obsolete.  If the caller is going to make further use of the
array, it must obtain the latest version, i.e., that produced by the
function.


File: acl2-doc-emacs.info,  Node: COMPILATION,  Next: DECLARE,  Prev: ARRAYS,  Up: PROGRAMMING

COMPILATION    compiling ACL2 functions

ACL2 has several mechanisms to speed up the evaluation of function
calls by _compiling_ functions: see *note COMP::, see *note
SET-COMPILE-FNS::, and see *note CERTIFY-BOOK::.  The intention is that
compilation never changes the value returned by a function call, though
it could cause the call to succeed rather than fail, for example by
avoiding a stack overflow.

The state global variable 'compiler-enabled is set automatically when
the system is built, and may depend on the underlying Lisp
implementation.  (In order to disable the compiler at build time, which
will defeat the speed-up but usually be pretty harmless when the host
Lisp is CCL or SBCL, see the discussion of ACL2_COMPILER_DISABLED in
distributed file GNUmakefile.)  The value of 'compiler-enabled, as
returned by (@ compiler-enabled), can be t, :books, or nil.  If the
value is nil, then include-book and certify-book coerce their arguments
:load-compile-file and compile-flg arguments (respectively) to nil.
Otherwise, the value is :books or t and there is no such coercion; but
if the value is not t, then comp and set-compile-fns are no-ops, which
is probably desirable for Lisps such as CCL and SBCL that compile
on-the-fly even when the compiler is not explicitly invoked.

However, you may have reason to want to change the above (default)
behavior.  To enable compilation by default for certify-book and
include-book but not for comp or set-compile-fns:

     (set-compiler-enabled :books state)

To enable compilation not only as above but also for comp and
set-compile-fns:

     (set-compiler-enabled t state)

To suppress compilation and loading of compiled files by include-book
(for example, if you get a raw Lisp error such as "Wrong FASL version"):

     (set-compiler-enabled nil state)

See *note BOOK-COMPILED-FILE:: for more discussion about compilation and
books.


File: acl2-doc-emacs.info,  Node: DECLARE,  Next: EQUALITY-VARIANTS,  Prev: COMPILATION,  Up: PROGRAMMING

DECLARE    declarations

     Examples:
     (declare (ignore x y z))
     (declare (ignorable x y z)
              (type integer i j k)
              (type (satisfies integerp) m1 m2))
     (declare (xargs :guard (and (integerp i)
                                 (<= 0 i))
                     :guard-hints (("Goal" :use (:instance lemma3
                                                   (x (+ i j)))))))

     * Menu:

     * TYPE-SPEC:: type specifiers in declarations

     General Form:
     (declare d1 ... dn)
     where, in ACL2, each di is of one of the following forms:

       (ignore v1 ... vn) -- where each vi is a variable introduced in
       the immediately superior lexical environment.  These variables must not
       occur free in the scope of the declaration.

       (ignorable v1 ... vn) -- where each vi is a variable introduced in
       the immediately superior lexical environment.  These variables need not
       occur free in the scope of the declaration.  This declaration can be useful
       for inhibiting compiler warnings.

       (type type-spec v1 ... vn) -- where each vi is a variable introduced in the
       immediately superior lexical environment and type-spec is a type specifier
       (as described in the documentation for type-spec).

       (xargs :key1 val1 ... :keyn valn) -- where the legal values of the keyi's
       and their respective vali's are described in the documentation for
       xargs.  Xargs declarations are only allowed at the top level of
       definitions (defun and defmacro, as shown below).

       (optimize ...) -- for example, (optimize (safety 3)).  This is allowed
       only at the top level of defun forms.  See any Common Lisp
       documentation for more information.

Declarations in ACL2 may occur only where dcl occurs below:

       (DEFUN name args doc-string dcl ... dcl body)
       (DEFMACRO name args doc-string dcl ... dcl body)
       (LET ((v1 t1) ...) dcl ... dcl body)
       (MV-LET (v1 ...) term dcl ... dcl body)
       (FLET ((name args dcl ... dcl body)
              ...))

Of course, if a form macroexpands into one of these (as let* expands
into nested lets and our er-let* expands into nested mv-lets) then
declarations are permitted as handled by the macros involved.

Declare is defined in Common Lisp.  See any Common Lisp documentation
for more information.


File: acl2-doc-emacs.info,  Node: TYPE-SPEC,  Prev: DECLARE,  Up: DECLARE

TYPE-SPEC    type specifiers in declarations

     Examples:
     The symbol INTEGER in (declare (type INTEGER i j k)) is a type-spec.  Other
     type-specs supported by ACL2 include RATIONAL, COMPLEX, (INTEGER 0 127),
     (RATIONAL 1 *), CHARACTER, and ATOM.

The type-specs and their meanings (when applied to the variable x as in
(declare (type type-spec x)) are given below.

     type-spec              meaning
     (AND type1 ... typek)  (AND (p1 X) ... (pk X))
                            where (pj x) is the meaning for type-spec typej
     ATOM                   (ATOM X)
     BIT                    (OR (EQUAL X 1) (EQUAL X 0))
     CHARACTER              (CHARACTERP X)
     COMPLEX                (AND (COMPLEX-RATIONALP X)
                                 (RATIONALP (REALPART X))
                                 (RATIONALP (IMAGPART X)))
     (COMPLEX RATIONAL)     same as COMPLEX, above
     (COMPLEX type)         (AND (COMPLEX-RATIONALP X)
                                 (p (REALPART X))
                                 (p (IMAGPART X)))
                            where (p x) is the meaning for type-spec type
     CONS                   (CONSP X)
     INTEGER                (INTEGERP X)
     (INTEGER i j)          (AND (INTEGERP X)   ; See notes below
                                 (<= i X)
                                 (<= X j))
     (MEMBER x1 ... xn)     (MEMBER X '(x1 ... xn))
     (MOD i)                same as (INTEGER 0 i-1)
     NIL                    NIL
     (NOT type)             (NOT (p X))
                            where (p x) is the meaning for type-spec type
     NULL                   (EQ X NIL)
     (OR type1 ... typek)   (OR (p1 X) ... (pk X))
                            where (pj x) is the meaning for type-spec typej
     RATIO                  (AND (RATIONALP X) (NOT (INTEGERP X)))
     RATIONAL               (RATIONALP X)
     (RATIONAL i j)         (AND (RATIONALP X)  ; See notes below
                                 (<= i X)
                                 (<= X j))
     REAL                   (RATIONALP X)       ; (REALP X) in ACL2(r)
     (REAL i j)             (AND (RATIONALP X)  ; See notes below
                                 (<= i X)
                                 (<= X j))
     (SATISFIES pred)       (pred X) ; Lisp requires a unary function, not a macro
     SIGNED-BYTE            (INTEGERP X)
     (SIGNED-BYTE i)        same as (INTEGER k m) where k=-2^(i-1), m=2^(i-1)-1
     STANDARD-CHAR          (STANDARD-CHARP X)
     STRING                 (STRINGP X)
     (STRING max)           (AND (STRINGP X) (EQUAL (LENGTH X) max))
     SYMBOL                 (SYMBOLP X)
     T                      T
     UNSIGNED-BYTE          same as (INTEGER 0 *)
     (UNSIGNED-BYTE i)      same as (INTEGER 0 (2^i)-1)

_Notes:_

In general, (integer i j) means

          (AND (INTEGERP X)
               (<= i X)
               (<= X j)).

But if i is the symbol *, the first inequality is omitted.  If j is the
symbol *, the second inequality is omitted.  If instead of being an
integer, the second element of the type specification is a list
containing an integer, (i), then the first inequality is made strict.
An analogous remark holds for the (j) case.  The RATIONAL and REAL type
specifiers are similarly generalized.


File: acl2-doc-emacs.info,  Node: EQUALITY-VARIANTS,  Next: IGNORABLE,  Prev: DECLARE,  Up: PROGRAMMING

EQUALITY-VARIANTS    versions of a function using different equality tests

The ACL2 environment includes not only a logic but also a programming
language, which is based on Common Lisp.  Execution efficiency may be
increased by using fast equality tests: eq for symbols and eql for
numbers, symbols, and characters (see *note EQLABLEP::).  Several
list-processing functions built into ACL2 thus have three variants,
depending on whether the equality function used is eq, eql, or equal; a
list is provided below.  ACL2 has taken measures to ensure that one can
reason about a single logical function even when one uses these
different variants.

Consider for example the case of list membership.  Common Lisp provides
a utility for this purposes, member, which can take a :TEST keyword
argument, default eql.  So for example, one might write

     (member a x :TEST 'eq)

if either a is a symbol or x is a list of symbols, so that the fastest
equality test (eq) may be used when comparing a to successive elements
of the list, x.  One might elsewhere write (member b (foo y)), which is
equivalent to (member b (foo y) :TEST 'eql), for example if b is a
number.  If one wants to reason about both (member a x :TEST 'eq) and
(member b y), it might be helpful for both calls of member to be the
same logically, even though Common Lisp will execute them differently
(using eq or eql, respectively).  ACL2 arranges that in fact, both
references to member generate calls of member-equal in the theorem
prover.

In fact, since member can take the optional :TEST keyword argument,
then in ACl2 it must be defined as a macro, not a function (see *note
DEFUN::).  ACL2 arranges that a call of member generates a
corresponding call of the function member-equal, regardless of the
value of TEST, in a manner that produces member-equal in prover output.
More generally, you can expect ACL2 to treat your use of member as
though you had written member-equal, for example in the way it stores
rewrite rules and other kinds of rules as well (see *note
RULE-CLASSES::).  We say little here about how this is all arranged by
ACL2, other than to mention that mbe is utilized (so, you might see
mention in proof logs) of the function return-last that implements mbe.
Such details, which probably can be ignored by most users, may be found
elsewhere; see *note EQUALITY-VARIANTS-DETAILS::.

As a convenience to the user, the macro member-eq is provided that
expands to a corresponding call of member with :TEST 'eq, as follows.

     ACL2 !>:trans1 (member-eq (foo x) (bar y))
      (MEMBER (FOO X) (BAR Y) :TEST 'EQ)
     ACL2 !>

For efficiency we recommend using the -equal equality variant, for
example member-equal or ... :TEST 'equal, in certain contexts:
defmacro, defpkg, defconst, and value-triple forms.  However, the
implementation of equality variants has been designed so that when
defining a function, one may choose freely in a definition an equality
variant of primitive F, to get efficient execution but where subsequent
reasoning is about F-equal.  For details about the above recommendation
and for a discussion of the implementation, see *note
EQUALITY-VARIANTS-DETAILS::.

The following alphabetical list includes all primitives that have
equality variants.  Each macro F listed below takes an optional :TEST
keyword argument of 'eq, 'eql, or 'equal, where 'eql is the default.
For each such F, a function F-equal is defined such that for logical
purposes (in particular theorem proving), each call of F expands to a
corresponding call of F-equal.  For convenience, a macro F-eq is also
defined, so that a call of F-eq expands to a corresponding call of F
with :TEST 'eq.

     add-to-set
     assoc
     delete-assoc
     intersection$ ; (see Note below)
     intersectp
     member
     no-duplicatesp
     position-ac
     position
     put-assoc
     rassoc
     remove-duplicates
     remove1
     remove
     set-difference$ ; (see Note below)
     subsetp
     union$ ; (see Note below)

Note: Three of the macros above have names ending with the character,
`$': intersection$, set-difference$, and union$.  In each case there is
a corresponding Common Lisp primitive without the trailing `$':
intersection, set-difference, and union.  However, Common Lisp does not
specify the order of elements in the list returned by those primitives,
so ACL2 has its own.  Nevertheless, the only use of the trailing `$' is
to distinguish the primitives; associated functions and macros, for
example union-eq and intersection-equal, do not include the `$'
character in their names.

* Menu:

* EQUALITY-VARIANTS-DETAILS:: details about equality-variants


File: acl2-doc-emacs.info,  Node: EQUALITY-VARIANTS-DETAILS,  Prev: EQUALITY-VARIANTS,  Up: EQUALITY-VARIANTS

EQUALITY-VARIANTS-DETAILS    details about equality-variants

Here we present details about equality variants, none of which is likely
to be important to the majority of ACL2 users.  Please see *note
EQUALITY-VARIANTS:: for relevant background.

We begin by presenting events that implement the equality variants for
member, as these illustrate the events introduced for all macros having
equality variants.  The definition of member, just below, calls the
macro let-mbe, which in turn is just an abbreviation for a combination
of let and mbe.

     (defmacro let-mbe (bindings &key logic exec)
       `(let ,bindings
          (mbe :logic ,logic
               :exec ,exec)))

This use of let arranges that each argument of a call of member is
evaluated only once.

     (defmacro member (x l &key (test ''eql))
       (declare (xargs :guard (or (equal test ''eq)
                                  (equal test ''eql)
                                  (equal test ''equal))))
       (cond
        ((equal test ''eq)
         `(let-mbe ((x ,x) (l ,l))
                   :logic (member-equal x l)
                   :exec  (member-eq-exec x l)))
        ((equal test ''eql)
         `(let-mbe ((x ,x) (l ,l))
                   :logic (member-equal x l)
                   :exec  (member-eql-exec x l)))
        (t ; (equal test 'equal)
         `(member-equal ,x ,l))))

Inspection of the definition above shows that every call of member
expands to one that is logically equivalent to the corresponding call of
member-equal, which is defined as follows.

     (defun member-equal (x lst)
       (declare (xargs :guard (true-listp lst)))
       (cond ((endp lst) nil)
             ((equal x (car lst)) lst)
             (t (member-equal x (cdr lst)))))

The following two definitions model equality variants of member for
tests eq and eql, respectively.

     (defun member-eq-exec (x lst)
       (declare (xargs :guard (if (symbolp x)
                                  (true-listp lst)
                                (symbol-listp lst))))
       (cond ((endp lst) nil)
             ((eq x (car lst)) lst)
             (t (member-eq-exec x (cdr lst)))))

     (defun member-eql-exec (x lst)
       (declare (xargs :guard (if (eqlablep x)
                                  (true-listp lst)
                                (eqlable-listp lst))))
       (cond ((endp lst) nil)
             ((eql x (car lst)) lst)
             (t (member-eql-exec x (cdr lst)))))

At this point the user can write (member x y) or (member-equal x y) to
call equality variants of member with test eql or equal, respectively.
We thus provide the following macro for the eq variant.

     (defmacro member-eq (x lst)
       `(member ,x ,lst :test 'eq))

Guard proof obligations generated by calls of member will include those
based on its use of mbe, and are supported by the following two lemmas.

     (defthm member-eq-exec-is-member-equal
       (equal (member-eq-exec x l)
              (member-equal x l)))

     (defthm member-eql-exec-is-member-equal
       (equal (member-eql-exec x l)
              (member-equal x l)))

Finally, the following two events arrange that in certain contexts such
as theories (including the use of in-theory in events and hints),
member-eq and member are treated as references to member-equal.

     (add-macro-alias member-eq member-equal)
     (add-macro-alias member member-equal)

We conclude this topic by exploring the following recommendation made
in the documentation for equality-variants.

     For efficiency we recommend using the -equal equality variant, for
     example member-equal or ... :TEST 'equal, in certain contexts:
     defmacro, defpkg, defconst, and value-triple forms.

ACL2 reliies on the underlying Common Lisp for evaluation.  It also
processes events in the ACL2 logic.  In order to guarantee consistency
of its logical and Common Lisp evaluations, ACL2 uses a "safe mode" to
avoid ill-guarded calls.  In particular, consider the use of mbe in
execution of a call of an equality variant of a primitive, F, other
than its F-equal variant.  The mbe call discussed above requires a
connection to be established between the :logic and :exec forms.  For
example, if F is called with :TEST 'eql (either explicitly or as the
default), then ACL2 will call both F-eql-exec and F-equal, and check
that the two results are equal.

The following partial log illustrates the point above.  We define a
macro that calls member, and when a call of this macro is expanded
during processing of a subsequent definition, we see that two
membership functions are called on the same arguments.

     ACL2 !>(defmacro mac (lst)
              (list 'quote (and (true-listp lst)
                                (member 'c lst :test 'eq))))

     Summary
     Form:  ( DEFMACRO MAC ...)
     Rules: NIL
     Time:  0.01 seconds (prove: 0.00, print: 0.00, other: 0.01)
      MAC
     ACL2 !>(trace$ member-equal member-eq-exec)
      ((MEMBER-EQUAL) (MEMBER-EQ-EXEC))
     ACL2 !>(defun f () (mac (a b c d)))
     1> (ACL2_*1*_ACL2::MEMBER-EQ-EXEC C (A B C D))
       2> (MEMBER-EQ-EXEC C (A B C D))
       <2 (MEMBER-EQ-EXEC (C D))
     <1 (ACL2_*1*_ACL2::MEMBER-EQ-EXEC (C D))
     1> (ACL2_*1*_ACL2::MEMBER-EQUAL C (A B C D))
       2> (MEMBER-EQUAL C (A B C D))
       <2 (MEMBER-EQUAL (C D))
     <1 (ACL2_*1*_ACL2::MEMBER-EQUAL (C D))

     Since F is non-recursive, its admission is trivial.

If performance is an issue then we can avoid such a problem, for
example as follows.  In a fresh session, let us define a suitable
wrapper for calling member with :TEST 'eq.  This time, the trace in our
partial log shows that we have avoided calling two membership functions.

     ACL2 !>(defun mem-eq (x lst)
              (declare (xargs :guard (if (symbolp x)
                                         (true-listp lst)
                                       (symbol-listp lst))))
              (member x lst :test 'eq))
     [[ ... output omitted here ... ]]
      MEM-EQ
     ACL2 !>(defmacro mac (lst)
              (list 'quote (and (true-listp lst)
                                (mem-eq 'c lst))))

     Summary
     Form:  ( DEFMACRO MAC ...)
     Rules: NIL
     Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)
      MAC
     ACL2 !>(trace$ member-equal member-eq-exec mem-eq)
      ((MEMBER-EQUAL)
       (MEMBER-EQ-EXEC)
       (MEM-EQ))
     ACL2 !>(defun f () (mac (a b c d)))
     1> (ACL2_*1*_ACL2::MEM-EQ C (A B C D))
       2> (MEM-EQ C (A B C D))
       <2 (MEM-EQ (C D))
     <1 (ACL2_*1*_ACL2::MEM-EQ (C D))

     Since F is non-recursive, its admission is trivial.


File: acl2-doc-emacs.info,  Node: IGNORABLE,  Next: IGNORE,  Prev: EQUALITY-VARIANTS,  Up: PROGRAMMING

IGNORABLE    See *note DECLARE::.


File: acl2-doc-emacs.info,  Node: IGNORE,  Next: IRRELEVANT-FORMALS,  Prev: IGNORABLE,  Up: PROGRAMMING

IGNORE    See *note DECLARE::.


File: acl2-doc-emacs.info,  Node: IRRELEVANT-FORMALS,  Next: OPTIMIZE,  Prev: IGNORE,  Up: PROGRAMMING

IRRELEVANT-FORMALS    formals that are used but only insignificantly

Let fn be a function of n arguments.  Let x be the ith formal of fn.
We say x is "irrelevant in fn" if x does not occur in either the guard
or the measure for fn, and the value of (fn a1...ai...an) is
independent of ai.

The easiest way to define a function with an irrelevant formal is
simply not to use the formal in the body of the function.  Such formals
are said to be "ignored" by Common Lisp and a special declaration is
provided to allow ignored formals.  ACL2 makes a distinction between
ignored and irrelevant formals.  Note however that if a variable is
declared ignored or ignorable, then it will not be reported as
irrelevant.

An example of an irrelevant formal is x in the definition of fact below.

     (defun fact (i x)
       (declare (xargs :guard (and (integerp i) (<= 0 i))))
       (if (zerop i) 1 (* i (fact (1- i) (cons i x))))).

Observe that x is only used in recursive calls of fact; it never "gets
out" into the result.  ACL2 can detect some irrelevant formals by a
closure analysis on how the formals are used.  For example, if the ith
formal is only used in the ith argument position of recursive calls,
then it is irrelevant.  This is how x is used above.

It is possible for a formal to appear only in recursive calls but still
be relevant.  For example, x is *not* irrelevant below, even though it
only appears in the recursive call.

     (defun fn (i x) (if (zerop i) 0 (fn x (1- i))))

The key observation above is that while x only appears in a recursive
call, it appears in an argument position, namely i's, that is relevant.
(The function above can be admitted with a :measure of (+ (nfix i)
(nfix x)).)

Establishing that a formal is irrelevant, in the sense defined above,
can be an arbitrarily hard problem because it requires theorem proving.
For example, is x irrelevant below?

     (defun test (i j k x) (if (p i j k) 0 x))

Note that the value of (test i j k x) is independent of x -- thus
making x irrelevant -- precisely if (p i j k) is a theorem.  ACL2's
syntactic analysis of a definition does not guarantee to notice all
irrelevant formals.

We regard the presence of irrelevant formals as an indication that
something is wrong with the definition.  We cause an error on such
definitions and suggest that you recode the definition so as to
eliminate the irrelevant formals.  If you must have an irrelevant
formal, one way to "trick" ACL2 into accepting the definition, without
slowing down the execution of your function, is to use the formal in an
irrelevant way in the guard.  For example, to admit fact, above, with
its irrelevant x one might use

     (defun fact (i x)
       (declare (xargs :guard (and (integerp i) (<= 0 i) (equal x x))))
       (if (zerop i) 0 (* i (fact (1- i) (cons i x)))))

For those who really want to turn off this feature, we have provided a
way to use the acl2-defaults-table for this purpose; see *note
SET-IRRELEVANT-FORMALS-OK::.


File: acl2-doc-emacs.info,  Node: OPTIMIZE,  Next: REDEFINING-PROGRAMS,  Prev: IRRELEVANT-FORMALS,  Up: PROGRAMMING

OPTIMIZE    See *note DECLARE::.


File: acl2-doc-emacs.info,  Node: REDEFINING-PROGRAMS,  Next: SINGLE-THREADED-OBJECTS,  Prev: OPTIMIZE,  Up: PROGRAMMING

REDEFINING-PROGRAMS    an explanation of why we restrict redefinitions

ACL2 does not in general allow the redefinition of functions because
logical inconsistency can result:  previously stored theorems can be
rendered invalid if the axioms defining the functions involved are
changed.  However, to permit prototyping of both :program and :logic
mode systems, ACL2 permits redefinition if the user has accepted
logical responsibility for the consequences by setting
ld-redefinition-action to an appropriate non-nil value.  The refusal of
ACL2 to support the unrestricted redefinition of :program mode
functions may appear somewhat capricious.  After all, what are the
logical consequences of changing a definition if no axioms are involved?

Three important points should be made before we discuss redefinition
further.

The first is that ACL2 does support redefinition (of both :program and
:logic functions) when ld-redefinition-action is non-nil.

The second is that a "redefinition" that does not change the mode,
formals, guards, type declarations, stobjs, or body of a function is
considered redundant and is permitted even when ld-redefinition-action
is nil.  We recognize and permit redundant definitions because it is not
uncommon for two distinct books to share identical function
definitions.  When determining whether the body of a function is
changed by a proposed redefinition, we actually compare the
untranslated versions of the two bodies.  See *note TERM::.  For
example, redundancy is not recognized if the old body is (list a b) and
the new body is (cons a (cons b nil)).  We use the untranslated bodies
because of the difficulty of translating the new body in the presence
of the old syntactic information, given the possibility that the
redefinition might attempt to change the signature of the function,
i.e., the number of formals, the number of results, or the position of
single-threaded objects in either.

The third important point is that a "redefinition" that preserves the
formals, guard, types, stobjs, and body but changes the mode from
:program to :logic is permitted even when ld-redefinition-action is
nil.  That is what verify-termination does.

This note addresses the temptation to allow redefinition of :program
functions in situations other than the three described above.
Therefore, suppose ld-redefinition-action is nil and consider the cases.

Case 1.  Suppose the new definition attempts to change the formals or
more generally the signature of the function.  Accepting such a
redefinition would render ill-formed other :program functions which
call the redefined function.  Subsequent attempts to evaluate those
callers could arbitrarily damage the Common Lisp image.  Thus,
redefinition of :program functions under these circumstances requires
the user's active approval, as would be sought with
ld-redefinition-action '(:query . :overwrite).

Case 2.  Suppose the new definition attempts to change the body (even
though it preserves the signature).  At one time we believed this was
acceptable and ACL2 supported the quiet redefinition of :program mode
functions in this circumstance.  However, because such functions can be
used in macros and redundancy checking is based on untranslated bodies,
this turns out to be unsound!  (Aside: Perhaps this is not an issue if
the function takes state or a user-defined stobj argument; but we do
not further consider this distinction.)  Such redefinition is therefore
now prohibited.  We illustrate such an unsoundness below.  Let
foo-thm1.lisp be a book with the following contents.

     (in-package "ACL2")
     (defun p1 (x) (declare (xargs :mode :program)) (list 'if x 't 'nil))
     (defmacro p (x) (p1 x))
     (defun foo (x) (p x))
     (defthm foo-thm1 (iff (foo x) x) :rule-classes nil)

Note that the macro form (p x) translates to (if x t nil).  The
:program function p1 is used to generate this translation.  The
function foo is defined so that (foo x) is (p x) and a theorem about
foo is proved, namely, that (foo x) is true iff x is true.

Now let foo-thm2.lisp be a book with the following contents.

     (in-package "ACL2")
     (defun p1 (x) (declare (xargs :mode :program)) (list 'if x 'nil 't))
     (defmacro p (x) (p1 x))
     (defun foo (x) (p x))
     (defthm foo-thm2 (iff (foo x) (not x)) :rule-classes nil)

In this book, the :program function p1 is defined so that (p x) means
just the negation of what it meant in the first book, namely, (if x nil
t).  The function foo is defined identically -- more precisely, the
untranslated body of foo is identical in the two books, but because of
the difference between the two versions of the :program function p1 the
axioms defining the two foos are different.  In the second book we prove
the theorem that (foo x) is true iff x is nil.

Now consider what would happen if the signature-preserving redefinition
of :program functions were permitted and these two books were included.
When the second book is included the redefinition of p1 would be
permitted since the signature is preserved and p1 is just a :program.
But then when the redefinition of foo is processed it would be
considered redundant and thus be permitted.  The result would be a
logic in which it was possible to prove that (foo x) is equivalent to
both x and (not x).  In particular, the following sequence leads to a
proof of nil:

     (include-book "foo-thm1")
     (include-book "foo-thm2")
     (thm nil :hints (("Goal" :use (foo-thm1 foo-thm2))))

It might be possible to loosen the restrictions on the redefinition of
:program functions by allowing signature-preserving redefinition of
:program functions not involved in macro definitions.  Alternatively,
we could implement definition redundancy checking based on the
translated bodies of functions (though that is quite problematic).
Barring those two changes, we believe it is necessary simply to impose
the same restrictions on the redefinition of :program mode functions as
we do on :logic mode functions.


File: acl2-doc-emacs.info,  Node: SINGLE-THREADED-OBJECTS,  Next: STATE,  Prev: REDEFINING-PROGRAMS,  Up: PROGRAMMING

SINGLE-THREADED-OBJECTS    See *note STOBJ::.


File: acl2-doc-emacs.info,  Node: STATE,  Next: TIME-TRACKER,  Prev: SINGLE-THREADED-OBJECTS,  Up: PROGRAMMING

STATE    the von Neumannesque ACL2 state object

Note: If you are interested in programming with state, see *note
PROGRAMMING-WITH-STATE:: after reading the information below.

* Menu:

* ERROR-TRIPLES:: a common ACL2 programming idiom

* PROGRAMMING-WITH-STATE:: programming using the von Neumannesque ACL2 state object

The ACL2 state object is used extensively in programming the ACL2
system, and has been used in other ACL2 programs as well.  However,
most users, especially those interested in specification and
verification (as opposed to programming per se), need not be aware of
the role of the state object in ACL2, and will not write functions that
use it explicitly.  We say more about this point at the end of this
documentation topic.

The ACL2 state object is an example of a single-threaded object or
stobj.  ACL2 allows the user to define new single-threaded objects.
Generally, ACL2 may need to access the ACL2 state but should not
(cannot) change it except via a certain set of approved functions such
as defun and defthm.  If you need a state-like object to which you have
complete rights, you may want a stobj.

Key to the idea of our state is the notion of single-threadedness.  For
an explanation, see *note STOBJ::.  The upshot of it is that state is a
variable symbol with severe restrictions on its use, so that it can be
passed into only certain functions in certain slots, and must be
returned by those functions that "modify" it.  Henceforth, we do not
discuss single-threaded objects in general (which the user can introduce
with defstobj and defabsstobj) but one in particular, namely ACL2's
state object.

The global table is perhaps the most visible portion of the state
object.  Using the interface functions @ and assign, a user may bind
global variables to the results of function evaluations (much as an
Nqthm user exploits the Nqthm utility r-loop).  See *note @: atsign,
and see *note ASSIGN::.

ACL2 supports several facilities of a truly von Neumannesque state
machine character, including file io and global variables.  Logically
speaking, the state is a true list of the 14 components described
below.  There is a "current" state object at the top-level of the ACL2
command loop.  This object is understood to be the value of what would
otherwise be the free variable state appearing in top-level input.
When any command returns a state object as one of its values, that
object becomes the new current state.  But ACL2 provides von Neumann
style speed for state operations by maintaining only one physical (as
opposed to logical) state object.  Operations on the state are in fact
destructive.  This implementation does not violate the applicative
semantics because we enforce certain draconian syntactic rules
regarding the use of state objects.  For example, one cannot "hold on"
to an old state, access the components of a state arbitrarily, or
"modify" a state object without passing it on to subsequent
state-sensitive functions.

Every routine that uses the state facilities (e.g. does io, or calls a
routine that does io), must be passed a "state object." And a routine
must return a state object if the routine modifies the state in any
way.  Rigid syntactic rules governing the use of state objects are
enforced by the function translate, through which all ACL2 user input
first passes.  State objects can only be "held" in the formal parameter
state, never in any other formal parameter and never in any structure
(excepting a multiple-value return list field which is always a state
object).  State objects can only be accessed with the primitives we
specifically permit.  Thus, for example, one cannot ask, in code to be
executed, for the length of state or the car of state.  In the
statement and proof of theorems, there are no syntactic rules
prohibiting arbitrary treatment of state objects.

Logically speaking, a state object is a true list whose members are as
follows:

     Open-input-channels, an alist with keys that are symbols in
     package "ACL2-INPUT-CHANNEL".  The value (cdr) of each pair has
     the form ((:header type file-name open-time) . elements), where
     type is one of :character, :byte, or :object and elements is a
     list of things of the corresponding type, i.e. characters,
     integers of type (mod 255), or lisp objects in our theory.
     File-name is a string.  Open-time is an integer.  See *note IO::.

     Open-output-channels, an alist with keys that are symbols in
     package "ACL2-OUTPUT-CHANNEL".  The value of a pair has the form
     ((:header type file-name open-time) .  current-contents).  See
     *note IO::.

     Global-table, an alist associating symbols (to be used as "global
     variables") with values.  See *note @: atsign, and see *note
     ASSIGN::.

     T-stack, a list of arbitrary objects accessed and changed by the
     functions aref-t-stack and aset-t-stack.

     32-bit-integer-stack, a list of arbitrary 32-bit-integers accessed
     and changed by the functions aref-32-bit-integer-stack and
     aset-32-bit-integer-stack.

     Big-clock-entry, an integer, that is used logically to bound the
     amount of effort spent to evaluate a quoted form.

     Idates, a list of dates and times, used to implement the function
     print-current-idate, which prints the date and time.

     Acl2-oracle, a list of objects, used for example to implement the
     functions that let ACL2 report how much time was used, but
     inaccessible to the user.  Also see *note WITH-PROVER-TIME-LIMIT::.

     File-clock, an integer that is increased on every file opening and
     closing, and on each call of sys-call, and is used to maintain the
     consistency of the io primitives.

     Readable-files, an alist whose keys have the form (string type
     time), where string is a file name and time is an integer.  The
     value associated with such a key is a list of characters, bytes,
     or objects, according to type.  The time field is used in the
     following way:  when it comes time to open a file for input, we
     will only look for a file of the specified name and type whose
     time field is that of file-clock.  This permits us to have a
     "probe-file" aspect to open-file: one can ask for a file, find it
     does not exist, but come back later and find that it does now
     exist.

     Written-files, an alist whose keys have the form (string type
     time1 time2), where string is a file name, type is one of
     :character, :byte or :object, and time1 and time2 are integers.
     Time1 and time2 correspond to the file-clock time at which the
     channel for the file was opened and closed.  This field is
     write-only; the only operation that affects this field is
     close-output-channel, which conses a new entry on the front.

     Read-files, a list of the form (string type time1 time2), where
     string is a file name and time1 and time2 were the times at which
     the file was opened for reading and closed.  This field is write
     only.

     Writeable-files, an alist whose keys have the form (string type
     time).  To open a file for output, we require that the name, type,
     and time be on this list.

     List-all-package-names-lst, a list of true-listps.  Roughly
     speaking, the car of this list is the list of all package names
     known to this Common Lisp right now and the cdr of this list is
     the value of this state variable after you look at its car.  The
     function, list-all-package-names, which takes the state as an
     argument, returns the car and cdrs the list (returning a new state
     too).  This essentially gives ACL2 access to what is provided by
     CLTL's list-all-packages.  Defpkg uses this feature to ensure that
     the about-to-be-created package is new in this lisp.  Thus, for
     example, in akcl it is impossible to create the package "COMPILER"
     with defpkg because it is on the list, while in Lucid that package
     name is not initially on the list.

     User-stobj-alist, an alist which associates user-defined
     single-threaded objects (see *note STOBJ::) with their values.


We recommend avoiding the use of the state object when writing ACL2
code intended to be used as a formal model of some system, for several
reasons.  First, the state object is complicated and contains many
components that are oriented toward implementation and are likely to be
irrelevant to the model in question.  Second, there is currently not
much support for reasoning about ACL2 functions that manipulate the
state object, beyond their logical definitions.  Third, the
documentation about state is not as complete as one might wish.

User-defined single-threaded objects offer the speed of state while
giving the user complete access to all the fields.  See *note STOBJ::.

Again, if you are interested in programming with state see *note
PROGRAMMING-WITH-STATE::.


File: acl2-doc-emacs.info,  Node: ERROR-TRIPLES,  Next: PROGRAMMING-WITH-STATE,  Prev: STATE,  Up: STATE

ERROR-TRIPLES    a common ACL2 programming idiom

When evaluation returns three values, where the first two are ordinary
(non-stobj) objects and the third is the ACL2 state, the result may be
called an "error triple".  If an error triple is (mv erp val state), we
think of erp as an error flag and val as the returned value.  By
default, if the result of evaluating a top-level form is an error triple
(mv erp val state), then that result is not printed if erp is non-nil
or if val is the keyword :INVISIBLE, and otherwise val is printed with
a preceding space.  For example:

     ACL2 !>(+ 3 4) ; ordinary value
     7
     ACL2 !>(mv nil (+ 3 4) state) ; error triple, error component of nil
      7
     ACL2 !>(mv t (+ 3 4) state) ; error triple, non-nil error component
     ACL2 !>(mv nil :invisible state) ; special case for :INVISIBLE
     ACL2 !>

See *note PROGRAMMING-WITH-STATE:: for a discussion of error triples
and how to program with them.  Also see *note LD-ERROR-TRIPLES:: and
see *note LD:: for a discussion of the value :COMMAND-CONVENTIONS for
keyword :LD-POST-EVAL-PRINT.


File: acl2-doc-emacs.info,  Node: PROGRAMMING-WITH-STATE,  Prev: ERROR-TRIPLES,  Up: STATE

PROGRAMMING-WITH-STATE    programming using the von Neumannesque ACL2 state object

This documentation section introduces some common techniques for
programming using the ACL2 state object.  A prerequisite is thus a basic
understanding of that object; see *note STATE::.  We hope this section
is useful, and we invite suggestions for improvements and additions.

A supplement to this section is the ACL2 source code, which uses most
(and probably all) of the techniques discussed here.  That code is thus
a source of many examples, which can serve as "templates" to guide
one's own programming with state.

Recall that "ACL2" stands for "A Computational Logic for Applicative
Common Lisp".  In particular, the language is applicative: there are no
global variables or side effects.  For many purposes this does not feel
restrictive; for example, an ACL2 user who is programming in raw Lisp
may well be more comfortable coding a factorial function applicatively,
using recursion, rather than using iteration with repeated assignment
to the same variable.

However, there are situations that call for reading or modifying the
system state, such as performing input and output, signalling errors,
saving information from one computation for use in a later one, or
reading and updating system-level or environmental data.  This section
provides an introductory guide for writing functions that traffic in
state.  We emphasize that this guide is intended as an introduction;
more complete documentation may often be found by following links to
documentation of individual utilities, and again, more examples may be
found by searching the ACL2 source code for uses of the functions and
macros mentioned below.  The rest of this section is organized as
follows.

     ENABLING PROGRAMMING WITH STATE
     STATE GLOBALS AND THE ACL2 LOGICAL WORLD
     A REMARK ON GUARDS
     ERRORS AND ERROR TRIPLES
     SEQUENTIAL PROGRAMMING
     BINDING VARIABLES USING ERROR TRIPLES
     BINDING STATE GLOBAL VARIABLES
     INPUT AND OUTPUT
     TIMINGS
     ENVIRONMENT AND SYSTEM
     REMARKS ON EVENTS AND LD
     ADVANCED TOPICS

ENABLING PROGRAMMING WITH STATE

In order to submit a definition that takes state as a formal parameter,
you must either declare state as a :stobj (see *note XARGS::) or first
evaluate the following form at the top level: (set-state-ok t).

Consider for example the following trivial definition.

     (defun foo (state)
       (mv 3 state))

If you submit the above definition in a fresh ACL2 session, you will
get this error message.

       ACL2 Error in ( DEFUN FOO ...):  The variable symbol STATE should not
       be used as a formal parameter of a defined function unless you are
       aware of its unusual status and the restrictions enforced on its use.
       See :DOC set-state-ok.

If first you evaluate (set-state-ok t), you can admit the above
definition.  Alternatively, you can declare state as a :stobj, as
follows.

     (defun foo (state)
       (declare (xargs :stobjs state))
       (mv 3 state))

A difference in the two approaches is that for the latter, a guard proof
obligation is generated by default.  See the section below entitled "A
remark on guards".

STATE GLOBALS AND THE ACL2 LOGICAL WORLD

Recall (see *note STATE::) that one of the fields of the ACL2 state
object is the global-table, which logically is an alist associating
symbols, known as "state globals" or "state global variables", with
values.  But no such alist actually exists in the implementation.
Instead, ACL2 provides utilities for reading state globals -- see *note
@: atsign. and see *note F-GET-GLOBAL:: -- and utilities for writing
them -- see *note ASSIGN:: and see *note F-PUT-GLOBAL::.  The following
log shows how they work; further explanation follows below.

     ACL2 !>(assign my-var (+ 3 4))
      7
     ACL2 !>(@ my-var)
     7
     ACL2 !>(f-put-global 'my-var (+ 1 5) state)
     <state>
     ACL2 !>(f-get-global 'my-var state)
     6
     ACL2 !>

Note that the first result is indented by one space.  This is ACL2's
way to indicate that the assign expression returned an "error triple"
and that no error was signalled.  We discuss error triples in more
detail below; also see *note ERROR-TRIPLES::.

As illustrated above, the output signatures of the utilities for
assigning to state globals differ from each other as follows:
f-put-global returns state, but assign returns an error triple (mv nil
val state) where val is the value assigned to the state global.  The
output signatures of the utilities for reading, @ and f-get-global, are
identical.  In fact, the form (f-get-global 'my-var state) is the
single-step macroexpansion of the form (@ my-var), as can be confirmed
using trans1.

     ACL2 !>:trans1 (@ my-var)
      (F-GET-GLOBAL 'MY-VAR STATE)
     ACL2 !>

State globals are useful for conveying persistent state information.
Consider for example the utility set-inhibit-output-lst.  The form
(set-inhibit-output-lst '(prove proof-tree)) is approximately equivalent
to (assign inhibit-output-lst '(prove proof-tree)).  We say
"approximately" because set-inhibit-output-lst additionally does some
error checking to insure that all the tokens in the new list are legal.
When deciding whether to print output, the ACL2 system reads the value
of state global variable inhibit-output-lst.

A particularly useful state global is current-acl2-world, whose value is
the ACL2 logical world.  Because the ACL2 world is commonly accessed in
applications that use the ACL2 state, ACL2 provides a function that
returns the world: (w state) = (f-get-global 'current-acl2-world
state).  While it is common to read the world, only functions set-w and
set-w! are available to write the world, but these are untouchable and
these should generally be avoided except by system implementors
(pl[remove-untouchable]).

A REMARK ON GUARDS

For a function definition (see *note DEFUN::), if state is specified as
a stobj as with the form (declare (xargs :stobjs state)), then the
guard for that function is considered to include the condition (state-p
state).  By default, guard verification will then be performed.

We can illustrate this point by modifying the example above as follows,
to read the value of state global gag-mode.

     (defun foo (state)
       (declare (xargs :stobjs state))
       (f-get-global 'gag-mode state))

If you try this in a fresh ACL2 session, the proof will fail with the
following key checkpoint, which says that the state global gag-mode is
bound in the global-table of the state.

       (IMPLIES (STATE-P1 STATE)
                (ASSOC-EQUAL 'GAG-MODE (NTH 2 STATE)))

How can we deal with this proof failure?   One way is simply to ignore
the issue by defining the function in :program mode, as follows.

     (defun foo (state)
       (declare (xargs :stobjs state
                       :mode :program))
       (f-get-global 'gag-mode state))

Perhaps a better way is to strengthen the guard to assert that the
indicated state global is bound, as follows.

     (defun foo (state)
       (declare (xargs :guard (boundp-global 'gag-mode state)
                       :stobjs state))
       (f-get-global 'gag-mode state))

Also see *note GUARD-MISCELLANY:: for a discussion of how guards are
generated from xargs fields of declare forms, specifically, for keywords
:guard and :stobjs.

ERRORS AND ERROR TRIPLES

When evaluation returns three values, where the first two are ordinary
objects and the third is the ACL2 state, the result may be called an
"error triple".  (Whether it is treated as an error triple depends on
the programmer.)  Error triples are often denoted (mv erp val state),
and common ACL2 programming idioms treat erp as a flag indicating
whether an error is being signalled and val as the "value" computed.
Also see *note ERROR-TRIPLES::.

Even ACL2 users who are not programmers encounter error triples, because
these are the values returned by evaluation of ACL2 events.  Consider
the following log, where the only user input is the defun form
following the prompt.

     ACL2 !>(defun foo (x) x)

     Since FOO is non-recursive, its admission is trivial.  We observe that
     the type of FOO is described by the theorem (EQUAL (FOO X) X).

     Summary
     Form:  ( DEFUN FOO ...)
     Rules: NIL
     Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)
      FOO
     ACL2 !>

All output above results from explicit calls of output functions,
except for the next-to-last line, which contains FOO.  Notice the
single-space indentation preceding FOO.  That space indicates that in
fact, the value returned by evaluation of the defun form is the error
triple whose error flag is nil and whose computed value is FOO.  By
default, ACL2 prints any error triple (mv nil val state) by inserting a
space before printing val.  You can change the default by setting state
global ld-post-eval-print to t; notice how the same result is printed
below.

     ACL2 !>:u
               0:x(EXIT-BOOT-STRAP-MODE)
     ACL2 !>(set-ld-post-eval-print t state)
     (NIL T <state>)
     ACL2 !>(defun foo (x) x)

     Since FOO is non-recursive, its admission is trivial.  We observe that
     the type of FOO is described by the theorem (EQUAL (FOO X) X).

     Summary
     Form:  ( DEFUN FOO ...)
     Rules: NIL
     Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)
     (NIL FOO <state>)
     ACL2 !>

The way error triples are printed by ld is controlled not only by state
global ld-post-eval-print, but also by state global ld-error-triples.
These are examples of "ld specials"; see *note LD::, see *note
LD-POST-EVAL-PRINT::, and see *note LD-ERROR-TRIPLES::.

It is so common to produce an error triple whose first (error flag)
component is nil that ACL2 provides a handy macro, value, for this
purpose.  Thus, (value <expression>) is equivalent to (mv nil
<expression> state).  Also see *note VALUE-TRIPLE:: for a similar
construct that is a legal event form.

We turn now to the topic of errors.  The macro ER "causes" an error,
but there are really two quite different kinds of errors: "soft" and
"hard" errors.  We use the term "soft error" to refer to a form that
returns an error triple (mv erp val state) for which erp is non-nil.
Soft errors do not interrupt the normal flow of evaluation: the error
triple is returned to the caller which interprets the erp flag and val
as directed by the programmer.  Macros discussed below make it
convenient to think about soft errors as short-circuiting the
computation.  Hard errors, on the other hand, do actually rip control
away from the current evaluation and return it to the top-level loop.
Logically speaking, expressions that cause hard errors return nil in
the error case, but the nil is never seen in actual evaluation because
control does not return to the caller.

Note that the function abort!, which you can invoke by typing :a!,
always returns to the top level.  Note that ACL2 can prove that
(abort!) returns nil but that this cannot be confirmed by computation.

     ACL2 !>(thm (equal (abort!) nil))

     Q.E.D.

     Summary
     Form:  ( THM ...)
     Rules: ((:FAKE-RUNE-FOR-TYPE-SET NIL)
             (:TYPE-PRESCRIPTION ABORT!))
     Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)

     Proof succeeded.
     ACL2 !>(equal (abort!) nil)
     Abort to ACL2 top-level
     ...
     ACL2 !>

(What actually happens with a hard error, including non-default cases,
is a bit subtle; most readers will probably want to skip this
paragraph.  The read-eval-print loop implemented by ld is implemented
by a call of the ACL2 evaluator function, trans-eval, on each input
form.  If a hard error occurs during evaluation of an input form, its
trans-eval call will return with a soft error.  Ld, in turn handles
that soft error appropriately; see *note LD-ERROR-ACTION::.)

The most common way to signal errors is the macro er, which prints a
formatted error message and returns a soft or hard error as specified
by the call.  Note however that soft errors are signalled using :program
mode functions.

Since the output signatures of soft and hard errors are different --
hard errors "return" a single value while soft errors return a triple --
mixing them in an expression requires embedding the hard error form in
(an irrelevant) triple, as illustrated below.  All branches of the
expression must produce an error triple if any branch does.

     ACL2 !>(defun chk-find-or-abort (e x state)
              (declare (xargs :mode :program))
              (if (endp x)
                  (value                          ; Note use of VALUE!
                    (er hard 'chk-find-or-abort
                        "Did not find ~x0!"
                         e))
                  (if (not (integerp (car x)))
                      (er soft 'chk-find-or-abort
                          "Non-integer, ~x0, in list!"
                          (car x))
                      (if (eql (car x) e)
                          (value x)
                          (chk-find-or-abort e (cdr x) state)))))

     Summary
     Form:  ( DEFUN CHK-FIND-OR-ABORT ...)
     Rules: NIL
     Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)
      CHK-FIND-OR-ABORT
     ACL2 !>(chk-find-or-abort 3 '(1 2 3 4 5) state)
      (3 4 5)
     ACL2 !>(chk-find-or-abort 3 '(1 A 3 4 5) state)


     ACL2 Error in CHK-FIND-OR-ABORT:  Non-integer, A, in list!

     ACL2 !>(chk-find-or-abort 3 '(1 2 4 5) state)

     HARD ACL2 ERROR in CHK-FIND-OR-ABORT:  Did not find 3!
     ...
     ACL2 !>

See *note ER:: for further discussion of errors.  For some other
individual topics related to errors see *note ASSERT$::, see *note
BREAK-ON-ERROR::, see *note ERROR1::, see *note HARD-ERROR::, see *note
ILLEGAL::, and see *note LD-ERROR-TRIPLES::.

In the next section we discuss soft errors further, in the context of
programming.

SEQUENTIAL PROGRAMMING

This section describes handy ways to modify state in steps, using
macros that implement a sequence of let or mv-let bindings.  For
example, suppose you want to assign the values 1 and 2 to two state
globals one-var and two-var, respectively.  Because of ACL2's syntactic
restrictions on state, it is not legal simply to write (f-put-global
'two-var 2 (f-put-global 'one-var 1 state)).  However, let comes to the
rescue as follows.

     (let ((state (f-put-global 'one-var 1 state)))
       (let ((state (f-put-global 'two-var 2 state)))
         state))

It is so common to bind state successively in such a manner that ACL2
provides a macro, pprogn, for this purpose.  Thus, an equivalent
solution to the problem above is

     (pprogn (f-put-global 'one-var 1 state)
             (f-put-global 'two-var 2 state)
             state)

or, more simply, as follows.

     (pprogn (f-put-global 'one-var 1 state)
             (f-put-global 'two-var 2 state))

See *note PPROGN::.  Note that the last form is allowed to return
multiple values; the only requirement on the last form is that its
value include state.

It is also common to update the state using a sequence of forms such
that each returns an error triple, where the intention is for
evaluation to short-circuit immediately if a soft error is encountered.
Suppose <expr1> and <expr2> are expressions that return error triples,
where the state components of the error triples might be updated, and
one wishes to evaluate <expr1> and then <expr2>, returning the
(multiple) values returned by <expr2> unless the error triple returned
by <expr1> is a soft error, in which case that error triple is returned.
One can of course do so as follows.

     (mv-let (erp val state)
             <expr1>
             (cond (erp (mv erp val state))
                   (t <expr2>)))

But ACL2 provides a handy macro, er-progn, for this purpose.  The
following code is equivalent to the code just above.

     (er-progn <expr1> <expr2>)

See *note ER-PROGN:: for more details.  Note that unlike pprogn, the
return signature for the last expression must be the same as that of the
others: an error triple.

Let's consider how to use pprogn and er-progn together.  In the
following example f1 and f2 both return state, while each of g1 and g2
returns an error triple.  The following code modifies state by
executing these in the order f1, g1, f2, and finally g2, returning (mv
nil val state) where val is the value component of the error triple
returned by g2 -- except we return a soft error if g1 or g2 returns a
soft error.

     (pprogn (f1 x state)
             (er-progn (g1 x state)
                       (pprogn (f2 x state)
                               (g2 x state))))

Finally, consider the events progn and progn!.  These have similar
behavior to that of er-progn.  However, progn and progn! may only be
used in event contexts, for example at the top level or immediately
underneath a call of encapsulate or progn, while er-progn has no such
restriction.  So when writing code, use er-progn rather than progn or
progn!.  In particular, the body of a defun must not have any calls of
progn (or of progn!  either), and the same restriction holds for any
code to be executed, such as the body of a make-event form.

BINDING VARIABLES USING ERROR TRIPLES

In this section we discuss the macro er-let*, which is a variant of the
special form, let*, that is useful when programming with state.

The macro er-let* is useful when binding variables to the value
components of error triples.  It is actually quite similar to er-progn,
described above, except that er-let* binds variables.  First consider
the following example.

     (er-let* ((x1 (f1 state))
               (x2 (f2 x1 state)))
       (value (cons x1 x2)))

The code just above is essentially equivalent to writing the following.

     (mv-let (erp x1 state)
             (f1 state)
             (cond (erp (mv erp x1 state))
                   (t (mv-let (erp x2 state)
                              (f2 x1 state)
                              (cond (erp (mv erp x2 state))
                                    (t (value (cons x1 x2))))))))

As suggested by the example above, er-let* has the same syntax as let*,
except that declarations are not supported.  (But note that ignore
declarations are not needed; all variables that are bound are also
used, at least in the error case.  Consider replacing (cons x1 x2) by
nil in the example displayed immediately above, and note that x1 and x2
are still used.)  However, unlike let*, er-let* requires that for each
binding (var expr), the expression expr must evaluate to an error
triple and, moreover, it requires that the second argument (the "body")
of er-let* must evaluate to an error triple.  If one of the variable
expressions (e.g., the f1 and f2 calls above) signals an error, its
error triple is returned as the value of the er-let*.

Of course, soft errors can be "caught" by using mv-let instead of
er-let* and simply ignoring the error flag or, more generally, by
returning a non-erroneous error triple even if the error flag was on.

BINDING STATE GLOBAL VARIABLES

In this section we introduce a utility, state-global-let*, that is an
analogue of let* for state global variables.  Consider the following
example.

     (state-global-let*
      ((inhibit-output-lst (add-to-set-eq 'summary (@ inhibit-output-lst))))
      (thm (equal x x)))

This form binds state global variable inhibit-output-lst to the result
of adding the symbol, summary, to the current value of that state
global.  Thus (see *note SET-INHIBIT-OUTPUT-LST::), the usual summary
is not printed when evaluating this call of thm.

See *note STATE-GLOBAL-LET*:: for more complete documentation.

INPUT AND OUTPUT

In ACL2, most input and output involves the ACL2 state.  See *note IO::.

TIMINGS

For how to obtain the time elapsed since the start of the ACL2 session,
see *note READ-RUN-TIME::.

For a utility for saving times into the ACL2 state and for printing
those saved times, see the community book misc/save-time.lisp.

To time an evaluation (though this really isn't about state), see *note
TIME$::.

ENVIRONMENT AND SYSTEM

Next, we mention briefly some ways in which ACL2 interacts with its
environment using the ACL2 state.

For how to read and write environment variables, see *note GETENV$:: and
see *note SETENV$::.

For how to run a command in the host operating system, see *note
SYS-CALL::.

REMARKS ON EVENTS AND LD

In general, undefined or surprising behavior may occur when using ACL2
events or calling ld in your programs.  In some cases ACL2 enforces
restrictions against these uses.  We strongly discourage using ld in
programs, as it has been designed to be called only at the top level of
a read-eval-print loop.

There is also a restriction on contexts in which make-event may be
called: it may only be called in a context where an event is expected,
such as the top level, in a book, or as an argument of encapsulate or
progn.  The reason is that ACL2 does very subtle and careful tracking
of make-event expansions; and it is only able to do this in event
contexts, where it is able to carry out such tracking accurately.

ADVANCED TOPICS

ACL2 provides the function trans-eval to evaluate an arbitrary form
(after translating it to a term, i.e., into internal form).  For more
information, we refer to reader to comments in the definition of
trans-eval in the ACL2 source code.  There are also many examples of its
use in the ACL2 sources.

For a function that provides the true absolute filename, with soft links
resolved, see *note CANONICAL-PATHNAME::.

For a function that returns a check-sum on the characters in a channel,
see *note CHECK-SUM::.

To obtain a random number, see *note RANDOM$::.

If you are programming in raw-mode (see *note SET-RAW-MODE::) or in raw
Lisp, use the variable *the-live-state* in place of the variable state.

We invite suggestions for additional advanced topics.


File: acl2-doc-emacs.info,  Node: TIME-TRACKER,  Next: TYPE,  Prev: STATE,  Up: PROGRAMMING

TIME-TRACKER    display time spent during specified evaluation

The time-tracker macro is a utility for displaying time spent during
specified evaluation.  In general, the user provides this specification.
However, ACL2 itself uses this utility for tracking uses of its
tau-system reasoning utility (see *note TIME-TRACKER-TAU::).  We
discuss that use as an example before discussing the general form for
calls of time-tracker.

Note that by default, the time being tracked is runtime (cpu time); to
switch to realtime (elapsed time), see *note GET-INTERNAL-TIME::.

Remark for ACL2(p) users (see *note PARALLELISM::): time-tracker is
merely a no-op in ACL2(p).

During the development of the tau-system, we were concerned about the
possibility that it would slow down proofs without any indication of
how one might avoid the problem.  We wanted a utility that would alert
the user in such situations.  However, the tau-system code does not
return state, so we could not track time spent in the state.  We
developed the time-tracker utility to track time and print messages,
and we did it in a general way so that others can use it in their own
code.  Here is an example of such a message that could be printed
during a proof.

     TIME-TRACKER-NOTE [:TAU]: Elapsed runtime in tau is 2.58 secs; see
     :DOC time-tracker-tau.

And here is an example of such a message that could be printed at the
end of the proof.

     TIME-TRACKER-NOTE [:TAU]: For the proof above, the total time spent
     in the tau system was 20.29 seconds.  See :DOC time-tracker-tau.

The time-tracker utility tracks computation time spent on behalf of a
user-specified "tag".  In the case of the tau-system, we chose the tag,
:tau.  The first argument of time-tracker is the tag, which in our
running example is always :tau.  Note that although all arguments of
time-tracker are evaluated, the first argument is typically a keyword
and the second is always a keyword, and such arguments evaluate to
themselves.

An ACL2 function invoked at the start of a proof includes approximately
the following code.

     (progn$
      (time-tracker :tau :end)
      (time-tracker :tau :init
                    :times '(1 2 3 4 5)
                    :interval 5
                    :msg "Elapsed runtime in tau is ~st secs; see :DOC ~
                          time-tracker-tau.~|~%")
      ...)

The first time-tracker call (above) ends any existing time-tracking for
tag :tau.  One might have expected it be put into code managing the
proof summary, but we decided not to rely on that code being executed,
say, in case of an interrupt.  When a given tag is not already being
time-tracked, then :end is a no-op (rather than an error).

The second time-tracker call (above) initiates time-tracking for the
tag, :tau.  Moreover, it specifies the effect of the :print? keyword.
Consider the following abbreviated definition from the ACL2 source code.

     (defun tau-clausep-lst-rec (clauses ens wrld ans ttree state calist)
       (cond
        ((endp clauses)
         (mv (revappend ans nil) ttree calist))
        (t (mv-let
            (flg1 ttree1 calist)
            (tau-clausep (car clauses) ens wrld state calist)
            (prog2$ (time-tracker :tau :print?)
                    (tau-clausep-lst-rec (cdr clauses) ...))))))

Notice that (time-tracker :tau :print?) is executed immediately after
tau-clausep is called.  The idea is to check whether the total time
elapsed inside the tau-system justifies printing a message to the user.
The specification of :times '(1 2 3 4 5) in the :init form above says
that a message should be printed after 1 second, after 2 seconds, ...,
and after 5 seconds.  Thereafter, the specification of :interval 5 in
the :init form above says that each time we print, at least 5 additional
seconds should have been tracked before (time-tracker :tau :print?)
prints again.  Finally, the :msg keyword above specifies just what
should be printed.  If it is omitted, then a reasonable default message
is printed (as discussed below), but in this case we wanted to print a
custom message.  The :msg string above is what is printed using
formatted printing (see *note FMT::), where the character #\t is bound
to a string giving a decimal representation with two decimal points of
the time tracked so far for tag :tau.  (As our general description
below points out, :msg can also be a "message" list rather than a
string.)

But when is time actually tracked for :tau?  Consider the following
definition from the ACL2 source code.

     (defun tau-clausep-lst (clauses ens wrld ans ttree state calist)
       (prog2$ (time-tracker :tau :start)
               (mv-let
                (clauses ttree calist)
                (tau-clausep-lst-rec clauses ens wrld ans ttree state calist)
                (prog2$ (time-tracker :tau :stop)
                        (mv clauses ttree calist)))))

The two calls of time-tracker above first start, and then stop,
time-tracking for the tag, :tau.  Thus, time is tracked during
evaluation of the call of tau-clausep-lst-rec, which is the function
(discussed above) that does the tau-system's work.

Finally, as noted earlier above, ACL2 may print a time-tracking message
for tag :tau at the end of a proof.  The ACL2 function print-summary
contains essentially the following code.

     (time-tracker :tau :print?
                   :min-time 1
                   :msg "For the proof above, the total runtime ~
                         spent in the tau system was ~st seconds.  ~
                         See :DOC time-tracker-tau.~|~%")

The use of :min-time says that we are to ignore the :times and
:interval established by the :init call described above, and instead,
print a message if and only if at least 1 second (since 1 is the value
of keyword :min-time) has been tracked for tag :tau.  Formatted printing
(see *note FMT::) is used for the value of :msg, where the character
#\t is bound to a decimal string representation of the time in seconds,
as described above.

The example above covers all legal values for the second argument of
time-tracker and discusses all the additional legal keyword arguments.
We conclude with a precise discussion of all arguments.  Note that all
arguments are evaluated; thus when we refer to an argument, we are
discussing the value of that argument.  All times discussed are
runtimes, i.e., cpu times, unless that default is changed; see *note
GET-INTERNAL-TIME::.

     General forms:

     (time-tracker t)        ; enable time-tracking (default)

     (time-tracker nil)      ; disable time-tracking

     (time-tracker tag       ; a symbol other than t or nil
                   option    ; :init, :end, :start, :stop, or :print?
                   ;; keyword arguments:
                   :times    ; non-nil if and only if option is :init
                   :interval ; may only be non-nil with :init option
                   :min-time ; may only be non-nil with :print? option
                   :msg      ; may only be non-nil with :init and :print? options

Time-tracking is enabled by default.  If the first argument is t or
nil, then no other arguments are permitted and time-tracking is enabled
or disabled, respectively.  When time-tracking is disabled, nothing
below takes place.  Thus we assume time-tracking is enabled for the
remainder of this discussion.  We also assume below that the first
argument is neither t nor nil.

We introduce some basic notions about time-tracking.  A given tag, such
as :tau in the example above, might or might not currently be "tracked":
:init causes the specified tag to be tracked, while :end causes the
specified tag not to be tracked.  If the tag is being tracked, the tag
might or might not be "active": :start causes the tag to be in an active
state, whie :stop causes the tag not to be active.  Note that only
tracked tags can be in an active or inactive state.  For a tag that is
being tracked, the "accumulated time" is the total time spent in an
active state since the time that the tag most recently started being
tracked, and the "checkpoint list" is a non-empty list of rational
numbers specifying when printing may take place, as described below.

We now consider each legal value for the second argument, or "option",
for a call of time-tracker on a given tag.

:Init specifies that the tag is to be tracked.  It also establishes
defaults for the operation of :print?, as described below, using the
:times, :interval, and :msg keywords.  Of these three, only :times is
required, and its value must be a non-empty list of rational numbers
specifying the initial checkpoint list for the tag.  It is an error to
specify :init if the tag is already being tracked.  (So if you don't
care whether or not the tag is already being tracked and you want to
initiate tracking for that tag, use :end first.)

:End specifies that if the tag is being tracked, then it should nstop
being tracked.  If the tag is not being tracked, then :end has no
effect.

:Start specifies that the tag is to be active.  It is an error to
specify :start if the tag is not being tracked or is already active.

:Stop specifies that the tag is to stop being active.  It is an error to
specify :stop if the tag is not being tracked or is not active.

:Print? specifies that if the tag is being tracked (not necessarily
active), then a message should be printed if a suitable condition is
met.  The nature of that message and that condition depend on the
keyword options supplied with :print? as well as those supplied with
the :init option that most recently initiated tracking.  :Print? has no
effect if the tag is not being tracked, except that if certain keyword
values are checked if supplied with :print?: :min-time must be a
rational number or nil, and :msg must be either a string, a true-list
whose car is a string, or nil.  The remainder of this documentation
describes the :print? option in detail under the assumption that the
tag is being tracked: first, giving the conditions under which it
causes a message to be printed, and second, explaining what is printed.

When :print? is supplied a non-nil value of :min-time, that value must
be a rational number, in which case a message is printed if the
accumulated time for the tag is at least that value.  Otherwise a
message is printed if the accumulated time is greater than or equal to
the car of the checkpoint list for the tag.  In that case, the tracking
state for the tag is updated in the following two ways.  First, the
checkpoint list is scanned from the front and as long as the
accumulated time is greater than or equal to the car of the remaining
checkpoint list, that car is popped off the checkpoint list.  Second,
if the checkpoint list has been completely emptied and a non-nil
:interval was supplied when tracking was most recently initiated with
the :init option, then the checkpoint list is set to contain a single
element, namely the sum of the accumulated time with that value of
:interval.

Finally, suppose the above criteria are met, so that :print? results in
printing of a message.  We describe below the message, msg, that is
printed.  Here is how it is printed (see *note FMT::), where
seconds-as-decimal-string is a string denoting the number of seconds of
accumulated time for the tag, with two digits after the decimal point.

     (fms "TIME-TRACKER-NOTE [~x0]: ~@1~|"
          (list (cons #0 tag)
                (cons #1 msg)
                (cons #t seconds-as-decimal-string))
          (proofs-co state) state nil)

The value of msg is the value of the :msg keyword supplied with
:print?, if non-nil; else, the value of :msg supplied when most
recently initialization with the :init option, if non-nil; and
otherwise, the string "~st s" (the final "s" abbreviating the word
"seconds").  It is convenient to supply :msg as a call (msg str arg-0
arg-1 ... arg-k), where str is a string and each arg-i is the value to
be associated with #\i upon formatted printing (as with fmt) of the
string str.


File: acl2-doc-emacs.info,  Node: TYPE,  Next: ZERO-TEST-IDIOMS,  Prev: TIME-TRACKER,  Up: PROGRAMMING

TYPE    See *note DECLARE::.


File: acl2-doc-emacs.info,  Node: ZERO-TEST-IDIOMS,  Prev: TYPE,  Up: PROGRAMMING

ZERO-TEST-IDIOMS    how to test for 0

Below are six commonly used idioms for testing whether x is 0.  Zip and
zp are the preferred termination tests for recursions down the integers
and naturals, respectively.

     idiom       logical              guard                 primary
                 meaning                                 compiled code*

     (equal x 0) (equal x 0)          t                   (equal x 0)

     (eql x 0)   (equal x 0)          t                   (eql x 0)

     (zerop x)   (equal x 0)          x is a number       (= x 0)

     (= x 0)     (equal x 0)          x is a number       (= x 0)

     (zip x)     (equal (ifix x) 0)   x is an integer     (= x 0)

     (zp x)      (equal (nfix x) 0)   x is a natural      (int= x 0)

     (zpf x)     (equal (nfix x) 0)   x is a fixnum >= 0  (eql (the-fixnum x) 0)

*See *note GUARDS-AND-EVALUATION::, especially the subsection titled
"Guards and evaluation V: efficiency issues".  Primary code is relevant
only if guards are verified.  The "compiled code" shown is only
suggestive.

The first four idioms all have the same logical meaning and differ only
with respect to their executability and efficiency.  In the absence of
compiler optimizing, (= x 0) is probably the most efficient, (equal x
0) is probably the least efficient, and (eql x 0) is in between.
However, an optimizing compiler could always choose to compile (equal x
0) as (eql x 0) and, in situations where x is known at compile-time to
be numeric, (eql x 0) as (= x 0).  So efficiency considerations must, of
course, be made in the context of the host compiler.

Note also that (zerop x) and (= x 0) are indistinguishable.  They have
the same meaning and the same guard, and can reasonably be expected to
generate equally efficient code.

Note that (zip x) and (zp x) do not have the same logical meanings as
the others or each other.  They are not simple tests for equality to 0.
They each coerce x into a restricted domain, zip to the integers and zp
to the natural numbers, choosing 0 for x when x is outside the domain.
Thus, 1/2, #c(1 3), and 'abc, for example, are all "recognized" as zero
by both zip and zp.  But zip reports that -1 is different from 0 while
zp reports that -1 "is" 0.  More precisely, (zip -1) is nil while (zp
-1) is t.

Note that the last five idioms all have guards that restrict their
Common Lisp executability.  If these last five are used in situations
in which guards are to be verified, then proof obligations are incurred
as the price of using them.  If guard verification is not involved in
your project, then the first five can be thought of as synonymous.

Zip and zp are not provided by Common Lisp but are ACL2-specific
functions.  Why does ACL2 provide these functions?  The answer has to
do with the admission of recursively defined functions and efficiency.
Zp is provided as the zero-test in situations where the controlling
formal parameter is understood to be a natural number.  Zip is
analogously provided for the integer case.  We illustrate below.

Here is an admissible definition of factorial

     (defun fact (n) (if (zp n) 1 (* n (fact (1- n)))))

Observe the classic recursion scheme: a test against 0 and recursion by
1-.  Note however that the test against 0 is expressed with the zp
idiom.  Note also the absence of a guard making explicit our intention
that n is a natural number.

This definition of factorial is readily admitted because when (zp n)

is false (i.e., nil) then n is a natural number other than 0 and so (1-
n) is less than n.  The base case, where (zp n) is true, handles all
the "unexpected" inputs, such as arise with (fact -1) and (fact 'abc).
When calls of fact are evaluated, (zp n) checks (integerp n) and (> n
0).  Guard verification is unsuccessful for this definition of fact
because zp requires its argument to be a natural number and there is no
guard on fact, above.  Thus the primary raw lisp for fact is
inaccessible and only the :logic definition (which does runtime "type"
checking) is used in computation.  In summary, this definition of
factorial is easily admitted and easily manipulated by the prover but
is not executed as efficiently as it could be.

Runtime efficiency can be improved by adding a guard to the definition.

     (defun fact (n)
       (declare (xargs :guard (and (integerp n) (>= n 0))))
       (if (zp n) 1 (* n (fact (1- n)))))

This guarded definition has the same termination conditions as before -
termination is not sensitive to the guard.  But the guards can be
verified.  This makes the primary raw lisp definition accessible during
execution.  In that definition, the (zp n) above is compiled as (= n
0), because n will always be a natural number when the primary code is
executed.  Thus, by adding a guard and verifying it, the elegant and
easily used definition of factorial is also efficiently executed on
natural numbers.

Now let us consider an alternative definition of factorial in which (=
n 0) is used in place of (zp n).

     (defun fact (n) (if (= n 0) 1 (* n (fact (1- n)))))

This definition does not terminate.  For example (fact -1) gives rise
to a call of (fact -2), etc.  Hence, this alternative is inadmissible.
A plausible response is the addition of a guard restricting n to the
naturals:

     (defun fact (n)
      (declare (xargs :guard (and (integerp n) (>= n 0))))
      (if (= n 0) 1 (* n (fact (1- n)))))

But because the termination argument is not sensitive to the guard, it
is still impossible to admit this definition.  To influence the
termination argument one must change the conditions tested.  Adding a
runtime test that n is a natural number would suffice and allow both
admission and guard verification.  But such a test would slow down the
execution of the compiled function.

The use of (zp n) as the test avoids this dilemma.  Zp provides the
logical equivalent of a runtime test that n is a natural number but the
execution efficiency of a direct = comparison with 0, at the expense of
a guard conjecture to prove.  In addition, if guard verification and
most-efficient execution are not needed, then the use of (zp n) allows
the admission of the function without a guard or other extraneous
verbiage.

While general rules are made to be broken, it is probably a good idea
to get into the habit of using (zp n) as your terminating "0 test"
idiom when recursing down the natural numbers.  It provides the logical
power of testing that n is a non-0 natural number and allows efficient
execution.

We now turn to the analogous function, zip.  Zip is the preferred
0-test idiom when recursing through the integers toward 0.  Zip
considers any non-integer to be 0 and otherwise just recognizes 0.  A
typical use of zip is in the definition of integer-length, shown below.
(ACL2 can actually accept this definition, but only after appropriate
lemmas have been proved.)

     (defun integer-length (i)
       (declare (xargs :guard (integerp i)))
       (if (zip i)
           0
         (if (= i -1)
           0
           (+ 1 (integer-length (floor i 2))))))

Observe that the function recurses by (floor i 2).  Hence, calling the
function on 25 causes calls on 12, 6, 3, 1, and 0, while calling it on
-25 generates calls on -13, -7, -4, -2, and -1.  By making (zip i) the
first test, we terminate the recursion immediately on non-integers.
The guard, if present, can be verified and allows the primary raw lisp
definition to check (= i 0) as the first terminating condition (because
the primary code is executed only on integers).


File: acl2-doc-emacs.info,  Node: PROOF-CHECKER,  Next: PROOF-TREE,  Prev: PROGRAMMING,  Up: Top

PROOF-CHECKER    support for low-level interaction

Call this up with (verify ...).

* Menu:

* DEFINE-PC-HELP:: define a macro command whose purpose is to print something

* DEFINE-PC-MACRO:: define a proof-checker macro command

* DEFINE-PC-META:: define a proof-checker meta command

* INSTRUCTIONS:: instructions to the proof checker

* MACRO-COMMAND:: compound command for the proof-checker

* PROOF-CHECKER-COMMANDS:: list of commands for the proof-checker

* RETRIEVE:: re-enter a (specified) proof-checker state

* TOGGLE-PC-MACRO:: change an ordinary macro command to an atomic macro, or vice-versa

* UNSAVE:: remove a proof-checker state

* VERIFY:: enter the interactive proof checker

This is an interactive system for checking ACL2 theorems, or at least
exploring their proofs.  One enters it using the VERIFY command (see
*note VERIFY::), and then invokes commands at the resulting prompt to
operate on a stack of goals, starting with the single goal that was
supplied to VERIFY.  The final command (or "instruction") can be an exit
command, which can print out a defthm event if the goal stack is empty;
see *note PROOF-CHECKER-COMMANDS::, in particular the exit command.
That resulting defthm event includes an :instructions parameter, which
directs replay of the proof-checker commands (for example during
certification of a book containing that event; see *note BOOKS::).

If you exit the proof-checker interactive loop, you may re-enter that
session at the same point using the command (verify), i.e., with no
arguments.  The commands save and retrieve may be invoked to manage
more than one session.

The proof-checker can be invoked on a specific subgoal, and the
resulting :instructions can be given as a hint to the theorem prover
for that subgoal.  See *note INSTRUCTIONS::.

A tutorial is available on the world-wide web:
`http://www.cs.utexas.edu/users/kaufmann/tutorial/rev3.html'.
The tutorial illustrates more than just the proof-checker.  The portion
relevant to the proof-checker may be accessed directly:
`http://www.cs.utexas.edu/users/kaufmann/tutorial/rev3.html#slide29'

See *note SET-EVISC-TUPLE:: for how to arrange that output is printed
in abbreviated form.  In general, the proof-checker uses the :TERM
evisc-tuple described in that documentation.

Individual proof-checker commands are documented in subsection
proof-checker-commands.  When inside the interactive loop (i.e., after
executing verify), you may use the help command to get a list of legal
instructions and (help instr) to get help for the instruction instr.


File: acl2-doc-emacs.info,  Node: DEFINE-PC-HELP,  Next: DEFINE-PC-MACRO,  Prev: PROOF-CHECKER,  Up: PROOF-CHECKER

DEFINE-PC-HELP    define a macro command whose purpose is to print something

     Example:
     (define-pc-help pp ()
       (if (goals t)
           (io? proof-checker nil state
                (state-stack)
                (fms0 "~|~y0~|"
                      (list (cons #0
                                  (fetch-term (conc t)
                                              (current-addr t))))))
         (print-all-goals-proved-message state)))

     General Form:
     (define-pc-help name args &rest body)

This defines a macro command named name, as explained further below.
The body should (after removing optional declarations) be a form that
returns state as its single value.   Typically, it will just print
something.

What (define-pc-help name args &rest body) really does is to create a
call of define-pc-macro that defines name to take arguments args, to
have the declarations indicated by all but the last form in body, and
to have a body that (via pprogn) first executes the form in the last
element of body and then returns a call to the command skip (which will
return (mv nil t state)).


File: acl2-doc-emacs.info,  Node: DEFINE-PC-MACRO,  Next: DEFINE-PC-META,  Prev: DEFINE-PC-HELP,  Up: PROOF-CHECKER

DEFINE-PC-MACRO    define a proof-checker macro command

     Example:
     (define-pc-macro ib (&optional term)
       (value
        (if term
            `(then (induct ,term) bash)
          `(then induct bash))))

The example above captures a common paradigm:  one attempts to prove
the current goal by inducting and then simplifying the resulting goals.
(see *note PROOF-CHECKER-COMMANDS:: for documentation of the command
then, which is itself a pc-macro command, and commands induct and
bash.)  Rather than issuing (then induct bash), or worse yet issuing
induct and then issuing bash for each resulting goals, the above
definition of ib would let you issue ib and get the same effect.

     General Form:
     (define-pc-macro cmd args doc-string dcl ... dcl body)

where cmd is the name of the pc-macro than you want to define, args is
its list of formal parameters.  Args may include lambda-list keywords
&optional and &rest; see *note MACRO-ARGS::, but note that here, args
may not include &key or &whole.

The value of body should be an error triple (see *note
ERROR-TRIPLES::), of the form (mv erp xxx state) for some erp and xxx.
If erp is nil, then xxx is handed off to the proof-checker's instruction
interpreter.  Otherwise, evaluation typically halts.  We may write more
on the full story later if there is interest in reading it.


File: acl2-doc-emacs.info,  Node: DEFINE-PC-META,  Next: INSTRUCTIONS,  Prev: DEFINE-PC-MACRO,  Up: PROOF-CHECKER

DEFINE-PC-META    define a proof-checker meta command

Built-in proof-checker meta commands include undo and restore, and
others (lisp, exit, and sequence); see *note PROOF-CHECKER-COMMANDS::.
The advanced proof-checker user can define these as well.  See ACL2
source file proof-checker-b.lisp for examples, and contact the ACL2
implementors if those examples do not provide sufficient documentation.


File: acl2-doc-emacs.info,  Node: INSTRUCTIONS,  Next: MACRO-COMMAND,  Prev: DEFINE-PC-META,  Up: PROOF-CHECKER

INSTRUCTIONS    instructions to the proof checker

See *note PROOF-CHECKER:: for an introduction to the interactive
"proof-checker" goal manager, which supports much more direct control
of the proof process than is available by direct calls to the prover
(as are normally made using defthm or thm).  In brief, typical use is
to evaluate the form (verify SOME-GOAL), where SOME-GOAL is a formula
(i.e., term) that you would like to prove.  Various commands
(instructions) are available at the resulting prompt; see *note
PROOF-CHECKER-COMMANDS::.  When the proof is completed, suitable
invocation of the exit command will print out a form containing an
:instructions field that provides the instructions that you gave
interactively, so that this form can be evaluated non-interactively.

Thus, also see *note DEFTHM:: for the role of :instructions in place of
:hints.  As illustrated by the following example, the value associated
with :instructions is a list of proof-checker commands.

     Example:
     (defthm associativity-of-append
             (equal (append (append x y) z)
                    (append x (append y z)))
             :instructions
             (:induct (:dv 1) (:dv 1) :x :up :x (:dv 2) := (:drop 2)
              :top (:dv 2) :x :top :s :bash))

When you are inside the interactive loop (i.e., after executing
verify), you may invoke help to get a list of legal instructions and
(help instr) to get help for the instruction instr.

Below, we describe a capability for supplying :instructions as :hints.

The most basic utilities for directing the discharge of a proof
obligation are :hints and (less commonly) :instructions.  Individual
instructions may call the prover with :hints; in that sense, prover
hints may occur inside instructions.  We now describe how, on the other
hand, instructions may occur inside hints.

ACL2 supports :instructions as a hints keyword.  The following example
forms the basis for our running example.  This example does not
actually need hints, but imagine that the inductive step -- which is
"Subgoal *1/2" -- was difficult.  You could submit that goal to verify,
do an interactive proof, submit (exit t) to obtain the list of
:instructions, and then paste in those instructions.  When you submit
the resulting event, you might see the following.  Below we'll explain
the hint processing.

     ACL2 !>(thm (equal (append (append x y) z)
                        (append x (append y z)))
                 :hints (("Subgoal *1/2"
                          :instructions
                          (:promote (:dv 1) (:dv 1) :x :up :x (:dv 2) :=
                           (:drop 2) :top (:dv 2) :x :top :s))))

     Name the formula above *1.

     Perhaps we can prove *1 by induction.  Three induction schemes are
     suggested by this conjecture.  Subsumption reduces that number to two.
     However, one of these is flawed and so we are left with one viable
     candidate.

     We will induct according to a scheme suggested by (BINARY-APPEND X Y).
     This suggestion was produced using the :induction rule BINARY-APPEND.
     If we let (:P X Y Z) denote *1 above then the induction scheme we'll
     use is
     (AND (IMPLIES (AND (NOT (ENDP X)) (:P (CDR X) Y Z))
                   (:P X Y Z))
          (IMPLIES (ENDP X) (:P X Y Z))).
     This induction is justified by the same argument used to admit BINARY-APPEND.
     When applied to the goal at hand the above induction scheme produces
     two nontautological subgoals.

     [Note:  A hint was supplied for our processing of the goal below.
     Thanks!]

     Subgoal *1/2
     (IMPLIES (AND (NOT (ENDP X))
                   (EQUAL (APPEND (APPEND (CDR X) Y) Z)
                          (APPEND (CDR X) Y Z)))
              (EQUAL (APPEND (APPEND X Y) Z)
                     (APPEND X Y Z))).

     But the trusted :CLAUSE-PROCESSOR function PROOF-CHECKER-CL-PROC replaces
     this goal by T.

     Subgoal *1/1
     (IMPLIES (ENDP X)
              (EQUAL (APPEND (APPEND X Y) Z)
                     (APPEND X Y Z))).

     By the simple :definition ENDP we reduce the conjecture to

     Subgoal *1/1'
     (IMPLIES (NOT (CONSP X))
              (EQUAL (APPEND (APPEND X Y) Z)
                     (APPEND X Y Z))).

     But simplification reduces this to T, using the :definition BINARY-APPEND
     and primitive type reasoning.

     That completes the proof of *1.

     Q.E.D.

     Summary
     Form:  ( THM ...)
     Rules: ((:DEFINITION BINARY-APPEND)
             (:DEFINITION ENDP)
             (:DEFINITION NOT)
             (:FAKE-RUNE-FOR-TYPE-SET NIL)
             (:INDUCTION BINARY-APPEND))
     Time:  0.02 seconds (prove: 0.01, print: 0.01, other: 0.00)

     Proof succeeded.
     ACL2 !>

To understand how the :instructions supplied above were processed,
observe proof-checker instruction interpreter may be viewed as a
"clause-processor": a function that takes an input goal and returns a
list of goals (which can be the empty list).  Such a function has the
property that if all goals in that returned list are theorems, then so
is the input goal.  This view of the proof-checker instruction
interpreter as a clause-processor leads to the following crucial
observation.

*IMPORTANT!*.  Each call of the proof-checker instruction interpreter is
treated as a standalone clause-processor that is insensitive to the
surrounding prover environment.  In particular:

     o The proof-checker's theory is not sensitive to :in-theory hints
     already processed in the surrounding proof.  Indeed, the current
     theory for which proof-checker commands are processed is just the
     current theory of the ACL2 logical world, i.e., the value of
     (current-theory :here).  Moreover, references to (current-theory
     :here) in a proof-checker in-theory command, even implicit
     references such as provided by enable and disable expressions, are
     also references to the current theory of the ACL2 logical world.

     o The runes used during an :instructions hint are not tracked
     beyond that hint, hence may not show up in the summary of the
     overall proof.  Again, think of the :instructions hint as a
     clause-processor call, which has some effect not tracked by the
     surrounding proof other than for the child goals that it returns.

We continue now with our discussion of the proof-checker instruction
interpreter as a clause-processor.

In the example above, the input goal ("Subgoal *1/2") was processed by
the proof-checker instruction interpreter.  The result was the empty
goal stack, therefore proving the goal, as reported in the output,
which we repeat here.

     [Note:  A hint was supplied for our processing of the goal below.
     Thanks!]

     Subgoal *1/2
     (IMPLIES (AND (NOT (ENDP X))
                   (EQUAL (APPEND (APPEND (CDR X) Y) Z)
                          (APPEND (CDR X) Y Z)))
              (EQUAL (APPEND (APPEND X Y) Z)
                     (APPEND X Y Z))).

     But the trusted :CLAUSE-PROCESSOR function PROOF-CHECKER-CL-PROC replaces
     this goal by T.

*Remark.*  This brief remark can probably be ignored, but we include it
for completeness.  The :CLAUSE-PROCESSOR message above may be
surprising, since the hint attached to "Subgoal *1/2" is an
:instructions hint, not a :clause-processor hint.  But :instructions is
actually a custom keyword hint (see *note CUSTOM-KEYWORD-HINTS::), and
may be thought of as a macro that expands to a :clause-processor hint,
one that specifies proof-checker-cl-proc as the clause-processor
function.  The keen observer may notice that the clause-processor is
referred to as "trusted" in the above output.  Normally one needs a
trust tag (see *note DEFTTAG::) to install a trusted clause-processor,
but that is not the case for the built-in clause-processor,
proof-checker-cl-proc.  Finally, we note that :instructions hints are
"spliced" into the hints as follows: the appropriate :clause-processor
hint replaces the :instructions hint, and the other hints remain
intact.  It may seems surprising that one can thus, for example, use
:instructions and :in-theory together; but although the :in-theory hint
will have no effect on execution of the :instructions (see first bullet
above), the :in-theory hint will apply in the usual manner to any child
goals (see *note HINTS-AND-THE-WATERFALL::).  End of Remark.

Now consider the case that the supplied instructions do not prove the
goal.  That is, suppose that the execution of those instructions
results in a non-empty goal stack.  In that case, the resulting goals
become children of the input goals.  The following edited log provides
an illustration using a modification of the above example, this time
with a single instruction that splits into two cases.

     ACL2 !>(thm (equal (append (append x y) z)
                        (append x (append y z)))
                 :hints (("Subgoal *1/2"
                          :instructions
                          ((:casesplit (equal x y))))))

     [[ ... output omitted ... ]]

     Subgoal *1/2
     (IMPLIES (AND (NOT (ENDP X))
                   (EQUAL (APPEND (APPEND (CDR X) Y) Z)
                          (APPEND (CDR X) Y Z)))
              (EQUAL (APPEND (APPEND X Y) Z)
                     (APPEND X Y Z))).

     We now apply the trusted :CLAUSE-PROCESSOR function PROOF-CHECKER-CL-PROC
     to produce two new subgoals.

     Subgoal *1/2.2

     [[ ... output omitted ... ]]

     Subgoal *1/2.1

     [[ ... output omitted ... ]]

We have seen that an :instructions hint may produce zero or more
subgoals.  There may be times where you wish to insist that it produce
zero subgoals, i.e., that it prove the desired goal.  The proof-checker
`finish' command works nicely for this purpose.  For example, the
following form is successfully admitted, but if you delete some of the
commands (for example, the :s command at the end), you will see an
informative error message.

     (thm (equal (append (append x y) z)
                 (append x (append y z)))
          :hints (("Subgoal *1/2"
                   :instructions
                   ((finish :promote (:dv 1) (:dv 1) :x :up :x (:dv 2) :=
                            (:drop 2) :top (:dv 2) :x :top :s)))))

If an :instructions hint of the form ((finish ...)) fails to prove the
goal, the clause-processor is deemed to have caused an error.  Indeed,
any "failure" of a supplied proof-checker instruction will be deemed to
cause an error.  In this case, you should see an error message such as
the following:


     Saving proof-checker error state; see :DOC instructions.  To retrieve:

     (RETRIEVE :ERROR1)

In this case, you can evaluate the indicated retrieve command in the
ACL2 read-eval-print loop, to get to the point of failure.

You may have noticed that there is no output from the proof-checker in
the examples above.  This default behavior prevents confusion that
could arise from use of proof-checker commands that call the theorem
prover such as prove, bash, split, and induct.  These commands produce
output for what amounts to a fresh proof attempt, which could confuse
attempts to understand the surrounding proof log.  You can override the
default behavior by providing a command of the form

     (comment inhibit-output-lst VAL)

where VAL is either the keyword :SAME (indicating that no change should
be made to which output is inhibited) or else is a legal value for
inhibited output; see *note SET-INHIBIT-OUTPUT-LST::.  The following
two variants of the immediately preceding THM form will each produce
output from the proof-checker commands, assuming in the first variant
that output hasn't already been inhibited.

     (thm (equal (append (append x y) z)
                        (append x (append y z)))
                 :hints (("Subgoal *1/2"
                          :instructions
                          ((comment inhibit-output-lst :same)
                           (:casesplit (equal x y))))))

     (thm (equal (append (append x y) z)
                        (append x (append y z)))
                 :hints (("Subgoal *1/2"
                          :instructions
                          ((comment inhibit-output-lst (proof-tree))
                           (:casesplit (equal x y))))))

Note that such a comment instruction must be provided explicitly (i.e.,
not by way of a proof-checker macro-command) as the first instruction,
in order to have the effect on inhibited output that is described above.

The following contrived example gives a sense of how one might want to
use :instructions within :hints.  If you submit the following theorem

     (thm (implies (true-listp x)
                   (equal (reverse (reverse x)) x)))

then you will see the following checkpoint printed with the summary.

     Subgoal *1/3''
     (IMPLIES (AND (CONSP X)
                   (EQUAL (REVAPPEND (REVAPPEND (CDR X) NIL) NIL)
                          (CDR X))
                   (TRUE-LISTP (CDR X)))
              (EQUAL (REVAPPEND (REVAPPEND (CDR X) (LIST (CAR X)))
                                NIL)
                     X))

This suggests proving the following theorem.  Here we state it using
defthmd, so that it is immediately disabled.  Normally disabling would
be unnecessary, but for our contrived example it is useful to imagine
disabling it, say because we are following a methodology that tends to
keep rewrite rules disabled.

     (defthmd revappend-revappend
       (equal (revappend (revappend x y) z)
              (revappend y (append x z))))

We might then enter the proof-checker to prove the original theorem
interactively, as follows.

     ACL2 !>(verify (implies (true-listp x)
                             (equal (reverse (reverse x)) x)))
     ->: bash
     ***** Now entering the theorem prover *****
     Goal'

     ([ A key checkpoint:

     Goal'
     (IMPLIES (TRUE-LISTP X)
              (EQUAL (REVAPPEND (REVAPPEND X NIL) NIL)
                     X))

     Goal' is subsumed by a goal yet to be proved.

     ])

     Q.E.D.


     Creating one new goal:  (MAIN . 1).

     The proof of the current goal, MAIN, has been completed.  However,
     the following subgoals remain to be proved:
       (MAIN . 1).
     Now proving (MAIN . 1).
     ->: th ; show current goal ("th" for "theorem")
     *** Top-level hypotheses:
     1. (TRUE-LISTP X)

     The current subterm is:
     (EQUAL (REVAPPEND (REVAPPEND X NIL) NIL)
            X)
     ->: p ; show current subterm only
     (EQUAL (REVAPPEND (REVAPPEND X NIL) NIL)
            X)
     ->: 1 ; dive to first argument
     ->: p
     (REVAPPEND (REVAPPEND X NIL) NIL)
     ->: sr ; show-rewrites

     1. REVAPPEND-REVAPPEND (disabled)
       New term: (REVAPPEND NIL (APPEND X NIL))
       Hypotheses: <none>
       Equiv: EQUAL

     2. REVAPPEND
       New term: (AND (CONSP (REVAPPEND X NIL))
                      (REVAPPEND (CDR (REVAPPEND X NIL))
                                 (LIST (CAR (REVAPPEND X NIL)))))
       Hypotheses: <none>
       Equiv: EQUAL
     ->: (r 1) ; rewrite with rule #1 above
     Rewriting with REVAPPEND-REVAPPEND.
     ->: p
     (REVAPPEND NIL (APPEND X NIL))
     ->: top ; move to the top of the conclusion, making it the current subterm
     ->: p
     (EQUAL (REVAPPEND NIL (APPEND X NIL)) X)
     ->: prove ; finish the proof
     ***** Now entering the theorem prover *****

     Q.E.D.

     *!*!*!*!*!*!* All goals have been proved! *!*!*!*!*!*!*
     You may wish to exit.
     ->: (exit t) ; the argument, t, causes :instructions to be printed
     (DEFTHM T
             (IMPLIES (TRUE-LISTP X)
                      (EQUAL (REVERSE (REVERSE X)) X))
             :INSTRUCTIONS (:BASH (:DV 1)
                                  (:REWRITE REVAPPEND-REVAPPEND)
                                  :TOP :PROVE))
      NIL
     ACL2 !>(thm
             (IMPLIES (TRUE-LISTP X)
                      (EQUAL (REVERSE (REVERSE X)) X))
             :hints (("Goal"
                      :INSTRUCTIONS ; copy what was printed above:
                      (:BASH (:DV 1)
                             (:REWRITE REVAPPEND-REVAPPEND)
                             :TOP :PROVE))))
     Goal'

     Q.E.D.

     Q.E.D.

     Q.E.D.

     Summary
     Form:  ( THM ...)
     Rules: NIL
     Hint-events: ((:CLAUSE-PROCESSOR PROOF-CHECKER-CL-PROC))
     Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)

     Proof succeeded.
     ACL2 !>

Finally we present an even more contrived example, based on the one
above.  This example illustrates that there is actually no limit
imposed on the nesting of :instructions within :hints within
:instructions, and so on.  Notice the indication of nesting levels:
"1>" to "<1" for output from nesting level 1, and "2>" to "<2" for
output from nesting level 2.

     (thm (implies (true-listp x)
                   (equal (reverse (reverse x)) x))
          :hints (("Goal"
                   :instructions
                   ((comment inhibit-output-lst :same)
                    (:prove
                     :hints (("Goal" :in-theory (disable append))
                             ("Subgoal *1/3''"
                              :instructions
                              ((comment inhibit-output-lst :same)
                               :bash
                               (:dv 1)
                               (:rewrite revappend-revappend)))))))))

Here is an edited version of the resulting log.


     [Note:  A hint was supplied for our processing of the goal above.
     Thanks!]

     [[1> Executing proof-checker instructions]]

     ->: (COMMENT INHIBIT-OUTPUT-LST :SAME)
     ->: (:PROVE
              :HINTS
              (("Goal" :IN-THEORY (DISABLE APPEND))
               ("Subgoal *1/3''" :INSTRUCTIONS ((COMMENT INHIBIT-OUTPUT-LST :SAME)
                                                :BASH (:DV 1)
                                                (:REWRITE REVAPPEND-REVAPPEND)))))
     ***** Now entering the theorem prover *****

     [[ ... output omitted ... ]]

     [Note:  A hint was supplied for our processing of the goal below.
     Thanks!]

     Subgoal *1/3''
     (IMPLIES (AND (CONSP X)
                   (EQUAL (REVAPPEND (REVAPPEND (CDR X) NIL) NIL)
                          (CDR X))
                   (TRUE-LISTP (CDR X)))
              (EQUAL (REVAPPEND (REVAPPEND (CDR X) (LIST (CAR X)))
                                NIL)
                     X)).

     [[2> Executing proof-checker instructions]]

     ->: (COMMENT INHIBIT-OUTPUT-LST :SAME)
     ->: :BASH
     ***** Now entering the theorem prover *****

     [Note:  A hint was supplied for our processing of the goal above.
     Thanks!]

     But we have been asked to pretend that this goal is subsumed by the
     yet-to-be-proved |PROOF-CHECKER Goal|.

     Q.E.D.


     Creating one new goal:  (MAIN . 1).

     The proof of the current goal, MAIN, has been completed.  However,
     the following subgoals remain to be proved:
       (MAIN . 1).
     Now proving (MAIN . 1).
     ->: (:DV 1)
     ->: (:REWRITE REVAPPEND-REVAPPEND)
     Rewriting with REVAPPEND-REVAPPEND.

     [[<2 Completed proof-checker instructions]]

     We now apply the trusted :CLAUSE-PROCESSOR function PROOF-CHECKER-CL-PROC
     to produce one new subgoal.

     Subgoal *1/3'''

     [[ ... output omitted ... ]]

     [[<1 Completed proof-checker instructions]]

The nesting levels are independent of whether or not output is enabled;
for example, if the first (comment ...) form below is omitted, then we
will see only the output bracketed by "2>" to "<2".  Note also that
these levels are part of the error states saved for access by retrieve
(as indicated above); for example, a failure at level 1 would be
associated with symbol :ERROR1 as indicated above, while a failure at
level 2 would be associated with symbol :ERROR2.


File: acl2-doc-emacs.info,  Node: MACRO-COMMAND,  Next: PROOF-CHECKER-COMMANDS,  Prev: INSTRUCTIONS,  Up: PROOF-CHECKER

MACRO-COMMAND    compound command for the proof-checker

The proof-checker (see *note PROOF-CHECKER::) allows the user to supply
interactive commands.  Compound commands, called macro commands, may be
defined; these expand into zero or more other commands.  Some of these
are "atomic" macro commands; these are viewed as a single command step
when completed successfully.

More documentation will be written on the proof-checker.  For now, we
simply point out that there are lots of examples of the use of
define-pc-macro and define-pc-atomic-macro in the ACL2 source file
"proof-checker-b.lisp".  The former is used to create macro commands,
which can be submitted to the interactive loop (see *note VERIFY::) and
will "expand" into zero or more commands.  The latter is similar,
except that the undoing mechanism (see *note ACL2-PC||UNDO::)
understands atomic macro commands to represent single interactive
commands.  Also see *note ACL2-PC||COMM:: and see *note
ACL2-PC||COMMANDS:: for a discussion of the display of interactive
commands.

Also see *note TOGGLE-PC-MACRO:: for how to change a macro command to
an atomic macro command, and vice versa.


File: acl2-doc-emacs.info,  Node: PROOF-CHECKER-COMMANDS,  Next: RETRIEVE,  Prev: MACRO-COMMAND,  Up: PROOF-CHECKER

PROOF-CHECKER-COMMANDS    list of commands for the proof-checker

This documentation section contains documentation for individual
commands that can be given inside the interactive proof-checker loop
that is entered using verify.

* Menu:

* ACL2-PC||=:: (atomic macro)
attempt an equality (or equivalence) substitution

* ACL2-PC||ACL2-WRAP:: (macro)
same as (lisp x)

* ACL2-PC||ADD-ABBREVIATION:: (primitive)
add an abbreviation

* ACL2-PC||AL:: (macro)
same as apply-linear

* ACL2-PC||APPLY-LINEAR:: (primitive)
apply a linear rule

* ACL2-PC||BASH:: (atomic macro)
call the ACL2 theorem prover's simplifier

* ACL2-PC||BDD:: (atomic macro)
prove the current goal using bdds

* ACL2-PC||BK:: (atomic macro)
move backward one argument in the enclosing term

* ACL2-PC||BOOKMARK:: (macro)
insert matching ``bookends'' comments

* ACL2-PC||CASESPLIT:: (primitive)
split into two cases

* ACL2-PC||CG:: (macro)
change to another goal.

* ACL2-PC||CHANGE-GOAL:: (primitive)
change to another goal.

* ACL2-PC||CL-PROC:: (macro)
same as clause-processor

* ACL2-PC||CLAIM:: (atomic macro)
add a new hypothesis

* ACL2-PC||CLAUSE-PROCESSOR:: (atomic macro)
use a clause-processor

* ACL2-PC||COMM:: (macro)
display instructions from the current interactive session

* ACL2-PC||COMMANDS:: (macro)
display instructions from the current interactive session

* ACL2-PC||COMMENT:: (primitive)
insert a comment

* ACL2-PC||CONTRADICT:: (macro)
same as contrapose

* ACL2-PC||CONTRAPOSE:: (primitive)
switch a hypothesis with the conclusion, negating both

* ACL2-PC||DEMOTE:: (primitive)
move top-level hypotheses to the conclusion

* ACL2-PC||DIVE:: (primitive)
move to the indicated subterm

* ACL2-PC||DO-ALL:: (macro)
run the given instructions

* ACL2-PC||DO-ALL-NO-PROMPT:: (macro)
run the given instructions, halting once there is a ``failure''

* ACL2-PC||DO-STRICT:: (macro)
run the given instructions, halting once there is a ``failure''

* ACL2-PC||DROP:: (primitive)
drop top-level hypotheses

* ACL2-PC||DV:: (atomic macro)
move to the indicated subterm

* ACL2-PC||ELIM:: (atomic macro)
call the ACL2 theorem prover's elimination process

* ACL2-PC||EQUIV:: (primitive)
attempt an equality (or congruence-based) substitution

* ACL2-PC||EX:: (macro)
exit after possibly saving the state

* ACL2-PC||EXIT:: (meta)
exit the interactive proof-checker

* ACL2-PC||EXPAND:: (primitive)
expand the current function call without simplification

* ACL2-PC||FAIL:: (macro)
cause a failure

* ACL2-PC||FINISH:: (macro)
require completion of instructions; save error if inside :hints

* ACL2-PC||FORWARDCHAIN:: (atomic macro)
forward chain from an implication in the hyps

* ACL2-PC||FREE:: (atomic macro)
create a ``free variable''

* ACL2-PC||GENEQV:: (macro)
show the generated equivalence relation maintained at the current subterm

* ACL2-PC||GENERALIZE:: (primitive)
perform a generalization

* ACL2-PC||GOALS:: (macro)
list the names of goals on the stack

* ACL2-PC||HELP:: (macro)
proof-checker help facility

* ACL2-PC||HELP!:: (macro)
proof-checker help facility

* ACL2-PC||HELP-LONG:: (macro)
same as help!

* ACL2-PC||HYPS:: (macro)
print the hypotheses

* ACL2-PC||ILLEGAL:: (macro)
illegal instruction

* ACL2-PC||IN-THEORY:: (primitive)
set the current proof-checker theory

* ACL2-PC||INDUCT:: (atomic macro)
generate subgoals using induction

* ACL2-PC||LEMMAS-USED:: (macro)
print the runes (definitions, lemmas, ...) used

* ACL2-PC||LISP:: (meta)
evaluate the given form in Lisp

* ACL2-PC||MORE:: (macro)
proof-checker help facility

* ACL2-PC||MORE!:: (macro)
proof-checker help facility

* ACL2-PC||NEGATE:: (macro)
run the given instructions, and ``succeed'' if and only if they ``fail''

* ACL2-PC||NIL:: (macro)
used for interpreting control-d

* ACL2-PC||NOISE:: (meta)
run instructions with output

* ACL2-PC||NX:: (atomic macro)
move forward one argument in the enclosing term

* ACL2-PC||ORELSE:: (macro)
run the first instruction; if (and only if) it ``fails'', run the
second

* ACL2-PC||P:: (macro)
prettyprint the current term

* ACL2-PC||P-TOP:: (macro)
prettyprint the conclusion, highlighting the current term

* ACL2-PC||PL:: (macro)
print the rules for a given name

* ACL2-PC||PP:: (macro)
prettyprint the current term

* ACL2-PC||PR:: (macro)
print the rules for a given name

* ACL2-PC||PRINT:: (macro)
print the result of evaluating the given form

* ACL2-PC||PRINT-ALL-CONCS:: (macro)
print all the conclusions of (as yet unproved) goals

* ACL2-PC||PRINT-ALL-GOALS:: (macro)
print all the (as yet unproved) goals

* ACL2-PC||PRINT-MAIN:: (macro)
print the original goal

* ACL2-PC||PRO:: (atomic macro)
repeatedly apply promote

* ACL2-PC||PROMOTE:: (primitive)
move antecedents of conclusion's implies term to top-level
hypotheses

* ACL2-PC||PROTECT:: (macro)
run the given instructions, reverting to existing state upon
failure

* ACL2-PC||PROVE:: (primitive)
call the ACL2 theorem prover to prove the current goal

* ACL2-PC||PSO:: (macro)
print the most recent proof attempt from inside the proof-checker

* ACL2-PC||PSO!:: (macro)
print the most recent proof attempt from inside the proof-checker

* ACL2-PC||PSOG:: (macro)
print the most recent proof attempt from inside the proof-checker

* ACL2-PC||PUT:: (macro)
substitute for a ``free variable''

* ACL2-PC||QUIET:: (meta)
run instructions without output

* ACL2-PC||R:: (macro)
same as rewrite

* ACL2-PC||REDUCE:: (atomic macro)
call the ACL2 theorem prover's simplifier

* ACL2-PC||REDUCE-BY-INDUCTION:: (macro)
call the ACL2 prover without induction, after going into
induction

* ACL2-PC||REMOVE-ABBREVIATIONS:: (primitive)
remove one or more abbreviations

* ACL2-PC||REPEAT:: (macro)
repeat the given instruction until it ``fails''

* ACL2-PC||REPEAT-REC:: (macro)
auxiliary to repeat

* ACL2-PC||REPLAY:: (macro)
replay one or more instructions

* ACL2-PC||RESTORE:: (meta)
remove the effect of an UNDO command

* ACL2-PC||RETAIN:: (atomic macro)
drop all *but* the indicated top-level hypotheses

* ACL2-PC||RETRIEVE:: (macro)
re-enter the proof-checker

* ACL2-PC||REWRITE:: (primitive)
apply a rewrite rule

* ACL2-PC||RUN-INSTR-ON-GOAL:: (macro)
auxiliary to THEN

* ACL2-PC||RUN-INSTR-ON-NEW-GOALS:: (macro)
auxiliary to then

* ACL2-PC||RUNES:: (macro)
print the runes (definitions, lemmas, ...) used

* ACL2-PC||S:: (primitive)
simplify the current subterm

* ACL2-PC||S-PROP:: (atomic macro)
simplify propositionally

* ACL2-PC||SAVE:: (macro)
save the proof-checker state (state-stack)

* ACL2-PC||SEQUENCE:: (meta)
run the given list of instructions according to a multitude of
options

* ACL2-PC||SHOW-ABBREVIATIONS:: (macro)
display the current abbreviations

* ACL2-PC||SHOW-LINEARS:: (macro)
display the applicable linear rules

* ACL2-PC||SHOW-REWRITES:: (macro)
display the applicable rewrite rules

* ACL2-PC||SHOW-TYPE-PRESCRIPTIONS:: (macro)
display the applicable type-prescription rules

* ACL2-PC||SKIP:: (macro)
``succeed'' without doing anything

* ACL2-PC||SL:: (atomic macro)
simplify with lemmas

* ACL2-PC||SLS:: (macro)
same as SHOW-LINEARS

* ACL2-PC||SPLIT:: (atomic macro)
split the current goal into cases

* ACL2-PC||SR:: (macro)
same as SHOW-REWRITES

* ACL2-PC||ST:: (macro)
same as SHOW-TYPE-PRESCRIPTIONS

* ACL2-PC||SUCCEED:: (macro)
run the given instructions, and ``succeed''

* ACL2-PC||TH:: (macro)
print the top-level hypotheses and the current subterm

* ACL2-PC||THEN:: (macro)
apply one instruction to current goal and another to new subgoals

* ACL2-PC||TOP:: (atomic macro)
move to the top of the goal

* ACL2-PC||TYPE-ALIST:: (macro)
display the type-alist from the current context

* ACL2-PC||UNDO:: (meta)
undo some instructions

* ACL2-PC||UNSAVE:: (macro)
remove a proof-checker state

* ACL2-PC||UP:: (primitive)
move to the parent (or some ancestor) of the current subterm

* ACL2-PC||USE:: (atomic macro)
use a lemma instance

* ACL2-PC||WRAP:: (atomic macro)
execute the indicated instructions and combine all the new goals

* ACL2-PC||WRAP-INDUCT:: (atomic macro)
same as induct, but create a single goal

* ACL2-PC||WRAP1:: (primitive)
combine goals into a single goal

* ACL2-PC||X:: (atomic macro)
expand and (maybe) simplify function call at the current subterm

* ACL2-PC||X-DUMB:: (atomic macro)
expand function call at the current subterm, without simplifying


File: acl2-doc-emacs.info,  Node: ACL2-PC||=,  Next: ACL2-PC||ACL2-WRAP,  Prev: PROOF-CHECKER-COMMANDS,  Up: PROOF-CHECKER-COMMANDS

ACL2-PC||=    (atomic macro)
attempt an equality (or equivalence) substitution

     Examples:
     =     -- replace the current subterm by a term equated to it in
              one of the hypotheses (if such a term exists)
     (= x) -- replace the current subterm by x, assuming that the prover
              can show that they are equal
     (= (+ x y) z)
           -- replace the term (+ x y) by the term z inside the current
              subterm, assuming that the prover can prove
              (equal (+ x y) z) from the current top-level hypotheses
              or that this term or (equal z (+ x y)) is among the
              current top-level hypotheses or the current governors
     (= & z)
           -- exactly the same as above, if (+ x y) is the current
              subterm
     (= (+ x y) z :hints :none)
           -- same as (= (+ x y) z), except that a new subgoal is
              created with the current goal's hypotheses and governors
              as its top-level hypotheses and (equal (+ x y) z) as its
              conclusion
     (= (+ x y) z 0)
           -- exactly the same as immediately above
     (= (p x)
        (p y)
        :equiv iff
        :otf-flg t
        :hints (("Subgoal 2" :BY FOO) ("Subgoal 1" :use bar)))
           -- same as (= (+ x y) z), except that the prover uses
              the indicated values for otf-flg and hints, and only
              propositional (iff) equivalence is used (however, it
              must be that only propositional equivalence matters at
              the current subterm)

     General Form:
     (= &optional x y &rest keyword-args)

If terms x and y are supplied, then replace x by y inside the current
subterm if they are "known" to be "equal".  Here "known" means the
following:  the prover is called as in the prove command (using
keyword-args) to prove (equal x y), except that a keyword argument
:equiv is allowed, in which case (equiv x y) is proved instead, where
equiv is that argument.  (See below for how governors are handled.)

Actually, keyword-args is either a single non-keyword or is a list of
the form ((kw-1 x-1) ... (kw-n x-n)), where each kw-i is one of the
keywords :equiv, :otf-flg, :hints.  Here :equiv defaults to equal if
the argument is not supplied or is nil, and otherwise should be the
name of an ACL2 equivalence relation.  :Otf-flg and :hints give
directives to the prover, as explained above and in the documentation
for the prove command; however, no prover call is made if :hints is a
non-nil atom or if keyword-args is a single non-keyword (more on this
below).

_Remarks on defaults_

(1) If there is only one argument, say a, then x defaults to the
current subterm, in the sense that x is taken to be the current subterm
and y is taken to be a.

(2) If there are at least two arguments, then x may be the symbol &,
which then represents the current subterm.  Thus, (= a) is equivalent
to (= & a).  (Obscure point:  actually, & can be in any package, except
the keyword package.)

(3) If there are no arguments, then we look for a top-level hypothesis
or a governor of the form (equal c u) or (equal u c), where c is the
current subterm.  In that case we replace the current subterm by u.

As with the prove command, we allow goals to be given "bye"s in the
proof, which may be generated by a :hints keyword argument in
keyword-args.  These result in the creation of new subgoals.

A proof is attempted unless the :hints argument is a non-nil atom other
than :none, or unless there is one element of keyword-args and it is
not a keyword.  In that case, if there are any hypotheses in the
current goal, then what is attempted is a proof of the implication
whose antecedent is the conjunction of the current hypotheses and
governors and whose conclusion is the appropriate equal term.

*Remarks:*  (1) It is allowed to use abbreviations in the hints.  (2)
The keyword :none has the special role as a value of :hints that is
shown clearly in an example above.  (3) If there are governors, then
the new subgoal has as additional hypotheses the current governors.


File: acl2-doc-emacs.info,  Node: ACL2-PC||ACL2-WRAP,  Next: ACL2-PC||ADD-ABBREVIATION,  Prev: ACL2-PC||=,  Up: PROOF-CHECKER-COMMANDS

ACL2-PC||ACL2-WRAP    (macro)
same as (lisp x)

     Example:
     (acl2-wrap (pe :here))

     General Form:
     (acl2-wrap form)

Same as (lisp form).  This is provided for interface tools that want to
be able to execute the same form in raw Lisp, in the proof-checker, or
in the ACL2 top-level loop (lp).


File: acl2-doc-emacs.info,  Node: ACL2-PC||ADD-ABBREVIATION,  Next: ACL2-PC||AL,  Prev: ACL2-PC||ACL2-WRAP,  Up: PROOF-CHECKER-COMMANDS

ACL2-PC||ADD-ABBREVIATION    (primitive)
add an abbreviation

Example:  (add-abbreviation v (* x y)) causes future occurrences of (*
x y) to be printed as (? v), until (unless) a corresponding invocation
of remove-abbreviations occurs.  In this case we say that v
"abbreviates" (* x y).

     General Form:
     (add-abbreviation var &optional raw-term)

Let var be an abbreviation for raw-term, if raw-term is supplied, else
for the current subterm.  Note that var must be a variable that does
not already abbreviate some term.

A way to think of abbreviations is as follows.  Imagine that whenever
an abbreviation is added, say v abbreviates expr, an entry associating
v to expr is made in an association list, which we will call
"*abbreviations-alist*".  Then simply imagine that ? is a function
defined by something like:

     (defun ? (v)
       (let ((pair (assoc v *abbreviations-alist*)))
         (if pair (cdr pair)
           (error ...))))

Of course the implementation isn't exactly like that, since the
"constant" *abbreviations-alist* actually changes each time an
add-abbreviation instruction is successfully invoked.  Nevertheless, if
one imagines an appropriate redefinition of the "constant"
*abbreviations-alist* each time an add-abbreviation is invoked, then
one will have a clear model of the meaning of such an instruction.

The effect of abbreviations on output is that before printing a term,
each subterm that is abbreviated by a variable v is first replaced by
(? v).

The effect of abbreviations on input is that every built-in
proof-checker command accepts abbreviations wherever a term is expected
as an argument, i.e., accepts the syntax (? v) whenever v abbreviates a
term.  For example, the second argument of add-abbreviation may itself
use abbreviations that have been defined by previous add-abbreviation
instructions.

See also remove-abbreviations and show-abbreviations.


File: acl2-doc-emacs.info,  Node: ACL2-PC||AL,  Next: ACL2-PC||APPLY-LINEAR,  Prev: ACL2-PC||ADD-ABBREVIATION,  Up: PROOF-CHECKER-COMMANDS

ACL2-PC||AL    (macro)
same as apply-linear

     Example:
     (al 3)

See the documentation for apply-linear, as al and apply-linear are
identical.

