This is documentation for ACL2 Version 4.1
Copyright (C) 2010  University of Texas at Austin

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

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.

RESET-LD-SPECIALS    restores initial settings of the ld specials

     Examples:
     (reset-ld-specials t)
     (reset-ld-specials nil)

Roughly speaking, the ld specials are certain state global variables,
such as current-package, ld-prompt, and ld-pre-eval-filter, which are
managed by ld as though they were local variables.  These variables
determine the channels on which ld reads and prints and control many
options of ld.  See LD for the details on what the ld specials
are.

This function, reset-ld-specials, takes one Boolean argument, flg.  The
function resets all of the ld specials to their initial, top-level
values, except for the three channel variables, standard-oi,
standard-co, and proofs-co, which are reset to their initial values
only if flg is non-nil.  Of course, if you are in a recursive call of
ld, then when you exit that call, the ld specials will be restored to
the values they had at the time ld was called recursively.  To see what
the initial values are, inspect the value of the constant
*initial-ld-special-bindings*.

SAVE-EXEC    save an executable image and (for most Common Lisps) a wrapper script

See SAVING-AND-RESTORING for an explanation of why one might
want to use this function.

     Examples:
     ; Save an executable named my-saved_acl2:
     (save-exec "my-saved_acl2"
                "This saved image includes Version 7 of Project Foo.")

     ; Same as above, but with a generic comment instead:
     (save-exec "my-saved_acl2" nil)

     General Form:
     (save-exec exec-filename extra-startup-string)

where exec-filename is the filename of the proposed executable and
extra-startup-string is a non-empty string to be printed after the
normal ACL2 startup message when you start up the saved image.  However,
extra-startup-string is allowed to be nil, in which case a generic
string will be printed instead.

*Notes*:

1. For technical reasons, you must first exit the ACL2 read-eval-print
loop, for example by executing :q, before evaluating a save-exec call.

2. The image will be saved so that in the new image, the raw Lisp
package and the package in the ACL2 read-eval-print loop (see
LP) will be the same as their respective values at the time save-exec
is called.

3. For most Common Lisps, the specified file (e.g., "my-saved_acl2" in
the examples above) will be written as a small script, which in turn
invokes a saved image to which an extension has been appended (e.g.,
my-saved_acl2.gcl for the examples above, when the underlying Common
Lisp is GCL on a non-Windows system).

SHARP-BANG-READER    package prefix that is not restricted to symbols

     Examples:

     ACL2 !>(defpkg "FOO" nil)

     Summary
     Form:  ( DEFPKG "FOO" ...)
     Rules: NIL
     Warnings:  None
     Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)
      "FOO"
     ACL2 !>'#!foo(a b)
     (FOO::A FOO::B)
     ACL2 !>'#!foo(a #!acl2 b)
     (FOO::A B)
     ACL2 !>'#!foo(#!acl2 a b)
     (A FOO::B)
     ACL2 !>'#!foo(#!"ACL2" a b)
     (A FOO::B)
     ACL2 !>

The ACL2 reader supports the syntax #!pkg-name expr where pkg-name is a
string or symbol that names a package known to ACL2.  As illustrated
above, this syntax nests as one might expect.  In the special case that
expr is a symbol, #!pkg-name expr is equivalent to pkg-name::expr.

SHARP-COMMA-READER    DEPRECATED read-time evaluation of constants

The use of `#,' has been deprecated.  Please use `#.' instead; see
SHARP-DOT-READER.

SHARP-DOT-READER    read-time evaluation of constants

     Example:

     ACL2 !>(defconst *a* '(a b c))

     Summary
     Form:  ( DEFCONST *A* ...)
     Rules: NIL
     Warnings:  None
     Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)
      *A*
     ACL2 !>(quote (1 2 #.*a* 3 4))
     (1 2 (A B C) 3 4)
     ACL2 !>

The ACL2 reader supports the syntax #.*a* where *a* was defined by
defconst.  In this case, the reader treats #.*a* as though it were
reading the value of *a*.  This feature can be useful in conjunction
with the use of evisc-table to abbreviate large constants, so that the
abbreviation can be read back in; see EVISC-TABLE.

Note that the ACL2 reader only supports `#.' as described above, unlike
Common Lisp.  Older versions (preceding  3.5) used `#.' to abort, but
that functionality is now carried out by (a!); see A!.  For a
related feature that only pops up one level, see P!.

SHOW-ACCUMULATED-PERSISTENCE    See ACCUMULATED-PERSISTENCE.

SKIP-PROOFS    skip proofs for a given form -- a quick way to introduce unsoundness

     Example Form:
     (skip-proofs
       (defun foo (x)
         (if (atom x) nil (cons (car x) (foo (reverse (cdr x)))))))

     General Form:
     (skip-proofs form)

where form is processed as usual except that the proof obligations
usually generated are merely assumed.

Normally form is an event; see EVENTS.  If you want to put
skip-proofs around more than one event, consider the following (see
PROGN): (skip-proofs (progn event1 event2 ... eventk)).

WARNING: Skip-proofs allows inconsistent events to be admitted to the
logic.  Use it at your own risk!

Sometimes in the development of a formal model or proof it is
convenient to skip the proofs required by a given event.  By embedding
the event in a skip-proofs form, you can avoid the proof burdens
generated by the event, at the risk of introducing unsoundness.  Below
we list four illustrative situations in which you might find
skip-proofs useful.

1. The termination argument for a proposed function definition is
complicated.  You presume you could admit it, but are not sure that
your definition has the desired properties.  By embedding the defun
event in a skip-proofs you can "admit" the function and experiment with
theorems about it before undoing (see UBT) and then paying the
price of its admission.  Note however that you might still have to
supply a measure.  The set of formals used in some valid measure, known
as the "measured subset" of the set of formals, is used by ACL2's
induction heuristics and therefore needs to be suitably specified.  You
may wish to specify the special measure of (:? v1 ... vk), where (v1
... vk) enumerates the measured subset.

2. You intend eventually to verify the guards for a definition but do
not want to take the time now to pursue that.  By embedding the
verify-guards event in a skip-proofs you can get the system to behave
as though the guards were verified.

3. You are repeatedly recertifying a book while making many experimental
changes.  A certain defthm in the book takes a very long time to prove
and you believe the proof is not affected by the changes you are
making.  By embedding the defthm event in a skip-proofs you allow the
theorem to be assumed without proof during the experimental
recertifications.

4. You are constructing a proof top-down and wish to defer the proof of
a defthm until you are convinced of its utility.  You can embed the
defthm in a skip-proofs.  Of course, you may find later (when you
attempt prove the theorem) that the proposed defthm is not a theorem.

Unsoundness or Lisp errors may result if the presumptions underlying a
use of skip-proofs are incorrect.  Therefore, skip-proofs must be
considered a dangerous (though useful) tool in system development.

Roughly speaking, a defthm embedded in a skip-proofs is essentially a
defaxiom, except that it is not noted as an axiom for the purposes of
functional instantiation (see LEMMA-INSTANCE).  But a skipped
defun is much more subtle since not only is the definitional equation
being assumed but so are formulas relating to termination and type.
The situation is also difficult to characterize if the skip-proofs
events are within the scope of an encapsulate in which constrained
functions are being introduced.  In such contexts no clear logical
story is maintained; in particular, constraints aren't properly tracked
for definitions.  A proof script involving skip-proofs should be
regarded as work-in-progress, not as a completed proof with some
unproved assumptions.  A skip-proofs event represents a promise by the
author to admit the given event without further axioms.  In other
words, skip-proofs should only be used when the belief is that the
proof obligations are indeed theorems in the existing ACL2 logical
world.

ACL2 allows the certification of books containing skip-proofs events by
providing the keyword argument :skip-proofs-okp t to the certify-book
command.  This is contrary to the spirit of certified books, since one
is supposedly assured by a valid certificate that a book has been
"blessed."  But certification, too, takes the view of skip-proofs as
"work-in-progress" and so allows the author of the book to promise to
finish.  When such books are certified, a warning to the author is
printed, reminding him or her of the incurred obligation.  When books
containing skip-proofs are included into a session, a warning to the
user is printed, reminding the user that the book is in fact incomplete
and possibly inconsistent.  This warning is in fact an error if
:skip-proofs-okp is nil in the include-book form; see
INCLUDE-BOOK.

THM    prove a theorem

     Example:
     (thm (equal (app (app a b) c)
                 (app a (app b c))))

Also see DEFTHM.  Unlike defthm, thm does not create an event;
it merely causes the theorem prover to attempt a proof.

     General Form:
     (thm term
          :hints        hints
          :otf-flg      otf-flg
          :doc          doc-string)

where term is a term alleged to be a theorem, and hints, otf-flg and
doc-string are as described in the corresponding :doc entries.  The
three keyword arguments above are all optional.

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.
     (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.  The particular message you see varies from Lisp to
Lisp, and may contain 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.

Without any keyword arguments, time$ often prints a rather verbose
message.  However, if time$ is provided with at least one keyword
argument, then it will display a custom message, either provided by
ACL2 or configured using the :msg and :args parameters.  Time$ can also
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 FMT), and it may refer
     to the elements of :args by their positions, just as for cw (see
     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 OPEN-TRACE-FILE), then you can expect to find
the time$ output there.

(2) You may see that the form being timed is a call of the ACL2
evaluator function ev-rec.  This is normal.

TOP-LEVEL    evaluate a top-level form as a function body

Some forms, such as calls of with-local-stobj, are illegal when
supplied directly to the ACL2 top-level loop.  The macro top-level
provides a workaround in such cases, by defining a temporary
:program-mode function named top-level-fn whose only argument is state
and whose body is the form to be evaluated.  When the call of top-level
returns there is no change to the existing ACL2 logical world.  The
following edited log illustrates all of the above points.

     ACL2 !>:pbt 0
               0  (EXIT-BOOT-STRAP-MODE)
     ACL2 !>(defstobj st fld)

     Summary
     Form:  ( DEFSTOBJ ST ...)
     Rules: NIL
     Time:  0.01 seconds (prove: 0.00, print: 0.00, other: 0.01)
      ST
     ACL2 !>(top-level
             (with-local-stobj
              st
              (mv-let (result st)
                      (let ((st (update-fld 17 st)))
                        (mv (fld st) st))
                      result)))
     17
     ACL2 !>(top-level
             (with-local-stobj
              st
              (mv-let (result st)
                      (let ((st (update-fld 17 st)))
                        (mv (fld st) st))
                      (mv nil result state))))
      17
     ACL2 !>(top-level
             (with-local-stobj
              st
              (mv-let (result st)
                      (let ((st (update-fld 17 st)))
                        (mv (fld st) st))
                      (mv result state))))
     (17 <state>)
     ACL2 !>:pbt 0
               0  (EXIT-BOOT-STRAP-MODE)
        d      1:x(DEFSTOBJ ST FLD)
     ACL2 !>

Each argument of top-level after the first should be a declare form or
documentation string, as the list of these extra arguments will be
placed before the first argument when forming the definition of
top-level-fn.

TRANS    print the macroexpansion of a form

     Examples:
     :trans (list a b c)
     :trans (caddr x)
     :trans (cond (p q) (r))

This function takes one argument, an alleged term, and translates it,
expanding the macros in it completely.  Either an error is caused or
the formal meaning of the term is printed.  We also print the "output
signature" which indicates how many results are returned and which are
single-threaded objects.  For example, a term that returns one ordinary
object (e.g., an object other than STATE or a user-defined
single-threaded object (see DEFSTOBJ)) has the output signature

     => *

A term that returns the single-threaded object STATE has the output
signature

     => STATE

and a term that returns four results might have the output signature

     => (MV $MEM * * STATE)

This signature indicates that the first result is the (user defined)
single-threaded object $MEM, that the next two results are ordinary,
and that the last result is STATE.

See TRANS! for a corresponding command that does not enforce
restrictions of single-threaded objects.

It is sometimes more convenient to use trans1 which is like trans but
which only does top-level macroexpansion.

For more, see TERM.

TRANS!    print the macroexpansion of a form without single-threadedness concerns

     Examples:
     :trans! (list a b c)
     :trans! (append x state)

:Trans! is identical to :trans, except that unlike :trans, :trans!
ignores single-threadedness restrictions.  Thus, the second form above
is legal for :trans!.  Also see TRANS and see TRANS1.

TRANS1    print the one-step macroexpansion of a form

     Examples:
     :trans1 (list a b c)
     :trans1 (caddr x)
     :trans1 (cond (p q) (r))

This function takes one argument, an alleged term, and expands the
top-level macro in it for one step only.  Either an error is caused,
which happens when the form is not a call of a macro, or the result is
printed.  Also see TRANS, which translates the given form
completely.

VERIFY-GUARDS-FORMULA    view the guard proof obligation, without proving it

See VERIFY-GUARDS and see GUARD for a discussion of
guards.  This utility is provided for viewing a guard proof obligation,
without doing a proof.

     Example Forms:
     (verify-guards-formula foo)
     (verify-guards-formula foo :guard-debug t)
     (verify-guards-formula foo :otf-flg dont-care :xyz whatever)
     (verify-guards-formula (+ (foo x) (bar y)) :guard-debug t)

Verify-guards-formula allows all keywords, but only pays attention to
:guard-debug, which has the same effect as in verify-guards (see
GUARD-DEBUG).  Apply verify-guards-formula to a name just as you
would use verify-guards, but when you only want to view the formula
rather than creating an event.  If the first argument is not a symbol

See GUARD-OBLIGATION if you want to obtain guard proof
obligations for use in a program.

WALKABOUT    explore an ACL2 cons tree

By typing (walkabout x state) for an ACL2 term x whose value is a cons
tree, you can walk around that tree.  For example, ACL2 developers
often use this utility to explore the ACL2 logical world.

When you issue a walkabout command, a summary of commands will be
printed before you enter an interactive loop.

     Commands:
     0, 1, 2, ..., nx, bk, pp, (pp n), (pp lev len), =, (= symb), and q.

In the interactive walkabout loop, a positive integer n takes you to the
nth position, while 0 takes you up a level.  The commands nx and bk
take you to the next and previous position, respectively, at the same
level.  The command pp prints the current object in full, while (pp
level length) hides sub-objects below the indicated level and past the
indicated length, if non-nil; see EVISC-TUPLE.  The command (pp
n) abbreviates (pp n n), so in particular (pp nil) is equivalent to pp.

The following example illustrates the commands described above.

     ACL2 !>(walkabout (append '(a (b1 b2 b3)) '(c d e f)) state)

     Commands:
     0, 1, 2, ..., nx, bk, pp, (pp n), (pp lev len), =, (= symb), and q.

     (A (B1 B2 B3) C ...)
     :2
     (B1 B2 B3)
     :3
     B3
     :0
     (B1 B2 B3)
     :nx
     C
     :nx
     D
     :0
     (A (B1 B2 B3) C ...)
     :pp
     (A (B1 B2 B3) C D E F)
     :(pp 4)
     (A (B1 B2 B3) C D ...)
     :(pp 1 4)
     (A # C D ...)
     :(pp nil 2)
     (A (B1 B2 ...) ...)
     :q
     ACL2 !>

Finally we describe the commands q, =, and (= symb), where symb is a
symbol.  The command q simply causes an exit from the walkabout loop.
The command = also exits, but causes the current object to be printed
in full.  The command (= symb) saves an association of symb with the
current object, which can be retrieved outside the walkabout loop using
the macro walkabout=, as illustrated below.

     :2
     (B1 B2 B3)
     :(= my-list)
     (walkabout= MY-LIST) is
     (B1 B2 B3)
     :q
     ACL2 !>(walkabout= MY-LIST)
     (B1 B2 B3)
     ACL2 !>

Finally, we remark that for trees that are not true-lists, walkabout
treats the dot as an object that can be "walked about".  The following
example illustrates this point.

     ACL2 !>(walkabout '(c d e . f) state)

     Commands:
     0, 1, 2, ..., nx, bk, pp, (pp n), (pp lev len), =, (= symb), and q.

     (C D E . F)
     :3
     E
     :nx
     .
     :nx
     F
     :0
     (C D E . F)
     :4
     .
     :0
     (C D E . F)
     :5
     F
     :

WITH-PROVER-TIME-LIMIT    limit the time for proofs

     Examples:

     ; Limit (mini-proveall) to about 1/4 second:
     (with-prover-time-limit 1/4 (mini-proveall))

     ; Limit (mini-proveall) to about 1/4 second, even if surrounding call of
     ; with-prover-time-limit provides for a more restrictive bound:
     (with-prover-time-limit '(1/4) (mini-proveall))

     ; Limit the indicated theorem to about 1/50 second, and if the proof does not
     ; complete or it fails, then put down a label instead.
     (mv-let (erp val state)
             (with-prover-time-limit
              1/50
              (thm (equal (append (append x x) x)
                          (append x x x))))
             (if erp
                 (deflabel foo :doc "Attempt failed.")
               (value (list :succeeded-with val))))

     General Form:
     (with-prover-time-limit time form)

where time evaluates to a positive rational number or to a list
containing such, and form is arbitrary.  Logically,
(with-prover-time-limit time form) is equivalent to form.  However, if
the runtime for evaluation of form exceeds the value specified by time,
and if ACL2 notices this fact during a proof, then that proof will
abort, for example like this:

     ACL2 Error in ( DEFTHM PERM-REFLEXIVE ...):  Out of time in the rewriter.

If there is already a surrounding call of with-prover-time-limit that
has set up an expiration time, the inner with-prover-time-limit call is
not allowed to push that time further into the future unless the inner
time is specified as a list containing a rational, rather than as a
rational.

Although with-prover-time-limit is an ACL2 function -- in particular it
evaluates both its arguments -- nevertheless, it is not a standard
function in some respects.  (1) The value of its first (time limit)
argument affects the evaluation of its second argument (by causing an
error during that evaluation if the time for completion is
insufficient).  (2) The second argument can return multiple values (see
MV), which are then returned by the call of
with-prover-time-limit. (3) Thus, there is not a fixed number of values
returned by with-prover-time-limit.

If you find that the time limit appears to be implemented too loosely,
you are encouraged to email an example to the ACL2 implementors with
instructions on how to observe the undesirable behavior.  This
information can probably be used to improve ACL2 by the insertion of
more checks for expiration of the time limit.

The rest of this documentation topic explains the rather subtle logical
story, and is not necessary for understanding how to use
with-prover-time-limit.  The ACL2 state object logically contains a
field called the acl2-oracle, which is an arbitrary true list of
objects.  This field can be read by a function called read-acl2-oracle,
which however is untouchable (see PUSH-UNTOUCHABLE), meaning
that it is cannot be called by ACL2 users.  The acl2-oracle field is
thus "secret".  Our claim is that any ACL2 session makes sense for
*some* value of acl2-oracle in the initial state for that session.
Logically, with-prover-time-limit is a no-op, just returning its second
value.  But under the hood, it provides a "hint" for the acl2-oracle,
so that (logically speaking) when its first element (car) is consulted
by ACL2's prover to see if the time limit has expired, it gets the
"right" answer (specifically, either nil if all is well or else a
message to print if the time limit has expired).  Logically, the
acl2-oracle is then cdr'ed -- that is, its first element is popped off
-- so that future results from read-acl2-oracle are independent of the
one just obtained.

PARALLELISM    experimental extension for evaluating forms in parallel

This documentation topic relates to an experimental extension of ACL2,
created initially by David L. Rager.  See PARALLELISM-BUILD for
how to build an executable image that supports parallel evaluation.
Also see books/parallel for examples.

One of ACL2's strengths lies in its ability to execute industrial models
efficiently.  The ACL2 source code provides an experimental parallel
evaluation capability that can increase the speed of explicit
evaluation, including simulator runs using such models, and it can also
decrease the time required for proofs that make heavy use of the
evaluation of ground terms.

The parallelism primitives are plet, pargs, pand, and por.  Pand and
por terminate early when an argument is found to evaluate to nil or
non-nil, respectively, thus potentially improving on the efficiency of
lazy evaluation.

The parallelism primitives allow for limiting parallel evaluation
(spawning of so-called "threads") depending on resource availability.
Specifically, the primitives allow specification of a size condition to
control the granularity under which threads are allowed to spawn.  You
can use such granularity declarations in recursively-defined functions
to implement data-dependent parallelism in their execution.

We recommend that in order to learn to use the parallelism primitives,
you begin by reading examples: see PARALLELISM-TUTORIAL.  That
section will direct you to further documentation topics.

EARLY-TERMINATION    early termination for pand and por.

The evaluation of (and expr1 expr2) returns nil if expr1 evaluates to
nil, avoiding the evaluation of expr2.  More generally, the evaluation
of (and expr1 expr2 ... exprk) terminates with a return value of nil as
soon as any expri evaluates to nil -- no exprj is evaluated in this
case for j > i.  This so-called "lazy evaluation" of and terms can thus
save some computation; roughly speaking, the smaller the i, the more
computation is saved.

If the above call of and is replaced by its parallel version, pand,
then there can be even more opportunity for skipping work.  The
arguments to pand can be evaluated in parallel, in which case the first
such evaluation that returns with a value of nil, if any, causes the
remaining such evaluations to abort.

Consider the following functions that compute whether a tree is valid
(see GRANULARITY for a discussion of the granularity form).

     (defun valid-tip (x)
       (declare (xargs :guard t))
       (or (eq x 'A)
           (eq x 'T)
           (eq x 'C)
           (eq x 'G)))

     (defun pvalid-tree (x depth)
       (declare (xargs :guard (natp depth)))
       (if (atom x)
           (valid-tip x)
         (pand (declare (granularity (< depth 10)))
               (pvalid-tree (car x) (1+ depth))
               (pvalid-tree (cdr x) (1+ depth)))))

We would like to stop execution as soon as any tip is found to be
invalid.  So, when computing the conjunction of terms by using pand,
once one of those terms evaluates to nil, the computations for the
other terms are aborted and the pand call returns nil.  By using pand,
we can in principle attain a speedup factor greater than the number of
available cores.

The concept of early termination also applies to por, except that early
termination occurs when an argument evaluates to non-nil.

GRANULARITY    limit the amount of parallelism

Some function calls are on arguments whose evaluation time is long
enough to warrant parallel evaluation, while others are not.  A
granularity form can be used to make appropriate restrictions on the
use of parallelism.

For example, consider the Fibonacci function.  Experiments have
suggested that execution time can be reduced if whenever the argument
is less than 27, a serial version of the Fibonacci function is called.
One way to utilize this information is to write two definitions of the
Fibonacci function, one serial and one parallel.

     (defun fib (x)
       (declare (xargs :guard (natp x)))
       (cond ((or (zp x) (<= x 0)) 0)
             ((= x 1) 1)
             (t (binary-+ (fib (- x 1))
                          (fib (- x 2))))))

     (defun pfib (x)
       (declare (xargs :guard (natp x)))
       (cond ((or (zp x) (<= x 0)) 0)
             ((= x 1) 1)
             ((< x 27) (binary-+ (fib (- x 1))
                                 (fib (- x 2))))
             (t (pargs (binary-+ (pfib (- x 1))
                                 (pfib (- x 2)))))))

We realize quickly that writing both of these function definitions is
cumbersome and redundant.  This problem can be avoided by using a
granularity declaration with a parallelism primitive.  This form ensures
that a call is parallelized only if resources are available and the
granularity form evaluates to a non-nil value at the time of the call.
Below is a definition of the Fibonacci function using a granularity
form.

     (defun pfib (x)
       (declare (xargs :guard (natp x)))
       (cond ((or (zp x) (<= x 0)) 0)
             ((= x 1) 1)
             (t (pargs (declare (granularity (>= x 27)))
                       (binary-+ (pfib (- x 1))
                                 (pfib (- x 2)))))))

A granularity form can reference an extra formal parameter that
describes the call depth of the function the user is parallelizing.
Consider for example the following parallel mergesort function, based
on Davis's Ordered Sets library.  It splits the data into symmetric
chunks for computation, so we increment the depth argument during the
recursive call on both the car and cdr.

     (include-book "finite-set-theory/osets/sets" :dir :system)
     (defun sets::pmergesort-exec (x depth)
       (declare (xargs :mode :program))
       (cond ((endp x) nil)
             ((endp (cdr x)) (sets::insert (car x) nil))
             (t (mv-let (part1 part2)
                        (sets::split-list x nil nil)
                        (pargs
                         (declare (granularity (< depth 2)))
                         (sets::union (sets::pmergesort-exec part1
                                                             (1+ depth))
                                      (sets::pmergesort-exec part2
                                                             (1+ depth))))))))

A less intrusive method (i.e., not requiring an extra formal parameter
like the depth argument just above), which however can be less
efficient, involves analyzing the data itself for structural
properties.  For example:

     (defun some-depth-exceeds (x n)
       (declare (xargs :guard (natp n)))
       (if (atom x)
           nil
         (if (zp n)
             t
           (or (some-depth-exceeds (car x) (1- n))
               (some-depth-exceeds (cdr x) (1- n))))))

     (defun valid-tip (x)
       (declare (xargs :guard t))
       (or (eq x 'A)
           (eq x 'T)
           (eq x 'C)
           (eq x 'G)))

     (defun pvalid-tree (x)
       (declare (xargs :guard t))
       (if (atom x)
           (valid-tip x)
         (pand (declare (granularity (some-depth-exceeds x 3)))
               (pvalid-tree (car x))
               (pvalid-tree (cdr x)))))

If you experiment with calls of pvalid-tree, you are likely to find that
the "speedup" it provides over a corresponding serial version is, in
fact, a slowdown!  The problem is likely that some-depth-exceeds is an
expensive function to run repeatedly.  Instead of the approach above,
it is often handy to add an extra formal parameter in order to allow
for more efficient granularity forms, as we have done above in the
definition of SETS::pmergesort-exec.

PAND    parallel, Boolean version of and

     Example Forms:
     (pand (subsetp-equal x y)
           (subsetp-equal y x))

     (pand (declare
            (granularity
             (and (> (length x) 500)
                  (> (length y) 500))))
            (subsetp-equal x y)
            (subsetp-equal y x))

     General Form:
     (pand (declare (granularity expr)) ; optional granularity declaration
           arg1 ... argN)

where N >= 0 and each argi and expr are arbitrary terms.

Pand evaluates its arguments in parallel.  It returns a Boolean result:
nil if any argument evaluates to nil, else t.  Note that pand always
returns a Boolean result, even though and can return a non-nil value
other than t, namely the value of its last argument.  (A moment's
reflection will make it clear that in order for por to parallelize
efficiently, it needs to return a Boolean value; so pand returns a
Boolean value for consistency with por.)

Another difference between pand and and is that for a call of pand,
even if an argument evaluates to nil, a subsequent argument may be
evaluated.  Consider the following example (where cw prints a string;
see CW).

     (defun bar ()
       (pand (equal (make-list 100000) nil) ; evaluates to nil
             (cw "hello world~%")))

When (bar) is evaluated, the above arguments of pand can execute in
parallel, causing "hello world" to be printed to the terminal.  If we
had used and rather than pand, then since (equal (make-list 100000)
nil) evaluates to nil, the above call of cw would be avoided and no
such printing would take place.  Even with pand, such printing _might_
not take place, depending on resources, timing of thread creation, and
whether or not parallel evaluation is enabled (see
SET-PARALLEL-EVALUATION).

Note that unlike the case for and, the definition of pand does not
provide (consp x) as a guard to (car x) in the call of pand below:

     (defun h (x)
       (declare (xargs :guard t))
       (pand (consp x) (equal (car x) 'foo)))

As a result, guard verification will fail for the above definition.  If
pand were replaced by and, then guard verification would succeed.

See PARALLELISM-TUTORIAL for another example.  Also see
PARALLELISM-AT-THE-TOP-LEVEL for restrictions on evaluating
parallelism primitives from within the ACL2 top-level loop.  Finally
see EARLY-TERMINATION to read how pand can offer more
efficiency than and by avoiding evaluation of some of its arguments.

PARALLEL    evaluating forms in parallel

See PARALLELISM.

PARALLELISM-AT-THE-TOP-LEVEL    parallel evaluation in the ACL2 top-level loop

Calls of parallelism primitives made explicitly in the ACL2 top-level
loop, as opposed to inside function bodies, will never cause parallel
evaluation.  Such calls will either execute with serial evaluation or
will cause an error; see SET-PARALLEL-EVALUATION.

Consider for example the following call of pargs in the ACL2 top-level
loop.  Instead of executing parge, ACL2 macroexpands away this call,
leaving us with serial evaluation of the arguments to the cons call, or
else causes an error (see SET-PARALLEL-EVALUATION).  If there
is no error, then

     (pargs (cons (expensive-fn-1 4) (expensive-fn-2 5)))

expands into:

     (cons (expensive-fn-1 4) (expensive-fn-2 5))

A trivial way to enable parallel evaluation of a form is to put it
inside a function body.  For example, consider the following definition.

     (defun foo (x y)
       (declare (xargs :guard t))
       (pargs (cons (expensive-fn-1 x) (expensive-fn-2 y))))

Then in an executable image that supports parallel evaluation -- see
PARALLELISM-BUILD for instructions on how to build such an
executable -- submission of the form (foo 4 5), even in the ACL2
top-level loop, can cause parallel evaluation of (expensive-fn-1 4) and
(expensive-fn-2 5).

Note that guards need not be verified in order to obtain parallel
evaluation.  The only restrictions on parallel evaluation are to use an
executable supporting it, to avoid calling parallelism primitives
directly in the top-level loop, to have sufficient resources
(especially, threads) available, and to avoid explicitly disabling
parallel evaluation see SET-PARALLEL-EVALUATION).

PARALLELISM-BUILD    building an ACL2 executable with parallel evaluation enabled

See PARALLEL and see PARALLELISM-TUTORIAL for an
introduction to parallel evaluation in ACL2 using parallelism
primitives pand, por, plet, and pargs.

You can build an experimental version of ACL2 that supports parallel
evaluation in the following host Common Lisp implementations:

     * CCL (OpenMCL)

     * SBCL with threads (feature :sb-thread)

An easy way is to build an executable supporting parallel evaluation is
to include the following with a make command:

     ACL2_PAR=p

So for example, to make an executable image and also documentation
(which will appear in subdirectories doc/EMACS and doc/HTML):

     make large DOC ACL2_PAR=p

PARALLELISM-PERFORMANCE    performance issues for parallel evaluation

See GRANULARITY for an important construct that limits the
spawning of parallel computations, which can be important when a
computation is too short-lived to warrant a separate thread.

There are times in which parallelism provides no speedup because of
garbage collection in the underlying Lisp implementation.  The
following example illustrates this phenomenon.  If you change the
granularity declaration so that the depth bound is 3, 4, or larger
instead of 2, you may still find no speedup.  In all cases you may find
that parallelism results in a significantly greater time spent in
garbage collection.

     (include-book "finite-set-theory/osets/sets" :dir :system)
     (defun sets::pmergesort-exec (x depth)
         (declare (xargs :mode :program))
         (cond ((endp x) nil)
               ((endp (cdr x)) (sets::insert (car x) nil))
               (t (mv-let (part1 part2)
                          (sets::split-list x nil nil)
                          (pargs
                           (declare (granularity (< depth 2)))
                           (sets::union (sets::pmergesort-exec part1
                                                               (1+ depth))
                                        (sets::pmergesort-exec part2
                                                               (1+ depth))))))))
     (defconst *x* (reverse (fromto 1 400000)))
     (time$ (length (sets::pmergesort-exec *x* 0)))
     (set-parallel-evaluation nil)
     (time$ (length (sets::pmergesort-exec *x* 0)))

PARALLELISM-TUTORIAL    a tutorial on how to use the parallelism library.

In this topic we introduce the ACL2 parallelism primitives using the
example of a doubly-recursive Fibonacci function, whose basic
definition is as follows.  See PARALLELISM for a very
high-level summary of the parallelism capability described here, and
see PARALLELISM-BUILD for how to build an executable image that
supports parallel evaluation.  Here, we assume that such an executable
is being used.

Serial Fibonacci

     (defun fib (x)
       (declare (xargs :guard (natp x)))
       (cond ((or (zp x) (<= x 0)) 0)
             ((= x 1) 1)
             (t (+ (fib (- x 1)) (fib (- x 2))))))

Introducing Pargs

A simple way to introduce parallelism into this function definition is
to wrap the addition expression with a call of pargs, and the arguments
to the addition will be computed in parallel whenever resources are
available.  As a result, we end up with a very similar and thus
intuitive function definition.  Note that we replaced + by binary-+,
since pargs expects a function call, not a macro call.

     (defun pfib (x)
       (declare (xargs :guard (natp x)))
       (cond ((or (zp x) (<= x 0)) 0)
             ((= x 1) 1)
             (t (pargs (binary-+ (pfib (- x 1))
                                 (pfib (- x 2)))))))

Introducing the Granularity Problem

After you submit the above two versions of the Fibonacci function, test
them with the following forms.

     (time$ (fib 10))
     (time$ (pfib 10))

Now increase the argument by increments of 5 to 10 until you find your
curiosity satisfied or your patience wearing thin.  You can interrupt
evaluation if necessary and return to the ACL2 loop.  You will
immediately notice that you have not increased execution speed, at
least not by much, by introducing parallelism.

First, consider the computation of (pfib 4).  Assuming resources are
available, (pfib 4) will create a thread for computing (pfib 3) and
another thread for (pfib 2).  It is easy to imagine that setting up each
thread takes much longer than the entire computation of (fib 4).

Second, we must realize that if we have two threads available for
computing (fib 10), then the evaluation of (fib 8) will probably
complete before the evaluation of (fib 9).  Once (fib 8) finishes,
parallelism resources will become available for the next recursive call
made on behalf of (fib 9).  If for example that call is (fib 3), we
will waste a lot of cycles just handing work to the thread that does
this relatively small computation.  We need a way to ensure that
parallelism resources are only used on problems of a "large" size.
Ensuring that only "large" problems are spawned is called the
"granularity problem."

In summary: We want to tell ACL2 that it can evaluate the arguments of
pargs in parallel only when the parameter of pfib is greater than some
threshold.  Our tests using CCL have suggested that 27 is a reasonable
threshold.

Explicit Programming for the Granularity Problem

One way to avoid the granularity problem is to duplicate code as
follows.

     (defun pfib (x)
       (declare (xargs :guard (natp x)))
       (cond ((or (zp x) (<= x 0)) 0)
             ((= x 1) 1)
             (t (if (> x 27) ; the granularity test
                    (pargs (binary-+ (pfib (- x 1))
                                     (pfib (- x 2))))
                  (binary-+ (pfib (- x 1))
                            (pfib (- x 2)))))))

Duplicating code is fundamentally a bad design principle, because it can
double the work for future maintenance.  A "granularity form" is an
expression

     (declare (granularity <form>))

that can allow threads to be spawned (without duplicating code)
whenever the evaluation of <form> results in a non-nil value.  It may
be placed inside any call of a parallelism primitive, in a position
documentated separately for each primitive.  Here is a definition of
pfib using this feature for a call of the parallelism primitive pargs.

     (defun pfib (x)
       (declare (xargs :guard (natp x)))
       (cond ((or (zp x) (<= x 0)) 0)
             ((= x 1) 1)
             (t (pargs
                 (declare (granularity (> x 27)))
                 (binary-+ (pfib (- x 1))
                           (pfib (- x 2)))))))

Test each version as follows (or substitute your own natural number for
33).

       (time$ (fib 33))
       (time$ (pfib 33))

Another Granularity Issue Related to Thread Limitations

Our implementation of parallelism primitives has the property that once
a thread is assigned a computation, that assignment stays in effect
until the computation is complete.  In particular, if a thread
encounters a parallelism primitive that spawns child threads, the
parent thread stays assigned, waiting until the child computations
complete before it can continue its own computation.  In the meantime,
the parent thread reduces the number of additional threads that Lisp
can provide by 1, rather than being reassigned to do other work.

How can this lack of reassignment affect the user?  Consider, for
example, the application of a recursive function to a long list.
Imagine that this function is written so that the body contains a
recursive call, for example as (pargs (process (car x)) (recur (cdr
x))).  Each such pargs call that spawns child work must wait for its
children, one of which is the work of evaluating (recur (cdr x)), to
complete.  There is an ACL2 limit on how much pending work can be in
the system, limiting the number of pargs calls that can result in
parallel evaluation.  For example, if the ACL2 limit is k and each call
of pargs actually spawns threads for evaluating  its arguments, then
after k cdrs there will be no further parallel evaluation.

Possible solutions may include reworking of algorithms (for example to
be tree-based rather than list-based) or using appropriate granularity
forms.  We hope that future implementations will allow thread
"re-deployment" in order to mitigate this problem.

Introducing Plet

We can use a let binding to compute the recursive calls of fib and then
add the bound variables together, as follows.

     (defun fib (x)
       (declare (xargs :guard (natp x)))
       (cond ((or (zp x) (<= x 0)) 0)
             ((= x 1) 1)
             (t (let ((a (fib (- x 1)))
                      (b (fib (- x 2))))
                  (+ a b)))))

By using the parallelism primitive plet, we can introduce parallelism
much as we did using pargs, with an optional granularity form, as
follows.

     (defun pfib (x)
       (declare (xargs :guard (natp x)))
       (cond ((or (zp x) (<= x 0)) 0)
             ((= x 1) 1)
             (t (plet
                 (declare (granularity (> x 27)))
                 ((a (pfib (- x 1)))
                  (b (pfib (- x 2))))
                 (+ a b)))))

Notice that this time, we were able to use + rather than being forced to
use binary-+.  Unlike pargs, which expects a function call (not a macro
call), plet allows macros at the top level of its body.

Introducing Pand (By Way of a Tree Validation Example)

Consider "genetic trees" that contains leaves of DNA elements, in the
sense that each tip is one of the symbols A, G, C, or T.  First we
define the function valid-tip which recognizes whether a tip contains
one of these symbols.

     (defun valid-tip (tip)
       (declare (xargs :guard t))
       (or (eq tip 'A)
           (eq tip 'G)
           (eq tip 'C)
           (eq tip 'T)))

Now we define a function that traverses the tree, checking that every
tip is valid.

     (defun valid-tree-serial (tree)
       (declare (xargs :guard t))
       (if (atom tree)
           (valid-tip tree)
         (and (valid-tree-serial (car tree))
              (valid-tree-serial (cdr tree)))))

We also define a parallel version.

     (defun valid-tree-parallel (tree)
       (declare (xargs :guard t))
       (if (atom tree)
           (valid-tip tree)
         (pand (valid-tree-parallel (car tree))
               (valid-tree-parallel (cdr tree)))))

Before we can time the functions, we need to create test trees.  We have
found that test trees need to be approximately 1 gigabyte before we
clearly see speedup, and we make them asymmetric to demonstrate the
ability of our implementation to adapt to asymmetric data.  We can
create the trees with the execution of the following forms.

     (defun make-valid-binary-tree (x)
       (declare (xargs :mode :program))
       (if (< x 0)
           (cons (cons 'C 'G) (cons 'A 'T))
         (cons (make-valid-binary-tree (- x 2)) ; 2 to make asymmetric
               (make-valid-binary-tree (- x 1)))))

     (defconst *valid-tree* (make-valid-binary-tree 30)) ; takes awhile
     (defconst *invalid-tree* (cons *valid-tree* nil)) ; nil is invalid tip

We can time our functions with the forms:

     (time$ (valid-tree-serial *valid-tree*))
     (time$ (valid-tree-parallel *valid-tree*))

Unfortunately, the serial version runs faster than the parallelism
version; however, there is more to this story.

Demonstrating Early Termination with an Invalid Tree

Now observe this magic:

     (time$ (valid-tree-serial   *invalid-tree*))
     (time$ (valid-tree-parallel *invalid-tree*))

The serial version took awhile, while the parallel version finished
almost immediately.  The test for validation was split into testing the
car and the cdr of the *invalid-tree* root, and since the cdr was equal
to nil, its test returned immediately.  This immediate return quickly
interrupted the computation associated with the car, and returned the
result.

Granularity with Pand

We can also define a parallel version with a granularity form:

     (defun valid-tree-parallel (tree depth)
       (declare (xargs :guard (natp depth)))
       (if (atom tree)
           (valid-tip tree)
         (pand
          (declare (granularity (< depth 5)))
          (valid-tree-parallel (car tree) (1+ depth))
          (valid-tree-parallel (cdr tree) (1+ depth)))))

We can test this form by executing our previous forms.  You will
probably find some speedup on a machine with several cores available,
but more speedup can likely be obtained with an expensive test on the
leaves in place of valid-tip.

     (time$ (valid-tree-serial   *valid-tree*))
     (time$ (valid-tree-parallel *valid-tree* 0))

Introducing Por

Por can be used in the same way as pand, but with early termination
occurring when an argument evaluates to a non-nil value, in which case
the value returned is t.  Finally, por also supports the use of a
granularity form.

PARGS    parallel evaluation of arguments in a function call

     Example Forms:
     (pargs (binary-+ (fibonacci (- x 1)) (fibonacci (- x 2))))

     (pargs (declare (granularity (> x 35)))
            (binary-+ (fibonacci (- x 1)) (fibonacci (- x 2))))

     General Form:
     (pargs (declare (granularity expr)) ; optional granularity declaration
            (f arg1 ... argN))

where N >= 0 and each argi and expr are arbitrary terms.  Logically,
pargs is just the identity macro, in the sense that the above forms can
logically be replaced by (f arg1 ... argN).  However, this pargs form
may parallelize the evaluation of arguments arg1 through argN before
applying function f to those results.  If the above granularity
declaration is present, then its expression (expr above) is first
evaluated, and if the result is nil, then such parallelism is avoided.
Even if parallelism is not thus avoided, parallelism may be limited by
available resources.

Since macros can change expressions in unexpected ways, it is illegal
to call pargs on a form that is a macro call.  To parallelize
computation of arguments to a macro, see PLET.

See PARALLELISM-AT-THE-TOP-LEVEL for restrictions on evaluating
parallelism primitives from within the ACL2 top-level loop.

PLET    parallel version of let

     Example Forms:
     (plet ((a (fibonacci (- x 1)))
            (b (fibonacci (- x 2))))
           (+ a b))

     (plet (declare (granularity (> x 35)))
           ((a (fibonacci (- x 1)))
            (b (fibonacci (- x 2))))
           (+ a b))

     General Form:
     (plet (declare (granularity expr)) ; optional granularity declaration
           ((var1 val1)
            ...
            (varN valN))
           (declare ...) ... (declare ...) ; optional declarations
           body)

The syntax of plet is identical to the syntax of let, except that plet
permits an optional granularity declaration in the first argument
position; see GRANULARITY.  In the logic a call of plet
macroexpands to the corresponding call of let, where the granularity
declaration (if any) is dropped.

Plet cause the evaluation of each vali above to be done in parallel
before processing the body.  If the above granularity declaration is
present, then its expression (expr above) is first evaluated, and if the
result is nil, then such parallelism is avoided.  Even if parallelism is
not thus avoided, parallelism may be limited by available resources.

See PARALLELISM-AT-THE-TOP-LEVEL for restrictions on evaluating
parallelism primitives from within the ACL2 top-level loop.

POR    parallel, Boolean version of or

     Example Forms:
     (por (subsetp-equal x y)
          (subsetp-equal y x))

     (por (declare
           (granularity
            (and (> (length x) 500)
                 (> (length y) 500))))
           (subsetp-equal x y)
           (subsetp-equal y x))

     General Form:
     (por (declare (granularity expr)) ; optional granularity declaration
          arg1 ... argN)

where N >= 0 and each argi and expr are arbitrary terms.

Por evaluates its arguments in parallel.  It returns a Boolean result:
t if any argument evaluates to non-nil, else nil.  Note that while or
returns the first non-nil value from evaluating its arguments
left-to-right (if any such value is not nil) por always returns a
Boolean result, in support of efficiency (see EARLY-TERMINATION)
in light of the nondeterministic order in which argument values are
returned.

Another difference between por and or is that for a call of por, even
if the an argument's value is not nil, a subsequent argument may be
evaluated.  See PAND for a discussion of the analogous property
of pand.  In particular, guards generated from calls of por may not
assume for an argument that the preceding arguments evaluated to nil.

See PARALLELISM-TUTORIAL for another example.  Also see
PARALLELISM-AT-THE-TOP-LEVEL for restrictions on evaluating
parallelism primitives from within the ACL2 top-level loop.  Finally
see EARLY-TERMINATION to read how por can offer more efficiency
than or by avoiding evaluation of some of its arguments.

SET-PARALLEL-EVALUATION    enabling or disabling parallel evaluation

See PARALLEL and see PARALLELISM-TUTORIAL for an
introduction to parallel evaluation in ACL2 using parallelism
primitives pand, por, plet, and pargs.

     General Forms:
     (set-parallel-evaluation nil) ; default for images not built for parallelism
     (set-parallel-evaluation t)   ; default for images built for parallelism
     (set-parallel-evaluation :bogus-parallelism-ok)

Set-parallel-evaluation takes an argument that specifies the enabling or
disabling of parallel evaluation.  However, calls of parallelism
primitives made explicitly in the ACL2 top-level loop, as opposed to
inside function bodies, will never cause parallel evaluation; see
PARALLELISM-AT-THE-TOP-LEVEL.  Parallel evaluation is determined by
the value of the argument to set-parallel-evaluation, as follows.

Value t:
All parallelism primitives used in bodies of function definitions are
given the opportunity to execute in parallel.  However, the use of
parallelism primitives directly in the ACL2 top-level loop causes an
error.

Value :bogus-parallelism-ok:
Parallel evaluation is enabled, as for value t.  However, the use of
parallelism primitives directly in the ACL2 top-level loop does not
cause an error, but rather, simply results in serial evaluation for
these primitives.

Value nil:
All parallelism primitives will degrade to their serial equivalents,
include their calls made directly in the ACL2 top-level loop, which
does not cause an error.

PROGRAMMING    built-in ACL2 functions

The built-in ACL2 functions that one typically uses in writing programs
are listed below.  See their individual documentations.  We do not
bother to document some of the more obscure functions provided by ACL2
that do not correspond to functions of Common Lisp.

Related topics other than immediate subtopics:

See any documentation for Common Lisp for more details on many of these
functions.

*    multiplication macro

* is really a macro that expands to calls of the function binary-*.  So
for example

     (* x y 4 z)

represents the same term as

     (binary-* x (binary-* y (binary-* 4 z))).

See BINARY-*.

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

*STANDARD-CI*    an ACL2 character-based analogue of CLTL's *standard-input*

The value of the ACL2 constant *standard-ci* is an open character input
channel that is synonymous to Common Lisp's *standard-input*.

ACL2 character input from *standard-ci* is actually obtained by reading
characters from the stream named by Common Lisp's *standard-input*.
That is, by changing the setting of *standard-input* in raw Common Lisp
you can change the source from which ACL2 reads on the channel
*standard-ci*.  See *STANDARD-CO*.

*STANDARD-CO*    the ACL2 analogue of CLTL's *standard-output*

The value of the ACL2 constant *standard-co* is an open character
output channel that is synonymous to Common Lisp's *standard-output*.

ACL2 character output to *standard-co* will go to the stream named by
Common Lisp's *standard-output*.  That is, by changing the setting of
*standard-output* in raw Common Lisp you can change the actual
destination of ACL2 output on the channel named by *standard-co*.
Observe that this happens without changing the logical value of
*standard-co* (which is some channel symbol).  Changing the setting of
*standard-output* in raw Common Lisp essentially just changes the map
that relates ACL2 to the physical world of terminals, files, etc.

To see the value of this observation, consider the following.  Suppose
you write an ACL2 function which does character output to the constant
channel *standard-co*.  During testing you see that the output actually
goes to your terminal.  Can you use the function to output to a file?
Yes, if you are willing to do a little work in raw Common Lisp: open a
stream to the file in question, set *standard-output* to that stream,
call your ACL2 function, and then close the stream and restore
*standard-output* to its nominal value.  Similar observations can be
made about the two ACL2 input channels, *standard-oi* and
*standard-ci*, which are analogues of *standard-input*.

Another reason you might have for wanting to change the actual streams
associated with *standard-oi* and *standard-co* is to drive the ACL2
top-level loop, ld, on alternative input and output streams.  This end
can be accomplished easily within ACL2 by either calling ld on the
desired channels or file names or by resetting the ACL2 state global
variables 'standard-oi and 'standard-co which are used by ld.  See
STANDARD-OI and see STANDARD-CO.

*STANDARD-OI*    an ACL2 object-based analogue of CLTL's *standard-input*

The value of the ACL2 constant *standard-oi* is an open object input
channel that is synonymous to Common Lisp's *standard-input*.

ACL2 object input from *standard-oi* is actually obtained by reading
from the stream named by Common Lisp's *standard-input*.  That is, by
changing the setting of *standard-input* in raw Common Lisp you can
change the source from which ACL2 reads on the channel *standard-oi*.
See *STANDARD-CO*.

+    addition macro

+ is really a macro that expands to calls of the function binary-+.  So
for example

     (+ x y 4 z)

represents the same term as

     (binary-+ x (binary-+ y (binary-+ 4 z))).

See BINARY-+.

-    macro for subtraction and negation

See BINARY-+ for addition and see UNARY-- for negation.

Note that - represents subtraction as follows:

     (- x y)

represents the same term as

     (+ x (- y))

which is really

     (binary-+ x (unary-- y)).

Also note that - represents arithmetic negation as follows:

     (- x)

expands to

     (unary-- x).

/    macro for division and reciprocal

See BINARY-* for multiplication and see UNARY-/ for
reciprocal.

Note that / represents division as follows:

     (/ x y)

represents the same term as

     (* x (/ y))

which is really

     (binary-* x (unary-/ y)).

Also note that / represents reciprocal as follows:

     (/ x)

expands to

     (unary-/ x).

/ is a Common Lisp macro.  See any Common Lisp documentation for more
information.

/=    test inequality of two numbers

(/= x y) is logically equivalent to (not (equal x y)).

Unlike equal, /= has a guard requiring both of its arguments to be
numbers.  Generally, /= is executed more efficiently than a combination
of not and equal.

For a discussion of the various ways to test against 0, See
ZERO-TEST-IDIOMS.

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

1+    increment by 1

(1+ x) is the same as (+ 1 x).  See +.

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

1-    decrement by 1

(1- x) is the same as (- x 1).  See -.

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

<    less-than

Completion Axiom:

     (equal (< x y)
            (if (and (rationalp x)
                     (rationalp y))
                (< x y)
              (let ((x1 (if (acl2-numberp x) x 0))
                    (y1 (if (acl2-numberp y) y 0)))
                (or (< (realpart x1) (realpart y1))
                    (and (equal (realpart x1) (realpart y1))
                         (< (imagpart x1) (imagpart y1)))))))

Guard for (< x y):

     (and (rationalp x) (rationalp y))

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

This function has the usual meaning on the rational numbers, but is
extended to the complex rational numbers using the lexicographic order:
first the real parts are compared, and if they are equal, then the
imaginary parts are compared.

<=    less-than-or-equal test

<= is a macro, and (<= x y) expands to the same thing as (not (< y x)).
See <.

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

=    test equality of two numbers

(= x y) is logically equivalent to (equal x y).

Unlike equal, = has a guard requiring both of its arguments to be
numbers.  Generally, = is executed more efficiently than equal.

For a discussion of the various ways to test against 0, See
ZERO-TEST-IDIOMS.

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

>    greater-than test

> is a macro, and (> x y) expands to the same thing as (< y x).  See
<.

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

>=    greater-than-or-equal test

>= is a macro, and (>= x y) expands to the same thing as (not (< x y)).
See <.

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

ABS    the absolute value of a real number

(Abs x) is -x if x is negative and is x otherwise.

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

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

From "Common Lisp the Language" page 205, we must not allow complex x
as an argument to abs in ACL2, because if we did we would have to
return a number that might be a floating point number and hence not an
ACL2 object.

ACL2-NUMBERP    recognizer for numbers

(acl2-numberp x) is true if and only if x is a number, i.e., a rational
or complex rational number.

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
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".

ACONS    constructor for association lists

(Acons key datum alist) equals the result of consing the pair (cons key
datum) to the front of the association list alist.

(Acons key datum alist) has a guard of (alistp alist).  Acons is a
Common Lisp function.  See any Common Lisp documentation for more
information.

ADD-TO-SET-EQ    add a symbol to a list

For a symbol x and a true list lst, (add-to-set-eq x lst) is the result
of consing x on to the front of lst, unless x is already a member of
lst, in which case it equals lst.

(add-to-set-eq x lst) has a guard that lst is a true list and moreover,
either x is a symbol or lst is a list of symbols.

ADD-TO-SET-EQL    add an object to a list

For an object x and a true list lst, (add-to-set-eql x lst) is the
result of consing x on to the front of lst, unless x is already a
member of lst, in which case it equals lst.

(add-to-set-eql x lst) has a guard that lst is a true list and
moreover, either x is eqlablep or lst is an eqlable-listp.

ADD-TO-SET-EQUAL    add an object to a list

For an object x and a true list lst, (add-to-set-equal x lst) is the
result of consing x on to the front of lst, unless x is already a
member of lst, in which case it equals lst.

(add-to-set-equal x lst) has a guard that lst is a true list.

ALISTP    recognizer for association lists

(alistp x) is true if and only if x is a list of cons pairs.

(alistp x) has a guard of t.

ALLOCATE-FIXNUM-RANGE    set aside fixnums in GCL

(Allocate-fixnum-range fixnum-lo fixnum-hi) causes Gnu Common Lisp
(GCL) to create a persistent table for the integers between fixnum-lo
and fixnum-hi (both bounds inclusive). This table is referenced first
when any integer is boxed and the existing box in the table is used if
the integer is in bounds.  This can speed up GCL considerably by
avoiding wasteful fixnum boxing.  Here, fixnum-lo and fixnum-hi should
be fixnums, more specifically of type (signed-byte 30), with fixnum-lo
<= fixnum-hi.

When this function is executed in a Lisp implementation other than GCL,
it has no side effect.  This function always returns nil.

ALPHA-CHAR-P    recognizer for alphabetic characters

(Alpha-char-p x) is true if and only if x is a alphabetic character,
i.e., one of the characters #a, #b, ..., #z, #A, #B, ..., #Z.

The guard for alpha-char-p requires its argument to be a character.

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

ALPHORDER    total order on atoms

Alphorder is a non-strict total order, a "less than or equal," on
atoms.  By "non-strict total order" we mean a function that always
returns t or nil and satisfies the following properties.

     o Antisymmetry:  XrY & YrX -> X=Y

     o Transitivity:  XrY & YrZ -> XrZ

     o Trichotomy:  XrY v YrX

Also see LEXORDER, which extends alphorder to all objects.

(Alphorder x y) has a guard of (and (atom x) (atom y)).

Within a single type: rationals are compared arithmetically, complex
rationals are compared lexicographically, characters are compared via
their char-codes, and strings and symbols are compared with alphabetic
ordering.  Across types, rationals come before complexes, complexes
come before characters, characters before strings, and strings before
symbols.  We also allow for "bad atoms," i.e., atoms that are not legal
Lisp objects but make sense in the ACL2 logic; these come at the end,
after symbols.

AND    conjunction

And is the macro for conjunctions.  And takes any number of arguments.
And returns nil if one of the arguments is nil, but otherwise returns
the last argument.  If there are no arguments, and returns t.

And is a Common Lisp macro.  See any Common Lisp documentation for more
information.

APPEND    concatenate two or more lists

Append, which takes two or more arguments, expects all the arguments
except perhaps the last to be true (null-terminated) lists.  It returns
the result of concatenating all the elements of all the given lists
into a single list.  Actually, in ACL2 append is a macro that expands
into calls of the binary function binary-append.

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

ASH    arithmetic shift operation

(ash i c) is the result of taking the two's complement representation
of the integer i and shifting it by c bits:  shifting left and padding
with c 0 bits if c is positive, shifting right and dropping (abs c)
bits if c is negative, and simply returning i if c is 0.

The guard for ash requires that its arguments are integers.

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

ASSERT$    cause a hard error if the given test is false

     General Form:
     (assert$ test form)

where test returns a single value and form is arbitrary.  Semantically,
this call of assert$ is equivalent to form.  However, it causes a hard
error (using illegal) if the value of test is nil.

ASSOC    look up key in association list, using eql as test

(Assoc x alist) is the first member of alist whose car is x, or nil if
no such member exists.

(Assoc x alist) is provably the same in the ACL2 logic as (assoc-equal
x alist).  It has a stronger guard than assoc-equal because it uses eql
to test whether x is equal to the car of a given member of alist.  Its
guard requires that alist is an alistp, and moreover, either (eqlablep
x) or all cars of members of alist are eqlablep.  See
ASSOC-EQUAL and see ASSOC-EQ.

Assoc is a Common Lisp function.  See any Common Lisp documentation for
more information.  Since ACL2 functions cannot take keyword arguments
(though macros can), the ACL2 functions assoc-equal and assoc-eq are
defined to correspond to calls of the Common Lisp function assoc whose
keyword argument :test is equal or eq, respectively.

ASSOC-EQ    look up key in association list, using eq as test

(Assoc-eq x alist) is the first member of alist whose car is x, or nil
if no such member exists.

(Assoc-eq x alist) is provably the same in the ACL2 logic as (assoc x
alist) and (assoc-equal x alist), but it has a stronger guard because
it uses eq for a more efficient test for whether x is equal to a given
key of alist.  Its guard requires that alist is an association list
(see ALISTP), and moreover, either x is a symbol or all keys of
alist are symbols, i.e., alist is a symbol-alistp.

ASSOC-EQUAL    look up key in association list

(Assoc-equal x alist) is the first member of alist whose car is x, or
nil if no such member exists.

(Assoc-equal x alist) has a guard of (alistp alist), and returns the
first member of alist whose car is x, or nil if no such member exists.
Thus, assoc-equal has the same functionality as the Common Lisp
function assoc, except that it uses the equal function to test whether
x is the same as each successive `key' of alist.  See ASSOC and
see ASSOC-EQ.

ASSOC-KEYWORD    look up key in a keyword-value-listp

If l is a list of even length of the form (k1 a1 k2 a2 ... kn an),
where each ki is a keyword, then (assoc-keyword key l) is the first
tail of l starting with key if key is some ki, and is nil otherwise.

The guard for (assoc-keyword key l) is (keyword-value-listp l).

ASSOC-STRING-EQUAL    look up key, a string, in association list

(Assoc-string-equal x alist) is similar to assoc-equal.  However, for
string x and alist alist, the comparison of x with successive keys in
alist is done using string-equal rather than equal.

The guard for assoc-string-equal requires that x is a string and alist
is an alist.

ATOM    recognizer for atoms

(atom x) is true if and only if x is an atom, i.e., not a cons pair.

Atom has a guard of t, and is a Common Lisp function.  See any Common
Lisp documentation for more information.

ATOM-LISTP    recognizer for a true list of atoms

The predicate atom-listp tests whether its argument is a true-listp of
atoms, i.e., of non-conses.

BINARY-*    multiplication function

Completion Axiom:

     (equal (binary-* x y)
            (if (acl2-numberp x)
                (if (acl2-numberp y)
                    (binary-* x y)
                  0)
              0))

Guard for (binary-* x y):

     (and (acl2-numberp x) (acl2-numberp y))

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

Calls of the macro * expand to calls of binary-*; see *.

BINARY-+    addition function

Completion Axiom:

     (equal (binary-+ x y)
            (if (acl2-numberp x)
                (if (acl2-numberp y)
                    (binary-+ x y)
                  x)
              (if (acl2-numberp y)
                  y
                0)))

Guard for (binary-+ x y):

     (and (acl2-numberp x) (acl2-numberp y))

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

Calls of the macro + expand to calls of binary-+; see +.

BINARY-APPEND    concatenate two lists

This binary function implements append, which is a macro in ACL2.  See
APPEND

The guard for binary-append requires the first argument to be a
true-listp.

BOOLE$    perform a bit-wise logical operation on 2 two's complement integers

When integers x and y are viewed in their two's complement
representation, (boole$ op x y) returns the result of applying the
bit-wise logical operation specified by op.  The following table is
adapted from documentation for analogous Common Lisp function boole in
the Common Lisp HyperSpec
(`http://www.lisp.org/HyperSpec/Body/fun_boole.html#boole').  Note that
the values of op for boole$ are ACL2 constants, rather than
corresponding values of op for the Common Lisp function boole.

     op               result
     -----------      ---------
     *boole-1*        x
     *boole-2*        y
     *boole-andc1*    and complement of x with y
     *boole-andc2*    and x with complement of y
     *boole-and*      and
     *boole-c1*       complement of x
     *boole-c2*       complement of y
     *boole-clr*      the constant 0 (all zero bits)
     *boole-eqv*      equivalence (exclusive nor)
     *boole-ior*      inclusive or
     *boole-nand*     not-and
     *boole-nor*      not-or
     *boole-orc1*     or complement of x with y
     *boole-orc2*     or x with complement of y
     *boole-set*      the constant -1 (all one bits)
     *boole-xor*      exclusive or

The guard of boole$ specifies that op is the value of one of the
constants above and that x and y are integers.

See any Common Lisp documentation for analogous information about
Common Lisp function boole.

BOOLEANP    recognizer for booleans

(Booleanp x) is t if x is t or nil, and is nil otherwise.

See GENERALIZED-BOOLEANS for a discussion of a potential
soundness problem for ACL2 related to the question:  Which Common Lisp
functions are known to return Boolean values?

BUTLAST    all but a final segment of a list

(Butlast l n) is the list obtained by removing the last n elements from
the true list l.  The following is a theorem (though it takes some
effort, including lemmas, to get ACL2 to prove it).

     (implies (and (integerp n)
                   (<= 0 n)
                   (true-listp l))
              (equal (length (butlast l n))
                     (if (< n (length l))
                         (- (length l) n)
                       0)))

For related functions, see TAKE and see NTHCDR.

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

Butlast is a Common Lisp function.  See any Common Lisp documentation
for more information.  Note:  In Common Lisp the second argument of
butlast is optional, but in ACL2 it is required.

CAAAAR    car of the caaar

See any Common Lisp documentation for details.

CAAADR    car of the caadr

See any Common Lisp documentation for details.

CAAAR    car of the caar

See any Common Lisp documentation for details.

CAADAR    car of the cadar

See any Common Lisp documentation for details.

CAADDR    car of the caddr

See any Common Lisp documentation for details.

CAADR    car of the cadr

See any Common Lisp documentation for details.

CAAR    car of the car

See any Common Lisp documentation for details.

CADAAR    car of the cdaar

See any Common Lisp documentation for details.

CADADR    car of the cdadr

See any Common Lisp documentation for details.

CADAR    car of the cdar

See any Common Lisp documentation for details.

CADDAR    car of the cddar

See any Common Lisp documentation for details.

CADDDR    car of the cdddr

See any Common Lisp documentation for details.

CADDR    car of the cddr

See any Common Lisp documentation for details.

CADR    car of the cdr

See any Common Lisp documentation for details.

CAR    returns the first element of a non-empty list, else nil

Completion Axiom:

     (equal (car x)
            (cond
             ((consp x)
              (car x))
             (t nil)))

Guard:

     (or (consp x) (equal x nil))

Notice that in the ACL2 logic, car returns nil for every atom.

CASE    conditional based on if-then-else using eql

     Example Form:
     (case typ
       ((:character foo)
        (open file-name :direction :output))
       (bar (open-for-bar file-name))
       (otherwise
        (my-error "Illegal.")))

is the same as

     (cond ((member typ '(:character foo))
            (open file-name :direction :output))
           ((eql typ 'bar)
            (open-for-bar file-name))
           (t (my-error "Illegal.")))

which in turn is the same as

     (if (member typ '(:character foo))
         (open file-name :direction :output)
         (if (eql typ 'bar)
             (open-for-bar file-name)
             (my-error "Illegal.")))

Notice the quotations that appear in the example above: '(:character
foo) and 'bar.

     General Forms:
     (case expr
       (x1 val-1)
       ...
       (xk val-k)
       (otherwise val-k+1))

     (case expr
       (x1 val-1)
       ...
       (xk val-k)
       (t val-k+1))

     (case expr
       (x1 val-1)
       ...
       (xk val-k))

where each xi is either eqlablep or a true list of eqlablep objects.
The final otherwise or t case is optional.

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

CASE-MATCH    pattern matching or destructuring

     General Form:
     (case-match x
       (pat1 dcl1 body1)
       ...
       (patk dclk bodyk))

where x is a variable symbol, the pati are structural patterns as
described below, the dcli are optional declare forms and the bodyi are
terms.  Return the value(s) of the bodyi corresponding to the first
pati matching x, or nil if none matches.

Pattern Language:
With the few special exceptions described below, matching requires that
the cons structure of x be isomorphic to that of the pattern, down to
the atoms in the pattern.  Non-symbol atoms in the pattern match only
themselves.  Symbols in the pattern denote variables which match
anything and which are bound by a successful match to the corresponding
substructure of x.  Variables that occur more than once must match the
same (EQUAL) structure in every occurrence.

     Exceptions:
     &               Matches anything and is not bound.  Repeated
                       occurrences of & in a pattern may match different
                       structures.
     nil, t, *sym*   These symbols cannot be bound and match only their
                       global values.
     !sym            where sym is a symbol that is already bound in the
                       context of the case-match, matches only the
                       current binding of sym.
     'obj            Matches only itself.

Some examples are shown below.

Below we show some sample patterns and examples of things they match
and do not match.

     pattern       matches         non-matches
     (x y y)       (ABC 3 3)       (ABC 3 4)    ; 3 is not 4
     (fn x . rst)  (P (A I) B C)   (ABC)        ; NIL is not (x . rst)
                   (J (A I))                    ; rst matches nil
     ('fn (g x) 3) (FN (H 4) 3)    (GN (G X) 3) ; 'fn matches only itself
     (& t & !x)    ((A) T (B) (C))              ; provided x is '(C)

Consider the two binary trees that contain three leaves.  They might be
described as (x . (y . z)) and ((x . y) . z), where x, y, and z are
atomic.  Suppose we wished to recognize those trees.  The following
case-match would do:

     (case-match tree
       ((x . (y . z))
        (and (atom x) (atom y) (atom z)))
       (((x . y) . z)
        (and (atom x) (atom y) (atom z))))

Suppose we wished to recognize such trees where all three tips are
identical.  Suppose further we wish to return the tip if the tree is
one of those recognized ones and to return the number 7 otherwise.

     (case-match tree
       ((x . (x . x))
        (if (atom x) x 7))
       (((x . x) . x)
        (if (atom x) x 7))
       (& 7))

Note that case-match returns nil if no pati matches.  Thus if we must
return 7 in that case, we have to add as the final pattern the &, which
always matches anything.

CDAAAR    cdr of the caaar

See any Common Lisp documentation for details.

CDAADR    cdr of the caadr

See any Common Lisp documentation for details.

CDAAR    cdr of the caar

See any Common Lisp documentation for details.

CDADAR    cdr of the cadar

See any Common Lisp documentation for details.

CDADDR    cdr of the caddr

See any Common Lisp documentation for details.

CDADR    cdr of the cadr

See any Common Lisp documentation for details.

CDAR    cdr of the car

See any Common Lisp documentation for details.

CDDAAR    cdr of the cdaar

See any Common Lisp documentation for details.

CDDADR    cdr of the cdadr

See any Common Lisp documentation for details.

CDDAR    cdr of the cdar

See any Common Lisp documentation for details.

CDDDAR    cdr of the cddar

See any Common Lisp documentation for details.

CDDDDR    cdr of the cdddr

See any Common Lisp documentation for details.

CDDDR    cdr of the cddr

See any Common Lisp documentation for details.

CDDR    cdr of the cdr

See any Common Lisp documentation for details.

CDR    returns the second element of a cons pair, else nil

Completion Axiom:

     (equal (cdr x)
            (cond
             ((consp x)
              (cdr x))
             (t nil)))

Guard:

     (or (consp x) (equal x nil))

Notice that in the ACL2 logic, cdr returns nil for every atom.

CEILING    division returning an integer by truncating toward positive infinity

     Example Forms:
     ACL2 !>(ceiling 14 3)
     5
     ACL2 !>(ceiling -14 3)
     -4
     ACL2 !>(ceiling 14 -3)
     -4
     ACL2 !>(ceiling -14 -3)
     5
     ACL2 !>(ceiling -15 -3)
     5

(Ceiling i j) is the result of taking the quotient of i and j and
returning the smallest integer that is at least as great as that
quotient.  For example, the quotient of -14 by 3 is -4 2/3, and the
smallest integer at least that great is -4.

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

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

CHAR    the nth element (zero-based) of a string

(Char s n) is the nth element of s, zero-based.  If n is greater than
or equal to the length of s, then char returns nil.

(Char s n) has a guard that n is a non-negative integer and s is a
stringp.

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

CHAR-CODE    the numeric code for a given character

Completion Axiom:

     (equal (char-code x)
            (if (characterp x)
                (char-code x)
              0))

Guard for (char-code x):

     (characterp x)

This function maps all non-characters to 0.

CHAR-DOWNCASE    turn upper-case characters into lower-case characters

(Char-downcase x) is equal to #a when x is #A, #b when x is #B, ...,
and #z when x is #Z, and is x for any other character.

The guard for char-downcase requires its argument to be a standard
character (see STANDARD-CHAR-P).

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

CHAR-EQUAL    character equality without regard to case

For characters x and y, (char-equal x y) is true if and only if x and y
are the same except perhaps for their case.

The guard on char-equal requires that its arguments are both standard
characters (see STANDARD-CHAR-P).

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

CHAR-UPCASE    turn lower-case characters into upper-case characters

(Char-upcase x) is equal to #A when x is #a, #B when x is #b, ..., and
#Z when x is #z, and is x for any other character.

The guard for char-upcase requires its argument to be a standard
character (see STANDARD-CHAR-P).

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

CHAR<    less-than test for characters

(char< x y) is true if and only if the character code of x is less than
that of y.  See CHAR-CODE.

The guard for char< specifies that its arguments are characters.

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

CHAR<=    less-than-or-equal test for characters

(char<= x y) is true if and only if the character code of x is less
than or equal to that of y.  See CHAR-CODE.

The guard for char<= specifies that its arguments are characters.

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

CHAR>    greater-than test for characters

(char> x y) is true if and only if the character code of x is greater
than that of y.  See CHAR-CODE.

The guard for char> specifies that its arguments are characters.

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

CHAR>=    greater-than-or-equal test for characters

(char>= x y) is true if and only if the character code of x is greater
than or equal to that of y.  See CHAR-CODE.

The guard for char>= specifies that its arguments are characters.

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

CHARACTER-ALISTP    recognizer for association lists with characters as keys

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

CHARACTER-LISTP    recognizer for a true list of characters

The predicate character-listp tests whether its argument is a true list
of characters.

CHARACTERP    recognizer for characters

(characterp x) is true if and only if x is a character.

CHARACTERS    characters in ACL2

ACL2 accepts 256 distinct characters, which are the characters obtained
by applying the function code-char to each integer from 0 to 255.
Among these, Common Lisp designates certain ones as _standard
characters_, namely those of the form (code-char n) where n is from 33
to 126, together with #\Newline and #\Space.  The actual standard
characters may be viewed by evaluating the defconst *standard-chars*.

To be more precise, Common Lisp does not specify the precise
relationship between code-char and the standard characters.  However,
we check that the underlying Common Lisp implementation uses a
particular relationship that extends the usual ASCII coding of
characters.  We also check that Space, Tab, Newline, Page, and Rubout
correspond to characters with respective char-codes 32, 9, 10, 12, and
127.

Code-char has an inverse, char-code.  Thus, when char-code is applied
to an ACL2 character, c, it returns a number n between 0 and 255
inclusive such that (code-char n) = c.

The preceding paragraph implies that there is only one ACL2 character
with a given character code.  CLTL allows for "attributes" for
characters, which could allow distinct characters with the same code,
but ACL2 does not allow this.

_The Character Reader_

ACL2 supports the `#\' notation for characters provided by Common Lisp,
with some restrictions.  First of all, for every character c, the
notation

     #\c

may be used to denote the character object c.  That is, the user may
type in this notation and ACL2 will read it as denoting the character
object c.  In this case, the character immediately following c must be
one of the following "terminating characters": a Tab, a Newline, a Page
character, a space, or one of the characters:

     "  '  (  )  ;  `  ,

Other than the notation above, ACL2 accepts alternate notation for five
characters.

     #\Space
     #\Tab
     #\Newline
     #\Page
     #\Rubout

Again, in each of these cases the next character must be from among the
set of "terminating characters" described in the single-character case.
Our implementation is consistent with IS0-8859, even though we don't
provide #\ syntax for entering characters other than that described
above.

Finally, we note that it is our intention that any object printed by
ACL2's top-level-loop may be read back into ACL2.  Please notify the
implementors if you find a counterexample to this claim.

CLOSE-INPUT-CHANNEL    See IO.

CLOSE-OUTPUT-CHANNEL    See IO.

CODE-CHAR    the character corresponding to a given numeric code

Completion Axiom:

     (equal (code-char x)
            (if (and (integerp x)
                     (>= x 0)
                     (< x 256))
                (code-char x)
              (code-char 0)))

Guard for (code-char x):

     (and (integerp x)
          (>= x 0)
          (< x 256))

ACL2 supports 8-bit characters.  Inputs not between 0 and 255 are
treated as 0.

COERCE    coerce a character list to a string and a string to a list

Completion Axiom:

     (equal (coerce x y)
            (cond
             ((equal y 'list)
              (if (stringp x)
                  (coerce x 'list)
                nil))
             (t
              (coerce (make-character-list x) 'string))))

Guard for (coerce x y):

     (if (equal y 'list)
         (stringp x)
       (if (equal y 'string)
           (character-listp x)
         nil))

Also see distributed book books/misc/fast-coerce.lisp, contributed by
Jared Davis, for a version of coerce that may be faster for Common Lisp
implementations other than CCL 1.3 or later, if the second argument is
'list (for coercing a string to a list).

COMPILATION    compiling ACL2 functions

ACL2 has several mechanisms to speed up the evaluation of function
calls by _compiling_ functions: see COMP, see
SET-COMPILE-FNS, and see 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:

     (set-compiler-enabled nil state)

See BOOK-COMPILED-FILE for more discussion about compilation and
books.

COMPLEX    create an ACL2 number

     Examples:
     (complex x 3) ; x + 3i, where i is the principal square root of -1
     (complex x y) ; x + yi
     (complex x 0) ; same as x, for rational numbers x

The function complex takes two rational number arguments and returns an
ACL2 number.  This number will be of type (complex rational) [as
defined in the Common Lisp language], except that if the second
argument is zero, then complex returns its first argument.  The
function complex-rationalp is a recognizer for complex rational
numbers, i.e. for ACL2 numbers that are not rational numbers.

The reader macro #C (which is the same as #c) provides a convenient way
for typing in complex numbers.  For explicit rational numbers x and y,
#C(x y) is read to the same value as (complex x y).

The functions realpart and imagpart return the real and imaginary parts
(respectively) of a complex (possibly rational) number.  So for
example, (realpart #C(3 4)) = 3, (imagpart #C(3 4)) = 4, (realpart 3/4)
= 3/4, and (imagpart 3/4) = 0.

The following built-in axiom may be useful for reasoning about complex
numbers.

     (defaxiom complex-definition
       (implies (and (real/rationalp x)
                     (real/rationalp y))
                (equal (complex x y)
                       (+ x (* #c(0 1) y))))
       :rule-classes nil)

A completion axiom that shows what complex returns on arguments
violating its guard (which says that both arguments are rational
numbers) is the following.

     (equal (complex x y)
            (complex (if (rationalp x) x 0)
                     (if (rationalp y) y 0)))

COMPLEX-RATIONALP    recognizes complex rational numbers

     Examples:
     (complex-rationalp 3)       ; nil, as 3 is rational, not complex rational
     (complex-rationalp #c(3 0)) ; nil, since #c(3 0) is the same as 3
     (complex-rationalp t)       ; nil
     (complex-rationalp #c(3 1)) ; t, as #c(3 1) is the complex number 3 + i

See COMPLEX for more about complex rationals in ACL2.

COMPLEX/COMPLEX-RATIONALP    recognizer for complex numbers

For most ACL2 users, this is a macro abbreviating complex-rationalp;
see COMPLEX-RATIONALP.  In  ACL2(r) (see REAL), a
complex number x may have irrational real and imaginary parts.  This
macro abbreviates the predicate complexp in ACL2(r), which holds for
such x.  Most ACL2 users can ignore this macro and use complex-rationalp
instead.  Some books in the ACL2 distribution use
complex/complex-rationalp so that they are suitable for ACL2(r) as well.

CONCATENATE    concatenate lists or strings together

     Examples:
     (concatenate 'string "ab" "cd" "ef")     ; equals "abcdef"
     (concatenate 'string "ab")               ; equals "ab"
     (concatenate 'list '(a b) '(c d) '(e f)) ; equals '(a b c d e f)
     (concatenate 'list)                      ; equals nil

     General Form:
     (concatenate result-type x1 x2 ... xn)

where n >= 0 and either:  result-type is 'string and each xi is a
string; or result-type is 'list and each xi is a true list.
Concatenate simply concatenates its arguments to form the result string
or list.  Also see APPEND and see STRING-APPEND.  (The
latter immediately generates a call to concatenate when applied to
strings.)

Note:  We do *not* try to comply with the Lisp language's insistence
that concatenate copies its arguments.  Not only are we in an
applicative setting, where this issue shouldn't matter for the logic,
but also we do not actually modify the underlying lisp implementation
of concatenate; we merely provide a definition for it.

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

COND    conditional based on if-then-else

Cond is the construct for IF, THEN, ELSE IF, ...  The test is against
nil.  The argument list for cond is a list of "clauses", each of which
is a list.  In ACL2, clauses must have length 1 or 2.

Cond is a Common Lisp macro.  See any Common Lisp documentation for
more information.

CONJUGATE    complex number conjugate

Conjugate takes an ACL2 number as an argument, and returns its complex
conjugate (i.e., the result of negating its imaginary part.).

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

CONS    pair and list constructor

(cons x y) is a pair whose first component is x and second component is
y.  If y is a list, then (cons x y) is a list that has an addtional
element x on the front.

CONSP    recognizer for cons pairs

(consp x) is true if and only if x is a cons pair.

COUNT    count the number of occurrences of an item in a string or true-list

     Example Forms:
     (count #\D "DabcDefcDe")                 ; = 3
     (count #\D "DabcDefcDe" :start 1)        ; = 2
     (count #\D "DabcDefcDe" :start 1 :end 5) ; = 1
     (count #\D "DabcDefcDe" :start 1 :end 4) ; = 0
     (count #\z "DabcDefcDe")                 ; = 0
     (count '(a b) '(17 (a b) 23 (a b) (c d)))   ; = 2

     General Form:
     (count item sequence &key start end)

(Count item sequence) returns the number of times item occurs in
sequence.  The guard for calls of count (which is actually a macro in
ACL2) specifies that sequence is a string or a true-list, and that
start, which defaults to 0, and end, which defaults to the length of
sequence, are valid indices into sequence.

See any Common Lisp documentation for more information about count,
which is a Common Lisp utility.  At this time ACL2 does not support
keyword arguments for count other than :start and :end; we may add
support for the :from-end keyword upon request.

CPU-CORE-COUNT    the number of cpu cores

Unless the ACL2 executable supports parallel evaluation (see
PARALLELISM), this function returns (mv 1 state).  Otherwise:

(Cpu-core-count state) returns (mv core-count state), where core-count
is the number of cpu cores if ACL2 can get that information from the
underlying Common Lisp implementation.  Otherwise an error occurs,
unless global 'cpu-core-count is assigned to a positive integer value
(see ASSIGN), in which case that value is returned as the
core-count.

     Example:
     (cpu-core-count state) ==> (mv 4 state)
.

CW    print to the comment window

Example:

     (cw "The goal is ~p0 and the alist is ~x1.~%"
         (untranslate term t nil)
         unify-subst)

Logically, this expression is equivalent to nil.  However, it has the
effect of first printing to the so-called "comment window" the fmt
string as indicated.  Thus, cw is like fmt (see FMT) except in
three important ways.  First, it is a macro whose calls expand to calls
of a :logic mode function.  Second, it neither takes nor returns the
ACL2 state; logically cw simply returns nil, although it prints to a
_comment window_ that just happens to share the terminal screen with
the standard character output *standard-co*.  Third, its fmt args are
positional references, so that for example

     (cw "Answers: ~p0 and ~p1" ans1 ans2)

prints in the same manner as:

     (fmt "Answers: ~p0 and ~p1"
          (list (cons #\0 ans1) (cons #\1 ans2))
          *standard-co* state nil)

Typically, calls of cw are embedded in prog2$ forms, e.g.,

     (prog2$ (cw ...)
             (mv a b c))

which has the side-effect of printing to the comment window and
logically returning (mv a b c).

     General Form:
     (cw fmt-string arg1 arg2 ... argn)

where n is between 0 and 9 (inclusive).  The macro uses
fmt-to-comment-window, passing it the column 0 and evisc-tuple nil,
after assembling the appropriate alist binding the fmt vars #\0 through
#\9; see FMT.  If you want

     (a) more than 10 vars,
     (b) vars other than the digit chars,
     (c) a different column, or
     (d) a different evisc-tuple,

then call fmt-to-comment-window instead.

Also see CW!, which is useful if you want to be able to read
the printed forms back in.

Finally, we discuss another way to create formatted output that also
avoids the need to pass in the ACL2 state.  The idea is to use
wormholes; see WORMHOLE.  Below is a function you can write,
along with some calls, providing an illustration of this approach.

     (defun my-fmt-to-comment-window (str alist)
       (wormhole 'my-fmt-to-comment-window
                 '(lambda (whs) whs)
                 (list str alist)
                 '(pprogn
                   (fms (car (@ wormhole-input))
                        (cadr (@ wormhole-input))
                        *standard-co*
                        state
                        nil)
                   (value :q))
                 :ld-verbose nil
                 :ld-error-action :return ; harmless return on error
                 :ld-prompt nil))

     ; A non-erroneous call:
     (my-fmt-to-comment-window "Here is ~x0 for your inspection~%"
                               (list (cons #0 'foo)))

     ; An error inside the fmt string (unbound fmt var); note that even
     ; with the error, the wormhole is exited.
     (my-fmt-to-comment-window "Here is ~x1 for your inspection~%"
                               (list (cons #0 'foo)))

     ; A guard violation in the binding; note that even with the error,
     ; the wormhole is exited.
     (my-fmt-to-comment-window "Here is ~x0 for your inspection~%"
                               (list (cons #0 (car 'foo))))

CW!    print to the comment window

This is the same as cw, except that cw inserts backslash (\) characters
when forced to print past the right margin, in order to make the output
a bit clearer in that case.  Use cw! instead if you want to be able to
read the forms back in.

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

     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.

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

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.

DEFN    definition with guard t

Defn is defun with guard t.

DENOMINATOR    divisor of a ratio in lowest terms

Completion Axiom:

     (equal (denominator x)
            (if (rationalp x)
                (denominator x)
              1))

Guard for (denominator x):

     (rationalp x)

DIGIT-CHAR-P    the number, if any, corresponding to a given character

(digit-char-p ch) is the integer corresponding to the character ch in
base 10.  For example, (digit-char-p #\3) is equal to the integer 3.
More generally, an optional second argument specifies the radix
(default 10, as indicated above).

The guard for digit-char-p (more precisely, for the function
our-digit-char-p that calls of this macro expand to) requires its
second argument to be an integer between 2 and 36, inclusive, and its
first argument to be a character.

Digit-char-p is a Common Lisp function, though it is implemented in the
ACL2 logic as an ACL2 macro.  See any Common Lisp documentation for
more information.

DIGIT-TO-CHAR    map a digit to a character

     Example:
     ACL2 !>(digit-to-char 8)
     #\8

For an integer n from 0 to 15, (digit-to-char n) is the character
corresponding to n in hex notation, using uppercase letters for digits
exceeding 9.  If n is in the appropriate range, that result is of course
also the binary, octal, and decimal digit.

The guard for digit-to-char requires its argument to be an integer
between 0 and 15, inclusive.

E0-ORD-<    the old ordering function for ACL2 ordinals

See O< for the current new ordering function for ACL2 ordinals.

The functions e0-ordinalp and e0-ord-< were replaced in ACL2
Version_2.8 by o-p and o<, respectively.  However, books created before
that version used the earlier functions for termination proofs; the old
functions might be of use in these cases.  To use the old functions in
termination proofs, include the book books/ordinals/e0-ordinal and
execute the event (set-well-founded-relation e0-ord-<) (see
SET-WELL-FOUNDED-RELATION).  For a more thorough discussion of these
functions, see the documentation at the end of
books/ordinals/e0-ordinal.lisp.

E0-ORDINALP    the old recognizer for ACL2 ordinals

See O-P for the current recognizer for ACL2 ordinals.

The functions e0-ordinalp and e0-ord-< were replaced in ACL2
Version_2.8 by o-p and o<, respectively.  However, books created before
that version used the earlier functions for termination proofs; the old
functions might be of use in these cases.  To use the old functions in
termination proofs, include the book books/ordinals/e0-ordinal and
execute the event (set-well-founded-relation e0-ord-<) (see
SET-WELL-FOUNDED-RELATION).  For a more thorough discussion of these
functions, see the documentation at the end of
books/ordinals/e0-ordinal.lisp.

EC-CALL    execute a call in the ACL2 logic instead of raw Lisp

The name "ec-call" represents "executable-counterpart call."  This
utility is intended for users who are familiar with guards.  See
GUARD for a general discussion of guards.

Logically, ec-call is the identity function; indeed, during proofs it
behaves more like the identity macro, in the sense that (ec-call TERM)
is typically replaced quickly by TERM during a proof attempt.  However,
ec-call causes function calls to be evaluated in the ACL2 logic rather
than raw Lisp, as explained below.

     General Form:
     (ec-call (fn term1 ... termk))

where fn is a known function symbol other than those in the list that is
the value of the constant *ec-call-bad-ops*.  Semantically, (ec-call
(fn term1 ... termk)) equals (fn term1 ... termk).  However, this use
of ec-call has two effects.

     (1) Guard verification generates no proof obligations from the
     guard of fn for this call.  Indeed, guards need not have been
     verified for fn.

     (2) During evaluation, after the arguments of fn are evaluated as
     usual, the executable counterpart of fn is called, rather than fn
     as defined in raw Lisp.  That is, the call of fn is made on its
     evaluated arguments as though this call is being made in the ACL2
     top-level loop, rather than in raw Lisp.  In particular, the guard
     of fn is checked, at least by default (see
     SET-GUARD-CHECKING.

Note that in the term (ec-call (fn term1 ... termk)), only the indicated
call of fn is made in the logic; each termi is evaluated in the normal
manner.  If you want an entire term evaluated in the logic, wrap
ec-call around each function call in the term (other than calls of if
and ec-call).

Here is a small example.  We define foo recursively but with guard
verification inhibited on the recursive call, which is to be evaluated
in the ACL2 logic.

     ACL2 !>(defun foo (x y)
             (declare (xargs :guard (consp y)))
             (if (consp x)
                 (cons (car x) (ec-call (foo (cdr x) (cdr y))))
               (car y)))

     The admission of FOO is trivial, using the relation O< (which is known
     to be well-founded on the domain recognized by O-P) and the measure
     (ACL2-COUNT X).  We could deduce no constraints on the type of FOO.

     Computing the guard conjecture for FOO....

     The guard conjecture for FOO is trivial to prove.  FOO is compliant
     with Common Lisp.

     Summary
     Form:  ( DEFUN FOO ...)
     Rules: NIL
     Warnings:  None
     Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)
      FOO
     ACL2 !>(foo '(2 3 4 5) '(6 7))

     ACL2 Error in TOP-LEVEL:  The guard for the function symbol FOO, which
     is (CONSP Y), is violated by the arguments in the call (FOO '(4 5) NIL).
     See :DOC trace for a useful debugging utility.  See :DOC set-guard-
     checking for information about suppressing this check with (set-guard-
     checking :none), as recommended for new users.

The error above arises because eventually, foo recurs down to a value of
parameter y that violates the guard.  This is clear from tracing (see
TRACE$ and see TRACE).  Each call of the executable
counterpart of foo (the so-called "*1*" function for foo) checks the
guard and then invokes the raw Lisp version of foo.  The raw Lisp
version calls the executable counterpart on the recursive call.  When
the guard check fails we get a violation.

     ACL2 !>(trace$ foo)
      ((FOO))
     ACL2 !>(foo '(2 3 4 5) '(6 7))
     1> (ACL2_*1*_ACL2::FOO (2 3 4 5) (6 7))
       2> (FOO (2 3 4 5) (6 7))
         3> (ACL2_*1*_ACL2::FOO (3 4 5) (7))
           4> (FOO (3 4 5) (7))
             5> (ACL2_*1*_ACL2::FOO (4 5) NIL)

     ACL2 Error in TOP-LEVEL:  The guard for the function symbol FOO, which
     is (CONSP Y), is violated by the arguments in the call (FOO '(4 5) NIL).
     See :DOC trace for a useful debugging utility.  See :DOC set-guard-
     checking for information about suppressing this check with (set-guard-
     checking :none), as recommended for new users.

     ACL2 !>

If we turn off guard errors then we can see the trace as above, but
where we avoid calling the raw Lisp function when the guard fails to
hold.

     ACL2 !>:set-guard-checking nil

     Masking guard violations but still checking guards except for self-
     recursive calls.  To avoid guard checking entirely, :SET-GUARD-CHECKING
     :NONE.  See :DOC set-guard-checking.

     ACL2 >(foo '(2 3 4 5) '(6 7))
     1> (ACL2_*1*_ACL2::FOO (2 3 4 5) (6 7))
       2> (FOO (2 3 4 5) (6 7))
         3> (ACL2_*1*_ACL2::FOO (3 4 5) (7))
           4> (FOO (3 4 5) (7))
             5> (ACL2_*1*_ACL2::FOO (4 5) NIL)
               6> (ACL2_*1*_ACL2::FOO (5) NIL)
                 7> (ACL2_*1*_ACL2::FOO NIL NIL)
                 <7 (ACL2_*1*_ACL2::FOO NIL)
               <6 (ACL2_*1*_ACL2::FOO (5))
             <5 (ACL2_*1*_ACL2::FOO (4 5))
           <4 (FOO (3 4 5))
         <3 (ACL2_*1*_ACL2::FOO (3 4 5))
       <2 (FOO (2 3 4 5))
     <1 (ACL2_*1*_ACL2::FOO (2 3 4 5))
     (2 3 4 5)
     ACL2 >

EIGHTH    eighth member of the list

See any Common Lisp documentation for details.

ENDP    recognizer for empty lists

In the ACL2 logic, (endp x) is the same as (atom x).  See ATOM.

Unlike atom, the guard for endp requires that x is a cons pair or is
nil.  Thus, endp is typically used as a termination test for functions
that recur on a true-listp argument.  See GUARD for general
information about guards.

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

EQ    equality of symbols

Eq is the function for determining whether two objects are identical
(i.e., have the exact same store address in the current von Neumann
implementation of Common Lisp).  It is the same as equal in the ACL2
logic.

Eq is a Common Lisp function.  In order to ensure conformance with
Common Lisp, the ACL2 guard on eq requires at least one of the
arguments to eq to be a symbol.  Common Lisp guarantees that if x is a
symbol, then x is eq to y if and only if x is equal to y.  Thus, the
ACL2 user should think of eq as nothing besides a fast means for
checking equal when one argument is known to be a symbol.  In
particular, it is possible that an eq test will not even require the
cost of a function call but will be as fast as a single machine
instruction.

EQL    test equality (of two numbers, symbols, or characters)

(eql x y) is logically equivalent to (equal x y).

Unlike equal, eql has a guard requiring at least one of its arguments
to be a number, a symbol, or a character.  Generally, eql is executed
more efficiently than equal.

For a discussion of the various ways to test against 0, See
ZERO-TEST-IDIOMS.

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

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

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

EQLABLE-LISTP    recognizer for a true list of objects each suitable for eql

The predicate eqlable-listp tests whether its argument is a true-listp
of objects satisfying eqlablep.

EQLABLEP    the guard for the function eql

The predicate eqlablep tests whether its argument is suitable for eql,
at least one of whose arguments must satisfy this predicate in Common
Lisp.  (Eqlablep x) is true if and only if its argument is a number, a
symbol, or a character.

EQUAL    true equality

(equal x y) is equal to t or nil, according to whether or not x and y
are the same value.

For a discussion of the various idioms for testing against 0, See
ZERO-TEST-IDIOMS.

ER    print an error message and "cause an error"

     Example Forms:
     (er hard  'top-level "Illegal inputs, ~x0 and ~x1." a b)
     (er hard? 'top-level "Illegal inputs, ~x0 and ~x1." a b)
     (er soft  'top-level "Illegal inputs, ~x0 and ~x1." a b)

The examples above all print an error message to standard output saying
that a and b are illegal inputs.  However, the first two abort
evaluation after printing an error message, while the third returns (mv
t nil state) after printing an error message.  The result in the third
case can be interpreted as an "error" when programming with the ACL2
state, something most ACL2 users will probably not want to do; see
LD-ERROR-TRIPLES and see ER-PROGN.

The difference between the hard and hard? forms is one of guards.  Use
hard if you want the call to generate a (clearly impossible) guard
proof obligation of (essentially) NIL.  But use hard? if you want to be
able to call this function in guard-verified code, since the call
generates a (trivially satisfied) guard proof obligation of T.

Er is a macro, and the above three examples expand to calls of ACL2
functions, as shown below.  See ILLEGAL, see
HARD-ERROR, and see ERROR1.  The first two have guards of
(essentially) NIL and T, respectively, while error1 is in :program mode.

     General forms:
     (er hard  ctx fmt-string arg1 arg2 ... argk)
       ==> {macroexpands, in essence, to:}
     (ILLEGAL    CTX FMT-STRING
                 (LIST (CONS #\0 ARG1) (CONS #\1 ARG2) ... (CONS #\k ARGk)))

     (er hard? ctx fmt-string arg1 arg2 ... argk)
       ==> {macroexpands, in essence, to:}
     (HARD-ERROR CTX FMT-STRING
                 (LIST (CONS #\0 ARG1) (CONS #\1 ARG2) ... (CONS #\k ARGk)))

     (er soft  ctx fmt-string arg1 arg2 ... argk)
       ==> {macroexpands, in essence, to:}
     (ERROR1     CTX FMT-STRING
                 (LIST (CONS #\0 ARG1) (CONS #\1 ARG2) ... (CONS #\k ARGk)))

ER-PROGN    perform a sequence of state-changing "error triples"

     Example:
     (er-progn (check-good-foo-p (f-get-global 'my-foo state) state)
               (value (* (f-get-global 'my-foo state)
                         (f-get-global 'bar state))))

This sequencing primitive is only useful when programming with state,
something that very few users will probably want to do.  See
STATE.

Er-progn is used much the way that progn is used in Common Lisp, except
that it expects each form within it to evaluate to an "error triple" of
the form (mv erp val state).  The first such form, if any, that
evaluates to such a triple where erp is not nil yields the error triple
returned by the er-progn.  If there is no such form, then the last form
returns the value of the er-progn form.

We intend to write more about this topic, especially if there are
requests to do so.

ERROR1    print an error message and cause a "soft error"

(Error1 ctx str alist) returns (mv t nil state).  An error message is
first printed using the the "context" ctx, as well as the string str
and alist alist that are of the same kind as expected by fmt.  See
FMT.

Error1 can be interpreted as causing an "error" when programming with
the ACL2 state, something most ACL2 users will probably not want to do;
see LD-ERROR-TRIPLES and see ER-PROGN.  In order to
cause errors with :logic mode functions, see HARD-ERROR and see
ILLEGAL.  Better yet, see ER for a macro that provides
a unified way of signaling errors.

As mentioned above, error1 always returns (mv t nil state).  But if a
call (error1 ctx str alist) is encountered during evaluation, then the
string str is first printed using the association list alist (as in
fmt).  Here is a trivial, contrived example.

     ACL2 !>(error1 'my-context
                    "Printing 4: ~n0"
                    (list (cons #\0 4))
                    state)

     ACL2 Error in MY-CONTEXT:  Printing 4: four

     ACL2 !>

EVENP    test whether an integer is even

(evenp x) is true if and only if the integer x is even.  Actually, in
the ACL2 logic (evenp x) is defined to be true when x/2 is an integer.

The guard for evenp requires its argument to be an integer.

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

EXPLODE-NONNEGATIVE-INTEGER    the list of characters in the radix-r form of a number

     Examples:
     ACL2 !>(explode-nonnegative-integer 925 10 nil)
     (#9 #2 #5)
     ACL2 !>(explode-nonnegative-integer 325 16 nil)
     (#3 #9 #D)

For a non-negative integer n, (explode-nonnegative-integer n r nil) is
the list of characters in the radix-r (base-r) representation of n.

The guard for explode-nonnegative-integer requires the first argument
to be a nonnegative integer and second argument to be a valid radix for
ACL2 (2, 8, 10, or 16).

EXPT    exponential function

(Expt r i) is the result of raising the number r to the integer power i.

The guard for (expt r i) is that r is a number and i is an integer, and
furthermore, if r is 0 then i is nonnegative.  When the type
requirements of the guard aren't met, (expt r i) first coerces r to a
number and i to an integer.

Expt is a Common Lisp function.  See any Common Lisp documentation for
more information.  Note that r can be a complex number; this is
consistent with Common lisp.

FIFTH    fifth member of the list

See any Common Lisp documentation for details.

FIRST    first member of the list

See any Common Lisp documentation for details.

FIX    coerce to a number

Fix simply returns any numeric argument unchanged, returning 0 on a
non-numeric argument.  Also see NFIX, see IFIX, and see
RFIX for analogous functions that coerce to a natural number,
an integer, and a rational number, respectively.

Fix has a guard of t.

FIX-TRUE-LIST    coerce to a true list

Fix-true-list is the identity function on true-listp objects.  It
converts every list to a true list by dropping the final cdr, and it
converts every atom to nil.

FLET    local binding of function symbols

     Example Form:
     ; The following evaluates to (mv 7 10):
     (flet ((f (x)
               (+ x 3))
            (g (x)
               (declare (type integer x))
               (* x 2)))
       (mv (f 4) (g 5)))

     General Form:
     (flet (def1 ... defk) body)

where body is a term, and each defi is a definition as in defun but
with the leading defun symbol omitted.  See DEFUN.  The
innermost flet-binding of a function symbol, f, above a call of f, is
the one that provides the definition of f for that call.  Note that
flet does not provide recursion.  Consider the following example.

     (defun f (x) (+ x 3))
     (flet ((f (x) (cons x (f (1+ x)))))
       (f 4))

In the above term (cons x (f (1+ x))), f refers to the global
definition of f above the flet expression.  However, (f 4) refers to
the flet-binding of f, (f (x) (cons x (f x))).  The result of the flet
expression is thus obtained by evaluating (f 4) where (f 4) is (cons 4
(f (1+ 4))), where the latter call of f refers to the global
definition; thus we have (cons 4 (f 5)), which evaluates to (4 . 8).

Although flet behaves in ACL2 essentially as it does in Common Lisp,
ACL2 imposes the following restrictions and qualifications.

     o Every declare form for a local definition (def1 through defk,
     above) must be an ignore, ignorable, or type expression.

     o Each defi must bind a different function symbol.

     o Each defi must bind a symbol that is a legal name for an ACL2
     function symbol.  In particular, the symbol may not be in the
     keyword package or the main Lisp package.  Moreover, the symbol
     may not be a built-in ACL2 function or macro.

     o Every variable occurring in the body of a defi must be a formal
     parameter of that defi.  (This restriction is not enforced in
     Common Lisp.  If the restriction is inconvenient for you, the ACL2
     implementors may be able to remove it, with some effort, if you
     ask.)

     o If the flet-binding defi is in the body of a function f, then
     the stobj inputs for defi are implicitly those of its inputs that
     are declared stobj inputs of f.

Flet bindings are evaluated in parallel.  Consider the following
example.

     (defun f (x) x)
     (flet ((f (x) (cons x x))
            (g (x) (f x)))
       (g 3))

The binding of g refers to the global value of f, not the flet-binding
of f.  Thus, the flet expression evaluates to 3.  Compare the flet
expression above to the following one, which instead evaluates to (3 .
3).

     (defun f (x) x)
     (flet ((f (x) (cons x x)))
       (flet ((g (x) (f x)))
         (g 3)))

Under the hood, ACL2 translates flet bindings to lambda expressions
(see TERM).  The following example illustrates this point.

     ACL2 !>:trans (flet ((f (x) (cons x x))
                          (g (x y) (+ x y)))
                     (f (g 3 4)))

     ((LAMBDA (X) (CONS X X))
      ((LAMBDA (X Y) (BINARY-+ X Y)) '3 '4))

     => *

     ACL2 !>

Flet is part of Common Lisp.  See any Common Lisp documentation for
more information.  We conclude by pointing out an important aspect of
flet shared by ACL2 and Common Lisp: The binding is lexical, not
dynamic.  That is, the flet binding of a function symbol only applies to
calls of that function symbol in the body of the flet, not other calls
made in the course of evaluation.  Consider the following example.
Suppose we define:

     (defun f (x) x)
     (defun g (x) x)
     (defun h (x)
       (flet ((f (x) (cons x x)))
         (g x)))

Then evaluation of (h 3) results in 3, not in the cons pair (3 . 3),
because the flet binding of f only applies to calls of f that appear in
the body of that flet.  In this case, only g is called in the body of
that flet.

FLOOR    division returning an integer by truncating toward negative infinity

     Example Forms:
     ACL2 !>(floor 14 3)
     4
     ACL2 !>(floor -14 3)
     -5
     ACL2 !>(floor 14 -3)
     -5
     ACL2 !>(floor -14 -3)
     4
     ACL2 !>(floor -15 -3)
     5

(Floor i j) returns the result of taking the quotient of i and j and
returning the greatest integer not exceeding that quotient.  For
example, the quotient of -14 by 3 is -4 2/3, and the largest integer
not exceeding that rational number is -5.

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

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

FMS    :(str alist co-channel state evisc) => state

See FMT for further explanation, including documentation of the
tilde-directives.

FMS!    :(str alist co-channel state evisc) => state

This function is nearly identical to fms; see FMS.  The only
difference is that fms may insert backslash (\) characters when forced
to print past the right margin in order to make the output a bit
clearer in that case.  Use fms! instead if you want to be able to read
the forms back in.

FMT    formatted printing

ACL2 provides the functions fmt, fmt1, and fms as substitutes for Common
Lisp's format function.  Also see FMT!, see FMT1!, and
see FMS! for versions of these functions that write forms to
files in a manner that allows them to be read, by avoiding using
backslash (\) to break long lines.

All three print a given string under an alist pairing character objects
with values, interpreting certain "tilde-directives" in the string.
Channel must be a character output channel (e.g., *standard-co*).

     General Forms:                                            result
     (fms string alist channel state evisc-tuple)         ; state
     (fmt string alist channel state evisc-tuple)         ; (mv col state)
     (fmt1 string alist column channel state evisc-tuple) ; (mv col state)

Fms and fmt print an initial newline to put channel in column 0; Fmt1
requires the current column as input.  Columns are numbered from 0.
The current column is the column into which the next character will be
printed.  (Thus, the current column number is also the number of
characters printed since the last newline.)  The col returned by fmt
and fmt1 is the current column at the conclusion of the formatting.
Evisc-tuple must be either nil (meaning no abbreviations are used when
objects are printed) or an "evisceration tuple"; see
EVISC-TUPLE.

We list the tilde-directives below.  The notation is explained after
the chart.

     ~xx  pretty print vx (maybe after printing a newline)
     ~yx  pretty print vx starting in current column; end with newline
     ~Xxy like ~xx but use vy as the evisceration tuple
     ~Yxy like ~yx but use vy as the evisceration tuple
     ~@x  if vx is a string, "str",  recursively format "str"
          if vx is ("str" . a), recursively format "str" under a+
     ~#x~[...~/...~/ ... ~/...~] cases on vx
          ^    ^     ...   ^  if 0<=vx<=k, choose vxth alternative
          0    1     ...   k  if vx is a list of length 1, case 0; else 1
     ~*x  iterator: vx must be of the form
          ("str0" "str1" "str2" "str3" lst . a);
          if lst is initially empty, format "str0" under a+; otherwise,
          bind #\* successively to the elements of lst and then
          recursively format "stri" under a+, where i=1 if there is one
          element left to process, i=2 if there are two left, and i=3
          otherwise.
     ~&x  print elements of vx with ~x, separated by commas and a
          final ``and''
     ~vx  print elements of vx with ~x, separated by commas and a
          final ``or''
     ~nx  if vx is a small positive integer, print it as a word, e.g.,
          seven;
          if vx is a singleton containing a small positive integer, print
            the corresponding ordinal as a word, e.g., seventh
     ~Nx  like ~nx but the word is capitalized, e.g., Seven or Seventh
     ~tx  tab out to column vx; newline first if at or past column vx
     ~cx  vx is (n . w), print integer n right justified in field of
          width w
     ~fx  print object vx flat over as many lines as necessary
     ~Fx  same as ~f, except that subsequent lines are indented to
          start one character to the right of the first character printed
     ~sx  if vx is a symbol, print vx, breaking on hyphens (unless the
          symbol would normally be printed with surrounding vertical bar
          characters (|), in which case print as with ~fx); if vx is a
          string, print the characters in it, breaking on hyphens; else
          vx is a number, to be printed using the current print-base
     ~    tilde space: print a space
     ~_x  print vx spaces
     ~
          tilde newline: skip following whitespace
     ~%   output a newline
     ~|   output a newline unless already on left margin
     ~~   print a tilde
     ~-   if close to rightmargin, output a hyphen and newline; else
          skip this char

If x is a character, then vx is the value of #\x under the current
alist.  When we say "format str under a+" we mean recursively process
the given string under an alist obtained by appending a to the current
alist.

Note:  ~p, ~q, ~P, and ~Q are also currently supported, but are
deprecated.  These are respectively the same as ~x, ~y, ~X, and ~Y,
except that their arguments are expected to be terms, preferably
untranslated (user-level) terms, that could be printed using infix
notation in certain environments.  Infix printing is not currently
supported but may be if there is sufficient need for it.

ACL2's formatting functions print to the indicated channel, keeping
track of which column they are in.  Fmt1 can be used if the caller
knows which column the channel is in (i.e., how many characters have
been printed since the last newline).  Otherwise, fmt or fms must be
used, both of which output a newline so as to establish the column
position at 0.  Unlike Common Lisp's format routine, fmt and its
relatives break the output into lines so as to try to avoid printing
past column 77.  That number is built-into the definitions of ACL2's
formatting functions.  Line breaks are automatically inserted as
necessary in place of spaces and after hyphens in the text being
printed.

The formatting functions scan the string from left to right, printing
each successive character unless it is a tilde (~).  Upon encountering
tildes the formatters take action determined by the character or
characters immediately following the tilde.  The typical
tilde-directive is a group of three successive characters from the
string being printed.  For example, ~x0 is a 3 character
tilde-directive.  The first character in a tilde-directive is always
the tilde character itself.  The next character is called the "command"
character.  The character after that is usually taken as the name of a
"format variable" that is bound in the alist under which the string is
being printed.  Format variables are, by necessity, characters.  The
objects actually printed by a tilde-directive are the objects obtained
by looking up the command's format variables in the alist.  Typical
format variable names are 0, 1, 2, ..., 9, a, b, c, etc., and if a
tilde-directive uses the format variable 0, as in ~x0, then the
character #\0 must be bound in the alist.  Some tilde commands take no
arguments and others take more than one, so some directives are of
length two and others are longer.

It should be noted that this use of characters in the string to denote
arguments is another break from Common Lisp's format routine.  In
Common Lisp, the directives refer implicitly to the "next item to be
printed."  But in ACL2 the directives name each item explicitly with
our format variables.

The following text contains examples that can be evaluated.  To make
this process easier, we use a macro which is defined as part of ACL2
just for this documentation.  The macro is named fmx and it takes up to
eleven arguments, the first of which is a format string, str, and the
others of which are taken as the values of format variables.  The
variables used are #\0 through #\9.  The macro constructs an
appropriate alist, a, and then evaluates (fmt str a *standard-co* state
nil).

Thus,

     (fmx "Here is v0, ~x0, and here is v1, ~x1."
          (cons 'value 0)
          (cons 'value 1))

is just an abbreviation for

     (fmt "Here is v0, ~x0, and here is v1, ~x1."
          (list (cons #\0 (cons 'value 0))
                (cons #\1 (cons 'value 1)))
          *standard-co*
          state
          nil)

which returns (mv 53 state) after printing the line

        Here is v0, (VALUE . 0), and here is v1, (VALUE . 1).

We now devote special attention to three of the tilde-directives whose
use is non-obvious.

_The Case Statement_

~#x is essentially a "case statement" in the language of fmt.  The
proper form of the statement is

     ~#x~[case-0~/case-1~/ ... ~/case-k~],

where each of the case-i is a format string.  In the most common use,
the variable x has an integer value, vx, between 0 and k, inclusive.
The effect of formatting the directive is to format case-vx.

For example

     (fmx "Go ~#0~[North~/East~/South~/West~].~%" 1)

will print "Go East." followed by a newline and will return

(mv 0 state), while if you change the 1 above to 3 (the maximum legal
value), it will print "Go West."

In order to make it easier to print such phrases as "there are seven
cases" requiring agreement between subject and verb based on the number
of elements of a list, the case statement allows its variable to take a
list as its value and selects case-0 if the list has length 1 and
case-1 otherwise.

     (let ((cases '(a b c)))
       (fmx "There ~#0~[is ~n1 case~/are ~n1 cases~]."
            cases
            (length cases)))

will print "There are three cases." but if you change the

'(a b c) above simply to '(a) it will print "There is one case." and if
you change it to nil it will print "There are zero cases."

_Indirection_

Roughly speaking, ~@ will act as though the value of its argument is a
format string and splice it into the current string at the current
position.  It is often used when the phrase to be printed must be
computed.  For example,

     (let ((ev 'DEFUN))
      (fmx "~x0 is an event~@1."
           'foo
           (if (member-eq ev '(defun defstub encapsulate))
               " that may introduce a function symbol"
               "")))

will print "foo is an event that may introduce a function symbol," but
if the value of ev is changed from 'defun to 'defthm, it prints "foo is
an event."  The ~@ directive "splices" in the computed phrase (which
might be empty).  Of course, this particular example could be done with
the case statement

     ~#1~[~/ that may introduce a function symbol~]

where the value of #\1 is appropriately computed to be 0 or 1.

If the argument to ~@ is a pair, it is taken to be a format string
consed onto an alist, i.e., ("str" . a), and the alist, a, is used to
extend the current one before "str" is recursively processed.  This
feature of fmt can be used to pass around "phrases" that contain
computed contextual information in a.  The most typical use is as
"error messages."  For example, suppose you are writing a function
which does not have access to state and so cannot print an error
message.  It may nevertheless be necessary for it to signal an error to
its caller, say by returning two results, the first of which is
interpreted as an error message if non-nil.  Our convention is to use a
~@ pair to represent such messages.  For example, the error value might
be produced by the code:

     (cons
       "Error:  The instruction ~x0 is illegal when the stack is ~x1.~%"
       (list (cons #\0 (current-instruction st))
             (cons #\1 (i-stack st))))

If the current-instruction and i-stack (whatever they are) are '(popi
3) and '(a b) when the cons above is evaluated, then it produces

     '("Error:  The instruction ~x0 is illegal when the stack is ~x1.~%"
       (#\0 POPI 3)
       (#\1 A B))

and if this pair is made the value of the fmt variable 0, then ~@0 will
print

        Error:  The instruction (POPI 3) is illegal when the stack is (A B).

For example, evaluate

     (let
      ((pair
       '("Error:  The instruction ~x0 is illegal when the stack is ~x1.~%"
         (#\0 POPI 3)
         (#\1 A B))))
      (fmx "~@0" pair)).

Thus, even though the function that produced the "error" could not
print it, it could specify exactly what error message and data are to
be printed.

This example raises another issue.  Sometimes it is desirable to break
lines in your format strings so as to make your source code more
attractive.  That is the purpose of the tilde-newline directive.  The
following code produces exactly the same output as described above.

     (let ((pair '("Error:  The instruction ~x0 ~
                   is illegal when the stack is ~
                   ~x1.~%"
                   (#\0 POPI 3)
                   (#\1 A B))))
      (fmx "~@0" pair)).

Finally, observe that when ~@0 extends the current alist, alist, with
the one, a, in its argument, the bindings from a are added to the front
of alist, overriding the current values of any shared variables.  This
ensures that the variable values seen by the recursively processed
string, "str", are those from a, but if "str" uses variables not bound
in a, their values are as specified in the original alist.
Intuitively, variables bound in a are local to the processing of ("str"
. a) but "str" may use "global variables."  The example above
illustrates this because when the ~@0 is processed, #\0 is bound to the
error message pair.  But when the ~x0 in the error string is processed,
#\0 is bound to the illegal instruction.

_Iteration_

The ~* directive is used to process each element of a list.  For
example,

     (let ((lst '(a b c d e f g h))) ; a true-list whose elements we exhibit
      (fmx "~*0"
           `("Whoa!"          ; what to print if there's nothing to print
             "~x*!"           ; how to print the last element
             "~x* and "       ; how to print the 2nd to last element
             "~x*, "          ; how to print all other elements
             ,lst)))          ; the list of elements to print

will print "A, B, C, D, E, F, G and H!".  Try this example with other
true list values of lst, such as '(a b), '(a), and nil.  The
tilde-directives ~&0 and ~v0, which take a true list argument and
display its elements separated by commas and a final "and" or "or," are
implemented in terms of the more general ~*.

The ~* directive allows the 5-tuple to specify in its final cdr an
alist with which to extend the current one before processing the
individual elements.

We often use ~* to print a series of phrases, separated by suitable
punctuation, whitespace and noise words.  In such use, the ~* handles
the separation of the phrases and each phrase is generally printed by
~@.

Here is a complex example.  In the let*, below, we bind phrases to a
list of ~@ pairs and then we create a ~* 5-tuple to print out the
conjunction of the phrases with a parenthetical "finally!" if the
series is longer than 3.

     (let* ((phrases
             (list (list "simplifying with the replacement rules ~&0"
                         (cons #\0 '(rewrite-rule1
                                     rewrite-rule2
                                     rewrite-rule3)))
                   (list "destructor elimination using ~x0"
                         (cons #\0 'elim-rule))
                   (list "generalizing the terms ~&0"
                         (cons #\0 '((rev x) (app u v))))
                   (list "inducting on ~x0"
                         (cons #\0 'I))))
            (5-tuple
             (list
              "magic"                            ; no phrases
              "~@*"                              ; last phrase
              "~@*, and~#f~[~/ (finally!)~] "    ; second to last phrase
              "~@*, "                            ; other phrases
              phrases                            ; the phrases themselves
              (cons #\f
                    (if (>(length phrases) 3) 1 0))))) ;print ``finally''?
       (fmx "We did it by ~*0." 5-tuple))

This let* prints

        We did it by simplifying with the replacement rules REWRITE-RULE1,
        REWRITE-RULE2 and REWRITE-RULE3, destructor elimination using ELIM-
        RULE, generalizing the terms (REV X) and (APP U V), and (finally!)
        inducting on I.

You might wish to try evaluating the let* after removing elements of
phrases.

Most of the output produced by ACL2 is produced via fmt statements.
Thus, inspection of the source code will yield many examples.  A
complicated example is the code that explains the simplifier's work.
See :pc simplify-clause-msg1.  An ad hoc example is provided by the
function fmt-doc-example, which takes two arguments: an arbitrary true
list and state.  To see how fmt-doc-example works, :pe fmt-doc-example.

     (fmt-doc-example '(a b c d e f g h i j k l m n o p) state)

will produce the output

        Here is a true list:  (A B C D E F G H I J K L M N O P).  It has 16
        elements, the third of which is C.

        We could print each element in square brackets:
        ([A], [B], [C], [D], [E], [F], [G], [H], [I], [J], [K], [L], [M], [N],
        [almost there: O], [the end: P]).  And if we wished to itemize them
        into column 15 we could do it like this
        0123456789012345
            0 (zeroth) A
            1 (first)  B
            2 (second) C
            3 (third)  D
            4 (fourth) E
            5 (fifth)  F
            6 (sixth)  G
            7 (seventh)
                       H
            8 (eighth) I
            9 (ninth)  J
           10 (tenth)  K
           11 (eleventh)
                       L
           12 (twelfth)
                       M
           13 (thirteenth)
                       N
           14 (14th)   O
           15 (15th)   P
        End of example.

and return (mv 15 state).

Finally, we should remind the reader that fmt and its subfunctions,
most importantly fmt0, are written entirely in ACL2.  We make this
comment for two reasons.  First, it illustrates the fact that quite low
level code can be efficiently written in the language.  Second, it
means that as a last resort for documentation purposes you can read the
source code without changing languages.

FMT!    :(str alist co-channel state evisc) => state

This function is nearly identical to fmt; see FMT.  The only
difference is that fmt may insert backslash (\) characters when forced
to print past the right margin in order to make the output a bit
clearer in that case.  Use fmt! instead if you want to be able to read
the forms back in.

FMT-TO-COMMENT-WINDOW    print to the comment window

See CW for an introduction to the comment window and the usual
way to print it.

Function fmt-to-comment-window is identical to fmt1 (see FMT),
except that the channel is in essence *standard-co* and the ACL2 state
is neither an input nor an output.  An analogous function,
fmt-to-comment-window!, prints with fmt! instead of fmt, in order to
avoid insertion of backslash (\) characters for margins; also see
CW!.

     General Form:
     (fmt-to-comment-window fmt-string alist col evisc-tuple)

where these arguments are as desribed for fmt1; see FMT.

FMT1    :(str alist col co-channel state evisc) => (mv col state)

See FMT for further explanation, including documentation of the
tilde-directives.

FMT1!    :(str alist col channel state evisc) => (mv col state)

This function is nearly identical to fmt1; see FMT1.  The only
difference is that fmt1 may insert backslash (\) characters when forced
to print past the right margin in order to make the output a bit
clearer in that case.  Use fmt1! instead if you want to be able to read
the forms back in.

FOURTH    fourth member of the list

See any Common Lisp documentation for details.

GETENV$    read an environment variable

(Getenv$ str state), where str is a string, reads the value of
environment variable str, returning nil if none is found or if the read
fails.  The formal story is that getenv$ reads its value from the
oracle field of the ACL2 state.  The return value is thus a triple of
the form (mv erp val state), where erp will always be nil in practice,
val is the value that has been read, and state is the new state, which
is obtained by popping val from the top of the state's oracle.

     Example:
     (getenv$ "PWD" state) ==> (mv nil "/u/joe/work" state)

Also see SETENV$.

GETPROP    access fast property lists

     General form:
     (getprop symb key default world-name world-alist)

See 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.

HARD-ERROR    print an error message and stop execution

(Hard-error ctx str alist) causes evaluation to halt with a short
message using the "context" ctx.  An error message is first printed
using the string str and alist alist that are of the same kind as
expected by fmt.  See FMT.  Also see ER for a macro
that provides a unified way of signaling errors.

Hard-error has a guard of t.  Also see ILLEGAL for a similar
capability which however has a guard of nil that supports static
checking using guard verification, rather than using dynamic (run-time)
checking.   This distinction is illustrated elsewhere: see
PROG2$ for examples.

Semantically, hard-error ignores its arguments and always returns nil.
But if a call (hard-error ctx str alist) is encountered during
evaluation, then the string str is printed using the association list
alist (as in fmt), after which evaluation halts immediately.  Here is a
trivial, contrived example.

     ACL2 !>(cons 3 (hard-error 'my-context
                                 "Printing 4: ~n0"
                                 (list (cons #\0 4))))

     HARD ACL2 ERROR in MY-CONTEXT:  Printing 4: four

     ACL2 Error in TOP-LEVEL:  Evaluation aborted.

     ACL2 !>

IDENTITY    the identity function

(Identity x) equals x; what else can we say?

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

IF    if-then-else function

(if x y z) is equal to y if x is any value other than nil, and is equal
to z if x is nil.

Only one of y, z is evaluated when (if x y z) is evaluated.

If has a guard of t.

If is part of Common Lisp.  See any Common Lisp documentation for more
information.

IFF    logical "if and only if"

Iff is the ACL2 biconditional, "if and only if".  (iff P Q) means that
either P and Q are both false (i.e., nil) or both true (i.e., not nil).

IFIX    coerce to an integer

Ifix simply returns any integer argument unchanged, returning 0 on a
non-integer argument.  Also see NFIX, see RFIX, see
REALFIX and see FIX for analogous functions that coerce
to a natural number, a rational number, a real, and a number,
respectively.

Ifix has a guard of t.

IGNORABLE    See DECLARE.

IGNORE    See DECLARE.

ILLEGAL    print an error message and stop execution

(Illegal ctx str alist) causes evaluation to halt with a short message
using the "context" ctx.  An error message is first printed using the
string str and alist alist that are of the same kind as expected by
fmt.  See FMT, and see PROG2$ for an example of how to
use a related function, hard-error (see HARD-ERROR).  Also see
ER for a macro that provides a unified way of signaling errors.

The difference between illegal and hard-error is that the former has a
guard of nil while the latter has a guard of t.  Thus, you may want to
use illegal rather than hard-error when you intend to do guard
verification at some point, and you expect the guard to guarantee that
the illegal call is never executed.  See PROG2$ for an example.

IMAGPART    imaginary part of a complex number

Completion Axiom:

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

Guard for (imagpart x):

     (acl2-numberp x)

IMPLIES    logical implication

Implies is the ACL2 implication function.  (implies P Q) means that
either P is false (i.e., nil) or Q is true (i.e., not nil).

IMPROPER-CONSP    recognizer for improper (non-null-terminated) non-empty lists

Improper-consp is the function that checks whether its argument is a
non-empty list that ends in other than nil.  See PROPER-CONSP
and also see TRUE-LISTP.

INT=    test equality of two integers

(int= x y) is logically equivalent to (equal x y).

Unlike equal, int= requires its arguments to be numbers (or else causes
a guard violation; see GUARD).  Generally, int= is executed
more efficiently than equal or = on integers.

INTEGER-LENGTH    number of bits in two's complement integer representation

For non-negative integers, (integer-length i) is the minimum number of
bits needed to represent the integer.  Any integer can be represented
as a signed two's complement field with a minimum of (+ (integer-length
i) 1) bits.

The guard for integer-length requires its argument to be an integer.
Integer-length is defined in Common Lisp.  See any Common Lisp
documentation for more information.

INTEGER-LISTP    recognizer for a true list of integers

The predicate integer-listp tests whether its argument is a true list
of integers.

INTEGERP    recognizer for whole numbers

(integerp x) is true if and only if x is an integer.

INTERN    create a new symbol in a given package

(intern symbol-name symbol-package-name) returns a symbol with the
given symbol-name and the given symbol-package-name.  We restrict
Common Lisp's intern so that the second argument is either the symbol
*main-lisp-package-name*, the value of that constant, or is one of
"ACL2", "ACL2-INPUT-CHANNEL", "ACL2-OUTPUT-CHANNEL", or "KEYWORD".  To
avoid that restriction, see INTERN$.

In ACL2 intern is actually implemented as a macro that expands to a
call of a similar function whose second argument is a symbol.  Invoke
:pe intern to see the definition, or see
INTERN-IN-PACKAGE-OF-SYMBOL.

To see why is intern so restricted consider (intern "X" "P").  In
particular, is it a symbol and if so, what is its symbol-package-name?
One is tempted to say "yes, it is a symbol in the package "P"."  But if
package "P" has not yet been defined, that would be premature because
the imports to the package are unknown.  For example, if "P" were
introduced with

     (defpkg "P" '(LISP::X))

then in Common Lisp (symbol-package-name (intern "X" "P")) returns
"LISP".

The obvious restriction on intern is that its second argument be the
name of a package known to ACL2.  We cannot express such a restriction
(except, for example, by limiting it to those packages known at some
fixed time, as we do).  Instead, we provide intern-in-package-of-symbol
which requires a "witness symbol" for the package instead of the
package.  The witness symbol is any symbol (expressible in ACL2) and
uniquely specifies a package necessarily known to ACL2.

INTERN$    create a new symbol in a given package

Intern$ is a macro that behaves the same as the macro intern, except
for weakening the restriction to a fixed set of package names so that
any package name other than "" is legal.  See INTERN.  Note
that if you evaluate a call (intern$ x y) for which there is no package
with name y that is known to ACL2, you will get an error.

(Intern$ x y) expands to:

     (intern-in-package-of-symbol x (pkg-witness y))

See INTERN-IN-PACKAGE-OF-SYMBOL and see PKG-WITNESS.

INTERN-IN-PACKAGE-OF-SYMBOL    create a symbol with a given name

Completion Axiom:

     (equal (intern-in-package-of-symbol x y)
            (if (and (stringp x)
                     (symbolp y))
                (intern-in-package-of-symbol x y)
              nil))

Guard for (intern-in-package-of-symbol x y):

     (and (stringp x) (symbolp y))

Intuitively, (intern-in-package-of-symbol x y) creates a symbol with
symbol-name x interned in the package containing y.  More precisely,
suppose x is a string, y is a symbol with symbol-package-name pkg and
that the defpkg event creating pkg had the list of symbols imports as
the value of its second argument.  Then (intern-in-package-of-symbol x
y) returns a symbol, ans, the symbol-name of ans is x, and the
symbol-package-name of ans is pkg, unless x is the symbol-name of some
member of imports with symbol-package-name ipkg, in which case the
symbol-package-name of ans is ipkg.  Because defpkg requires that there
be no duplications among the symbol-names of the imports,
intern-in-package-of-symbol is uniquely defined.

For example, suppose "MY-PKG" was created by

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

Let w be 'my-pkg::witness.  Observe that

     (symbolp w) is t                     ; w is a symbol
     (symbol-name w) is "WITNESS"         ; w's name is "WITNESS"
     (symbol-package-name w) is "MY-PKG"  ; w is in the package "MY-PKG"

The construction of w illustrates one way to obtain a symbol in a given
package:  write it down as a constant using the double-colon notation.

But another way to obtain a symbol in a given package is to create it
with intern-in-package-of-symbol.

     (intern-in-package-of-symbol "XYZ" w) is MY-PKG::XYZ

     (intern-in-package-of-symbol "ABC" w) is ACL2::ABC

     (intern-in-package-of-symbol "CAR" w) is LISP::CAR

     (intern-in-package-of-symbol "car" w) is MY-PKG::|car|

INTERSECTP    test whether two lists of eqlablep objects intersect

See INTERSECTP-EQUAL, which is logically the same function.

(Intersectp x y) has a guard that x and y are lists containing only
numbers, symbols, and characters.

INTERSECTP-EQ    test whether two lists of symbols intersect

See INTERSECTP-EQUAL, which is logically the same function.

(Intersectp-eq x y) has a guard that x and y are lists of symbols.

INTERSECTP-EQUAL    test whether two lists intersect

(Intersectp-equal x y) returns t if x and y have a member in common,
else it returns nil.  Also see INTERSECTP-EQ, which is
logically the same but can be more efficient since it uses eq instead
of equal to look for members common to the two given lists.

(Intersectp-equal x y) has a guard that x and y are true lists.

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 is not involved in either the guard
or the measure for fn, x is used in the body, but 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) 0 (* 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 :guard requiring both
arguments to be nonnegative integers and the :measure (+ i 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
SET-IRRELEVANT-FORMALS-OK.

KEYWORD-VALUE-LISTP    recognizer for true lists whose even-position elements are keywords

(keyword-value-listp l) is true if and only if l is a list of even
length of the form (k1 a1 k2 a2 ... kn an), where each ki is a keyword.

KEYWORDP    recognizer for keywords

(Keywordp x) is true if and only if x is a keyword, i.e., a symbol in
the "KEYWORD" package.  Such symbols are typically printed using a colon
(:) followed by the symbol-name of the symbol.

Keywordp has a guard of t.

Keywordp is a Common Lisp function.  See any Common Lisp documentation
for more information.  The following log may be illuminating.

     ACL2 !>(intern "ABC" "KEYWORD")
     :ABC
     ACL2 !>(symbol-name ':ABC)
     "ABC"
     ACL2 !>(symbol-package-name ':ABC)
     "KEYWORD"
     ACL2 !>

KWOTE    quote an arbitrary object

For any object x, (kwote x) returns the two-element list whose elements
are the symbol quote and the given x, respectively.  The guard of
(kwote x) is t.

KWOTE-LST    quote an arbitrary true list of objects

The function kwote-lst applies the function kwote to each element of a
given list.  The guard of (kwote-lst lst) is (true-listp lst).

LAST    the last cons (not element) of a list

(Last l) is the last cons of a list.  Here are examples.

     ACL2 !>(last '(a b . c))
     (B . C)
     ACL2 !>(last '(a b c))
     (C)

(Last l) has a guard of (listp l); thus, l need not be a true-listp.

Last is a Common Lisp function.  See any Common Lisp documentation for
more information.  Unlike Common Lisp, we do not allow an optional
second argument for last.

LEN    length of a list

Len returns the length of a list.

A Common Lisp function that is appropriate for both strings and proper
lists is length; see LENGTH.  The guard for len is t.

(Low-level implementation note.  ACL2 provides a highly-optimized
implementation of len, which is tail-recursive and fixnum-aware, that
differs from its simple ACL2 definition.)

LENGTH    length of a string or proper list

Length is the function for determining the length of a sequence.  In
ACL2, the argument is required to be either a true-listp or a string.

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

LET    binding of lexically scoped (local) variables

     Example LET Form:
     (let ((x (* x x))
           (y (* 2 x)))
      (list x y))

If the form above is executed in an environment in which x has the
value -2, then the result is '(4 -4).

Let expressions bind variables so that their "local" values, the values
they have when the "body" of the let is evaluated, are possibly
different than their "global" values, the values they have in the
context in which the let expression appears.  In the let expression
above, the local variables bound by the let are x and y.  They are
locally bound to the values delivered by the two forms (* x x) and (* 2
x), respectively, that appear in the "bindings" of the let.  The body
of the let is (list x y).

Suppose that the let expression above occurs in a context in which x
has the value -2.  (The global value of y is irrelevant to this
example.)  For example, one might imagine that the let form above
occurs as the body of some function, fn, with the formal parameter x
and we are evaluating (fn -2).

To evaluate the let above in a context in which x is -2, we first
evaluate the two forms specifying the local values of the variables.
Thus, (* x x) is evaluated and produces 4 (because x is -2) and (* 2 x)
is evaluated and produces -4 (because x is -2).  Then x and y are bound
to these values and the body of the let is evaluated.  Thus, when the
body, (list x y) is evaluated, x is 4 and y is -4.  Thus, the body
produces '(4 -4).

Note that the binding of y, which is written after the binding of x and
which mentions x, nevertheless uses the global value of x, not the new
local value.  That is, the local variables of the let are bound "in
parallel" rather than "sequentially." In contrast, if the

     Example LET* Form:
     (let* ((x (* x x))
            (y (* 2 x)))
      (list x y))

is evaluated when the global value of x is -2, then the result is '(4
8), because the local value of y is computed after x has been bound to
4.  Let* binds its local variables "sequentially."

     General LET Forms:
     (let ((var1 term1) ... (varn termn)) body)
     and
     (let ((var1 term1) ... (varn termn))
      (declare ...) ... (declare ...)
      body)

where the vari are distinct variables, the termi are terms involving
only variables bound in the environment containing the let, and body is
a term involving only the vari plus the variables bound in the
environment containing the let.  Each vari must be used in body or else
declared ignored.

A let form is evaluated by first evaluating each of the termi,
obtaining for each a vali.  Then, each vari is bound to the
corresponding vali and body is evaluated.

Actually, let forms are just abbreviations for certain uses of lambda
notation.  In particular

     (let ((var1 term1) ... (varn termn)) (declare ...) body)

is equivalent to

     ((lambda (var1 ... varn)
        (declare ...)
        body)
      term1 ... termn).

Let* forms are used when it is desired to bind the vari sequentially,
i.e., when the local values of preceding varj are to be used in the
computation of the local value for vari.

     General LET* Forms:
     (let* ((var1 term1) ... (varn termn)) body)
     and
     (let* ((var1 term1) ... (varn termn))
      (declare (ignore x1 ... xm))
      body)

where the vari are variables (not necessarily distinct), the termi are
terms involving only variables bound in the environment containing the
let* and those varj such that j<i, and body is a term involving only
the vari plus the variables bound in the environment containing the
let*.  Each vari must be used either in some subsequent termj or in
body, except that in the second form above we make an exception when
vari is among the xk, in which case vari must not be thus used.  Note
that let* does not permit the inclusion of any declare forms other than
one as shown above.  In the second general form above, every xk must be
among the vari, and furthermore, xk may not equal vari and varj for
distinct i, j.

The first let* above is equivalent to

     (let ((var1 term1))
      ...
      (let ((varn termn)) body)...)

Thus, the termi are evaluated successively and after each evaluation
the corresponding vali is bound to the value of termi.  The second let*
is similarly expanded, except that each for each vari that is among the
(x1 ... xm), the form (declare (ignore vari)) is inserted immediately
after (vari termi).

Each (vari termi) pair in a let or let* form is called a "binding" of
vari and the vari are called the "local variables" of the let or let*.
The common use of let and let* is to save the values of certain
expressions (the termi) so that they may be referenced several times in
the body without suggesting their recomputation.

Let is part of Common Lisp.  See any Common Lisp documentation for more
information.

LET*    binding of lexically scoped (local) variables

     Example LET* Forms:
     (let* ((x (* x x))
            (y (* 2 x)))
      (list x y))

     (let* ((x (* x x))
            (y (* 2 x))
            (x (* x y))
            (a (* x x)))
      (declare (ignore a))
      (list x y))

If the forms above are executed in an environment in which x has the
value -2, then the respective results are '(4 8) and '(32 8).  See
LET for a discussion of both let and let*, or read on for a
briefer discussion.

The difference between let and let* is that the former binds its local
variables in parallel while the latter binds them sequentially.  Thus,
in let*, the term evaluated to produce the local value of one of the
locally bound variables is permitted to reference any locally bound
variable occurring earlier in the binding list and the value so
obtained is the newly computed local value of that variable.  See
LET.

In ACL2 the only declare forms allowed for a let* form are ignore,
ignorable, and type.  See DECLARE.  Moreover, no variable
declared ignored or ignorable may be bound more than once.  A variable
with a type declaration may be bound more than once, in which case the
type declaration is treated by ACL2 as applying to each binding
occurrence of that variable.  It seems unclear from the Common Lisp spec
whether the underlying Lisp implementation is expected to apply such a
declaration to more than one binding occurrence, however, so
performance in such cases may depend on the underlying Lisp.

Let* is a Common Lisp macro.  See any Common Lisp documentation for
more information.

LEXORDER    total order on ACL2 objects

Lexorder is a non-strict total order, a "less than or equal," on ACL2
objects.  Also see ALPHORDER, the restriction of lexorder to
atoms; the notion of "non-strict total order" is defined there.

Lexorder has a guard of t.

For lexorder, an atom and a cons are ordered so that the atom comes
first, and two conses are ordered so that the one with the recursively
smaller car comes first, with the cdrs being compared only if the cars
are equal.   Lexorder compares two atoms by using alphorder.

LIST    build a list

List is the macro for building a list of objects.  For example, (list 5
6 7) returns a list of length 3 whose elements are 5, 6, and 7
respectively.  Also see LIST*.

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

LIST*    build a list

List* is the Common Lisp macro for building a list of objects from
given elements and a tail.  For example, (list* 5 6 '(7 8 9)) equals
the list '(5 6 7 8 9).  Also see LIST.

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

LISTP    recognizer for (not necessarily proper) lists

(listp x) is true when x is either a cons pair or is nil.

Listp has no guard, i.e., its guard is t.

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

LOGAND    bitwise logical `and' of zero or more integers

When integers are viewed in their two's complement representation,
logand returns their bitwise logical `and'.  In ACL2 logand is a macro
that expands into calls of the binary function binary-logand, except
that (logand) expands to -1 and (logand x) expands to x.

The guard for binary-logand requires its arguments to be integers.
Logand is defined in Common Lisp.  See any Common Lisp documentation
for more information.

LOGANDC1    bitwise logical `and' of two ints, complementing the first

When integers are viewed in their two's complement representation,
logandc1 returns the bitwise logical `and' of the second with the
bitwise logical `not' of the first.

The guard for logandc1 requires its arguments to be integers.  Logandc1
is defined in Common Lisp.  See any Common Lisp documentation for more
information.

LOGANDC2    bitwise logical `and' of two ints, complementing the second

When integers are viewed in their two's complement representation,
logandc2 returns the bitwise logical `and' of the first with the
bitwise logical `not' of the second.

The guard for logandc2 requires its arguments to be integers.  Logandc2
is defined in Common Lisp.  See any Common Lisp documentation for more
information.

LOGBITP    the ith bit of an integer

For a nonnegative integer i and an integer j, (logbitp i j) is the
value of the ith bit in the two's complement representation of j.

(Logbitp i j) has a guard that i is a nonnegative integer and j is an
integer.

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

LOGCOUNT    number of "on" bits in a two's complement number

(Logcount x) is the number of "on" bits in the two's complement
representation of x.

(Logcount x) has a guard of (integerp x).

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

LOGEQV    bitwise logical equivalence of zero or more integers

When integers are viewed in their two's complement representation,
logeqv returns their bitwise logical equivalence.  In ACL2 logeqv is a
macro that expands into calls of the binary function binary-logeqv,
except that (logeqv) expands to -1 and (logeqv x) expands to x.

The guard for binary-logeqv requires its arguments to be integers.
Logeqv is defined in Common Lisp.  See any Common Lisp documentation
for more information.

LOGIOR    bitwise logical inclusive or of zero or more integers

When integers are viewed in their two's complement representation,
logior returns their bitwise logical inclusive or.  In ACL2 logior is a
macro that expands into calls of the binary function binary-logior,
except that (logior) expands to 0 and (logior x) expands to x.

The guard for binary-logior requires its arguments to be integers.
Logior is defined in Common Lisp.  See any Common Lisp documentation
for more information.

LOGNAND    bitwise logical `nand' of two integers

When integers are viewed in their two's complement representation,
lognand returns their bitwise logical `nand'.

The guard for lognand requires its arguments to be integers.  Lognand
is defined in Common Lisp.  See any Common Lisp documentation for more
information.

LOGNOR    bitwise logical `nor' of two integers

When integers are viewed in their two's complement representation,
lognor returns the bitwise logical `nor' of the first with the second.

The guard for lognor requires its arguments to be integers.  Lognor is
defined in Common Lisp.  See any Common Lisp documentation for more
information.

LOGNOT    bitwise not of a two's complement number

(lognot i) is the two's complement bitwise `not' of the integer i.

Lognot is actually defined by coercing its argument to an integer (see
IFIX), negating the result, and then subtracting 1.

The guard for lognot requires its argument to be an integer.

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

LOGORC1    bitwise logical inclusive or of two ints, complementing the first

When integers are viewed in their two's complement representation,
logorc1 returns the bitwise logical inclusive or of the second with the
bitwise logical `not' of the first.

The guard for logorc1 requires its arguments to be integers.  Logorc1
is defined in Common Lisp.  See any Common Lisp documentation for more
information.

LOGORC2    bitwise logical inclusive or of two ints, complementing the second

When integers are viewed in their two's complement representation,
logorc2 returns the bitwise logical inclusive or of the first with the
bitwise logical `not' of the second.

The guard for logorc2 requires its arguments to be integers.  Logorc2
is defined in Common Lisp.  See any Common Lisp documentation for more
information.

LOGTEST    test if two integers share a `1' bit

When integers x and y are viewed in their two's complement
representation, (logtest x y) is true if and only if there is some
position for which both x and y have a `1' bit in that position.

The guard for logtest requires its arguments to be integers.  Logtest
is defined in Common Lisp.  See any Common Lisp documentation for more
information.

LOGXOR    bitwise logical exclusive or of zero or more integers

When integers are viewed in their two's complement representation,
logxor returns their bitwise logical exclusive or.  In ACL2 logxor is a
macro that expands into calls of the binary function binary-logxor,
except that (logxor) expands to 0 and (logxor x) expands to x.

The guard for binary-logxor requires its arguments to be integers.
Logxor is defined in Common Lisp.  See any Common Lisp documentation
for more information.

LOWER-CASE-P    recognizer for lower case characters

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

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

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

MAKE-CHARACTER-LIST    coerce to a list of characters

Non-characters in the given list are coerced to the character with code
0.

MAKE-LIST    make a list of a given size

For a nonnegative integer size, (Make-list size) is a list of elements
of length size, each of which is initialized to the :initial-element
(which defaults to nil).

Make-list is a macro in ACL2, defined in terms of a tail recursive
function make-list-ac whose guard requires size to be a nonnegative
integer.  Make-list is a Common Lisp function.  See any Common Lisp
documentation for more information.

MAKE-ORD    a constructor for ordinals.

Make-ord is the ordinal constructor.  Its use is recommended instead of
using cons to make ordinals.  For a discussion of ordinals, see
ORDINALS.

For any ordinal, alpha < epsilon-0, there exist natural numbers p and
n, positive integers x1, x2, ..., xn and ordinals a1 > a2 > ... > an >
0 such that alpha > a1 and alpha = w^(a1)x1 + w^(a2)x2 + ... + w^(an)xn
+ p.  We call a1 the "first exponent", x1 the "first coefficient", and
the remainder (w^(a2)x2 + ... + w^(an)xn + p) the "rest" of alpha.

(Make-ord fe fco rst) corresponds to the ordinal (w^fe)fco + rst.  Thus
the first infinite ordinal, w (omega), is constructed by

     (make-ord 1 1 0)

and, for example, the ordinal (w^2)5 + w2 + 7 is constructed by:

     (make-ord 2 5 (make-ord 1 2 7)) .

The reason make-ord is used rather than cons is that it allows us to
reason more abstractly about the ordinals, without having to worry
about the underlying representation.

MAX    the larger of two numbers

(Max x y) is the larger of the numbers x and y.

The guard for max requires its arguments to be rational (real, in
ACL2(r)) numbers.

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

MBE    attach code for execution

The macro mbe ("must be equal") can be used in function definitions in
order to cause evaluation to use alternate code to that provided for the
logic.  An example is given below.  However, the use of mbe can lead to
non-terminating computations.  See DEFEXEC, perhaps after
reading the present documentation, for a way to guarantee termination
(at least theoretically).

In the ACL2 logic, (mbe :exec exec-code :logic logic-code) equals
logic-code; the value of exec-code is ignored.  However, in raw Lisp it
is the other way around:  this form macroexpands simply to exec-code.
ACL2's guard verification mechanism ensures that the raw Lisp code is
only evaluated when appropriate, since the guard proof obligations
generated for this call of mbe are (equal exec-code logic-code)
together with the guard proof obligations from exec-code.  See
VERIFY-GUARDS and, for general discussion of guards, see
GUARD.

Warning for nested mbe calls: The equality of :exec and :logic code is
not checked in the scope of superior :logic code, as for the equality
of x and y in the following.

     (mbe :logic
          (mbe :logic x :exec y)
          :exec
          z)

The form (mbe :exec exec-code :logic logic-code) expands in the logic to
the function call (must-be-equal logic-code exec-code).  The guard for
(must-be-equal logic exec) is (equal logic exec).  We recommend that
you use mbe instead of must-be-equal because the use of keywords
eliminates errors caused by unintentially reversing the order of
arguments.  The :exec and the :logic code in an mbe call must have the
same return type; for example, one cannot return (mv * *) while the
other returns just a single value.

Also see MBT, which stands for "must be true."  You may find it
more natural to use mbt for certain applications, as described in its
documentation.

Related topics other than immediate subtopics:

Here is an example of the use of mbe.  Suppose that you want to define
factorial in the usual recursive manner, as follows.

     (defun fact (n)
       (if (zp n)
           1
         (* n (fact (1- n)))))

But perhaps you want to be able to execute calls of fact on large
arguments that cause stack overflows, perhaps during proofs.  (This
isn't a particularly realistic example, but it should serve.)  So,
instead you can define this tail-recursive version of factorial:

     (defun fact1 (n acc)
       (declare (xargs :guard (and (integerp n) (>= n 0) (integerp acc))))
       (if (zp n)
           acc
         (fact1 (1- n) (* n acc))))

We are now ready to define fact using mbe.  Our intention is that
logically, fact is as shown in the first definition above, but that
fact should be executed by calling fact1.  Notice that we defer guard
verification, since we are not ready to prove the correspondence
between fact1 and fact.

     (defun fact (n)
       (declare (xargs :guard (and (integerp n) (>= n 0))
                       :verify-guards nil))
       (mbe :exec  (fact1 n 1)
            :logic (if (zp n)
                       1
                     (* n (fact (1- n))))))

Next, we prove the necessary correspondence lemmas.  Notice the
inclusion of a standard book to help with the arithmetic reasoning.

     (include-book "books/arithmetic/top-with-meta")

     (defthm fact1-fact
       (implies (integerp acc)
                (equal (fact1 n acc)
                       (* acc (fact n)))))

We may now do guard verification for fact, which will allow the
execution of the raw Lisp fact function, where the above mbe call
expands simply to (fact1 n 1).

     (verify-guards fact)

Now that guards have been verified, a trace of function calls
illustrates that the evaluation of calls of fact is passed to
evaluation of calls of fact1.  The outermost call below is of the
logical function stored for the definition of fact; all the others are
of actual raw Common Lisp functions.

     ACL2 !>(trace$ fact fact1)
     NIL
     ACL2 !>(fact 3)
     1> (ACL2_*1*_ACL2::FACT 3)
       2> (FACT 3)
         3> (FACT1 3 1)
           4> (FACT1 2 3)
             5> (FACT1 1 6)
               6> (FACT1 0 6)
               <6 (FACT1 6)
             <5 (FACT1 6)
           <4 (FACT1 6)
         <3 (FACT1 6)
       <2 (FACT 6)
     <1 (ACL2_*1*_ACL2::FACT 6)
     6
     ACL2 !>

You may occasionally get warnings when you compile functions defined
using mbe.  (For commands that invoke the compiler, see
COMPILATION.)  These can be inhibited by using an ignorable declare
form.  Here is a simple but illustrative example.  Note that the
declarations can optionally be separated into two declare forms.

     (defun foo (x y)
       (declare (ignorable x)
                (xargs :guard (equal x y)))
       (mbe :logic x :exec y))

Finally, we observe that when the body of a function contains a term of
the form (mbe :exec exec-code :logic logic-code), the user is very
unlikely to see any logical difference than if this were replaced by
logic-code.  ACL2 takes various steps to ensure this.  For example, the
proof obligations generated for admitting a function treat the above
mbe term simply as logic-code.  Function expansion, :use hints,
:definition rules, generation of constraints for functional
instantiation, and creation of rules of class :rewrite and
:forward-chaining also treat mbe calls as their :logic code.

MBT    introduce a test not to be evaluated

The macro mbt ("must be true") can be used in order to add code in
order to admit function definitions in :logic mode, without paying a
cost in execution efficiency.  Examples below illustrate its intended
use.

Semantically, (mbt x) equals x.  However, in raw Lisp (mbt x) ignores x
entirely, and macroexpands to t.  ACL2's guard verification mechanism
ensures that the raw Lisp code is only evaluated when appropriate,
since a guard proof obligation (equal x t) is generated.  See
VERIFY-GUARDS and, for general discussion of guards, see
GUARD.

Also see MBE, which stands for "must be equal."  Although mbt
is more natural in many cases, mbe has more general applicability.  In
fact, (mbt x) is essentially defined to be (mbe :logic x :exec t).

We can illustrate the use of mbt on the following generic example, where
<g>, <test>, <rec-x>, and <base> are intended to be terms involving
only the variable x.

     (defun foo (x)
       (declare (xargs :guard <g>))
       (if <test>
           (foo <rec-x>)
         <base>))

In order to admit this function, ACL2 needs to discharge the proof
obligation that <rec-x> is smaller than x, namely:

     (implies <test>
              (o< (acl2-count <rec-x>)
                   (acl2-count x)))

But suppose we need to know that <g> is true in order to prove this.
Since <g> is only the guard, it is not part of the logical definition
of foo.  A solution is to add the guard to the definition of foo, as
follows.

     (defun foo (x)
       (declare (xargs :guard <g>))
       (if (mbt <g>)
           (if <test>
               (foo <rec-x>)
             <base>)
         nil))

If we do this using <g> rather than (mbt <g>), then evaluation of every
recursive call of foo will cause the evaluation of (the appropriate
instance of) <g>.  But since (mbt <g>) expands to t in raw Lisp, then
once we verify the guards of foo, the evaluations of <g> will be
avoided (except at the top level, when we check the guard before
allowing evaluation to take place in Common Lisp).

Other times, the guard isn't the issue, but rather, the problem is that
a recursive call has an argument that itself is a recursive call.  For
example, suppose that <rec-x> is of the form (foo <expr>).  There is no
way we can hope to discharge the termination proof obligation shown
above.  A standard solution is to add some version of this test:

     (mbt (o< (acl2-count <rec-x>) (acl2-count x)))

Here is a specific example based on one sent by Vernon Austel.

     (defun recurX2 (n)
       (declare (xargs :guard (and (integerp n) (<= 0 n))
                       :verify-guards nil))
       (cond ((zp n) 0)
             (t (let ((call (recurX2 (1- n))))
                  (if (mbt (< (acl2-count call) n))
                      (recurX2 call)
                    1 ;; this branch is never actually taken
                    )))))

     (defthm recurX2-0
      (equal (recurX2 n) 0))

     (verify-guards recurX2)

If you (trace$ acl2-count), you will see that evaluation of (recurX2 2)
causes several calls of acl2-count before the verify-guards.  But this
evaluation does not call acl2-count after the verify-guards, because
the ACL2 evaluation mechanism uses raw Lisp to do the evaluation, and
the form (mbt (< (acl2-count call) n)) macroexpands to t in Common Lisp.

You may occasionally get warnings when you compile functions defined
using mbt.  (For commands that invoke the compiler, see
COMPILATION.)  These can be inhibited by using an ignorable declare
form.  Here is a simple but illustrative example.  Note that the
declarations can optionally be separated into two declare forms.

     (defun foo (x y)
       (declare (ignorable x)
                (xargs :guard (equal x t)))
       (and (mbt x) y))

MEMBER    membership predicate, using eql as test

(Member x l) equals the longest tail of l that begins with x, or else
nil if no such tail exists.

(Member x l) is provably the same in the ACL2 logic as (member-equal x
l).  It has a stronger guard than member-equal because uses eql to test
for whether x is equal to a given member of l.  Its guard requires that
l is a true list, and moreover, either (eqlablep x) or all members of l
are eqlablep.  See MEMBER-EQUAL and see MEMBER-EQ.

Member is a Common Lisp function.  See any Common Lisp documentation
for more information.  Since ACL2 functions cannot take keyword
arguments (though macros can), the ACL2 functions member-equal and
member-eq are defined to correspond to calls of the Common Lisp
function member whose keyword argument :test is equal or eq,
respectively.

MEMBER-EQ    membership predicate, using eq as test

(Member-eq x lst) equals the longest tail of lst that begins with x, or
else nil if no such tail exists.

(Member-eq x lst) is provably the same in the ACL2 logic as (member x
lst) and (member-equal x lst), but it has a stronger guard because it
uses eq for a more efficient test for whether x is equal to a given
member of lst.  Its guard requires that lst is a true list, and
moreover, either x is a symbol or lst is a list of symbols.  See
MEMBER-EQUAL and see MEMBER.

MEMBER-EQUAL    membership predicate

(Member-equal x lst) equals the longest tail of lst that begins with x,
or else nil if no such tail exists.

(Member-equal x lst) has a guard of (true-listp lst).  Member-equal has
the same functionality as the Common Lisp function member, except that
it uses the equal function to test whether x is the same as each
successive element of lst.  See MEMBER and see
MEMBER-EQ.

MIN    the smaller of two numbers

(Min x y) is the smaller of the numbers x and y.

The guard for min requires its arguments to be rational (real, in
ACL2(r)) numbers.

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

MINUSP    test whether a number is negative

(Minusp x) is true if and only if x < 0.

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

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

MOD    remainder using floor

     ACL2 !>(mod 14 3)
     2
     ACL2 !>(mod -14 3)
     1
     ACL2 !>(mod 14 -3)
     -1
     ACL2 !>(mod -14 -3)
     -2
     ACL2 !>(mod -15 -3)
     0
     ACL2 !>

(Mod i j) is that number k that (* j (floor i j)) added to k equals i.

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

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

MOD-EXPT    exponential function

(mod-expt r i m) is the result of raising the number r to the integer
power i and then taking the residue mod m.  That is, (mod-expt r i m)
is equal to (mod (expt r i) m).

The guard for (mod-expt r i m) is that r is a rational number and i is
an integer; if r is 0 then i is nonnegative; and m is a non-zero
rational number.

In some implementations (GCL Version 2.7.0 as of this writing), this
function is highly optimized when r and i are natural numbers, not both
zero, and m is a positive integer.  For other Lisp implementations,
consider using function mod-expt-fast, defined in the book
arithmetic-3/floor-mod/mod-expt-fast.lisp, which should still provide
significantly improved performance over this function.

MUST-BE-EQUAL    attach code for execution

The form (must-be-equal logic exec) evaluates to logic in the ACL2
logic but evaluates to exec in raw Lisp.  The point is to be able to
write one definition to reason about logically but another for
evaluation.  Please see MBE and see MBT for appropriate
macros to use, rather than calling must-be-equal directly, since it is
easy to commute the arguments of must-be-equal by accident.

The guard for (must-be-equal x y) is (equal x y).

MV    returning a multiple value

Mv is the mechanism provided by ACL2 for returning two or more values.
Logically, (mv x1 x2 ... xn) is the same as (list x1 x2 ... xn), a list
of the indicated values.  However, ACL2 avoids the cost of building
this list structure, with the cost that mv may only be used in a
certain style in definitions:  if a function ever returns using mv
(either directly, or by calling another function that returns a
multiple value), then this function must always return the same number
of values.

For more explanation of the multiple value mechanism, see
MV-LET.

ACL2 does not support the Common Lisp construct values, whose logical
meaning seems difficult to characterize.  Mv is the ACL2 analogue of
that construct.

MV-LET    calling multi-valued ACL2 functions

     Example Form:
     (mv-let (x y z)              ; local variables
             (mv 1 2 3)           ; multi-valued expression
             (declare (ignore y)) ; optional declarations
             (cons x z))          ; body

The form above binds the three "local variables," x, y, and z, to the
three results returned by the multi-valued expression and then
evaluates the body.  The result is '(1 . 3).  The second local, y, is
declared ignored.  The multi-valued expression can be any ACL2
expression that returns k results, where k is the number of local
variables listed.  Often however it is simply the application of a
k-valued function.  Mv-let is the standard way to invoke a multi-valued
function when the caller must manipulate the vector of results returned.

     General Form:
     (mv-let (var1 ... vark)
             term
             body)
     or
     (mv-let (var1 ... vark)
             term
             (declare ...) ... (declare ...)
             body)

where the vari are distinct variables, term is a term that returns k
results and mentions only variables bound in the environment containing
the mv-let expression, and body is a term mentioning only the vari and
variables bound in the environment containing the mv-let.  Each vari
must occur in body unless it is declared ignored or ignorable in one of
the optional declare forms, unless this requirement is turned off; see
SET-IGNORE-OK.  The value of the mv-let term is the result of
evaluating body in an environment in which the vari are bound, in
order, to the k results obtained by evaluating term in the environment
containing the mv-let.

Here is an extended example that illustrates both the definition of a
multi-valued function and the use of mv-let to call it.  Consider a
simple binary tree whose interior nodes are conses and whose leaves are
non-conses.  Suppose we often need to know the number, n, of interior
nodes of such a tree; the list, syms, of symbols that occur as leaves;
and the list, ints, of integers that occur as leaves.  (Observe that
there may be leaves that are neither symbols nor integers.)  Using a
multi-valued function we can collect all three results in one pass.

Here is the first of two definitions of the desired function.  This
definition is "primitive recursive" in that it has only one argument
and that argument is reduced in size on every recursion.

     (defun count-and-collect (x)

     ; We return three results, (mv n syms ints) as described above.

       (cond ((atom x)

     ; X is a leaf.  Thus, there are 0 interior nodes, and depending on
     ; whether x is a symbol, an integer, or something else, we return
     ; the list containing x in as the appropriate result.

              (cond ((symbolp x) (mv 0 (list x) nil))
                    ((integerp x)(mv 0 nil      (list x)))
                    (t           (mv 0 nil      nil))))
             (t

     ; X is an interior node.  First we process the car, binding n1, syms1, and
     ; ints1 to the answers.

                (mv-let (n1 syms1 ints1)
                        (count-and-collect (car x))

     ; Next we process the cdr, binding n2, syms2, and ints2.

                        (mv-let (n2 syms2 ints2)
                                (count-and-collect (car x))

     ; Finally, we compute the answer for x from those obtained for its car
     ; and cdr, remembering to increment the node count by one for x itself.

                                (mv (1+ (+ n1 n2))
                                    (append syms1 syms2)
                                    (append ints1 ints2)))))))

This use of a multiple value to "do several things at once" is very
common in ACL2.  However, the function above is inefficient because it
appends syms1 to syms2 and ints1 to ints2, copying the list structures
of syms1 and ints1 in the process.  By adding "accumulators" to the
function, we can make the code more efficient.

     (defun count-and-collect1 (x n syms ints)
       (cond ((atom x)
              (cond ((symbolp x) (mv n (cons x syms) ints))
                    ((integerp x) (mv n syms (cons x ints)))
                    (t (mv n syms ints))))
             (t (mv-let (n2 syms2 ints2)
                        (count-and-collect1 (cdr x) (1+ n) syms ints)
                        (count-and-collect1 (car x) n2 syms2 ints2)))))

We claim that (count-and-collect x) returns the same triple of results
as (count-and-collect1 x 0 nil nil).  The reader is urged to study this
claim until convinced that it is true and that the latter method of
computing the results is more efficient.  One might try proving the
theorem

     (defthm count-and-collect-theorem
       (equal (count-and-collect1 x 0 nil nil) (count-and-collect x))).

Hint:  the inductive proof requires attacking a more general theorem.

ACL2 does not support the Common Lisp construct multiple-value-bind,
whose logical meaning seems difficult to characterize.  Mv-let is the
ACL2 analogue of that construct.

MV-LIST    converting multiple-valued result to a single-valued list

     Example Forms:
     ; Returns the list (3 4):
     (mv-list 2 (mv 3 4))

     ; Returns a list containing the three values returned by var-fn-count:
     (mv-list 3 (var-fn-count '(cons (binary-+ x y) z) nil))

     General form:
     (mv-list n term)

Logically, (mv-list n term) is just term; that is, in the logic mv-list
simply returns its second argument.  However, the evaluation of a call
of mv-list on explicit values always results in a single value, which
is a (null-terminated) list.  For evaluation, the term n above (the
first argument to an mv-list call) must "essentially" (see below) be an
integer not less than 2, where that integer is the number of values
returned by the evaluation of term (the second argument to that mv-list
call).

We say "essentially" above because it suffices that the translation of
n to a term (see TRANS) be of the form (quote k), where k is an
integer greater than 1.  So for example, if term above returns three
values, then n can be the expression 3, or (quote 3), or even (mac 3)
if mac is a macro defined by (defmacro mac (x) x).  But n cannot be (+
1 2), because even though that expression evaluates to 3, nevertheless
it translates to (binary-+ '1 '2), not to (quote 3).

Mv-list is the ACL2 analogue of the Common Lisp construct
multiple-value-list.

MV-NTH    the mv-nth element (zero-based) of a list

(Mv-nth n l) is the nth element of l, zero-based.  If n is greater than
or equal to the length of l, then mv-nth returns nil.

(Mv-nth n l) has a guard that n is a non-negative integer and l is a
true-listp.

Mv-nth is equivalent to the Common Lisp function nth, but is used by
ACL2 to access the nth value returned by a multiply valued expression.
For an example of the use of mv-nth, try

     ACL2 !>:trans1 (mv-let (erp val state)
                            (read-object ch state)
                            (value (list erp val)))

NATP    a recognizer for the natural numbers

The natural numbers is the set of all non-negative integers,
{0,1,2,3,...}.  Natp returns t if and only its argument is a   natural
number, and nil otherwise.  We recommend the file
books/arithmetic/natp-posp.lisp as a book for reasoning about posp
and natp.  This book is included in books/arithmetic/top and
books/arithmetic/top-with-meta.

NFIX    coerce to a natural number

Nfix simply returns any natural number argument unchanged, returning 0
on an argument that is not a natural number.  Also see IFIX,
see RFIX, see REALFIX, and see FIX for
analogous functions that coerce to an integer, a rational number, a
real, and a number, respectively.

Nfix has a guard of t.

NINTH    ninth member of the list

See any Common Lisp documentation for details.

NO-DUPLICATESP    check for duplicates in a list (using eql for equality)

(no-duplicatesp l) is true if and only if no member of l occurs twice
in l.

(no-duplicatesp l) has a guard of (eqlable-listp l).  Membership is
tested using member, hence using eql as the test.

NO-DUPLICATESP-EQUAL    check for duplicates in a list (using equal for equality)

(no-duplicatesp-equal l) is true if and only if no member of l occurs
twice in l.

(no-duplicatesp-equal l) has a guard of (true-listp l).  Membership is
tested using member-equal, hence using equal as the test.

NONNEGATIVE-INTEGER-QUOTIENT    natural number division function

     Example Forms:
     (nonnegative-integer-quotient 14 3) ; equals 4
     (nonnegative-integer-quotient 15 3) ; equals 5

(nonnegative-integer-quotient i j) returns the integer quotient of the
integers i and (non-zero) j, i.e., the largest k such that (* j k) is
less than or equal to i.  Also see FLOOR, see CEILING
and see TRUNCATE, which are derived from this function and
apply to rational numbers.

The guard of (nonnegative-integer-quotient i j) requires that i is a
nonnegative integer and j is a positive integer.

NOT    logical negation

Not is the ACL2 negation function.  The negation of nil is t and the
negation of anything else is nil.

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

NTH    the nth element (zero-based) of a list

(Nth n l) is the nth element of l, zero-based.  If n is greater than or
equal to the length of l, then nth returns nil.

(Nth n l) has a guard that n is a non-negative integer and l is a
true-listp.

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

NTHCDR    final segment of a list

(Nthcdr n l) removes the first n elements from the list l.

The following is a theorem.

     (implies (and (integerp n)
                   (<= 0 n)
                   (true-listp l))
              (equal (length (nthcdr n l))
                     (if (<= n (length l))
                         (- (length l) n)
                       0)))

For related functions, see TAKE and see BUTLAST.

The guard of (nthcdr n l) requires that n is a nonnegative integer and
l is a true list.

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

NULL    recognizer for the empty list

Null is the function that checks whether its argument is nil.  For
recursive definitions it is often preferable to test for the end of a
list using endp instead of null; see ENDP.

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

NUMERATOR    dividend of a ratio in lowest terms

Completion Axiom:

     (equal (numerator x)
            (if (rationalp x)
                (numerator x)
              0))

Guard for (numerator x):

     (rationalp x)

O-FINP    recognizes if an ordinal is finite

We introduce the function o-finp which returns t for any ordinal that
is finite, else nil.  This function is equivalent to the function atom,
and is introduced so that we can disable its definition when dealing
with ordinals (also see MAKE-ORD).

O-FIRST-COEFF    returns the first coefficient of an ordinal

An ACL2 ordinal is either a natural number or, for an infinite ordinal,
a list whose elements are exponent-coefficient pairs (see O-P).
In the latter case, this function returns the cdr of the first pair in
the list.  In the case of a natural number, this function returns the
ordinal itself (since a natural number, n, can be thought of as (w^0)n).

For the corresponding exponent, see O-FIRST-EXPT.

O-FIRST-EXPT    the first exponent of an ordinal

An ACL2 ordinal is either a natural number or, for an infinite ordinal,
a list whose elements are exponent-coefficient pairs (see O-P).
In the latter case, this function returns the car of the first pair in
the list.  In the case of a natural number, the value returned is 0
(since a natural number, n, can be thought of as (w^0)n).

For the corresponding coefficient, see O-FIRST-COEFF.

O-INFP    recognizes if an ordinal is infinite

O-infp is a macro.  (O-infp x) opens up to (not (o-finp x)) (see
O-FINP).

O-P    a recognizer for the ordinals up to epsilon-0

Using the nonnegative integers and lists we can represent the ordinals
up to epsilon-0. The ordinal representation used in ACL2 has changed as
of Version_2.8 from that of Nqthm-1992, courtesy of Pete Manolios and
Daron Vroon; additional discussion may be found in "Ordinal Arithmetic
in ACL2", proceedings of ACL2 Workshop 2003,
`http://www.cs.utexas.edu/users/moore/acl2/workshop-2003/'.  Previously,
ACL2's notion of ordinal was very similar to the development given in
"New Version of the Consistency Proof for Elementary Number Theory" in
The Collected Papers of Gerhard Gentzen, ed. M.E. Szabo, North-Holland
Publishing Company, Amsterdam, 1969, pp 132-213.

The following essay is intended to provide intuition about ordinals.
The truth, of course, lies simply in the ACL2 definitions of o-p and o<.

Very intuitively, think of each non-zero natural number as by being
denoted by a series of the appropriate number of strokes, i.e.,

     0             0
     1             |
     2             ||
     3             |||
     4             ||||
     ...           ...

Then "omega," here written as w, is the ordinal that might be written as

     w             |||||...,

i.e., an infinite number of strokes.  Addition here is just
concatenation.  Observe that adding one to the front of w in the
picture above produces w again, which gives rise to a standard
definition of w:  w is the least ordinal such that adding another
stroke at the beginning does not change the ordinal.

We denote by w+w or w*2 the "doubly infinite" sequence that we might
write as follows.

     w*2           |||||... |||||...

One way to think of w*2 is that it is obtained by replacing each stroke
in 2 (||) by w.  Thus, one can imagine w*3, w*4, etc., which leads
ultimately to the idea of "w*w," the ordinal obtained by replacing each
stroke in w by w.  This is also written as "omega squared" or w^2, or:

      2
     w             |||||... |||||... |||||... |||||... |||||... ...

We can analogously construct w^3 by replacing each stroke in w by w^2
(which, it turns out, is the same as replacing each stroke in w^2 by
w).  That is, we can construct w^3 as w copies of w^2,

      3              2       2       2       2
     w              w  ...  w  ...  w  ...  w ... ...

Then we can construct w^4 as w copies of w^3, w^5 as w copies of w^4,
etc., ultimately suggesting w^w.  We can then stack omegas, i.e.,
(w^w)^w etc.  Consider the "limit" of all of those stacks, which we
might display as follows.

            .
           .
          .
         w
        w
       w
      w
     w

That is epsilon-0.

Below we begin listing some ordinals up to epsilon-0; the reader can
fill in the gaps at his or her leisure.  We show in the left column the
conventional notation, using w as "omega," and in the right column the
ACL2 object representing the corresponding ordinal.

       ordinal            ACL2 representation

       0                  0
       1                  1
       2                  2
       3                  3
       ...                ...
       w                 '((1 . 1) . 0)
       w+1               '((1 . 1) . 1)
       w+2               '((1 . 1) . 2)
       ...                ...
       w*2               '((1 . 2) . 0)
       (w*2)+1           '((1 . 2) . 1)
       ...                ...
       w*3               '((1 . 3) . 0)
       (w*3)+1           '((1 . 3) . 1)
       ...                ...

        2
       w                 '((2 . 1) . 0)
       ...                ...

        2
       w +w*4+3          '((2 . 1) (1 . 4) . 3)
       ...                ...

        3
       w                 '((3 . 1) . 0)
       ...                ...

        w
       w                 '((((1 . 1) . 0) . 1) . 0)
       ...                ...

        w  99
       w +w  +w4+3       '((((1 . 1) . 0) . 1) (99 . 1) (1 . 4) . 3)
       ...                ...

         2
        w
       w                 '((((2 . 1) . 0) . 1) . 0)

       ...                ...

         w
        w
       w                 '((((((1 . 1) . 0) . 1) . 0) . 1) . 0)
       ...               ...

Observe that the sequence of o-ps starts with the natural numbers
(which are recognized by natp). This is convenient because it means
that if a term, such as a measure expression for justifying a recursive
function (see O<) must produce an o-p, it suffices for it to
produce a natural number.

The ordinals listed above are listed in ascending order.  This is the
ordering tested by o<.

The "epsilon-0 ordinals" of ACL2 are recognized by the recursively
defined function o-p.  The base case of the recursion tells us that
natural numbers are epsilon-0 ordinals.  Otherwise, an epsilon-0
ordinal is a list of cons pairs whose final cdr is a natural number,
((a1 . x1) (a2 . x2) ... (an . xn) . p).  This corresponds to the
ordinal (w^a1)x1 + (w^a2)x2 + ... + (w^an)xn + p.  Each ai is an
ordinal in the ACL2 representation that is not equal to 0.  The
sequence of the ai's is strictly decreasing (as defined by o<). Each xi
is a positive integer (as recognized by posp).

Note that infinite ordinals should generally be created using the
ordinal constructor, make-ord, rather than cons. The functions
o-first-expt, o-first-coeff, and o-rst are ordinals destructors.
Finally, the function o-finp and the macro o-infp tell whether an
ordinal is finite or infinite, respectively.

The function o< compares two epsilon-0 ordinals, x and y.  If both are
integers, (o< x y) is just x<y.  If one is an integer and the other is
a cons, the integer is the smaller.  Otherwise, o< recursively compares
the o-first-expts of the ordinals to determine which is smaller.  If
they are the same, the o-first-coeffs of the ordinals are compared.  If
they are equal, the o-rsts of the ordinals are recursively compared.

Fundamental to ACL2 is the fact that o< is well-founded on epsilon-0
ordinals.  That is, there is no "infinitely descending chain" of such
ordinals.  See PROOF-OF-WELL-FOUNDEDNESS.

O-RST    returns the rest of an infinite ordinal

An ACL2 infinite ordinal is a list whose elements are
exponent-coefficient pairs (see O-P and see O-INFP).
The first exponent and first coefficient of an ordinal can be obtained
by using o-first-expt and o-first-coeff respectively.  To obtain the
rest of the ordinal (for recursive analysis), use the o-rst function.
It returns the rest of the ordinal after the first exponent and
coefficient are removed.

O<    the well-founded less-than relation on ordinals up to epsilon-0

If x and y are both o-ps (see O-P) then (o< x y) is true iff x
is strictly less than y.  o< is well-founded on the o-ps.  When x and y
are both nonnegative integers, o< is just the familiar "less than"
relation (<).

o< plays a key role in the formal underpinnings of the ACL2 logic.  In
order for a recursive definition to be admissible it must be proved to
"terminate."  By terminate we mean that the arguments to the function
"get smaller" as the function recurses and this sense of size
comparison must be such that there is no "infinitely descending"
sequence of ever smaller arguments.  That is, the relation used to
compare successive arguments must be well-founded on the domain being
measured.

The most basic way ACL2 provides to prove termination requires the user
to supply (perhaps implicitly) a mapping of the argument tuples into
the ordinals with some "measure" expression in such a way that the
measures of the successive argument tuples produced by recursion
decrease according to the relation o<.  The validity of this method
rests on the well-foundedness of o< on the o-ps.

Without loss of generality, suppose the definition in question
introduces the function f, with one formal parameter x (which might be
a list of objects).  Then we require that there exist a measure
expression, (m x), that always produces an o-p.  Furthermore, consider
any recursive call, (f (d x)), in the body of the definition.  Let hyps
be the conjunction of terms, each of which is either the test of an if
in the body or else the negation of such a test, describing the path
through the body to the recursive call in question.  Then it must be a
theorem that

       (IMPLIES hyps (O< (m (d x)) (m x))).

When we say o< is "well-founded" on the o-ps we mean that there is no
infinite sequence of o-ps such that each is smaller than its
predecessor in the sequence.  Thus, the theorems that must be proved
about f when it is introduced establish that it cannot recur forever
because each time a recursive call is taken (m x) gets smaller.  From
this, and the syntactic restrictions on definitions, it can be shown
(as on page 44 in "A Computational Logic", Boyer and Moore, Academic
Press, 1979) that there exists a function satisfying the definition;
intuitively, the value assigned to any given x by the alleged function
is that computed by a sufficiently large machine.  Hence, the logic is
consistent if the axiom defining f is added.

See O-P for a discussion of the ordinals and how to compare two
ordinals.

The definitional principle permits the use of relations other than o<
but they must first be proved to be well-founded on some domain.  See
WELL-FOUNDED-RELATION.  Roughly put, alternative relations are
shown well-founded by providing an order-preserving mapping from their
domain into the ordinals.  See DEFUN for details on how to
specify which well-founded relation is to be used.

O<=    the less-than-or-equal relation for the ordinals

o<= is a macro and (o<= x y) expands to (not (o< y x)).  See O<.

O>    the greater-than relation for the ordinals

O> is a macro and (o> x y) expands to (o< y x).  See O<.

O>=    the greater-than-or-equal relation for the ordinals

O>= is a macro and (o>= x y) expands to (not (o< x y)).  See O<.

ODDP    test whether an integer is odd

(oddp x) is true if and only if x is odd, i.e., not even in the sense
of evenp.

The guard for oddp requires its argument to be an integer.

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

OPEN-INPUT-CHANNEL    See IO.

OPEN-INPUT-CHANNEL-P    See IO.

OPEN-OUTPUT-CHANNEL    See IO.

OPEN-OUTPUT-CHANNEL-P    See IO.

OPTIMIZE    See DECLARE.

OR    disjunction

Or is the macro for disjunctions.  Or takes any number of arguments and
returns the first that is non-nil, or nil if there is no non-nil
element.

In the ACL2 logic, the macroexpansion of (or x y) is an IF term that
appears to cause x to be evaluated twice:

     ACL2 !>:trans (or x y)

     (IF X X Y)

     => *

     ACL2 !>

If x were replaced by an expression whose evaluation takes a long time,
then such an expansion would be ineffecient.  However, don't be fooled:
you can expect Common Lisp implementations to avoid this problem, say by
generating a new variable, for example:

     ACL2 !>:q ; Exit the ACL2 loop and go into raw Common Lisp

     Exiting the ACL2 read-eval-print loop.  To re-enter, execute (LP).
     ACL2>(macroexpand '(or x y))

     (LET ((#:G5374 X)) (IF #:G5374 #:G5374 Y))
     T

     ACL2>

Or is a Common Lisp macro.  See any Common Lisp documentation for more
information.

PAIRLIS    See 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
PAIRLIS$.

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.

PEEK-CHAR$    See IO.

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

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.

POSITION    position of an item in a string or a list, using eql as test

(Position item seq) is the least index (zero-based) of the element item
in the string or list seq, if in fact item is an element of seq.
Otherwise (position item seq) is nil.

(Position item lst) is provably the same in the ACL2 logic as
(position-equal item lst).  It has a stronger guard than position-equal
because uses eql to test equality of item with members of lst.  Its
guard requires that either lst is a string, or else lst is a true list
such that either (eqlablep item) or all members of lst are eqlablep.
See POSITION-EQUAL and see POSITION-EQ.

Position is a Common Lisp function.  See any Common Lisp documentation
for more information.  Since ACL2 functions cannot take keyword
arguments (though macros can), the ACL2 functions position-equal and
position-eq are defined to correspond to calls of the Common Lisp
function position whose keyword argument :test is equal or eq,
respectively.

POSITION-EQ    position of an item in a string or a list, using eq as test

(Position-eq item seq) is the least index (zero-based) of the element
item in the list seq, if in fact item is an element of seq.  Otherwise
(position-eq item seq) is nil.

(Position-eq item lst) is provably the same in the ACL2 logic as
(position item lst) and (position-equal item lst) when lst is a true
list, but it has a stronger guard because it uses eq for a more
efficient test for whether item is equal to a given member of lst.  Its
guard requires that lst is a true list, and moreover, either item is a
symbol or lst is a list of symbols.  See POSITION-EQUAL and see
POSITION, which unlike position-eq have guards that allow the
second argument to be a string.

POSITION-EQUAL    position of an item in a string or a list

(Position item seq) is the least index (zero-based) of the element item
in the string or list seq, if in fact item is an element of seq.
Otherwise (position item seq) is nil.

(Position-equal item lst) has a guard of (true-listp lst).
Position-equal has the same functionality as the Common Lisp function
position, except that it uses the equal function to test whether item
is the same as each successive element of lst.  See POSITION
and see POSITION-EQ.

POSP    a recognizer for the positive integers

(posp x) is logically equivalent to (not (zp x)) (see ZP) and
also   to (and (natp x) (not (equal x 0))).  We recommend the file
books/ordinals/natp-posp as a book for reasoning about posp and   natp.
This book is included in books/arithmetic/top and
books/arithmetic/top-with-meta.

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

PRINT-OBJECT$    See IO.

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

See HARD-ERROR, see ILLEGAL, and see CW for
examples of functions to call in the first argument of prog2$.

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

PROOFS-CO    the proofs character output channel

Proofs-co is an ld special (see 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
*STANDARD-CO*).

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 TRUE-LISTP.

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

(Put-assoc-eq 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 of (put-assoc-eq name val alist) requires that alist is an
alistp, and moreover, either name is a symbol or alist is a
symbol-alistp.

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

(Put-assoc-eql 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 of (put-assoc-eql name val alist) requires that alist is an
alistp, and moreover, either name is eqlablep or alist is an
eqlable-alistp.

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

(Put-assoc-equal 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.

The guard of (put-assoc-equal name val alist) requires that alist is an
alistp.

PUTPROP    update fast property lists

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

See 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.

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$.

RASSOC    look up value in association list, using eql as test

(Rassoc x alist) is 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 ASSOC.

The guard of rassoc requires its second argument to be an alist, and in
addition, that either its first argument is eqlablep or else all second
components of pairs belonging to the second argument are eqlablep.  See
EQLABLEP.

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

RASSOC-EQ    look up value in association list, using eq as test

(Rassoc-eq x alist) is similar to (assoc-eq x alist), the difference
being that it looks for the first pair in the given alist whose cdr,
rather than car, is eq to x.  See ASSOC.

The guard of rassoc-eq requires its second argument to be an alist, and
in addition, that either its first argument is a symbolp or else all
second components of pairs belonging to the second argument are
symbolps.

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

RASSOC-EQUAL    look up value in association list, using equal as test

(Rassoc-equal x alist) is similar to (assoc-equal x alist), the
difference being that it looks for the first pair in the given alist
whose cdr, rather than car, is equal to x.  See ASSOC-EQUAL.

The guard of rassoc-equal requires its second argument to be an alist.
See RASSOC and see RASSOC-EQ.

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.

RATIONALP    recognizer for rational numbers (ratios and integers)

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

READ-BYTE$    See IO.

READ-CHAR$    See IO.

READ-OBJECT    See IO.

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 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 books
in the ACL2 distribution use real/rationalp so that these books will be
suitable for ACL2(r) as well.

REALFIX    coerce to a real number

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

Realfix has a guard of t.

REALPART    real part of a complex number

Completion Axiom:

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

Guard for (realpart x):

     (acl2-numberp x)

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

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.

REMOVE    remove all occurrences, testing using eql

(remove x l) is l if x is not a member of l, else is the result of
removing all occurrences of x from l.

The guard for (remove x l) requires l to be a true list and moreover,
either x is eqlablep or all elements of l are eqlablep.

Remove is a Common Lisp function.  See any Common Lisp documentation
for more information.  Note that we do not allow keyword arguments
(such as test) in ACL2 functions, in particular, in remove.

Also see REMOVE1, see REMOVE-EQUAL, and see
REMOVE-EQ.

REMOVE-DUPLICATES    remove duplicates from a string or (using eql) a list

Remove-duplicates returns the result of deleting duplicate elements
from the beginning of the given string or true list, i.e., leaving the
last element in place.  For example,

     (remove-duplicates '(1 2 3 2 4))

is equal to '(1 3 2 4).

The guard for Remove-duplicates requires that its argument is a string
or a true-list of eqlablep objects.  It uses the function eql to test
for equality between elements of its argument.

Remove-duplicates is a Common Lisp function.  See any Common Lisp
documentation for more information.  Note that we do not allow keyword
arguments (such as test) in ACL2 functions, in particular, in
remove-duplicates.  But see REMOVE-DUPLICATES-EQUAL, which is
similar but uses the function equal to test for duplicate elements.

REMOVE-DUPLICATES-EQUAL    remove duplicates from a list

Remove-duplicates-equal is the same as remove-duplicates, except that
its argument must be a true list (not a string), and equal is used to
check membership rather than eql.  See REMOVE-DUPLICATES.

The guard for Remove-duplicates-equal requires that its argument is a
true list.  Note that unlike remove-duplicates, it does not allow
string arguments.

REMOVE-EQ    remove all occurrences, testing using eq

(remove-eq x l) is l if x is not a member of l as tested with
member-eq, else is the result of removing all occurrences of x from l.

The guard for (remove-eq x l) requires l to be a true list and
moreover, either x is a symbolp or all elements of l are symbols (i.e.,
l is a symbol-listp).

Also see REMOVE1-EQ, see REMOVE, and see
REMOVE-EQUAL.

REMOVE-EQUAL    remove all occurrences, testing using equal

(remove-equal x l) is l if x is not a member of l as tested with
member-equal, else is the result of removing all occurrences of x from
l.

The guard for (remove-equal x l) requires l to be a true list.

Also see REMOVE1-EQUAL, see REMOVE, and see
REMOVE-EQ.

REMOVE1    remove first occurrences, testing using eql

(remove1 x l) is l if x is not a member of l, else is the result of
removing the first occurrence of x from l.

The guard for (remove1 x l) requires l to be a true list and moreover,
either x is eqlablep or all elements of l are eqlablep.

Also see REMOVE, see REMOVE1-EQUAL, and see
REMOVE1-EQ.

REMOVE1-EQ    remove first occurrences, testing using eq

(remove1-eq x l) is l if x is not a member of l as tested with
member-eq, else is the result of removing the first occurrences of x
from l.

The guard for (remove1-eq x l) requires l to be a true list and
moreover, either x is a symbolp or all elements of l are symbols (i.e.,
l is a symbol-listp).

Also see REMOVE-EQ, see REMOVE1, and see
REMOVE1-EQUAL.

REMOVE1-EQUAL    remove first occurrences, testing using equal

(remove1-equal x l) is l if x is not a member of l as tested with
member-equal, else is the result of removing the first occurrence of x
from l.

The guard for (remove1-equal x l) requires l to be a true list.

Also see REMOVE-EQUAL, see REMOVE1, and see
REMOVE1-EQ.

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.

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.

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.

RFIX    coerce to a rational number

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

Rfix has a guard of t.

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,

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

SECOND    second member of the list

See any Common Lisp documentation for details.

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

(Set-difference-eq x y) is logically equivalent to
set-difference-equal, except that the guard requires not only that the
two arguments are true-listps but also that at least one is a
symbol-listp.  Also see SET-DIFFERENCE-EQUAL.

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

(Set-difference-equal x y) equals a list whose members (see
MEMBER-EQUAL) contains the members of x that are not members of y.
More precisely, the resulting list is the same as one gets by deleting
the members of y from x, leaving the remaining elements in the same
order as they had in x.

The guard for set-difference-equal requires both arguments to be true
lists.  Essentially, set-difference-equal has the same functionality as
the Common Lisp function set-difference, except that it uses the equal
function to test membership rather than eql.  However, we do not
include the function set-difference in ACL2, because the Common Lisp
language does not specify the order of the elements in the list that it
returns.

Also see SET-DIFFERENCE-EQ for a semantically equivalent
function that executes more efficiently on lists of symbols.

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
GETENV$), and returns nil.  Or, if this operation is not
implemented for the host Common Lisp, an error will occur.

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

SEVENTH    seventh member of the list

See any Common Lisp documentation for details.

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

SIXTH    sixth member of the list

See any Common Lisp documentation for details.

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
STANDARD-CHAR-P.

Standard-char-listp has a guard of t.

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.