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

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

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

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

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

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

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


File: acl2-doc-emacs.info,  Node: SPLITTER,  Next: SPLITTER-OUTPUT,  Prev: SPECIOUS-SIMPLIFICATION,  Up: MISCELLANEOUS

SPLITTER    reporting of rules whose application may have caused case splits

The application of a rule to a term may cause a goal to simplify to
more than one subgoal.  A rule with such an application is called a
"splitter".  Here, we explain the output produced for splitters when
proof output is enabled (see *note SET-INHIBIT-OUTPUT-LST::) and such
reporting is turned on (as it is by default) -- that is, when the value
of (splitter-output) is true.

See *note SET-SPLITTER-OUTPUT:: for how to turn off, or on, the
reporting of splitters.  Also see *note SET-CASE-SPLIT-LIMITATIONS::
for information on how to control case splits.

We begin by describing three types of splitters.

     if-intro: The rule application may have introduced a call of IF, in
     the sense discussed at the end below.

     case-split: For the application of a rule with hypothesis of the
     form (case-split <hyp>), <hyp> did not simplify to true or false.

     immed-forced: For the application of a rule with hypothesis of the
     form (force <hyp>), <hyp> did not simplify to true or false, where
     immediate-force-modep is enabled (see *note
     IMMEDIATE-FORCE-MODEP::).

These three annotations -- if-intro, case-split, and immed-forced --
may be used in proof output and summaries for describing rule
applications, as discussed below.  A fourth annotation, forced, maybe
also be used in proof output to indicate the application of a rule with
hypothesis of the form (force <hyp>) when <hyp> did not simplify to
true or false, where immediate-force-modep is disabled (see *note
IMMEDIATE-FORCE-MODEP::).  We don't consider such uses of force to be
splitters, because they do not cause case splits (though they do produce
goals to prove after lower-case "q.e.d." is printed); see *note FORCE::.

There are three kinds of output affected by splitters, illustrated in
turn below using examples.

     (a) During the proof, gag-mode off
     (b) During the proof, gag-mode on
     (c) Summary


Of course, (a) and (b) are skipped if proof output is inhibited, which
(c) is skipped if summary output is inhibited; see *note
SET-INHIBIT-OUTPUT-LST::.

(a) During the proof, gag-mode off

With gag-mode off (or when using :pso, :psof, or :psog) one normally
gets an English commentary.  The following output indicates that at
least one application of each rule F and G is of type if-intro, at
least one application of rules G and R1 are of type case-split, and at
least one application of rule R3 is of type immed-forced.  If
immediate-force-modep is off then "immed-forced" would be replaced by
"forced".

       This simplifies, using the :definitions F (if-intro), G (case-split and
       if-intro) and H and the :rewrite rules R1, R2 (case-split), and
       R3 (immed-forced), to the following two conjectures.

Note that any such printing of "forced" is done even if
(splitter-output) is false.  Such forcing indication is also made when
raw proof format is used -- see *note SET-RAW-PROOF-FORMAT:: -- but in
that case, no indication is made for splitters in the proof output.

(b) During the proof, gag-mode on

With gag-mode on the proof output is greatly abbreviated.  However,
"Splitter Notes" are printed so that even with gag-mode on, one can get
important information to help control large case splits, by disabling
splitter rules as appropriate.  These are printed at the point when a
goal splits into subgoals.  Here, for example, is the Splitter Note that
corresponds to the output shown in (a) above.  It shows the goal whose
simplification has produced a split into more than one subgoal, and it
shows how many subgoals have been created.

     Splitter note (see :DOC splitter) for Subgoal *1/2.2.1' (2 subgoals).
       case-split: ((:DEFINITION G) (:REWRITE R2))
       immed-forced: ((:REWRITE R3))
       if-intro: ((:DEFINITION G) (:DEFINITION F))

No such splitter notes are printed for the use of force (when
immediate-force-modep is off).

(c) Summary

Here is a possible summary corresponding to our running example.  In the
summary, "Splitter rules" is omitted if there are no splitter rules,
and a splitter type is only mentioned if there is at least one
corresponding splitter rule.

     Summary
     Form:  ( THM ...)
     Rules: ((:DEFINITION F)
             (:DEFINITION G)
             (:DEFINITION H)
             (:REWRITE R1)
             (:REWRITE R2)
             (:REWRITE R3))
     Splitter rules (see :DOC splitter):
       case-split: ((:DEFINITION G) (:REWRITE R2))
       immed-forced: ((:REWRITE R3))
       if-intro: ((:DEFINITION G) (:DEFINITION F))
     Time:  0.01 seconds (prove: 0.00, print: 0.00, other: 0.00)
     Prover steps counted:  145

No indication for "forced" is given for "Splitter rules".  (As
discussed earlier above, the forced hypotheses are not considered
relevant for determining splitter rule applications unless
immediate-force-modep is on.)

We conclude by giving the criteria for a rewrite or definition rule
application to be a splitter of type if-intro.

     o Reporting of splitter rules is on, i.e., the value of
     (splitter-output) is true.

     o At least two subgoals are created, even before considering
     subgoals generated by hypotheses that are calls of case-split or
     force.

     o The term to which the rule is applied is at the top level,
     rather than being encountered when trying to establish the
     hypothesis of a rule.

     o The rule is a rewrite rule, a definition rule, or a meta rule.

     o There is a call of the function symbol IF in the right-hand side
     of the rewrite rule; or, in the case of a definition rule, in the
     body of the definition; or, in the case of a meta rule, in the
     result of applying the metafunction.

     o There is a call of the function symbol IF in the result of
     rewriting: the right-hand side (for a rewrite rule), the
     definition body (for a definition rule), or the metafunction
     application (for a meta rule).


Any rule application meeting the above criteria will be considered a
splitter of type if-intro, even if the call does not actually cause a
case split.  For example, if you are proving (implies (hyp x) (conc x))
and rule R rewrites (hyp x) to (if (h1 x) (h2 x) nil), which is really
the term (and (h1 x) (h2 x)), then R may be labelled as a splitter
rule.  If you want to find the causes of case-splitting, the list of
if-intro splitters can help you narrow your search, but may include
irrelevant rules as well.

Finally, note that you may see splits not attributed to splitters.  We
believe that this will be uncommon during simplification, though it can
occur for example when a call of IF is in the body of a LET expression,
i.e., in a call of a LAMBDA expression.  But splits caused by other
processes, notably destructor elimination (see *note ELIM::), will
typically not be attributed to splitters.


File: acl2-doc-emacs.info,  Node: SPLITTER-OUTPUT,  Next: STOBJS,  Prev: SPLITTER,  Up: MISCELLANEOUS

SPLITTER-OUTPUT    status for reporting of splitter rules

See *note SPLITTER:: for a discussion of splitter rules.  See *note
SET-SPLITTER-OUTPUT:: for how to turn off, or on, the reporting of
splitter rules.  When splitter-output is off, because either prove
output is inhibited (see *note SET-INHIBIT-OUTPUT-LST::) or
(set-splitter-output nil) has been invoked, then the value of
(splitter-output) is nil.  Otherwise, such reporting is on and the
value is non-nil.


File: acl2-doc-emacs.info,  Node: STOBJS,  Next: SUBVERSIVE-INDUCTIONS,  Prev: SPLITTER-OUTPUT,  Up: MISCELLANEOUS

STOBJS    xargs keyword :STOBJS

See *note XARGS::.


File: acl2-doc-emacs.info,  Node: SUBVERSIVE-INDUCTIONS,  Next: SUBVERSIVE-RECURSIONS,  Prev: STOBJS,  Up: MISCELLANEOUS

SUBVERSIVE-INDUCTIONS    why we restrict encapsulated recursive functions

See *note SUBVERSIVE-RECURSIONS::.


File: acl2-doc-emacs.info,  Node: SUBVERSIVE-RECURSIONS,  Next: SYNTAX,  Prev: SUBVERSIVE-INDUCTIONS,  Up: MISCELLANEOUS

SUBVERSIVE-RECURSIONS    why we restrict encapsulated recursive functions

Subtleties arise when one of the "constrained" functions, f, introduced
in the signature of an encapsulate event, is involved in the
termination argument for a non-local recursively defined function, g, in
that encapsulate.  During the processing of the encapsulated events, f
is locally defined to be some witness function, f'.  Properties of f'
are explicitly proved and exported from the encapsulate as the
constraints on the undefined function f.  But if f is used in a
recursive g defined within the encapsulate, then the termination proof
for g may use properties of f' -- the witness -- that are not
explicitly set forth in the constraints stated for f.

Such recursive g are said be "subversive" because if naively treated
they give rise to unsound induction schemes or (via functional
instantiation) recurrence equations that are impossible to satisfy.  We
illustrate what could go wrong below.

Subversive recursions are not banned outright.  Instead, they are
treated as part of the constraint.  That is, in the case above, the
definitional equation for g becomes one of the constraints on f.  This
is generally a severe restriction on future functional instantiations
of f.  In addition, ACL2 removes from its knowledge of g any
suggestions about legal inductions to "unwind" its recursion.

What should you do?  Often, the simplest response is to move the
offending recursive definition, e.g., g, out of the encapsulate.  That
is, introduce f by constraint and then define g as an "independent"
event.  You may need to constrain "additional" properties of f in order
to admit g, e.g., constrain it to reduce some ordinal measure.  However,
by separating the introduction of f from the admission of g you will
clearly identify the necessary constraints on f, functional
instantiations of f will be simpler, and g will be a useful function
which suggests inductions to the theorem prover.

Note that the functions introduced in the signature should not even
occur ancestrally in the termination proofs for non-local recursive
functions in the encapsulate.  That is, the constrained functions of an
encapsulate should not be reachable in the dependency graph of the
functions used in the termination arguments of recursive functions in
encapsulate.  If they are reachable, their definitions become part of
the constraints.

The following event illustrates the problem posed by subversive
recursions.

     (encapsulate (((f *) => *))
       (local (defun f (x) (cdr x)))
       (defun g (x)
         (if (consp x) (not (g (f x))) t)))

Suppose, contrary to how ACL2 works, that the encapsulate above were to
introduce no constraints on f on the bogus grounds that the only use of
f in the encapsulate is in an admissible function.  We discuss the
plausibility of this bogus argument in a moment.

Then it would be possible to prove the theorem:

     (defthm f-not-identity
       (not (equal (f '(a . b)) '(a . b)))
       :rule-classes nil
       :hints (("Goal" :use (:instance g (x '(a . b))))))

simply by observing that if (f '(a . b)) were '(a . b), then (g '(a .
b)) would be (not (g '(a . b))), which is impossible.

But then we could functionally instantiate f-not-identity, replacing f
by the identity function, to prove nil!  This is bad.

     (defthm bad
       nil
       :rule-classes nil
       :hints
       (("Goal" :use (:functional-instance f-not-identity (f identity)))))

This sequence of events was legal in versions of ACL2 prior to Version
1.5.  When we realized the problem we took steps to make it illegal.
However, our steps were insufficient and it was possible to sneak in a
subversive function (via mutual recursion) as late as Version 2.3.

We now turn to the plausibility of the bogus argument above.  Why might
one even be tempted to think that the definition of g above poses no
constraint on f?  Here is a very similar encapsulate.

     (encapsulate (((f *) => *))
       (local (defun f (x) (cdr x)))
       (defun map (x)
         (if (consp x)
             (cons (f x) (map (cdr x)))
           nil)))

Here map plays the role of g above.  Like g, map calls the constrained
function f.  But map truly does not constrain f.  In particular, the
definition of map could be moved "out" of the encapsulate so that map
is introduced afterwards.  The difference between map and g is that the
constrained function plays no role in the termination argument for the
one but does for the other.

As a "user-friendly" gesture, ACL2 implicitly moves map-like functions
out of encapsulations; logically speaking, they are introduced after the
encapsulation.  This simplifies the constraint.  When the constraint
cannot be thus simplfied the user is advised, via the "infected"
warning, to phrase the encapsulation in the simplest way possible.

The lingering bug between Versions 1.5 and 2.3 mentioned above was due
to our failure to detect the g-like nature of some functions when they
were defined in mutually recursively cliques with other functions.  The
singly recursive case was recognized.  The bug arose because our
detection "algorithm" was based on the "suggested inductions" left
behind by successful definitions.  We failed to recall that
mutually-recursive definitions do not, as of this writing, make any
suggestions about inductions and so did not leave any traces of their
subversive natures.

We conclude by elaborating on the criterion "involved in the termination
argument" mentioned at the outset.  Suppose that function f is
recursively defined in an encapsulate, where the body of f has no
"ancestor" among the functions introduced in the signature of that
encapsulate, i.e.: the body contains no call of a signature function,
no call of a function whose body calls a signature function, and so on.
Then ACL2 treats f as though it is defined in front of that encapsulate
form; so f is not constrained by the encapsulate, and its definition is
hence certainly not subversive in the sense discussed above.  But
suppose to the contrary that some function introduced in the signature
is an ancestor of the body of f.  Then the definition of f is
subversive if moreover, its termination proof obligation has an
ancestor among the signature functions.  Now, that proof obligation
involves terms from the first argument of selected calls of IF, as well
as recursive calls; for a detailed discussion, see *note
RULER-EXTENDERS::.  The important point here is that for the recursive
calls, only the arguments in "measured" positions are relevant to the
termination proof obligation.  Consider the following example.

       (encapsulate
        (((h *) => *))
        (local (defun h (n) n))
        (defun f (i n)
          (if (zp i)
              n
            (f (1- i) (h n)))))

ACL2 heuristically picks the measure (acl2-count i) for the definition
of f; thus, i is the only "measured formal" of f.  Since i is the first
formal of f, then for the recursive call of f, only the first argument
contributes to the termination proof obligation: in this case, (1- i)
but not (h n).  Thus, even though h is a signature function, the
definition of f is not considered to be subversive; an induction scheme
is thus stored for f.  (This restriction to measured formal positions
of recursive calls, for determining subversive definitions, is new in
Version_3.5 of ACL2.)


File: acl2-doc-emacs.info,  Node: SYNTAX,  Next: SYNTAXP,  Prev: SUBVERSIVE-RECURSIONS,  Up: MISCELLANEOUS

SYNTAX    the syntax of ACL2 is that of Common Lisp

For the details of ACL2 syntax, see CLTL.  For examples of ACL2 syntax,
use :pe to print some of the ACL2 system code.  For example:

     :pe assoc-equal
     :pe dumb-occur
     :pe var-fn-count
     :pe add-linear-variable-to-alist

There is no comprehensive description of the ACL2 syntax yet, except
that found in CLTL.  Also see *note TERM::.


File: acl2-doc-emacs.info,  Node: SYNTAXP,  Next: TERM,  Prev: SYNTAX,  Up: MISCELLANEOUS

SYNTAXP    attach a heuristic filter on a rule

A calls of syntaxp in the hypothesis of a :rewrite, :definition, or
:linear rule is treated specially, as described below.  Similar
treatment is given to the evaluation of a :meta rule's hypothesis
function call.

For example, consider the :rewrite rule created from the following
formula.

     Example:
     (IMPLIES (SYNTAXP (NOT (AND (CONSP X)
                                 (EQ (CAR X) 'NORM))))
              (EQUAL (LXD X)
                     (LXD (NORM X)))).

The syntaxp hypothesis in this rule will allow the rule to be applied to
(lxd (trn a b)) but will not allow it to be applied to (lxd (norm a)).

* Menu:

* SYNTAXP-EXAMPLES:: examples pertaining to syntaxp hypotheses

     General Form:
     (SYNTAXP test)

Syntaxp always returns t and so may be added as a vacuous hypothesis.
However, when relieving the hypothesis, the test "inside" the syntaxp
form is actually treated as a meta-level proposition about the proposed
instantiation of the rule's variables and that proposition must
evaluate to true (non-nil) to "establish" the syntaxp hypothesis.

Note that the test of a syntaxp hypothesis does not, in general, deal
with the meaning or semantics or values of the terms, but rather with
their syntactic forms.  In the example above, the syntaxp hypothesis
allows the rule to be applied to every target of the form (lxd u),
provided u is not of the form (norm v).  Observe that without this
syntactic restriction the rule above could loop, producing a sequence
of increasingly complex targets (lxd a), (lxd (norm a)), (lxd (norm
(norm a))), etc.  An intuitive reading of the rule might be "norm the
argument of lxd unless it has already been normed."

Note also that a syntaxp hypothesis deals with the syntactic form used
internally by ACL2, rather than that seen by the user.  In some cases
these are the same, but there can be subtle differences with which the
writer of a syntaxp hypothesis must be aware.  You can use :trans to
display this internal representation.

There are two types of syntaxp hypotheses.  The simpler type may be a
hypothesis of a :rewrite, :definition, or :linear rule provided test
contains at least one variable but no free variables (see *note
FREE-VARIABLES::).  In particular, test may not use stobjs; any stobj
name will be treated as an ordinary variable.  The case of :meta rules
is similar to the above, except that it applies to the result of
applying the hypothesis metafunction.  (Later below we will describe
the second type, an _extended_ syntaxp hypothesis, which may use state.)

We illustrate the use of simple syntaxp hypotheses by slightly
elaborating the example given above.  Consider a :rewrite rule:

     (IMPLIES (AND (RATIONALP X)
                   (SYNTAXP (NOT (AND (CONSP X)
                                      (EQ (CAR X) 'NORM)))))
              (EQUAL (LXD X)
                     (LXD (NORM X))))

How is this rule applied to (lxd (trn a b))?  First, we form a
substitution that instantiates the left-hand side of the conclusion of
the rule so that it is identical to the target term.  In the present
case, the substitution replaces x with (trn a b).

     (LXD X) ==> (LXD (trn a b)).

Then we backchain to establish the hypotheses, in order.  Ordinarily
this means that we instantiate each hypothesis with our substitution
and then attempt to rewrite the resulting instance to true.  Thus, in
order to relieve the first hypothesis above, we rewrite

     (RATIONALP (trn a b)).

If this rewrites to true, we continue.

Of course, many users are aware of some exceptions to this general
description of the way we relieve hypotheses.  For example, if a
hypothesis contains a "free-variable" -- one not bound by the current
substitution -- we attempt to extend the substitution by searching for
an instance of the hypothesis among known truths.  See *note
FREE-VARIABLES::.  Forced hypotheses are another exception to the
general rule of how hypotheses are relieved.

Hypotheses marked with syntaxp, as in (syntaxp test), are also
exceptions.  We instantiate such a hypothesis; but instead of rewriting
the instantiated instance, we evaluate the instantiated test.  More
precisely, we evaluate test in an environment in which its variable
symbols are bound to the quotations of the terms to which those
variables are bound in the instantiating substitution.  So in the case
in point, we (in essence) evaluate

     (NOT (AND (CONSP '(trn a b)) (EQ (CAR '(trn a b)) 'NORM))).

This clearly evaluates to t.  When a syntaxp test evaluates to true, we
consider the syntaxp hypothesis to have been established; this is sound
because logically (syntaxp test) is t regardless of test.  If the test
evaluates to nil (or fails to evaluate because of guard violations) we
act as though we cannot establish the hypothesis and abandon the
attempt to apply the rule; it is always sound to give up.

The acute reader will have noticed something odd about the form

     (NOT (AND (CONSP '(trn a b)) (EQ (CAR '(trn a b)) 'NORM))).

When relieving the first hypothesis, (RATIONALP X), we substituted (trn
a b) for X; but when relieving the second hypothesis, (SYNTAXP (NOT
(AND (CONSP X) (EQ (CAR X) 'NORM)))), we substituted the quotation of
(trn a b) for X.  Why the difference?  Remember that in the first
hypothesis we are talking about the value of (trn a b) -- is it
rational -- while in the second one we are talking about its syntactic
form.  Remember also that Lisp, and hence ACL2, evaluates the arguments
to a function before applying the function to the resulting values.
Thus, we are asking "Is the list (trn a b) a consp and if so, is its car
the symbol NORM?"  The quotes on both (trn a b) and NORM are therefore
necessary.  One can verify this by defining trn to be, say cons, and
then evaluating forms such as

     (AND (CONSP '(trn a b)) (EQ (CAR '(trn a b)) 'NORM))
     (AND (CONSP (trn a b)) (EQ (CAR (trn a b)) NORM))
     (AND (CONSP (trn 'a 'b)) (EQ (CAR (trn 'a 'b)) NORM))
     (AND (CONSP '(trn a b)) (EQ '(CAR (trn a b)) ''NORM))

at the top-level ACL2 prompt.

See *note SYNTAXP-EXAMPLES:: for more examples of the use of syntaxp.

An extended syntaxp hypothesis is similar to the simple type described
above, but it uses two additional variables, mfc and state, which must
not be bound by the left hand side or an earlier hypothesis of the rule.
They must be the last two variables mentioned by form; first mfc, then
state.  These two variables give access to the functions mfc-xxx; see
*note EXTENDED-METAFUNCTIONS::.  As described there, mfc is bound to
the so-called metafunction-context and state to ACL2's state.  See
*note SYNTAXP-EXAMPLES:: for an example of the use of these extended
syntaxp hypotheses.

We conclude with an example illustrating an error that may occur if you
forget that a syntaxp hypothesis will be evaluated in an environment
where variables are bound to syntactic terms, not to values.  Consider
the following stobj introduction (see *note DEFSTOBJ::).

       (defstobj st
         (fld1 :type (signed-byte 3) :initially 0)
         fld2)

The following syntaxp hypothesis is ill-formed for evaluation.  Indeed,
ACL2 causes an error because it anticipates that when trying to relieve
the syntaxp hypothesis of this rule, ACL2 would be evaluating (fld1 st)
where st is bound to a term, not to an actual stobj as required by the
function fld1.  The error message is intended to explain this problem.

       ACL2 !>(defthm bad
                (implies (syntaxp (quotep (fld1 st)))
                         (equal (stp st)
                                (and (true-listp st)
                                     (equal (len st) 2)
                                     (fld1p (car st))))))


       ACL2 Error in ( DEFTHM BAD ...):  The form (QUOTEP (FLD1 ST)), from
       a SYNTAXP hypothesis, is not suitable for evaluation in an environment
       where its variables are bound to terms.  See :DOC SYNTAXP.  Here is
       further explanation:
            The form ST is being used, as an argument to a call of FLD1, where
       the single-threaded object of that name is required.  But in the current
       context, the only declared stobj name is STATE.  Note:  this error
       occurred in the context (FLD1 ST).


       Summary
       Form:  ( DEFTHM BAD ...)
       Rules: NIL
       Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)

       ACL2 Error in ( DEFTHM BAD ...):  See :DOC failure.

       ******** FAILED ********
       ACL2 !>

Presumably the intention was to rewrite the term (stp st) when the fld1
component of st is seen to be an explicit constant.  As explained
elsewhere (see *note FREE-VARIABLES::), we can obtain the result of
rewriting (fld1 st) by binding a fresh variable to that term using
EQUAL, as follows.

       (defthm good
         (implies (and (equal f (fld1 st))
                       (syntaxp (quotep f)))
                  (equal (stp st)
                         (and (true-listp st)
                              (equal (len st) 2)
                              (fld1p (car st))))))

The event above is admitted by ACL2.  We can see it in action by
disabling the definition of stp so that only the rule above, good, is
available for reasoning about stp.

       (in-theory (disable stp))

Then the proof fails for the following, because the syntaxp hypothesis
of the rule, good, fails: (quotep f) evaluates to nil when f is bound
to the term (fld1 st).

       (thm (stp st))

However, the proof succeeds for the next form, as we explain below.

       (thm (stp (list 3 rest)))

Consider what happens in that case when rule good is applied to the term
(stp (list 3 rest)).  (See *note FREE-VARIABLES:: for relevant
background.)  The first hypothesis of good binds the variable f to the
result of rewriting (fld1 st), where st is bound to the (internal form
of) the term (list 3 rest) -- and that result is clearly the term, '3.
Then the syntaxp hypothesis is successfully relieved, because the
evaluation of (quotep f) returns t in the environment that binds f to
'3.


File: acl2-doc-emacs.info,  Node: SYNTAXP-EXAMPLES,  Prev: SYNTAXP,  Up: SYNTAXP

SYNTAXP-EXAMPLES    examples pertaining to syntaxp hypotheses

See *note SYNTAXP:: for a basic discussion of the use of syntaxp to
control rewriting.

A common syntactic restriction is

     (SYNTAXP (AND (CONSP X) (EQ (CAR X) 'QUOTE)))

or, equivalently,

     (SYNTAXP (QUOTEP X)).

A rule with such a hypothesis can be applied only if x is bound to a
specific constant.  Thus, if x is 23 (which is actually represented
internally as (quote 23)), the test evaluates to t; but if x prints as
(+ 11 12) then the test evaluates to nil (because (car x) is the symbol
binary-+).  We see the use of this restriction in the rule

     (implies (and (syntaxp (quotep c))
                   (syntaxp (quotep d)))
              (equal (+ c d x)
                     (+ (+ c d) x))).

If c and d are constants, then the executable-counterpart of binary-+
will evaluate the sum of c and d.  For instance, under the influence of
this rule

     (+ 11 12 foo)

rewrites to

     (+ (+ 11 12) foo)

which in turn rewrites to (+ 23 foo).  Without the syntactic
restriction, this rule would loop with the built-in rules
ASSOCIATIVITY-OF-+ or COMMUTATIVITY-OF-+.

We here recommend that the reader try the affects of entering
expressions such as the following at the top level ACL2 prompt.

     (+ 11 23)
     (+ '11 23)
     (+ '11 '23)
     (+ ''11 ''23)
     :trans (+ 11 23)
     :trans (+ '11 23)
     :trans (+ ''11 23)
     :trans (+ c d x)
     :trans (+ (+ c d) x)

We also recommend that the reader verify our claim above about looping
by trying the affect of each of the following rules individually.

     (defthm good
        (implies (and (syntaxp (quotep c))
                      (syntaxp (quotep d)))
                 (equal (+ c d x)
                        (+ (+ c d) x))))

     (defthm bad
        (implies (and (acl2-numberp c)
                      (acl2-numberp d))
                 (equal (+ c d x)
                        (+ (+ c d) x))))

on (the false) theorems:

     (thm
       (equal (+ 11 12 x) y))

     (thm
       (implies (and (acl2-numberp c)
                     (acl2-numberp d)
                     (acl2-numberp x))
                (equal (+ c d x) y))).

One can use :brr, perhaps in conjunction with cw-gstack, to investigate
any looping.

Here is a simple example showing the value of rule good above.  Without
good, the thm form below fails.

     (defstub foo (x) t)

     (thm (equal (foo (+ 3 4 x)) (foo (+ 7 x))))

The next three examples further explore the use of quote in syntaxp
hypotheses.

We continue the examples of syntaxp hypotheses with a rule from
community book books/finite-set-theory/set-theory.lisp.  We will not
discuss here the meaning of this rule, but it is necessary to point out
that (ur-elementp nil) is true in this book.

     (defthm scons-nil
       (implies (and (syntaxp (not (equal a ''nil)))
                     (ur-elementp a))
                (= (scons e a)
                   (scons e nil)))).

Here also, syntaxp is used to prevent looping.  Without the
restriction, (scons e nil) would be rewritten to itself since
(ur-elementp nil) is true.
Question: Why the use of two quotes in "nil?
Hints: Nil is a constant just as 23 is.  Try :trans (cons a nil),
:trans (cons 'a 'nil), and :trans (cons "a "nil).  Also, don't forget
that the arguments to a function are evaluated before the function is
applied.

The next two rules move negative constants to the other side of an
inequality.

     (defthm |(< (+ (- c) x) y)|
       (implies (and (syntaxp (quotep c))
                     (syntaxp (< (cadr c) 0))
                     (acl2-numberp y))
                (equal (< (+ c x) y)
                       (< (fix x) (+ (- c) y)))))

     (defthm |(< y (+ (- c) x))|
       (implies (and (syntaxp (quotep c))
                     (syntaxp (< (cadr c) 0))
                     (acl2-numberp y))
                (equal (< y (+ c x))
                       (< (+ (- c) y) (fix x)))))

Questions: What would happen if (< (cadr c) '0) were used?  What about
(< (cadr c) "0)?

One can also use syntaxp to restrict the application of a rule to a
particular set of variable bindings as in the following taken from
community book books/ihs/quotient-remainder-lemmas.lisp.

     (encapsulate ()

       (local
        (defthm floor-+-crock
          (implies
           (and (real/rationalp x)
                (real/rationalp y)
                (real/rationalp z)
                (syntaxp (and (eq x 'x) (eq y 'y) (eq z 'z))))
           (equal (floor (+ x y) z)
                  (floor (+ (+ (mod x z) (mod y z))
                            (* (+ (floor x z) (floor y z)) z)) z)))))

       (defthm floor-+
         (implies
          (and (force (real/rationalp x))
               (force (real/rationalp y))
               (force (real/rationalp z))
               (force (not (equal z 0))))
          (equal (floor (+ x y) z)
                 (+ (floor (+ (mod x z) (mod y z)) z)
                    (+ (floor x z) (floor y z))))))

       )

We recommend the use of :brr to investigate the use of floor-+-crock.

Another useful restriction is defined by

     (defun rewriting-goal-literal (x mfc state)

       ;; Are we rewriting a top-level goal literal, rather than rewriting
       ;; to establish a hypothesis from a rewrite (or other) rule?

       (declare (ignore x state))
       (null (access metafunction-context mfc :ancestors))).

We use this restriction in the rule

     (defthm |(< (* x y) 0)|
         (implies (and (syntaxp (rewriting-goal-literal x mfc state))
                       (rationalp x)
                       (rationalp y))
                  (equal (< (* x y) 0)
                         (cond ((equal x 0)
                                nil)
                               ((equal y 0)
                                nil)
                               ((< x 0)
                                (< 0 y))
                               ((< 0 x)
                                (< y 0))))))

which has been found to be useful, but which also leads to excessive
thrashing in the linear arithmetic package if used indiscriminately.

See *note EXTENDED-METAFUNCTIONS:: for information on the use of mfc
and metafunction-context.


File: acl2-doc-emacs.info,  Node: TERM,  Next: THE-METHOD,  Prev: SYNTAXP,  Up: MISCELLANEOUS

TERM    the three senses of well-formed ACL2 expressions or formulas

     Examples of Terms:
     (cond ((caar x) (cons t x)) (t 0))   ; an untranslated term

     (if (car (car x)) (cons 't x) '0)    ; a translated term

     (car (cons x y) 'nil v)              ; a pseudo-term

In traditional first-order predicate calculus a "term" is a syntactic
entity denoting some object in the universe of individuals.  Often, for
example, the syntactic characterization of a term is that it is either
a variable symbol or the application of a function symbol to the
appropriate number of argument terms.  Traditionally, "atomic formulas"
are built from terms with predicate symbols such as "equal" and
"member;" "formulas" are then built from atomic formulas with
propositional "operators" like "not," "and," and "implies." Theorems
are formulas.  Theorems are "valid" in the sense that the value of a
theorem is true, in any model of the axioms and under all possible
assignments of individuals to variables.

However, in ACL2, terms are used in place of both atomic formulas and
formulas.  ACL2 does not have predicate symbols or propositional
operators as distinguished syntactic entities.  The ACL2 universe of
individuals includes a "true" object (denoted by t) and a "false"
object (denoted by nil), predicates and propositional operators are
functions that return these objects.  Theorems in ACL2 are terms and
the "validity" of a term means that, under no assignment to the
variables does the term evaluate to nil.

We use the word "term" in ACL2 in three distinct senses.  We will speak
of "translated" terms, "untranslated" terms, and "pseudo-" terms.

_Translated Terms:  The Strict Sense and Internal Form_

In its most strict sense, a "term" is either a legal variable symbol, a
quoted constant, or the application of an n-ary function symbol or
closed lambda expression to a true list of n terms.

The legal variable symbols are symbols other than t or nil which are
not in the keyword package, do not start with ampersand, do not start
and end with asterisks, and if in the main Lisp package, do not violate
an appropriate restriction (see *note NAME::).

Quoted constants are expressions of the form (quote x), where x is any
ACL2 object.  Such expressions may also be written 'x.

Closed lambda expressions are expressions of the form (lambda (v1 ...
vn) body) where the vi are distinct legal variable symbols, body is a
term, and the only free variables in body are among the vi.

The function termp, which takes two arguments, an alleged term x and a
logical world w (see *note WORLD::), recognizes terms of a given
extension of the logic.  Termp is defined in :program mode.  Its
definition may be inspected with :pe termp for a complete specification
of what we mean by "term" in the most strict sense.  Most ACL2
term-processing functions deal with terms in this strict sense and use
termp as a guard.  That is, the "internal form" of a term satisfies
termp, the strict sense of the word "term."

_Untranslated Terms:  What the User Types_

While terms in the strict sense are easy to explore (because their
structure is so regular and simple) they can be cumbersome to type.
Thus, ACL2 supports a more sugary syntax that includes uses of macros
and constant symbols.  Very roughly speaking, macros are functions that
produce terms as their results.  Constants are symbols that are
associated with quoted objects.  Terms in this sugary syntax are
"translated" to terms in the strict sense; the sugary syntax is more
often called "untranslated."  Roughly speaking, translation just
implements macroexpansion, the replacement of constant symbols by their
quoted values, and the checking of all the rules governing the strict
sense of "term."

More precisely, macro symbols are as described in the documentation for
defmacro.  A macro, mac, can be thought of as a function, mac-fn, from
ACL2 objects to an ACL2 object to be treated as an untranslated term.
For example, caar is defined as a macro symbol; the associated macro
function maps the object x into the object (car (car x)).  A macro form
is a "call" of a macro symbol, i.e., a list whose car is the macro
symbol and whose cdr is an arbitrary true list of objects, used as a
term.  Macroexpansion is the process of replacing in an untranslated
term every occurrence of a macro form by the result of applying the
macro function to the appropriate arguments.  The "appropriate"
arguments are determined by the exact form of the definition of the
macro; macros support positional, keyword, optional and other kinds of
arguments.  See *note DEFMACRO::.

In addition to macroexpansion and constant symbol dereferencing,
translation implements the mapping of let and let* forms into
applications of lambda expressions and closes lambda expressions
containing free variables.  Thus, the translation of

     (let ((x (1+ i))) (cons x k))

can be seen as a two-step process that first produces

     ((lambda (x) (cons x k)) (1+ i))

and then

     ((lambda (x k) (cons x k)) (1+ i) k) .

Observe that the body of the let and of the first lambda expression
contains a free k which is finally bound and passed into the second
lambda expression.

Translation also maps flet forms into applications of lambda
expressions.  See *note FLET::.

When we say, of an event-level function such as defun or defthm, that
some argument "must be a term" we mean an untranslated term.  The event
functions translate their term-like arguments.

To better understand the mapping between untranslated terms and
translated terms it is convenient to use the keyword command :trans to
see examples of translations.  See *note TRANS:: and also see *note
TRANS1::.

Finally, we note that the theorem prover prints terms in untranslated
form.  But there can be more than one correct untranslated term
corresponding to a given translated term.  For example, the translated
term (if x y 'nil) can be untranslated as (if x y nil) and can also be
untranslated as (and x y).  The theorem prover attempts to print an
untranslated term that is as helpful to the user as possible.  In
particular, consider a term of the form (nth k st) where st is a
single-threaded object (see *note STOBJ::) and the kth accessor of st
is, say, kn.  The theorem prover typically would expand (kn st) to (nth
k st).  If k is large then it could be difficult for the user to make
sense out of a proof transcript that mentions the expanded term.
Fortunately, the untranslation of (nth k st) would be (nth *kn* st);
here *kn* would be a constant (see *note DEFCONST::) added by the
defstobj event introducing st, defined to have value k.  The user can
extend this user-friendly style of printing applications of nth to
stobjs; see *note ADD-NTH-ALIAS::.  These remarks about printing
applications of function nth extend naturally to function update-nth.
Moreover, the prover will attempt to treat terms as stobjs for the
above purpose when appropriate.  For example, if function foo has
signature ((foo * st) => (mv * * * st)), where st is introduced with
(defstobj st f0 f1), then the term (nth '1 (mv-nth '3 (foo x st0)))
will be printed as (nth *f1* (mv-nth 3 (foo x st0))).

_Pseudo-Terms:  A Common Guard for Metafunctions_

Because termp is defined in :program mode, it cannot be used
effectively in conjectures to be proved.  Furthermore, from the
perspective of merely guarding a term processing function, termp often
checks more than is required.  Finally, because termp requires the
logical world as one of its arguments it is impossible to use termp as
a guard in places where the logical world is not itself one of the
arguments.

For these reasons we support the idea of "pseudo-terms."  A pseudo-term
is either a symbol (but not necessarily one having the syntax of a
legal variable symbol), a true list beginning with quote (but not
necessarily well-formed), or the "application of" a symbol or pseudo
lambda expression to a true list of pseudo-terms.  A pseudo lambda
expression is an expression of the form (lambda (v1 ... vn) body) where
the vi are all symbols and body is a pseudo-term.

Pseudo-terms are recognized by the unary function pseudo-termp.  If
(termp x w) is true, then (pseudo-termp x) is true.  However, if x
fails to be a (strict) term it may nevertheless still be a pseudo-term.
For example, (car a b) is not a term, because car is applied to the
wrong number of arguments, but it is a pseudo-term.

The structures recognized by pseudo-termp can be recursively explored
with the same simplicity that terms can be.  In particular, if x is not
a variablep or an fquotep, then (ffn-symb x) is the function (symbol or
lambda expression) and (fargs x) is the list of argument pseudo-terms.
A metafunction (see *note META::) or clause-processor (see *note
CLAUSE-PROCESSOR::) may use pseudo-termp as the guard.


File: acl2-doc-emacs.info,  Node: THE-METHOD,  Next: TIME-TRACKER-TAU,  Prev: TERM,  Up: MISCELLANEOUS

THE-METHOD    how to find proofs

Also see *note INTRODUCTION-TO-THE-THEOREM-PROVER:: for a more detailed
tutorial on how to prove theorems with ACL2.

Many users develop proof scripts in an Emacs buffer and submit one
event at a time to the theorem prover running in a *shell* buffer.  The
script buffer is logically divided into two regions: the events that
have been accepted by the theorem prover and those that have not yet
been accepted.  An imaginary "barrier" divides these two regions.  The
region above the barrier describes the state of the *shell* buffer (and
ACL2's logical world).  The region below the barrier is the "to do"
list.

We usually start a proof project by typing the key lemmas, and main
goal into the to do list.  Definitions are here just regarded as
theorems to prove (i.e., the measure conjectures).  Then we follow "The
Method."

(1) Think about the proof of the first theorem in the to do list.
Structure the proof either as an induction followed by simplification
or just simplification.  Have the necessary lemmas been proved? That
is, are the necessary lemmas in the done list already?  If so, proceed
to Step 2.  Otherwise, add the necessary lemmas at the front of the to
do list and repeat Step 1.

(2) Call the theorem prover on the first theorem in the to do list and
let the output stream into the *shell* buffer.  Abort the proof if it
runs more than a few seconds.

(3) If the theorem prover succeeded, advance the barrier past the
successful command and go to Step 1.

(4) Otherwise, inspect the failed proof attempt, starting from the
beginning, not the end.  Basically you should look for the first place
the proof attempt deviates from your imagined proof.  If your imagined
proof was inductive, inspect the induction scheme used by ACL2.  If
that is ok, then find the first subsequent subgoal that is stable under
simplification and think about why it was not proved by the simplifier.
If your imagined proof was not inductive, then think about the first
subgoal stable under simplification, as above.  Modify the script
appropriately.  It usually means adding lemmas to the to do list, just
in front of the theorem just tried.  It could mean adding hints to the
current theorem.  In any case, after the modifications go to Step 1.

We do not seriously suggest that this or any rotely applied algorithm
will let you drive ACL2 to difficult proofs.  Indeed, to remind you of
this we call this "The Method" rather than "the method."  That is, we
are aware of the somewhat pretentious nature of any such advice.  But
these remarks have helped many users approach ACL2 in a constructive
and disciplined way.

We say much more about The Method in the ACL2 book.  See the home page.
Also see *note SET-GAG-MODE:: for a discussion of a way for ACL2 to
help you to use The Method.  And again, see *note
INTRODUCTION-TO-THE-THEOREM-PROVER:: for a more detailed tutorial.

Learning to read failed proofs is a useful skill.  There are several
kinds of "checkpoints" in a proof: (1) a formula to which induction is
being (or would be) applied, (2) the first formula stable under
simplification, (3) a formula that is possibly generalized, either by
cross-fertilizing with and throwing away an equivalence hypothesis or
by explicit generalization of a term with a new variable.

At the induction checkpoint, confirm that you believe the formula being
proved is a theorem and that it is appropriately strong for an inductive
proof.  Read the selected induction scheme and make sure it agrees with
your idea of how the proof should go.

At the post-simplification checkpoint, which is probably the most
commonly seen, consider whether there are additional rewrite rules you
could prove to make the formula simplify still further.  Look for
compositions of function symbols you could rewrite.  Look for
contradictions among hypotheses and prove the appropriate implications:
for example, the checkpoint might contain the two hypotheses (P (F A))
and (NOT (Q (G (F A)))) and you might realize that (implies (p x) (q (g
x))) is a theorem.  Look for signs that your existing rules did not
apply, e.g., for terms that should have been rewritten, and figure out
why they were not.  Possible causes include that they do not exactly
match your old rules, that your old rules have hypotheses that cannot
be relieved here - perhaps because some other rules are missing, or
perhaps your old rules are disabled.  If you cannot find any further
simplifications to make in the formula, ask yourself whether it is
valid.  If so, sketch a proof.  Perhaps the proof is by appeal to a
combination of lemmas you should now prove?

At the two generalization checkpoints -- where hypotheses are discarded
or terms are replaced by variables -- ask yourself whether the result
is a theorem.  It often is not.  Think about rewrite rules that would
prove the formula.  These are often restricted versions of the
overly-general formulas created by the system's heuristics.

See *note PROOF-TREE:: for a discussion of a tool to help you navigate
through ACL2 proofs.


File: acl2-doc-emacs.info,  Node: TIME-TRACKER-TAU,  Next: TRUST-TAG,  Prev: THE-METHOD,  Up: MISCELLANEOUS

TIME-TRACKER-TAU    messages about expensive use of the tau-system

This documentation topic explains messages printing by the theorem
prover about the tau-system, as follows.

During a proof you may see a message such as the following.

     TIME-TRACKER-NOTE [:TAU]: Elapsed runtime in tau is 4.95 secs; see
     :DOC time-tracker-tau.

Just below a proof summary you may see a message such as the following.

     TIME-TRACKER-NOTE [:TAU]: For the proof above, the total runtime spent
     in the tau system was 30.01 seconds.  See :DOC time-tracker-tau.

Both of these messages are intended to let you know that certain prover
heuristics (see *note TAU-SYSTEM::) may be slowing proofs down more
than they are helping.  If you are satisfied with the prover's
performance, you may ignore these messages or even turn them off by
disabling time-tracking entirely (see *note TIME-TRACKER::).
Otherwise, here are some actions that you can take to solve such a
performance problem.

The simplest solution is to disable the tau-system, in either of the
following equivalent ways.

     (in-theory (disable (:executable-counterpart tau-system)))
     (in-theory (disable (tau-system)))

But if you want to leave the tau-system enabled, you could investigate
the possibility is that the tau-system is causing an expensive
:logic-mode function to be executed.  You can diagnose that problem by
observing the rewriter -- see *note DMR:: -- or by interrupting the
system and getting a backtrace (see *note SET-DEBUGGER-ENABLE::).  A
solution in that case is to disable the executable-counterpart of that
function, for example in either of these equivalent ways.

     (in-theory (disable (:executable-counterpart foo)))
     (in-theory (disable (foo)))

As a result, the tau-system will be weakened, but perhaps only
negligibly.

In either case above, you may prefer to provide :in-theory hints rather
than :in-theory events; see *note HINTS::.

A more sophisticated solution is to record values of the :logic-mode
function in question, so that the tau-system will look up the necessary
values rather than calling the function, whether or not the
executable-counterpart of that function is enabled.  Here is an example
of a lemma that can provide such a solution.  See *note TAU-SYSTEM::.

     (defthm lemma
       (and (foo 0)
            (foo 17)
            (foo t)
            (not (foo '(a b c))))
       :rule-classes :tau-system)


File: acl2-doc-emacs.info,  Node: TRUST-TAG,  Next: TTAGS-SEEN,  Prev: TIME-TRACKER-TAU,  Up: MISCELLANEOUS

TRUST-TAG    See *note DEFTTAG::.


File: acl2-doc-emacs.info,  Node: TTAGS-SEEN,  Next: TTREE,  Prev: TRUST-TAG,  Up: MISCELLANEOUS

TTAGS-SEEN    list some declared trust tags (ttags)

     General Forms:
     :ttags-seen
     (ttags-seen)

Suppose the output is as follows.

     (T NIL)
     (FOO "/home/bob/bar.lisp"
          "/home/cindy/bar.lisp")
     Warning: This output is minimally trustworthy (see :DOC TTAGS-SEEN).

This output indicates that the current logical world has seen the
declaration of trust tag T at the top-level (see *note DEFTTAG::) and
the declaration of trust tag FOO in the two books included from the
listed locations.  The warning emphasizes that this command cannot be
used to validate the "purity" of an ACL2 session, because using a ttag
renders enough power to hide from this or any other command the fact
that the ttag was ever declared.

As discussed elsewhere (see *note DEFTTAG::), the only reliable way to
validate the "purity" of a session is to watch for "TTAG NOTE" output.

Another shortcoming of this command is that it only checks the current
logical world for ttag declarations.  For example, one could execute a
defttag event; then use progn! and set-raw-mode to replace system
functions with corrupt definitions or to introduce inconsistent axioms
in the ground-zero world; and finally, execute :ubt! 1 to remove all
evidence of the ttag in the world while leaving in place the corrupt
definitions or axioms.  The base world is now tainted, meaning we could
prove nil or certify a book that proves nil, but the resulting session
or book would contain no trace of the ttag that tainted it!

Despite shortcomings, this command might be useful to system hackers.
It also serves to illustrate the inherent flaw in asking a session
whether or how it is "tainted", justifying the "TTAG NOTE" approach
(see *note DEFTTAG::).


File: acl2-doc-emacs.info,  Node: TTREE,  Next: TYPE-SET,  Prev: TTAGS-SEEN,  Up: MISCELLANEOUS

TTREE    tag-trees

Many low-level ACL2 functions take and return "tag trees" or "ttrees"
(pronounced "tee-trees") which contain various useful bits of
information such as the lemmas used, the linearize assumptions made,
etc.

Abstractly a tag-tree represents a list of sets, each member set having
a name given by one of the "tags" (which are symbols) of the ttree.  The
elements of the set named tag are all of the objects tagged tag in the
tree.  You are invited to browse the source code.  Definitions of
primitives are labeled with the comment "; Note: Tag-tree primitive".

The rewriter, for example, takes a term and a ttree (among other
things), and returns a new term, term', and new ttree, ttree'.  Term'
is equivalent to term (under the current assumptions) and the ttree' is
an extension of ttree.  If we focus just on the set associated with the
tag LEMMA in the ttrees, then the set for ttree' is the extension of
that for ttree obtained by unioning into it all the runes used by the
rewrite.  The set associated with LEMMA can be obtained by
(tagged-objects 'LEMMA ttree).


File: acl2-doc-emacs.info,  Node: TYPE-SET,  Next: TYPESPEC-CHECK,  Prev: TTREE,  Up: MISCELLANEOUS

TYPE-SET    how type information is encoded in ACL2

To help you experiment with type-sets we briefly note the following
utility functions.

(type-set-quote x) will return the type-set of the object x.  For
example, (type-set-quote "test") is 2048 and (type-set-quote '(a b c))
is 512.

(type-set 'term nil nil nil (ens state) (w state) nil nil nil) will
return the type-set of term.  For example,

     (type-set '(integerp x) nil nil nil (ens state) (w state) nil nil nil)

will return (mv 192 nil).  192, otherwise known as *ts-boolean*, is the
type-set containing t and nil.  The second result may be ignored in
these experiments.  Term must be in the translated, internal form shown
by :trans.  See *note TRANS:: and see *note TERM::.

(type-set-implied-by-term 'x nil 'term (ens state)(w state) nil) will
return the type-set deduced for the variable symbol x assuming the
translated term, term, true.  The second result may be ignored in these
experiments.  For example,

     (type-set-implied-by-term 'v nil '(integerp v)
                               (ens state) (w state) nil)

returns 11.

(convert-type-set-to-term 'x ts (ens state) (w state) nil) will return
a term whose truth is equivalent to the assertion that the term x has
type-set ts.  The second result may be ignored in these experiments.
For example

     (convert-type-set-to-term 'v 523 (ens state) (w state) nil)

returns a term expressing the claim that v is either an integer or a
non-nil true-list.  523 is the logical-or of 11 (which denotes the
integers) with 512 (which denotes the non-nil true-lists).

The "actual primitive types" of ACL2 are listed in
*actual-primitive-types*, whose elements are shown below.  Each actual
primitive type denotes a set -- sometimes finite and sometimes not --
of ACL2 objects and these sets are pairwise disjoint.  For example,
*ts-zero* denotes the set containing 0 while *ts-positive-integer*
denotes the set containing all of the positive integers.

     *TS-ZERO*                  ;;; {0}
     *TS-POSITIVE-INTEGER*      ;;; positive integers
     *TS-POSITIVE-RATIO*        ;;; positive non-integer rationals
     *TS-NEGATIVE-INTEGER*      ;;; negative integers
     *TS-NEGATIVE-RATIO*        ;;; negative non-integer rationals
     *TS-COMPLEX-RATIONAL*      ;;; complex rationals
     *TS-NIL*                   ;;; {nil}
     *TS-T*                     ;;; {t}
     *TS-NON-T-NON-NIL-SYMBOL*  ;;; symbols other than nil, t
     *TS-PROPER-CONS*           ;;; null-terminated non-empty lists
     *TS-IMPROPER-CONS*         ;;; conses that are not proper
     *TS-STRING*                ;;; strings
     *TS-CHARACTER*             ;;; characters

The actual primitive types were chosen by us to make theorem proving
convenient.  Thus, for example, the actual primitive type *ts-nil*
contains just nil so that we can encode the hypothesis "x is nil" by
saying "x has type *ts-nil*" and the hypothesis "x is non-nil" by
saying "x has type complement of *ts-nil*."  We similarly devote a
primitive type to t, *ts-t*, and to a third type,
*ts-non-t-non-nil-symbol*, to contain all the other ACL2 symbols.

Let *ts-other* denote the set of all Common Lisp objects other than
those in the actual primitive types.  Thus, *ts-other* includes such
things as floating point numbers and CLTL array objects.  The actual
primitive types together with *ts-other* constitute what we call
*universe*.  Note that *universe* is a finite set containing one more
object than there are actual primitive types; that is, here we are
using *universe* to mean the finite set of primitive types, not the
infinite set of all objects in all of those primitive types.
*Universe* is a partitioning of the set of all Common Lisp objects:
every object belongs to exactly one of the sets in *universe*.

Abstractly, a "type-set" is a subset of *universe*.  To say that a
term, x, "has type-set ts" means that under all possible assignments to
the variables in x, the value of x is a member of some member of ts.
Thus, (cons x y) has type-set {*ts-proper-cons* *ts-improper-cons*}.  A
term can have more than one type-set.  For example, (cons x y) also has
the type-set {*ts-proper-cons* *ts-improper-cons* *ts-nil*}.
Extraneous types can be added to a type-set without invalidating the
claim that a term "has" that type-set.  Generally we are interested in
the smallest type-set a term has, but because the entire theorem-proving
problem for ACL2 can be encoded as a type-set question, namely, "Does p
have type-set complement of *ts-nil*?," finding the smallest type-set
for a term is an undecidable problem.  When we speak informally of
"the" type-set we generally mean "the type-set found by our heuristics"
or "the type-set assumed in the current context."

Note that if a type-set, ts, does not contain *ts-other* as an element
then it is just a subset of the actual primitive types.  If it does
contain *ts-other* it can be obtained by subtracting from *universe*
the complement of ts.  Thus, every type-set can be written as a
(possibly complemented) subset of the actual primitive types.

By assigning a unique bit position to each actual primitive type we can
encode every subset, s, of the actual primitive types by the
nonnegative integer whose ith bit is on precisely if s contains the ith
actual primitive type.  The type-sets written as the complement of s
are encoded as the twos-complement of the encoding of s.  Those
type-sets are thus negative integers.  The bit positions assigned to
the actual primitive types are enumerated from 0 in the same order as
the types are listed in *actual-primitive-types*.  At the concrete
level, a type-set is an integer between *min-type-set* and
*max-type-set*, inclusive.

For example, *ts-nil* has bit position 6.  The type-set containing just
*ts-nil* is thus represented by 64.  If a term has type-set 64 then the
term is always equal to nil.  The type-set containing everything but
*ts-nil* is the twos-complement of 64, which is -65.  If a term has
type-set -65, it is never equal to nil.  By "always" and "never" we
mean under all, or under no, assignments to the variables, respectively.

Here is a more complicated example.  Let s be the type-set containing
all of the symbols and the natural numbers.  The relevant actual
primitive types, their bit positions and their encodings are:

     actual primitive type       bit    value

     *ts-zero*                    0       1
     *ts-positive-integer*        1       2
     *ts-nil*                     6      64
     *ts-t*                       7     128
     *ts-non-t-non-nil-symbol*    8     256

Thus, the type-set s is represented by (+ 1 2 64 128 256) = 451.  The
complement of s, i.e., the set of all objects other than the natural
numbers and the symbols, is -452.


File: acl2-doc-emacs.info,  Node: TYPESPEC-CHECK,  Next: USE,  Prev: TYPE-SET,  Up: MISCELLANEOUS

TYPESPEC-CHECK    See *note META-EXTRACT::.


File: acl2-doc-emacs.info,  Node: USE,  Next: USING-COMPUTED-HINTS,  Prev: TYPESPEC-CHECK,  Up: MISCELLANEOUS

USE    hints keyword :USE

See *note HINTS::.


File: acl2-doc-emacs.info,  Node: USING-COMPUTED-HINTS,  Next: USING-COMPUTED-HINTS-1,  Prev: USE,  Up: MISCELLANEOUS

USING-COMPUTED-HINTS    how to use computed hints

Computed hints (see *note COMPUTED-HINTS::) are extraordinarily
powerful.  We show a few examples here to illustrate their use.  We
recommend that the using-computed-hints-n topics be read in the order
using-computed-hints-1, using-computed-hints-2, and so on.

* Menu:


Related topics other than immediate subtopics:
* ADD-DEFAULT-HINTS:: add to the default hints

* REMOVE-DEFAULT-HINTS:: remove from the default hints

* SET-DEFAULT-HINTS:: set the default hints

* USING-COMPUTED-HINTS-1:: Driving Home the Basics

* USING-COMPUTED-HINTS-2:: One Hint to Every Top-Level Goal in a Forcing Round

* USING-COMPUTED-HINTS-3:: Hints as a Function of the Goal (not its Name)

* USING-COMPUTED-HINTS-4:: Computing the Hints

* USING-COMPUTED-HINTS-5:: Debugging Computed Hints

* USING-COMPUTED-HINTS-6:: Using the computed-hint-replacement feature

* USING-COMPUTED-HINTS-7:: Using the stable-under-simplificationp flag

* USING-COMPUTED-HINTS-8:: Some Final Comments


File: acl2-doc-emacs.info,  Node: USING-COMPUTED-HINTS-1,  Next: USING-COMPUTED-HINTS-2,  Prev: USING-COMPUTED-HINTS,  Up: MISCELLANEOUS

USING-COMPUTED-HINTS-1    Driving Home the Basics

The common hint

     ("Subgoal 3.2.1''" :use lemma42)

has the same effect as the computed hint

     (if (equal id '((0) (3 2 1) . 2))
         '(:use lemma42)
         nil)

which, of course, is equivalent to

     (and (equal id '((0) (3 2 1) . 2))
          '(:use lemma42))

which is also equivalent to the computed hint

     my-special-hint

provided the following defun has first been executed

     (defun my-special-hint (id clause world)
       (declare (xargs :mode :program)
                (ignore clause world))
       (if (equal id '((0) (3 2 1) . 2))
           '(:use lemma42)
           nil))

It is permitted for the defun to be in :LOGIC mode (see *note
DEFUN-MODE::) also.

Just to be concrete, the following three events all behave the same way
(if my-special-hint is as above):

     (defthm main (big-thm a b c)
       :hints (("Subgoal 3.2.1''" :use lemma42)))

     (defthm main (big-thm a b c)
       :hints ((and (equal id '((0) (3 2 1) . 2)) '(:use lemma42))))

     (defthm main (big-thm a b c)
       :hints (my-special-hint))


File: acl2-doc-emacs.info,  Node: USING-COMPUTED-HINTS-2,  Next: USING-COMPUTED-HINTS-3,  Prev: USING-COMPUTED-HINTS-1,  Up: MISCELLANEOUS

USING-COMPUTED-HINTS-2    One Hint to Every Top-Level Goal in a Forcing Round

Suppose the main proof completes with a forcing round on three
subgoals, "[1]Subgoal 3", "[1]Subgoal 2", and "[1]Subgoal 1".  Suppose
you wish to :use lemma42 in all top-level goals of the first forcing
round.  This can be done supplying the hint

     (if test '(:use lemma42) nil),

where test is an expression that returns t when ID is one of the clause
ids in question.

         goal-spec     (parse-clause-id goal-spec)

     "[1]Subgoal 3"        ((1) (3) . 0)
     "[1]Subgoal 2"        ((1) (2) . 0)
     "[1]Subgoal 1"        ((1) (1) . 0)

Recall (see *note CLAUSE-IDENTIFIER::) that parse-clause-id maps from a
goal spec to a clause id, so you can use that function on the goal
specs printed in the failed proof attempt to determine the clause ids
in question.

So one acceptable test is

     (member-equal id '(((1) (3) . 0)
                        ((1) (2) . 0)
                        ((1) (1) . 0)))

or you could use parse-clause-id in your computed hint if you don't
want to see clause ids in your script:

     (or (equal id (parse-clause-id "[1]Subgoal 3"))
         (equal id (parse-clause-id "[1]Subgoal 2"))
         (equal id (parse-clause-id "[1]Subgoal 1")))

or you could use the inverse function (see *note CLAUSE-IDENTIFIER::):

     (member-equal (string-for-tilde-@-clause-id-phrase id)
                   '("[1]Subgoal 3"
                     "[1]Subgoal 2"
                     "[1]Subgoal 1"))

Recall that what we've shown above are the tests to use in the computed
hint.  The hint itself is (if test '(:use lemma42) nil) or something
equivalent like (and test '(:use lemma42)).

The three tests above are all equivalent.  They suffer from the problem
of requiring the explicit enumeration of all the goal specs in the
first forcing round.  A change in the script might cause more forced
subgoals and the ones other than those enumerated would not be given
the hint.

You could write a test that recognizes all first round top-level
subgoals no matter how many there are.  Just think of the programming
problem:  how do I recognize all the clause id's of the form ((1) (n) .
0)?  Often you can come to this formulation of the problem by using
parse-clause-id on a few of the candidate goal-specs to see the common
structure.  A suitable test in this case is:

     (and (equal (car id) '(1))     ; forcing round 1, top-level (pre-induction)
          (equal (len (cadr id)) 1) ; Subgoal n (not Subgoal n.i ...)
          (equal (cddr id) 0))      ; no primes

The test above is "overkill" because it recognizes precisely the clause
ids in question.  But recall that once a computed hint is used, it is
(by default) removed from the hints available to the children of the
clause.  Thus, we can widen the set of clause ids recognized to include
all the children without worrying that the hint will be applied to
those children.

In particular, the following test supplies the hint to every top-level
goal of the first forcing round:

     (equal (car id) '(1))

You might worry that it would also supply the hint to the subgoal
produced by the hint - the cases we ruled out by the "overkill" above.
But that doesn't happen since the hint is unavailable to the children.
You could even write:

     (equal (car (car id)) 1)

which would supply the hint to every goal of the form "[1]Subgoal ..."
and again, because we see and fire on the top-level goals first, we
will not fire on, say, "[1]Subgoal *1.3/2", i.e., the id '((1 1 3) (2)
. 0) even though the test recognizes that id.

Finally, the following test supplies the hint to every top-level goal
of every forcing round (except the 0th, which is the "gist" of the
proof, not "really" a forcing round):

     (not (equal (car (car id)) 0))

Recall again that in all the examples above we have exhibited the test
in a computed hint of the form (if test '(:key1 val1 ...) nil).


File: acl2-doc-emacs.info,  Node: USING-COMPUTED-HINTS-3,  Next: USING-COMPUTED-HINTS-4,  Prev: USING-COMPUTED-HINTS-2,  Up: MISCELLANEOUS

USING-COMPUTED-HINTS-3    Hints as a Function of the Goal (not its Name)

Sometimes it is desirable to supply a hint whenever a certain term
arises in a conjecture.  For example, suppose we have proved

     (defthm all-swaps-have-the-property
        (the-property (swap x))
        :rule-classes nil)

and suppose that whenever (SWAP A) occurs in a goal, we wish to add the
additional hypothesis that (THE-PROPERTY (SWAP A)).  Note that this is
equivalent supplying the hint

     (if test
         '(:use (:instance all-swaps-have-the-property (x A)))
         nil)

where test answers the question "does the clause contain (SWAP A)?"
That question can be asked with (occur-lst '(SWAP A) clause).  Briefly,
occur-lst takes the representation of a translated term, x, and a list
of translated terms, y, and determines whether x occurs as a subterm of
any term in y.  (By "subterm" here we mean proper or improper, e.g.,
the subterms of (CAR X) are X and (CAR X).)

Thus, the computed hint:

     (if (occur-lst '(swap a) clause)
         '(:use (:instance all-swaps-have-the-property (x A)))
         nil)

will add the hypothesis (THE-PROPERTY (SWAP A)) to every goal
containing (SWAP A) - except the children of goals to which the
hypothesis was added.

A COMMON MISTAKE users are likely to make is to forget that they are
dealing with translated terms.  For example, suppose we wished to look
for (SWAP (LIST 1 A)) with occur-lst.  We would never find it with

     (occur-lst '(SWAP (LIST 1 A)) clause)

because that presentation of the term contains macros and other
abbreviations.  By using :trans (see *note TRANS::) we can obtain the
translation of the target term.  Then we can look for it with:

     (occur-lst '(SWAP (CONS '1 (CONS A 'NIL))) clause)

Note in particular that you must

     * eliminate all macros and
     * explicitly quote all constants.

We recommend using :trans to obtain the translated form of the terms in
which you are interested, before programming your hints.

An alternative is to use the expression (prettyify-clause clause nil
nil) in your hint to convert the current goal clause into the
s-expression that is actually printed.  For example, the clause

     ((NOT (CONSP X)) (SYMBOLP Y) (EQUAL (CONS '1 (CAR X)) Y))

"prettyifies" to

     (IMPLIES (AND (CONSP X)
                   (NOT (SYMBOLP Y)))
              (EQUAL (CONS 1 (CAR X)) Y))

which is what you would see printed by ACL2 when the goal clause is
that shown.

However, if you choose to convert your clauses to prettyified form, you
will have to write your own explorers (like our occur-lst), because all
of the ACL2 term processing utilities work on translated and/or clausal
forms.  This should not be taken as a terrible burden.  You will, at
least, gain the benefit of knowing what you are really looking for,
because your explorers will be looking at exactly the s-expressions you
see at your terminal.  And you won't have to wade through our still
undocumented term/clause utilities.  The approach will slow things down
a little, since you will be paying the price of independently consing
up the prettyified term.

We make one more note on this example.  We said above that the computed
hint:

     (if (occur-lst '(swap a) clause)
         '(:use (:instance all-swaps-have-the-property (x A)))
         nil)

will add the hypothesis (THE-PROPERTY (SWAP A)) to every goal
containing (SWAP A) - except the children of goals to which the
hypothesis was added.

It bears noting that the subgoals produced by induction and top-level
forcing round goals are not children.  For example, suppose the hint
above fires on "Subgoal 3" and produces, say, "Subgoal 3'".  Then the
hint will not fire on "Subgoal 3'" even though it (still) contains
(SWAP A) because "Subgoal 3'" is a child of a goal on which the hint
fired.

But now suppose that "Subgoal 3'" is pushed for induction.  Then the
goals created by that induction, i.e., the base case and induction
step, are not considered children of "Subgoal 3'".  All of the original
hints are available.

Alternatively, suppose that "Subgoal 3' is proved but forces some other
subgoal, "[1]Subgoal 1" which is attacked in Forcing Round 1.  That
top-level forced subgoal is not a child.  All the original hints are
available to it.  Thus, if it contains (SWAP A), the hint will fire and
supply the hypothesis, producing "[1]Subgoal 1'".  This may be
unnecessary, as the hypothesis might already be present in "[1]Subgoal
1".  In this case, no harm is done.  The hint won't fire on "[1]Subgoal
1" because it is a child of "[1]Subgoal 1" and the hint fired on that.


File: acl2-doc-emacs.info,  Node: USING-COMPUTED-HINTS-4,  Next: USING-COMPUTED-HINTS-5,  Prev: USING-COMPUTED-HINTS-3,  Up: MISCELLANEOUS

USING-COMPUTED-HINTS-4    Computing the Hints

So far we have used computed hints only to compute when a fixed set of
keys and values are to be used as a hint.  But computed hints can, of
course, compute the set of keys and values.  You might, for example,
write a hint that recognizes when a clause "ought" to be provable by a
:BDD hint and generate the appropriate hint.  You might build in a set
of useful lemmas and check to see if the clause is provable :BY one of
them.  You can keep all function symbols disabled and use computed
hints to compute which ones you want to :EXPAND.  In general, you can
write a theorem prover for use in your hints, provided you can get it
to do its job by directing our theorem prover.

Suppose for example we wish to find every occurrence of an instance of
(SWAP x) and provide the corresponding instance of
ALL-SWAPS-HAVE-THE-PROPERTY.  Obviously, we must explore the clause
looking for instances of (SWAP x) and build the appropriate instances
of the lemma.  We could do this in many different ways, but below we
show a general purpose set of utilities for doing it.  The functions
are not defined in ACL2 but could be defined as shown.

Our plan is:  (1) Find all instances of a given pattern (term) in a
clause, obtaining a set of substitutions.  (2) Build a set of :instance
expressions for a given lemma name and set of substitutions.  (3)
Generate a :use hint for those instances when instances are found.

The pair of functions below find all instances of a given pattern term
in either a term or a list of terms.  The functions each return a list
of substitutions, each substitution accounting for one of the matches
of pat to a subterm.  At this level in ACL2 substitutions are lists of
pairs of the form (var . term).  All terms mentioned here are presumed
to be in translated form.

The functions take as their third argument a list of substitutions
accumulated to date and add to it the substitutions produced by
matching pat to the subterms of the term.  We intend this accumulator
to be nil initially.  If the returned value is nil, then no instances
of pat occurred.

     (mutual-recursion

     (defun find-all-instances (pat term alists)
      (declare (xargs :mode :program))
      (mv-let
       (instancep alist)
       (one-way-unify pat term)
       (let ((alists (if instancep (add-to-set-equal alist alists) alists)))
         (cond
          ((variablep term) alists)
          ((fquotep term) alists)
          (t (find-all-instances-list pat (fargs term) alists))))))

     (defun find-all-instances-list (pat list-of-terms alists)
      (declare (xargs :mode :program))
      (cond
       ((null list-of-terms) alists)
       (t (find-all-instances pat
                              (car list-of-terms)
                              (find-all-instances-list pat
                                                       (cdr list-of-terms)
                                                       alists))))))

Caveat: The following aside has nothing to do with computed hints.
Does an instance of (CAR (CDR x)) occur in ((LAMBDA (V) (CAR V)) (CDR
A))?  It does if one beta-reduces the lambda-expression to (CAR (CDR
A)); the appropriate substitution is to replace x by A.  But the
definition of find-all-instances above does not find this instance
because it does not do beta-reduction.

We now turn our attention to converting a list of substitutions into a
list of lemma instances, each of the form

     (:INSTANCE name (var1 term1) ... (vark termk))

as written in :use hints.  In the code shown above, substitutions are
lists of pairs of the form (var . term), but in lemma instances we must
write "doublets."  So here we show how to convert from one to the other:

     (defun pairs-to-doublets (alist)
       (declare (xargs :mode :program))
       (cond ((null alist) nil)
             (t (cons (list (caar alist) (cdar alist))
                      (pairs-to-doublets (cdr alist))))))

Now we can make a list of lemma instances:

     (defun make-lemma-instances (name alists)
       (declare (xargs :mode :program))
       (cond
        ((null alists) nil)
        (t (cons (list* :instance name (pairs-to-doublets (car alists)))
                 (make-lemma-instances name (cdr alists))))))

Finally, we can package it all together into a hint function.  The
function takes a pattern, pat, which must be a translated term, the
name of a lemma, name, and a clause.  If some instances of pat occur in
clause, then the corresponding instances of name are :USEd in the
computed hint.  Otherwise, the hint does not apply.

     (defun add-corresponding-instances (pat name clause)
       (declare (xargs :mode :program))
       (let ((alists (find-all-instances-list pat clause nil)))
         (cond
          ((null alists) nil)
          (t (list :use (make-lemma-instances name alists))))))

The design of this particular hint function makes it important that the
variables of the pattern be the variables of the named lemma and that
all of the variables we wish to instantiate occur in the pattern.  We
could, of course, redesign it to allow "free variables" or some sort of
renaming.

We could now use this hint as shown below:

     (defthm ... ...
       :hints ((add-corresponding-instances
                '(SWAP x)
                'ALL-SWAPS-HAVE-THE-PROPERTY
                clause)))

The effect of the hint above is that any time a clause arises in which
any instance of (SWAP x) appears, we add the corresponding instance of
ALL-SWAPS-HAVE-THE-PROPERTY.  So for example, if Subgoal *1/3.5
contains the subterm (SWAP (SWAP A)) then this hint fires and makes the
system behave as though the hint:

     ("Subgoal *1/3.5"
      :USE ((:INSTANCE ALL-SWAPS-HAVE-THE-PROPERTY (X A))
            (:INSTANCE ALL-SWAPS-HAVE-THE-PROPERTY (X (SWAP A)))))

had been present.


File: acl2-doc-emacs.info,  Node: USING-COMPUTED-HINTS-5,  Next: USING-COMPUTED-HINTS-6,  Prev: USING-COMPUTED-HINTS-4,  Up: MISCELLANEOUS

USING-COMPUTED-HINTS-5    Debugging Computed Hints

We have found that it is sometimes helpful to define hints so that they
print out messages to the terminal when they fire, so you can see what
hint was generated and which of your computed hints did it.

To that end we have defined a macro we sometimes use.  Suppose you have
a :hints specification such as:

     :hints (computed-hint-fn (hint-expr id))

If you defmacro the macro below you could then write instead:

     :hints ((show-hint computed-hint-fn 1)
             (show-hint (hint-expr id) 2))

with the effect that whenever either hint is fired (i.e., returns
non-nil), a message identifying the hint by the marker (1 or 2, above)
and the non-nil value is printed.

     (defmacro show-hint (hint &optional marker)
       (cond
        ((and (consp hint)
              (stringp (car hint)))
         hint)
        (t
         `(let ((marker ,marker)
                (ans ,(if (symbolp hint)
                          `(,hint id clause world stable-under-simplificationp)
                        hint)))
            (if ans
                (prog2$
                 (cw "~%***** Computed Hint~#0~[~/ (from hint ~x1)~]~%~x2~%~%"
                     (if (null marker) 0 1)
                     marker
                     (cons (string-for-tilde-@-clause-id-phrase id)
                           ans))
                 ans)
              nil)))))

Note that when show-hint is applied to a hint that is a symbol, e.g.,
computed-hint-fn, it applies the symbol to the four computed-hint
arguments: id, clause, world, and stable-under-simplificationp.  If
computed-hint-fn is of arity 3 the code above would cause an error.
One way to avoid it is to write

     :hints ((show-hints (computed-hint-fn id clause world) 1)
             (show-hint (hint-expr id) 2)).

If you only use computed hints of arity 3, you might eliminate the
occurrence of stable-under-simplificationp in the definition of
show-hint above.

Putting a show-hint around a common hint has no effect.  If you find
yourself using this utility let us know and we'll consider putting it
into the system itself.  But it does illustrate that you can use
computed hints to do unusual things.


File: acl2-doc-emacs.info,  Node: USING-COMPUTED-HINTS-6,  Next: USING-COMPUTED-HINTS-7,  Prev: USING-COMPUTED-HINTS-5,  Up: MISCELLANEOUS

USING-COMPUTED-HINTS-6    Using the computed-hint-replacement feature

So far none of our computed hints have used the
:COMPUTED-HINT-REPLACEMENT feature.  We now illustrate that.

The :computed-hint-replacement feature can easily lead to loops.  So as
you experiment with the examples in this section and your own hints
using this feature, be ready to interrupt the theorem prover and abort!

A non-looping use of the :computed-hint-replacement feature would be a
hint like this:

     (if (certain-terms-present clause)
         '(:computed-hint-replacement t
           :in-theory (enable lemma25))
         '(:computed-hint-replacement t
           :in-theory (disable lemma25)))

In this hint, if certain terms are present in clause, as determined by
the function with the obvious name (here undefined), then this hint
enables lemma25 and otherwise disables it.  Lemma25 might be a very
expensive lemma, e.g., one that matches frequently and has an expensive
and rarely established hypothesis.  One might wish it enabled only
under certain conditions.  Recall that theories are inherited by
children.  So once lemma25 is enabled it "stays" enabled for the
children, until disabled; and vice versa.  If the
:computed-hint-replacement feature were not present and computed hints
were always deleted after they had been used, then lemma25 would be
left enabled (or disabled) for all the childen produced by the first
firing of the hint.  But with the arrangement here, every subgoal gets
a theory deemed suitable by the hint, and the hint persists.

Now we will set up a toy to allow us to play with computed hints to
understand them more deeply.  To follow the discussion it is best to
execute the following events.

     (defstub wrapper (x) t)
     (defaxiom wrapper-axiom (wrapper x) :rule-classes nil)

Now submit the following event and watch what happens.

     (thm (equal u v)
       :hints (`(:use (:instance wrapper-axiom (x a)))))

The theorem prover adds (wrapper a) to the goal and then abandons the
proof attempt because it cannot prove the subgoal.  Since the computed
hint is deleted upon use, the hint is not applied to the subgoal (i.e.,
the child of the goal).

What happens if we do the following?

     (thm (equal u v)
       :hints (`(:computed-hint-replacement t
                 :use (:instance wrapper-axiom (x a)))))

As one might expect, this loops forever: The hint is applied to the
child and adds the hypothesis again.  When the hint fires, nothing is
actually changed, since (wrapper a) is already in the subgoal.

So let's change the experiment a little.  Let's make the hint add the
hypothesis (wrapper p) where p is the first literal of the clause.
This is silly but it allows us to explore the behavior of computed
hints a little more.

     (thm (equal u v)
       :hints (`(:use (:instance wrapper-axiom (x ,(car clause))))))

So in this case, the theorem prover changes the goal to

     (IMPLIES (WRAPPER (EQUAL U V)) (EQUAL U V))

which then simplifies to

     (IMPLIES (WRAPPER NIL) (EQUAL U V))

because the concluding equality can be assumed false in the hypothesis
(e.g., think of the contrapositive version).  Nothing else happens
because the hint has been removed and so is not applicable to the child.

Now consider the following - and be ready to interrupt it and abort!

     (thm (equal u v)
       :hints (`(:computed-hint-replacement t
                 :use (:instance wrapper-axiom (x ,(car clause))))))

This time the hint is not removed and so is applied to the child.  So
from Goal we get

     Goal'
     (IMPLIES (WRAPPER (EQUAL U V))
              (EQUAL U V))

and then

     Goal''
     (IMPLIES (AND (WRAPPER (NOT (WRAPPER (EQUAL U V))))
                   (WRAPPER (EQUAL U V)))
              (EQUAL U V))

etc.

First, note that the hint is repeatedly applied to its children.  That
is because we wrote :computed-hint-replacement t.  But second, note
that Goal' is not even being simplified before Goal" is produced from
it.  If it were being simplified, the (equal u v)'s in the hypotheses
would be replaced by nil.  This is a feature.  It means after a
computed hint has fired, other hints are given a chance at the result,
even the hint itself unless it is removed from the list of hints.

As an exercise, let's arrange for the hint to stay around and be
applied indefinitely but with a simplification between each use of the
the hint.  To do this we need to pass information from one application
of the hint to the next, essentially to say "stay around but don't
fire."

First, we will define a function to use in the hint.  This is more than
a mere convenience; it allows the hint to "reproduce itself" in the
replacement.

     (defun wrapper-challenge (clause parity)
       (if parity
           `(:computed-hint-replacement ((wrapper-challenge clause nil))
             :use (:instance wrapper-axiom (x ,(car clause))))
           `(:computed-hint-replacement ((wrapper-challenge clause t)))))

Note that this function is not recursive, even though it uses its own
name.  That is because the occurrence of its name is in a quoted
constant.

Now consider the following.  What will it do?

     (thm (equal u v)
       :hints ((wrapper-challenge clause t)))

First, observe that this is a legal hint because it is a term that
mentions only the free variable CLAUSE.  When defining hint functions
you may sometimes think their only arguments are the four variables id,
clause, world, and stable-under-simplificationp.  That is not so.  But
in your hints you must call those functions so that those are the only
free variables.  Note also that the occurrence of clause inside the
:computed-hint-replacement is not an occurrence of the variable clause
but just a constant.  Just store this note away for a moment.  We'll
return to it momentarily.

Second, the basic cleverness of this hint is that every time it fires
it reproduces itself with the opposite parity.  When the parity is t it
actually changes the goal by adding a hypothesis.  When the parity is
nil it doesn't change the goal and so allows simplification to proceed
- but it swaps the parity back to t.  What you can see with this simple
toy is that we can use the computed hints to pass information from
parent to child.

Ok, so what happens when the event above is executed?  Try it.  You will
see that ACL2 applied the hint the first time.  It doesn't get around to
printing the output because an error is caused before it can print.
But here is a blow-by-blow description of what happens.  The hint is
evaluated on Goal with the clause ((equal u v)).  It produces a hint
exactly as though we had typed:

     ("Goal" :use (:instance wrapper-axiom (x (equal u v))))

which is applied to this goal. In addition, it produces the new hints
argument

     :hints ((wrapper-challenge clause nil)).

By applying the "Goal" hint we get the new subgoal

     Goal'
     (implies (wrapper (equal u v))
              (equal u v))

but this is not printed because, before printing it, the theorem prover
looks for hints to apply to it and finds

     (wrapper-challenge clause nil)

That is evaluated and produces a hint exactly as though we had typed:

     ("Goal'" )

and the new hints argument:

     :hints ((wrapper-challenge clause nil)).

But if you supply the hint ("Goal'" ), ACL2 will signal an error
because it does not allow you to specify an empty hint!

So the definition of wrapper-challenge above is almost correct but
fatally flawed.  We need a non-empty "no-op" hint.  One such hint is to
tell the system to expand a term that will always be expanded anyway.
So undo wrapper-challenge, redefine it, and try the proof again.  Now
remember the observation about clause that we asked you to "store"
above.  The new definition of wrapper-challenge illustrates what we
meant.  Note that the first formal parameter of wrapper-challenge,
below, is no longer named clause but is called cl instead.  But the
"call" of wrapper-challenge in the replacements is on clause.  This may
seem to violate the rule that a function definition cannot use
variables other than the formals.  But the occurrences of clause below
are not variables but constants in an object that will eventually be
treated as hint term.

     :ubt wrapper-challenge

     (defun wrapper-challenge (cl parity)
       (if parity
           `(:computed-hint-replacement ((wrapper-challenge clause nil))
             :use (:instance wrapper-axiom (x ,(car cl))))
           `(:computed-hint-replacement ((wrapper-challenge clause t))
             :expand ((atom zzz)))))

     (thm (equal u v)
       :hints ((wrapper-challenge clause t)))

This time, things go as you might have expected!  Goal' is produced and
simplified, to

     Goal''
     (implies (wrapper nil)
              (equal u v)).

Simplification gets a chance because when the new hint
(wrapper-challenge clause nil) is fired it does not change the goal.
But it does change the parity in the hints argument so that before
Goal" is simplified again, the hint fires and adds the hypothesis:

     Goal'''
     (IMPLIES (AND (WRAPPER (NOT (WRAPPER NIL)))
                   (WRAPPER NIL))
              (EQUAL U V)).

This simplifies, replacing the first (NOT (WRAPPER NIL)) by NIL, since
(WRAPPER NIL) is known to be true here.  Thus the goal simplifies to

     Goal'4'
     (IMPLIES (WRAPPER NIL) (EQUAL U V)).

The process repeats indefinitely.

So we succeeded in getting a hint to fire indefinitely but allow a full
simplification between rounds.


File: acl2-doc-emacs.info,  Node: USING-COMPUTED-HINTS-7,  Next: USING-COMPUTED-HINTS-8,  Prev: USING-COMPUTED-HINTS-6,  Up: MISCELLANEOUS

USING-COMPUTED-HINTS-7    Using the stable-under-simplificationp flag

A problem with the example in using-computed-hints-6 is that exactly
one simplification occurs between each (effective) firing of the hint.
Much more commonly we wish to fire a hint once a subgoal has become
stable under simplification.

A classic example of this is when we are dealing with an interpreter
for some state machine.  We typically do not want the "step" function
to open up on the symbolic representation of a state until that state
has been maximally simplified.  We will illustrate with a simple state
machine.

Let us start by defining the step function, stp, and the corresponding
run function that applies it a given number of times.

     (defun stp (s)
       (+ 1 s))

     (defun run (s n)
       (if (zp n)
           s
           (run (stp s) (- n 1))))

The step function here is trivial:  a state is just a number and the
step function increments it.  In this example we will not be interested
in the theorems we prove but in how we prove them.  The formula we will
focus on is

     (thm (equal (run s 7) xxx))

This is not a theorem, of course.  But we want to test our advice on
non-theorems because we do not want the advice to work only for proofs
that succeed.  (In the past, we gave advice about using computed hints
and that advice caused the theorem prover to run forever when given
formulas that it couldn't prove - but most of the time the system is
presented with formulas it cannot prove!)

Furthermore, without some kind of additional rules, the (run s 7)
expression in the conjecture above will not expand at all, because
ACL2's heuristics do not approve.

In fact, we do not want to take chances that run will be expanded - we
want to control its expansion completely.  Therefore, disable run.

     (in-theory (disable run))

Now, what do we want?  (That is always a good question to ask!)  We want
(run s 7) to expand "slowly."  In particular, we want it to expand
once, to (run (stp s) 6).  Then we want the stp to be expanded and
fully simplified before the run expression is expanded again.  That is,
we want to force the expansion of run whenever the goal is stable under
simplification.  This is sometimes called "staged simplification."

We can achieve staged simplification for any given function symbol by
defining the functions shown below and then using a simple computed
hint:

     (thm (equal (run s 7) xxx)
          :hints ((stage run)))

By inspecting how stage is defined you can see how to extend it, but we
explain as we go.  To experiment, you can just paste the definitions
(and defmacro) below into your ACL2 shell and then try the thm command.

First, define this pair of mutually recursive functions.
Find-first-call finds the first call of the function symbol fn in a
given term.

     (mutual-recursion
      (defun find-first-call (fn term)
      ; Find the first call of fn in term.
       (cond ((variablep term) nil)
             ((fquotep term) nil)
             ((equal (ffn-symb term) fn)
              term)
             (t (find-first-call-lst fn (fargs term)))))
      (defun find-first-call-lst (fn lst)
      ; Find the first call of fn in a list of terms.
       (cond ((endp lst) nil)
             (t (or (find-first-call fn (car lst))
                    (find-first-call-lst fn (cdr lst)))))))

We will arrange for the computed hint to generate an :EXPAND hint for
the first call of fn, whenever the goal becomes stable under
simplification.  If no call is found, the hint will do nothing.  To
make sure the hint will not loop indefinitely (for example, by forcing
fn to expand only to have the rewriter "fold" it back up again), we
will provide the hint with a bound that stops it after some number of
iterations.  Here is the basic function that creates the expand hint
and replaces itself to count down.

     (defun stage1 (fn max clause flg)
     ; If the clause is stable under simplification and there is a call of
     ; fn in it, expand it.  But don't do it more than max times.
      (let ((temp (and flg
                       (find-first-call-lst fn clause))))
        (if temp
            (if (zp max)
                (cw "~%~%HINT PROBLEM:  The maximum repetition count of ~
                     your STAGE hint been reached without eliminating ~
                     all of the calls of ~x0.  You could supply a larger ~
                     count with the optional second argument to STAGE ~
                     (which defaults to 100).  But think about what is ~
                     happening! Is each stage permanently eliminating a ~
                     call of ~x0?~%~%"
                    fn)
              `(:computed-hint-replacement
                 ((stage1 ',fn ,(- max 1)
                          clause
                          stable-under-simplificationp))
                :expand (,temp)))
          nil)))

Suppose that when stage1 is called, fn is the function we want to
expand, max is the maximum number of iterations of this expansion,
clause is the current goal clause, and flg is the value of the
stable-under-simplificationp flag.  Then if clause is stable and we can
find a call of fn in it, we ask whether max is exhausted.  If so, we
print an "error message" to the comment window with cw and return nil
(the value of cw).  That nil means the hint does nothing.  But if max
is not yet exhausted, we return a new hint.  As you can see above, the
hint replaces itself with another stage1 hint with the same fn and a
decremented max to be applied to the new clause and the then-current
value of stable-under-simplificationp.  The hint also contains an
:expand directive for the call of fn found.

Thus, if the computed hint was:

     (stage1 'run 5 clause stable-under-simplificationp)

and (run s 7) occurs in the clause, then it will generate

     (:computed-hint-replacement
       ((stage1 'run 4 clause stable-under-simplificationp))
      :expand ((run s 7)))

which will in turn replace the old stage1 hint with the new one and
will apply :expand ((run s 7)) to the current goal.

We can make this more convenient by defining the macro:

     (defmacro stage (fn &optional (max '100))
      `(stage1 ',fn ,max clause stable-under-simplificationp))

Note that the macro allows us to either provide the maximum bound or
let it default to 100.

Henceforth, we can type

     (thm (equal (run s 7) xxx)
          :hints ((stage run)))

to stage the opening of run up to 100 times, or we can write

     (thm (equal (run s 7) xxx)
          :hints ((stage run 5)))

to stage it only 5 times.  In the latter example, the system with print
a "error message" after the fifth expansion.

Note that if we executed

     (set-default-hints '((stage run)))

then we could attack all theorems (involving run) with staged
simplification (up to bound 100), without typing an explicit hint.

     (thm (equal (run s 7) xxx))

Using techniques similar to those above we have implemented "priority
phased simplification" and provided it as a book.  See community book
books/misc/priorities.lisp.  This is an idea suggested by Pete Manolios,
by which priorities may be assigned to rules and then the simplifier
simplifies each subgoal maximally under the rules of a given priority
before enabling the rules of the next priority level.  The book above
documents both how we implement it with computed hints and how to use
it.

Here is another example of using the stable-under-simplificationp flag
to delay certain actions.  It defines a default hint, see *note
DEFAULT-HINTS::, which will enable non-linear-arithmetic on precisely
those goals which are stable-under-simplificationp.  It also uses the
HISTORY and PSPV variables to determine when toggling
non-linear-arithmetic is appropriate.  These variables are documented
only in the source code.  If you start using these variables
extensively, please contact the developers of ACL2 or Robert Krug
(rkrug@cs.utexas.edu) and let us know how we can help.

     (defun nonlinearp-default-hint (stable-under-simplificationp hist pspv)
       (cond (stable-under-simplificationp
              (if (not (access rewrite-constant
                               (access prove-spec-var pspv :rewrite-constant)
                               :nonlinearp))
                  '(:computed-hint-replacement t
                    :nonlinearp t)
                nil))
             ((access rewrite-constant
                      (access prove-spec-var pspv :rewrite-constant)
                      :nonlinearp)
              (if (not (equal (caar hist) 'SETTLED-DOWN-CLAUSE))
                  '(:computed-hint-replacement t
                    :nonlinearp nil)
                nil))
             (t
              nil)))


File: acl2-doc-emacs.info,  Node: USING-COMPUTED-HINTS-8,  Next: USING-ENABLED-RULES,  Prev: USING-COMPUTED-HINTS-7,  Up: MISCELLANEOUS

USING-COMPUTED-HINTS-8    Some Final Comments

None of the examples show the use of the variable WORLD, which is
allowed in computed hints.  There are some (undocumented) ACL2
utilities that might be useful in programming hints, but these
utilities need access to the ACL2 logical world (see *note WORLD::).

A very useful fact to know is that (table-alist name world) returns an
alist representation of the current value of the table named name.

The ACL2 source code is littered with :program mode functions for
manipulating world.  In our source code, the world is usually bound a
variable named wrld; so searching our code for that name might be
helpful.

Using these utilities to look at the WORLD one can, for example,
determine whether a symbol is defined recursively or not, get the body
and formals of a defined function, or fetch the statement of a given
lemma.  Because these utilities are not yet documented, we do not
expect users to employ WORLD in computed hints.  But experts might and
it might lead to the formulation of a more convenient language for
computed hints.

None of our examples illustrated the 7 argument form of a computed hint,
(fn ID CLAUSE WORLD STABLE-UNDER-SIMPLIFICATIONP HIST PSPV CTX).  When
used, the variables HIST, PSPV, and CTX, are bound to the clause
history, the package of "special variables" governing the clause, and
the "error message context."  These variables are commonly used
throughout our source code but are, unfortunately, undocumented.
Again, we expect a few experts will find them useful in developing
computed hints.

If you start using computed hints extensively, please contact the
developers of ACL2 and let us know what you are doing with them and how
we can help.


File: acl2-doc-emacs.info,  Node: USING-ENABLED-RULES,  Next: VERSION,  Prev: USING-COMPUTED-HINTS-8,  Up: MISCELLANEOUS

USING-ENABLED-RULES    avoiding :use hints for enabled :rewrite rules

Consider the following (admittedly silly) example.

     (thm (equal (append (append x y) z) (append x y z))
          :hints (("Subgoal *1/1" :use cdr-cons)))

ACL2's output includes the following warning.

     ACL2 Warning [Use] in ( THM ...):  It is unusual to :USE an enabled
     :REWRITE or :DEFINITION rule, so you may want to consider disabling
     (:REWRITE CDR-CONS) in the hint provided for Subgoal *1/1.

The warning is saying that if you leave the rewrite rule enabled, ACL2
may simplify away the hypothesis added by the :use hint.  We now
explain this danger in more detail and show how disabling the rule can
solve this problem.

Recall (see *note HINTS::) how :use hints work.  Such a hint specifies a
formula, F, which is based on an existing lemma.  Then the indicated
goal, G, is replaced by the implication (implies F G).  The intention
is that the truth of F will help in the simplification of G to T
(true).  The "[Use]" warning shown above is telling us of the danger
that F may be rewritten to T, reducing the implication above to
(implies T G) -- thus, sadly, F has disappeared and is not available to
help with the simplification of G.

Consider the following tiny example.

       (defun p (x) (cons x x))
       (defthm car-p
          (equal (car (p x)) x))
       (in-theory (disable p (:type-prescription p)))
       (thm (implies (equal (p x1) (p x2))
                     (equal x1 x2))
            :hints (("Goal"
                     :use ((:instance car-p (x x1))
                           (:instance car-p (x x2))))))

The proof of the final thm form fails, because the new hypotheses are
rewritten to t using the :rewrite rule CAR-P, in the manner described
above.  The following proof log shows the new hypotheses and their
disappearance via rewriting.

       We augment the goal with the hypotheses provided by the :USE hint.
       These hypotheses can be derived from CAR-P via instantiation.  We are
       left with the following subgoal.

       Goal'
       (IMPLIES (AND (EQUAL (CAR (P X1)) X1)
                     (EQUAL (CAR (P X2)) X2))
                (IMPLIES (EQUAL (P X1) (P X2))
                         (EQUAL X1 X2))).

       By the simple :rewrite rule CAR-P we reduce the conjecture to

       Goal''
       (IMPLIES (EQUAL (P X1) (P X2))
                (EQUAL X1 X2)).

When we disable the rule CAR-P as follows, the proof succeeds.

       (thm (implies (equal (p x1) (p x2))
                     (equal x1 x2))
            :hints (("Goal"
                     :use ((:instance car-p (x x1))
                           (:instance car-p (x x2)))
                     :in-theory (disable car-p))))

In general, then, a solution is to disable the rewrite rule that you are
supplying in a :use hint.


File: acl2-doc-emacs.info,  Node: VERSION,  Next: WATERFALL,  Prev: USING-ENABLED-RULES,  Up: MISCELLANEOUS

VERSION    ACL2 Version Number

To determine the version number of your copy of ACL2, evaluate the form
(@ acl2-version).  The value will be a string.  For example,

     ACL2 !>(@ acl2-version)
     "ACL2 Version 3.4"

The part of the string after "ACL2 Version " is of the form x.y or
x.y.z, optionally followed by a succession of values in parentheses,
where x, y, and z are natural numbers.  If z is omitted then it is
implicitly 0.  We refer to X, y, and z as the "major", "minor", and
"incrl" fields, respectively.  The incrl field is used for incremental
releases.  The discussion just below assumes that incremental releases
are not employed at the user's site, i.e., the incrl fields are always
0.  We remove this assumption when we discuss incremental releases at
the end of this documenttation topic.

Books are considered certified only in the same version of ACL2 in
which the certification was done.  The certificate file records the
version number of the certifying ACL2 and include-book considers the
book uncertified if that does not match the current version number.
Thus, each time we release a new version of ACL2, previously certified
books should be recertified.

Note that there are over 150 constants in the system, most having to do
with the fact that ACL2 is coded in ACL2.  Many of these, for example
*common-lisp-specials-and-constants* and *acl2-exports*, may change
from version to version, and this can cause unsoundness.  For example,
the symbol 'set-difference-eq was added to *acl2-exports* in
Version_2.9, so we can certify a book in Version_2.8 containing the
following theorem, which is false in Version_2.9.

     (null (member 'set-difference-eq *acl2-exports*))

Therefore, we need to disallow inclusion of such a book in a Version_2.9
session, which otherwise would allow us to prove nil.  Furthermore, it
is possible that from one version of the system to another we might
change, say, the default values on some system function or otherwise
make "intentional" changes to the axioms.  It is even possible one
version of the system is discovered to be unsound and we release a new
version to correct our error.

Therefore we adopted the draconian policy that books are certified by a
given version of ACL2 and "must" be recertified to be used in other
versions.  We put "must" in quotes because in fact, ACL2 allows a book
that was certified in one ACL2 version to be included in a later
version, using include-book.  But ACL2 does not allow certify-book to
succeed when such an include-book is executed on its behalf.  Also, you
may experience undesirable behavior if you avoid recertification when
moving to a different version.  Hence we recommend that you stick to
the draconion policy of recertifying books when updating to a new ACL2
version.

The string (@ acl2-version) can contain implementation-specific
information in addition to the version number.  For example, in
Macintosh Common Lisp (MCL) (char-code #Newline) is 13, while as far as
we know, it is 10 in every other Common Lisp.  Our concern is that one
could certify a book in an MCL-based ACL2 with the theorem

     (equal (char-code #Newline) 13)

and then include this book in another Lisp and thereby prove nil.  So,
when a book is certified in an MCL-based ACL2, the book's certificate
mentions "MCL" in its version string.  Moreover, (@ acl2-version)
similarly mentions "MCL" when the ACL2 image has been built on top of
MCL.  Thus, an attempt to include a book in an MCL-based ACL2 that was
certified in a non-MCL-based ACL2, or vice-versa, will be treated like
an attempt to include an uncertified book.

_Incremental releases._

From time to time, so-called "incremental releases" of ACL2 are made
available.  These releases are thoroughly tested on at least two
platforms; "normal" releases, on the other hand, are thoroughly tested
on many more platforms (perhaps a dozen or so) and are accompanied by
updates to the ACL2 home page.  We provide incremental releases in
order to provide timely updates for ACL2 users who want them, without
imposing unnecessary burdens on either on the ACL2 implementors or on
ACL2 users who prefer to update less frequently.  The implementors
expect users to update their copies of ACL2 when normal releases are
made available, but not necessarily when incremental releases are made
available.

Incremental releases are accompanied by a bump in the incrl field of the
version field, while normal releases are accompanied by a bump in the
minor or (much less frequently) major field and zeroing out of the
incrl field.  Note that incremental releases are full-fledged releases.


File: acl2-doc-emacs.info,  Node: WATERFALL,  Next: WHY-BRR,  Prev: VERSION,  Up: MISCELLANEOUS

WATERFALL    See *note HINTS-AND-THE-WATERFALL::.


File: acl2-doc-emacs.info,  Node: WHY-BRR,  Next: WORLD,  Prev: WATERFALL,  Up: MISCELLANEOUS

WHY-BRR    an explanation of why ACL2 has an explicit brr mode

Why isn't brr mode automatically disabled when there are no monitored
runes?  The reason is that the list of monitored runes is kept in a
wormhole state.

See *note WORMHOLE:: for more information on wormholes in general.  But
the fundamental property of the wormhole function is that it is a
logical no-op, a constant function that does not take state as an
argument.  When entering a wormhole, arbitrary information can be
passed in (including the external state).  That information is used to
construct a near copy of the external state and that "wormhole state"
is the one with respect to which interactions occur during breaks.  But
no information is carried by ACL2 out of a wormhole -- if that were
allowed wormholes would not be logical no-ops.  The only information
carried out of a wormhole is in the user's head.

Break-rewrite interacts with the user in a wormhole state because the
signature of the ACL2 rewrite function does not permit it to modify
state.  Hence, only wormhole interaction is possible.  (This has the
additional desirable property that the correctness of the rewriter does
not depend on what the user does during interactive breaks within it;
indeed, it is logically impossible for the user to affect the course of
rewrite.)

Now consider the list of monitored runes.  Is that kept in the external
state as a normal state global or is it kept in the wormhole state?  If
it is in the external state then it can be inspected within the
wormhole but not changed.  This is unacceptable; it is common to change
the monitored rules as the proof attempt progresses, installing
monitors when certain rules are about to be used in certain contexts.
Thus, the list of monitored runes must be kept as a wormhole variable.
Hence, its value cannot be determined outside the wormhole, where the
proof attempt is ongoing.

This raises another question: If the list of monitored runes is unknown
to the rewriter operating on the external state, how does the rewriter
know when to break?  The answer is simple: it breaks every time, for
every rune, if brr mode is enabled.  The wormhole is entered
(silently), computations are done within the wormhole state to
determine if the user wants to see the break, and if so, interactions
begin.  For unmonitored runes and runes with false break conditions,
the silent wormhole entry is followed by a silent wormhole exit and the
user perceives no break.

Thus, the penalty for running with brr mode enabled when there are no
monitored runes is high: a wormhole is entered on every application of
every rune and the user is simply unware of it.  The user who has
finally unmonitored all runes is therefore strongly advised to carry
this information out of the wormhole and to do :brr nil in the external
state when the next opportunity arises.


File: acl2-doc-emacs.info,  Node: WORLD,  Next: WORMHOLE,  Prev: WHY-BRR,  Up: MISCELLANEOUS

WORLD    ACL2 property lists and the ACL2 logical database

The ACL2 logical world is a data structure that includes all logical
content resulting from the commands evaluated, back through and
including initialization, but not including commands that have been
undone (see *note UBT::).  Thus in particular, the world includes a
represention of the current logical theory, as well as some
extra-logical information such as the values of ACL2 tables.  The rest
of this topic focuses on the structure of the the ACL2 world and, more
generally, the "world" data structure.

A "world" is a list of triples, each of the form (sym prop . val),
implementing the ACL2 notion of property lists.  ACL2 permits the
simultaneous existence of many property list worlds.  "The world" is
often used as a shorthand for "the ACL2 logical world" which is the
particular property list world used within the ACL2 system to maintain
a database that contiains rules, tables, and so on.

Common Lisp provides the notion of "property lists" by which one can
attach "properties" and their corresponding "values" to symbols.  For
example, one can arrange for the 'color property of the symbol 'box-14
to be 'purple and the 'color property of the symbol 'triangle-7 to be
'yellow.  Access to property lists is given via the Common Lisp function
get.  Thus, (get 'box-14 'color) might return 'purple.  Property lists
can be changed via the special form setf.  Thus, (setf (get 'box-14
'color) 'blue) changes the Common Lisp property list configuration so
that (get 'box-14 'color) returns 'blue.  It should be obvious that
ACL2 cannot provide this facility, because Common Lisp's get "function"
is not a function of its argument, but instead a function of some
implicit state object representing the property list settings for all
symbols.

ACL2 provides the functions getprop and putprop which allow one to
mimic the Common Lisp property list facility.  However, ACL2's getprop
takes as one of its arguments a list that is a direct encoding of what
was above called the "state object representing the property list
settings for all symbols."  Because ACL2 already has a notion of
"state" that is quite distinct from that used here, we call this
property list object a "world."  A world is just a true list of
triples.  Each triple is of the form (sym prop . val).  This world can
be thought of as a slightly elaborated form of association list and
getprop is a slightly elaborated form of assoc that takes two keys.
When getprop is called on a symbol, s, property p, and world, w, it
scans w for the first triple whose sym is s and prop is p and returns
the corresponding val. Getprop has two additional arguments, one of
which that controls what it returns if no such sym and prop exist in w,
and other other of which allows an extremely efficient implementation.
To set some property's value for some symbol, ACL2 provides putprop.
(putprop sym prop val w) merely returns a new world, w', in which (sym
prop . val) has been consed onto the front of w, thus "overwriting" the
prop value of sym in w to val and leaving all other properties in w
unchanged.

One aspect of ACL2's property list arrangment is that it is possible to
have many different property list worlds.  For example, 'box-14 can have
'color 'purple in one world and can have 'color 'yes in another, and
these two worlds can exist simultaneously because getprop is explicitly
provided the world from which the property value is to be extracted.

The efficiency alluded to above stems from the fact that Common Lisp
provides property lists.  Using Common Lisp's provisions behind the
scenes, ACL2 can "install" the properties of a given world into the
Common Lisp property list state so as to make retrieval via getprop
very fast in the special case that the world provided to getprop has
been installed.  To permit more than one installed world, each of which
is permitted to be changed via putprop, ACL2 requires that worlds be
named and these names are used to distinquish installed versions of the
various worlds.  At the moment we do not further document getprop and
putprop.

However, the ACL2 system uses a property list world, named
'current-acl2-world, in which to store the succession of user commands
and their effects on the logic.  This world is often referred to in our
documentation as "the world" though it should be stressed that the user
is permitted to have worlds and ACL2's is in no way distinguished
except that the user is not permitted to modify it except via event
commands.  The ACL2 world is part of the ACL2 state and may be obtained
via (w state).

*Warning*: The ACL2 world is very large.  Its length as of this writing
(Version 2.5) is over 40,000 and it grows with each release.
Furthermore, some of the values stored in it are pointers to old
versions of itself.  Printing (w state) is something you should avoid
because you likely will not have the patience to await its completion.
For these practical reasons, the only thing you should do with (w
state) is provide it to getprop, as in the form

       (getprop sym prop default 'current-acl2-world (w state))

to inspect properties within it, or to pass it to ACL2 primitives, such
as theory functions, where it is expected.

Some ACL2 command forms, such as theory expressions (see *note
THEORIES::) and the values to be stored in tables (see *note TABLE::),
are permitted to use the variable symbol world freely with the
understanding that when these forms are evaluated that variable is bound
to (w state).  Theoretically, this gives those forms complete knowledge
of the current logical configuration of ACL2.  However, at the moment,
few world scanning functions have been documented for the ACL2 user.
Instead, supposedly convenient macro forms have been created and
documented.  For example, (current-theory :here), which is the theory
expression which returns the currently enabled theory, actually
macroexpands to (current-theory-fn :here world).  When evaluated with
world bound to (w state), current-theory-fn scans the current ACL2
world and computes the set of runes currently enabled in it.


File: acl2-doc-emacs.info,  Node: WORMHOLE,  Next: WORMHOLE-DATA,  Prev: WORLD,  Up: MISCELLANEOUS

WORMHOLE    ld without state -- a short-cut to a parallel universe

     Example Form:
     ; The following form enters a recursive read-eval-print loop on a
     ; copy of the current state, allowing you to interact with that loop.
     ; Note that the form does not mention the ACL2 state variable!
     ; Evaluate the form below. Inside the resulting loop, define some function,
     ; e.g., with (defun foo (x) x).  Then exit with :q and observe,
     ; e.g., with :pe foo, that the external state did not change.

     (wormhole 'foo
               '(lambda (whs) (set-wormhole-entry-code whs :ENTER))
               nil
               '(list 'hello 'there))

     General Form:
     (wormhole name entry-lambda input form
       :current-package    ...  ; known package name
       :ld-skip-proofsp    ...  ; nil, t or 'include-book
       :ld-redefinition-action  ; nil or '(:a . :b)
       :ld-prompt          ...  ; nil, t, or some prompt printer fn
       :ld-missing-input-ok ... ; nil, t, :warn, or warning message
       :ld-pre-eval-filter ...  ; :all, :query, or some new name
       :ld-pre-eval-print  ...  ; nil, t, or :never
       :ld-post-eval-print ...  ; nil, t, or :command-conventions
       :ld-evisc-tuple     ...  ; nil or '(alist level length hiding-cars)
       :ld-error-triples   ...  ; nil or t
       :ld-error-action    ...  ; :return!, :return, :continue, or :error
       :ld-query-control-alist  ; alist supplying default responses
       :ld-verbose         ...) ; nil or t

The keyword arguments above are exactly those of ld (see *note LD::)
except that three of ld's keyword arguments are missing: the three that
specify the channels standard-oi, standard-co and proofs-co, which
default in wormhole to ACL2's comment window.

There are two ways to create and enter a wormhole:  wormhole as
described here and the simpler wormhole-eval.  We recommend you read
this full account of wormholes before using wormhole-eval.

Ignoring the use of entry-lambda, wormhole manufactures a named
"wormhole state" and calls the general-purpose ACL2 read-eval-print
loop ld on it.  However, when ld exits, the wormhole evaporates and the
function wormhole returns nil.  The manufactured state is like the
"current" ACL2 state except for two things.  First, some information
from the last wormhole state of this name is transferred into the new
state; this allows a wormhole to maintain some state from one call to
the next.  Second, some information from the wormhole call itself is
transferred into the new state; this allows the wormhole to be
sensitive to context.  These two changes to the current state are
reflected in the settings (@ wormhole-status) and (@ wormhole-input)
discussed in detail below.

Note that wormhole may be called from environments in which state is
not bound.  It is still applicative because it always returns nil.

There are some restrictions about what can be done inside a wormhole.
As you may imagine, we really do not "copy the current state" but
rather just keep track of how we modified it and undo those
modifications upon exit.  An error is signalled if you try to modify
state in an unsupported way.  For this same reason, wormholes do not
allow updating of any user-defined single-threaded objects.  See *note
STOBJ::.

One example wormhole is the implementation of the ACL2
accumulated-persistence facility for tracking the frequency with which
rules are tried.  To implement this feature directly the theorem prover
would have to take the tracking data as an argument and pass it around
so that updates could be accumulated.  This would greatly clutter the
code.  Instead, the tracking data is maintained in a wormhole.  The
theorem prover enters the wormhole to update the data as rules are
tried.  When you request a display of the data,
show-accumulated-persistence enters the wormhole and prints the data.
But the data is never available outside that wormhole.  The ACL2 system
uses a second wormhole to implement the brr facility, allowing the user
to interact with the rewriter as rules are applied.

We now specify the arguments and behavior of wormhole.

The name argument must be a quoted constant and is typically a symbol.
It will be the "name" of the wormhole.  A wormhole of that name will be
created the first time either wormhole or wormhole-eval is called.

Every wormhole name has a "status."  The status of a wormhole is stored
outside of ACL2; it is inaccessible to the ACL2 user except when in the
named wormhole.  But the status of a wormhole may be set by the user
from within the wormhole.

Upon the first call of wormhole or wormhole-eval on a name, the status
of that name is nil.  But in general you should arrange for the status
to be a cons.  The status is set by the quoted lambda every time
wormhole is called; but it may also be set in the form argument (the
first form evaluated in the interactive loop) by assigning to the state
global variable wormhole-status, as with

     (assign wormhole-status ...)

or even by the user interacting with the loop if you do not exit the
loop with the first form.  The car of the cons should be either :ENTER
or :SKIP and is called the wormhole's "entry code."  The entry code of
nil or an unexpectedly shaped status is :ENTER.  The cdr of the cons is
arbitrary data maintained by you.

When wormhole is invoked, the status of the specified name is
incorporated into the manufactured wormhole state.  In particular,
inside the wormhole, the status is the value of the state global
variable wormhole-status.  That is, inside the wormhole, the status may
be accessed by (@ wormhole-status) and set by (assign wormhole-status
...), f-get-global and f-put-global.  When ld exits - typically because
the form :q was read by ld - the then-current value of wormhole-status
is hidden away so that it can be restored when this wormhole is entered
again.  The rest of the wormhole state is lost.

This allows a sequence of entries and exits to a wormhole to maintain
some history in the status and this information can be manipulated by
ACL2 functions executing inside the wormhole.

The second argument to wormhole must be a quoted lambda expression.  We
explain it later.

The third argument, input, may be any term.  The value of the term is
passed into the manufactured wormhole state, allowing you to pass in
information about the calling context.  Inside the wormhole, the input
is available via (@ wormhole-input).  It could be reassigned via
(assign wormhole-input ...), but there is no reason to do that.

The fourth argument, form, may be any term; when ld is called on the
manufactured wormhole state, the first form evaluated by ld will be the
value of form.  Note that form will be translated by ld.  Errors,
including guard violations, in the translation or execution of that
first form will leave you in the interactive loop of the wormhole state.

When used properly, the first form allows you to greet your user before
reading the first interactive command or simply to do whatever
computation you want to do inside the wormhole and exit silently.  We
give examples below.

Manufacturing a wormhole state is relatively expensive; in addition, the
forms executed by ld must be read, translated, and interpreted as with
any user type-in.  The entry-lambda offers a way to avoid this or, at
least, to decide whether to incur that expense.

Before the wormhole state is manufactured and entered, the entry-lambda
is applied to the current wormhole status with wormhole-eval.  That
lambda application must produce a new wormhole status, which is stored
as the wormhole's status.  The entry code for the new status determines
whether wormhole actually manufactures a wormhole state and calls ld.

If the entry code for that new status is :ENTER the wormhole state is
manufactured and entered; otherwise, the new status is simply saved as
the most recent status but the wormhole state is not manufactured or
entered.  Note therefore that the entry-lambda may be used to perform
two functions: (a) to determine if it is really necessary to
manufacture a state and (b) to update the data in the wormhole status
as a function of the old status without invoking ld.

The entry-lambda must be a quoted lambda expression of at most one
argument.  Thus, the argument must be either

     '(lambda (whs) <body>)

or

     '(lambda () <body>)

Note the quote.  If a formal, e.g., whs, is provided, it must be used as
a variable in the lambda body.  The lambda-expression may contain free
variables, that is, the body may mention variables other than the
lambda formal.  These free variables are understood in the caller's
environment.  These conventions allow us to compile the entry-lambda
application very efficiently when the guard has been verified.

The guard on a call of wormhole is the conjunction of the guards on the
arguments conjoined with the guard on the body of the entry-lambda.
See *note WORMHOLE-EVAL:: for a discussion of the guard on the
lambda-expression.

The functions wormhole-statusp, wormhole-entry-code, wormhole-data,
set-wormhole-entry-code, set-wormhole-data, and make-wormhole-status
may be useful in manipulating entry codes and data in the entry-lambda.

Note that you access and manipulate the wormhole's status in two
different ways depending on whether you're "outside" of the wormhole
applying the quoted lambda or "inside" the read-eval-print loop of the
wormhole.

OUTSIDE (wormhole-eval): access via the value of the lambda formal and
set by returning the new status as the value of the lambda body.

INSIDE (ld phase of wormhole): access via (@ wormhole-status), and set
via (assign wormhole-status ...).

Pragmatic Advice on Designing a Wormhole: Suppose you are using
wormholes to implement some extra-logical utility.  You must
contemplate how you will use your wormhole's status to store hidden
information.  You might be tempted to exploit the entry code as part of
the status.  For example, you may think of :ENTER as indicating that
your utility is "turned on" and :SKIP as indicating that your utility
is "turned off."  We advise against such a design.  We recommend you
base your decisions on the wormhole data.  We recommend that you set
but not read the wormhole entry code to signal whether you wish to
enter a full-fledged wormhole.  To use the entry code as a flag
overloads it and invites confusion when your facility is "turned off"
but you have to enter the wormhole for some reason.

For a behind-the-scenes description of how wormholes work, See *note
WORMHOLE-IMPLEMENTATION::.

Here are some sample situations handled by wormhole-eval and wormhole.
Let the wormhole in question be named DEMO.  Initially its status is
NIL.  The functions below all maintain the convention that the status
is either nil or of the form (:key . lst), where :key is either :SKIP
or :ENTER and lst is a true-list of arbitrary objects.  But since there
is no way to prevent the user from entering the DEMO wormhole
interactively and doing something to the status, this convention cannot
be enforced.  Thus, the functions below do what we say they do, e.g.,
remember all the values of x ever seen, only if they're the only
functions messing with the DEMO status.  On the other hand, the guards
of all the functions below can be verified.  We have explicitly
declared that the guards on the functions below are to be verified, to
confirm that they can be.  Guard verification is optional but wormholes
(and wormhole-eval in particular) are more efficient when guards have
been verified.  All of the functions defined below return nil.

The examples below build on each other.  If you really want to
understand wormholes we recommend that you evaluate each of the forms
below, in the order they are discussed.

Q. How do I create a wormhole that prints its status to the comment
window?

     (defun demo-status ()
       (declare (xargs :verify-guards t))
       (wormhole-eval 'demo
                      '(lambda (whs)
                         (prog2$ (cw "DEMO status:~%~x0~%" whs)
                                 whs))
                      nil))

Note above that after printing the status to the comment window we
return the new (unchanged) status whs.  Had we just written the call of
cw, which returns nil, the function would print the status and then set
it to nil!

Q.  How do I use a wormhole to collect every symbol, x, passed to the
function?

     (defun demo-collect (x)
       (declare (xargs :verify-guards t))
       (wormhole-eval 'demo
                      '(lambda (whs)
                         (make-wormhole-status whs
                                               (wormhole-entry-code whs)
                                               (if (symbolp x)
                                                   (cons x (wormhole-data whs))
                                                   (wormhole-data whs))))
                      nil))

We could have also defined this function this way:

     (defun demo-collect (x)
       (declare (xargs :verify-guards t))
       (if (symbolp x)
           (wormhole-eval 'demo
                          '(lambda (whs)
                             (set-wormhole-data whs
                                                (cons x (wormhole-data whs))))
                          nil)
           nil))

Both versions always return nil and both versions collect into the
wormhole data field just the symbols x upon which demo-collect is
called.

Q.  How do I use demo-collect?  Below is a function that maps over a
list and computes its length.  But it has been annotated with a call to
demo-collect on every element.

      (defun my-len (lst)
        (if (endp lst)
            0
            (+ 1
               (prog2$ (demo-collect (car lst))
                       (my-len (cdr lst))))))

Thus, for example:

     ACL2 !>(my-len '(4 temp car "Hi" rfix))
     5
     ACL2 !>(demo-status)
     DEMO status:
     (:ENTER RFIX CAR TEMP)
     NIL
     ACL2 !>

Q.  How do I set the entry code to :ENTER or :SKIP according to whether
name is a member-equal of the list of things seen so far?  Note that we
cannot check this condition outside the wormhole, because it depends on
the list of things collected so far.  We make the decision inside the
lambda-expression.  Note that we explicitly check that the guard of
member-equal is satisfied by the current wormhole status, since we
cannot rely on the invariant that no other function interferes with the
status of the DEMO wormhole.  In the case that the status is
"unexpected" we act like the status is nil and set it to (:SKIP . NIL).

     (defun demo-set-entry-code (name)
       (declare (xargs :verify-guards t))
       (wormhole-eval 'demo
                      '(lambda (whs)
                         (if (true-listp (wormhole-data whs))
                             (set-wormhole-entry-code
                              whs
                              (if (member-equal name (wormhole-data whs))
                                  :ENTER
                                  :SKIP))
                             '(:SKIP . NIL)))
                      nil))

Thus

     ACL2 !>(demo-set-entry-code 'monday)
     NIL
     ACL2 !>(demo-status)
     DEMO status:
     (:SKIP RFIX CAR TEMP)
     NIL
     ACL2 !>(demo-set-entry-code 'rfix)
     NIL
     ACL2 !>(demo-status)
     DEMO status:
     (:ENTER RFIX CAR TEMP)
     NIL
     ACL2 !>

Q.  Suppose I want to collect every symbol and then, if the symbol has
an ABSOLUTE-EVENT-NUMBER property in the ACL2 logical world, print the
defining event with :pe and then enter an interactive loop; but if the
symbol does not have an ABSOLUTE-EVENT-NUMBER, don't print anything and
don't enter an interactive loop.

Here it is not important to know what ABSOLUTE-EVENT-NUMBER is; this
example just shows that we can use a wormhole to access the ACL2 logical
world, even in a function that does not take the state as an argument.

In the code below, we use wormhole instead of wormhole-eval, because we
might have to access the logical world and enter an interactive loop.
But for efficiency we do as much as we can inside the entry lambda,
where we can check whether x is symbol and collect it into the data
field of the wormhole status.  Note that if we collect x, we also set
the entry code to :ENTER.  If we don't collect x, we set the entry code
to :SKIP.

     (defun collect-symbols-and-print-events (x)
       (declare (xargs :guard t))
       (wormhole 'demo
                 '(lambda (whs)
                    (if (symbolp x)
                        (make-wormhole-status whs
                                              :ENTER
                                              (cons x (wormhole-data whs)))
                        (set-wormhole-entry-code whs :SKIP)))

     ; The wormhole will not get past here is unless the entry code is
     ; :ENTER.  If we get past here, we manufacture a state, put
     ; x into (@ wormhole-input) and call ld in such a way that the
     ; first form executed is the quoted if-expression below.

                 x
                 '(if (getprop (@ wormhole-input)
                               'absolute-event-number
                               nil
                               'CURRENT-ACL2-WORLD (w state))
                      (er-progn
                       (mv-let (col state)
                               (fmt "~%Entering a wormhole on the event name ~x0~%"
                                    (list (cons #\0 (@ wormhole-input)))
                                    *standard-co* state nil)
                               (declare (ignore col))
                               (value nil))
                       (pe (@ wormhole-input))
                       (set-ld-prompt 'wormhole-prompt state)
                       (value :invisible))
                      (value :q))
                 :ld-verbose nil
                 :ld-prompt nil))

The "first form" (the if) asks whether the wormhole-input (i.e., x) has
an ABSOLUTE-EVENT-NUMBER property.  If so, it enters an er-progn to
perform a sequence of commands, each of which returns an ACL2 error
triple (see *note PROGRAMMING-WITH-STATE::).  The first form uses fmt
to print a greeting.  Since fmt returns (mv col state) and we must
return an error triple, we embed the fmt term in an (mv-let (col state)
... (value nil)).  The macro value takes an object and returns a
"normal return" error triple.  The second form in the er-progn uses the
ACL2 history macro pe (see *note PE::) to print the defining event for
a name.  The third form sets the prompt of this read-eval-print loop to
the standard function for printing the wormhole prompt.  We silenced
the printing of the prompt when we called ld, thanks to the :ld-prompt
nil keyword option.  More on this below.  The fourth form returns the
error triple value :invisible as the value of the first form.  This
prevents ld from printing the value of the first form.  Since we have
not exited ld, that function just continues by reading the next form
from the comment window.  The user perceives this as entering a
read-eval-print loop.  We continue in the loop until the user types :q.

On the other branch of the if, if the symbol has no
ABSOLUTE-EVENT-NUMBER property, we execute the form (value :q), which
is the programming equivalent of typing :q.  That causes the ld to exit.

The ld special variables set in the call to wormhole and further
manipulated inside the first form to ld may require explanation.  By
setting :ld-verbose to nil, we prevent ld from printing the familiar
ACL2 banner when ld is called.  If :ld-verbose nil is deleted, then you
would see something like

     ACL2 Version  4.0.  Level 2.
     ...
     Type (good-bye) to quit completely out of ACL2.

before the first form is read and evaluated.

By setting :ld-prompt to nil we prevent ld from printing the prompt
before reading and evaluating the first form.

As this example shows, to use full-blown wormholes you must understand
the protocol for using wormhole status to control whether a wormhole
state is manufactured for ld and you must also understand programming
with state and the effects of the various ld "special variables."

From the discussion above we see that wormholes can be used to create
formatted output without passing in the ACL2 state.  For examples see
*note CW::, in particular the discussion at the end of that
documentation topic.


File: acl2-doc-emacs.info,  Node: WORMHOLE-DATA,  Next: WORMHOLE-ENTRY-CODE,  Prev: WORMHOLE,  Up: MISCELLANEOUS

WORMHOLE-DATA    determines the wormhole data object from a wormhole status object

     General Form:  (wormhole-data whs)

See *note WORMHOLE::.  Returns the wormhole data from a well-formed
wormhole status whs.  If whs is nil or not well-formed, the data is nil.


File: acl2-doc-emacs.info,  Node: WORMHOLE-ENTRY-CODE,  Next: WORMHOLE-EVAL,  Prev: WORMHOLE-DATA,  Up: MISCELLANEOUS

WORMHOLE-ENTRY-CODE    determines the wormhole entry code from a wormhole status object

     General Form:  (wormhole-entry-code whs)

See *note WORMHOLE::.  Returns :ENTER or :SKIP given a well-formed
wormhole status whs.  If whs is nil or not well-formed, the entry code
is :ENTER.


File: acl2-doc-emacs.info,  Node: WORMHOLE-EVAL,  Next: WORMHOLE-IMPLEMENTATION,  Prev: WORMHOLE-ENTRY-CODE,  Up: MISCELLANEOUS

WORMHOLE-EVAL    state-saving without state -- a short-cut to a parallel universe

     Example Form:
     (wormhole-eval 'demo
        '(lambda (whs)
           (set-wormhole-data whs
                              (cons (cons name info)
                                    (wormhole-data whs))))
        (prog2$ info name))

     General Form:
     (wormhole-eval name lambda varterm)

where name must be a quoted wormhole name and lambda must be a quoted
lambda-expression.  The lambda-expression must have at most one formal
parameter but the body of the lambda-expression may contain other
variables.  Note that in the example form given above, the lambda has
one formal, whs, and uses name and info freely.  Note that the lambda
is quoted.  The third argument of wormhole-eval, varterm, is an
arbitrary term that should mention all of the free variables in the
lambda-expression.  That term establishes your "right" to refer to
those free variables in the environment in which the wormhole-eval
expression occurs.  The value of varterm is irrelevant and if you
provide nil ACL2 will automatically provide a suitable term, namely a
prog2$ form like the one shown in the example above.

Aside: Exception for ACL2(p) (see *note PARALLELISM::) to the
irrelevance of varterm.  By default, calls of wormhole-eval employ a
lock, *wormhole-lock*.  To avoid such a lock, include the symbol
:NO-WORMHOLE-LOCK in varterm; for example, you might replace a last
argument of nil in wormhole-eval by :NO-WORMHOLE-LOCK.  End of Aside.

See *note WORMHOLE:: for a full explanation of wormholes.  Most
relevant here is that every wormhole has a name and a status.  The
status is generally a cons pair whose car is the keyword :ENTER or the
keyword :SKIP and whose cdr is an arbitrary object used to store
information from one wormhole call to the next.

Here is a succinct summary of wormhole-eval.  If the lambda-expression
has a local variable, wormhole-eval applies the lambda-expression to
the wormhole status of the named wormhole and remembers the value as
the new wormhole status.  If the lambda has no formal parameter, the
lambda is applied to no arguments and the value is the new status.
Wormhole-eval returns nil.  Thus, the formal parameter of the
lambda-expression, if provided, denotes the wormhole's hidden status
information; the value of the lambda is the new status and is hidden
away.

The guard of a wormhole-eval call is the guard of the body of the
lambda-expression, with a fresh variable symbol used in place of the
formal so that no assumptions are possible about the hidden wormhole
status.  If the guard of a wormhole-eval is verified, the call is
macroexpanded inline to the evaluation of the body in a suitable
environment.  Thus, it can be a very fast way to access and change
hidden state information, but the results must remain hidden.  To do
arbitrary computations on the hidden state (i.e., to access the ACL2
state or logical world or to interact with the user) see *note
WORMHOLE::.

Functions that are probably useful in the body of the lambda or the
guard of a function using wormhole-eval include the following:
wormhole-statusp, wormhole-entry-code, wormhole-data,
set-wormhole-entry-code, set-wormhole-data, and make-wormhole-status.

See *note WORMHOLE:: for a series of example uses of wormhole-eval and
wormhole.

For a behind-the-scenes description of how wormholes work, See *note
WORMHOLE-IMPLEMENTATION::.


File: acl2-doc-emacs.info,  Node: WORMHOLE-IMPLEMENTATION,  Next: WORMHOLE-P,  Prev: WORMHOLE-EVAL,  Up: MISCELLANEOUS

WORMHOLE-IMPLEMENTATION    notes on how wormholes are implemented

What happens when you call wormhole?  Recall that a typical call of the
function looks like this:

     (wormhole 'name
               '(lambda (whs) ...)
               input
               form
               :ld-verbose ...
               ...)

A brief recap of the advertised semantics for wormhole establishes our
terminology: When the above wormhole is evaluated, the
lambda-expression is applied to the wormhole's status and the result is
stored as the new status.  Then, if the entry-code of the new status is
:ENTER, ld is invoked on a copy of the "current state" with the
specified ld- "special variables;" output is directed to the comment
window.  In that copy of the state, the state-global variable
wormhole-input is set to the value of input and the state-global
variable wormhole-status is set to the (new) status computed by the
lambda-expression.  Thus, inside the wormhole, (@ wormhole-input)
returns the list of inputs, (@ wormhole-status) returns the current
status, and (assign wormhole-status ...) sets the wormhole's status.
The first form executed by the ld is the value of form and unless that
form returns (value :q), causing the ld to quit, the ld proceeds to
take subsequent input from the comment window.  Upon exiting from ld,
the wormhole state "evaporates."  The wormhole's status upon exit is
remembered and restored the next time the wormhole is entered.

Here is what really happens.

Each wormhole's status is recorded in an alist stored in a Common Lisp
global variable named *wormhole-status-alist*.  This variable is not
part of the ACL2 state.  If you exit the ACL2 loop with :q you can
inspect the value of *wormhole-status-alist*.  When the
lambda-expression is evaluated it is applied to the value associated
with name in the alist and the result is stored back into that alist.
This step is performed by wormhole-eval.  To make things more
efficient, wormhole-eval is just a macro that expands into a let that
binds the lambda formal to the current status and whose body is the
lambda body.  Guard clauses are generated from the body, with one
exception:  the lambda formal is replaced by a new variable so that no
prior assumptions are available about the value of the the wormhole
status.

If the newly computed status has an entry code of :ENTER ld will be
invoked.  But we don't really copy state, of course.  Instead we will
invoke ld on the live state, which is always available in the von
Neumann world in which ACL2 is implemented.  To give the illusion of
copying state, we will undo changes to the state upon exiting.  To
support this, we do two things just before invoking ld: we bind a
Common Lisp special variable is to t to record that ACL2 is in a
wormhole, and we initialize an accumulator that will be used to record
state changes made while in the wormhole.

Then ld is invoked, with first argument, standard-oi, being set to
(cons form *standard-oi*).  According to the standard semantics of ld,
this reads and evaluates form and then the forms in the specified
channel.  The standard channels are directed to and from the terminal,
which is the physical realization of the comment window.

All state modifying functions of ACL2 are sensitive to the special
variable that indicates that evaluation is in a wormhole.  Some ACL2
state-modifying functions (e.g., those that modify the file system like
write-byte$) are made to cause an error if invoked inside a wormhole on
a file other than the terminal.  Others, like f-put-global (the
function behind such features as assign and maintenance of the ACL2
logical world by such events as defun and defthm) are made to record
the old value of the state component being changed; these records are
kept in the accumulator initialized above.

Upon exit from ld for any reason, the final value of (@ wormhole-status)
is stored in *wormhole-status-alist* and then the accumulator is used to
"undo" all the state changes.

Wormhole always returns nil.


File: acl2-doc-emacs.info,  Node: WORMHOLE-P,  Next: WORMHOLE-STATUSP,  Prev: WORMHOLE-IMPLEMENTATION,  Up: MISCELLANEOUS

WORMHOLE-P    predicate to determine if you are inside a wormhole

See *note WORMHOLE:: for a discussion of wormholes.  (Wormhole-p state)
returns (mv nil t state) when evaluated inside a wormhole, else (mv nil
nil state).


File: acl2-doc-emacs.info,  Node: WORMHOLE-STATUSP,  Next: XARGS,  Prev: WORMHOLE-P,  Up: MISCELLANEOUS

WORMHOLE-STATUSP    predicate recognizing well-formed wormhole status object

     General Form:  (wormhole-statusp whs)

See *note WORMHOLE::.  This predicate is useful in guards for
wormholes.  It checks whether whs is either nil or a cons whose car is
:ENTER or :SKIP.


File: acl2-doc-emacs.info,  Node: XARGS,  Prev: WORMHOLE-STATUSP,  Up: MISCELLANEOUS

XARGS    extra arguments, for example to give hints to defun

Common Lisp's defun function does not easily allow one to pass extra
arguments such as "hints".  ACL2 therefore supports a peculiar new
declaration (see *note DECLARE::) designed explicitly for passing
additional arguments to defun via a keyword-like syntax.  This
declaration can also be used with defmacro, but only for xargs keyword
:GUARD; so we restrict attention below to use of xargs in defun events.

The following declaration is nonsensical but does illustrate all of the
xargs keywords for defun (which are the members of the list
*xargs-keywords*).

     (declare (xargs :guard (symbolp x)
                     :guard-hints (("Goal" :in-theory (theory batch1)))
                     :guard-debug t
                     :hints (("Goal" :in-theory (theory batch1)))
                     :measure (- i j)
                     :ruler-extenders :basic
                     :mode :logic
                     :non-executable t
                     :normalize nil
                     :otf-flg t
                     :stobjs ($s)
                     :verify-guards t
                     :split-types t
                     :well-founded-relation my-wfr))

     General Form:
     (xargs :key1 val1 ... :keyn valn)

where the keywords and their respective values are as shown below.
Note that once "inside" the xargs form, the "extra arguments" to defun
are passed exactly as though they were keyword arguments.

:GUARD
Value is a term involving only the formals of the function being
defined.  The actual guard used for the definition is the conjunction
of all the guards and types (see *note DECLARE::) declared.

:GUARD-HINTS
Value: hints (see *note HINTS::), to be used during the guard
verification proofs as opposed to the termination proofs of the defun.

:GUARD-DEBUG
Value: nil by default, else directs ACL2 to decorate each guard proof
obligation with hypotheses indicating its sources.  See *note
GUARD-DEBUG::.

:HINTS
Value: hints (see *note HINTS::), to be used during the termination
proofs as opposed to the guard verification proofs of the defun.

:MEASURE
Value is a term involving only the formals of the function being
defined.  This term is indicates what is getting smaller in the
recursion.  The well-founded relation with which successive measures
are compared is o<.  Also allowed is a special case, (:? v1 ... vk),
where  (v1 ... vk) enumerates a subset of the formal parameters such
that some valid measure involves only those formal parameters.
However, this special case is only allowed for definitions that are
redundant (see *note REDUNDANT-EVENTS::) or are executed when skipping
proofs (see *note SKIP-PROOFS::).  Another special case is :MEASURE
nil, which is treated the same as if :MEASURE is omitted.

:RULER-EXTENDERS
For recursive definitions (possibly mutually recursive), value controls
termination analysis and the resulting stored induction scheme.  See
*note RULER-EXTENDERS:: for a discussion of legal values and their
effects.

:MODE
Value is :program or :logic, indicating the defun mode of the function
introduced.  See *note DEFUN-MODE::.  If unspecified, the defun mode
defaults to the default defun mode of the current world.  To convert a
function from :program mode to :logic mode, see *note
VERIFY-TERMINATION::.

:NON-EXECUTABLE
Value is normally t or nil (the default).  Rather than stating
:non-executable t directly, which requires :logic mode and that the
definitional body has a certain form, we suggest using the macro
defun-nx or defund-nx; see *note DEFUN-NX::.  A third value of
:non-executable for advanced users is :program, which is generated by
expansion of defproxy forms; see *note DEFPROXY::.  For another way to
deal with non-executability, see *note NON-EXEC::.

:NORMALIZE
Value is a flag telling defun whether to propagate if tests upward.
Since the default is to do so, the value supplied is only of interest
when it is nil.  (See *note DEFUN::).

:OTF-FLG
Value is a flag indicating "onward through the fog" (see *note
OTF-FLG::).

:STOBJS
Value is either a single stobj name or a true list of stobj names (see
*note STOBJ:: and see *note DEFSTOBJ::, and perhaps see *note
DEFABSSTOBJ::).  Every stobj name among the formals of the function
must be listed, if the corresponding actual is to be treated as a
stobj.  That is, if a function uses a stobj name as a formal parameter
but the name is not declared among the :stobjs then the corresponding
argument is treated as ordinary.  The only exception to this rule is
state: whether you include it or not, state is always treated as a
single-threaded object.  This declaration has two effects.  One is to
enforce the syntactic restrictions on single-threaded objects.  The
other is to strengthen the guard of the function being defined so that
it includes conjuncts specifying that each declared single-threaded
object argument satisfies the recognizer for the corresponding
single-threaded object.

:VERIFY-GUARDS
Value is t or nil, indicating whether or not guards are to be verified
upon completion of the termination proof.  This flag should only be t
if the :mode is unspecified but the default defun mode is :logic, or
else the :mode is :logic.

:SPLIT-TYPES
Value is t or nil, indicating whether or not types are to be proved
from the guards.  The default is nil, indicating that type declarations
(see *note DECLARE::) contribute to the guards.  If the value is t,
then instead, the expressions corresponding to the type declarations
(see *note TYPE-SPEC::) are conjoined into a "split-type expression,"
and guard verification insists that this term is implied by the
specified :guard.  Suppose for example that a definition has the
following declare form.

       (declare (xargs :guard (p x y) :split-types t)
                (type integer x)
                (type (satisfies good-bar-p) y))

Then for guard verification, (p x y) is assumed, and in addition to the
usual proof obligations derived from the body of the definition, guard
verification requires a proof that (p x y) implies both (integerp x)
and (good-bar-p y).  See community book demos/split-types-examples.lisp
for small examples.

:WELL-FOUNDED-RELATION
Value is a function symbol that is known to be a well-founded relation
in the sense that a rule of class :well-founded-relation has been
proved about it.  See *note WELL-FOUNDED-RELATION::.


File: acl2-doc-emacs.info,  Node: OTHER,  Next: PARALLELISM,  Prev: MISCELLANEOUS,  Up: Top

OTHER    other commonly used top-level functions

* Menu:

* ACCUMULATED-PERSISTENCE:: to get statistics on which runes are being tried

* ACL2-DEFAULTS-TABLE:: a table specifying certain defaults, e.g., the default defun-mode

* ACL2-HELP:: the acl2-help mailing list

* CERTIFY-BOOK!:: a variant of certify-book

* COMMAND-LINE:: handling of command-line arguments when ACL2 is invoked

* CW-GSTACK:: debug a rewriting loop or stack overflow

* DEAD-EVENTS:: using proof supporters to identify dead code and unused theorems

* DISASSEMBLE$:: disassemble a function

* DMR:: dynamically monitor rewrites and other prover activity

* DYNAMICALLY-MONITOR-REWRITES:: See *note DMR::.

* EXIT:: quit entirely out of Lisp

* GOOD-BYE:: quit entirely out of Lisp

* GUARD-OBLIGATION:: the guard proof obligation

* IN-PACKAGE:: select current package

* LD:: the ACL2 read-eval-print loop, file loader, and command processor

* PRINT-GV:: print a form whose evaluation caused a guard violation

* PROPS:: print the ACL2 properties on a symbol

* PSO:: show the most recently saved output

* PSO!:: show the most recently saved output, including proof-tree output

* PSOF:: show the most recently saved output

* PSOG:: show the most recently saved output in gag-mode

* PSTACK:: seeing what the prover is up to

* Q:: quit ACL2 (type :q) --- reenter with (lp)

* QUICK-AND-DIRTY-SUBSUMPTION-REPLACEMENT-STEP:: (advanced topic) controlling a heuristic in the prover's clausifier

* QUIT:: quit entirely out of Lisp

* REBUILD:: a convenient way to reconstruct your old state

* REDO-FLAT:: redo on failure of a progn, encapsulate, or certify-book

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

* SAVE-EXEC:: save an executable image and a wrapper script

* SET-ACCUMULATED-PERSISTENCE:: See *note ACCUMULATED-PERSISTENCE::.

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

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

* SHARP-DOT-READER:: read-time evaluation of constants

* SHARP-U-READER:: allow underscore characters in numbers

* SHOW-ACCUMULATED-PERSISTENCE:: See *note ACCUMULATED-PERSISTENCE::.

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

* THM:: prove a theorem

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

* TRANS:: print the macroexpansion of a form

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

* TRANS1:: print the one-step macroexpansion of a form

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

* WALKABOUT:: explore an ACL2 cons tree

* WITH-PROVER-STEP-LIMIT:: limit the number of steps for proofs

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

* WOF:: direct standard output and proofs output to a file


Related topics other than immediate subtopics:
* BREAK$:: cause an immediate Lisp break

* CERTIFY-BOOK:: how to produce a certificate for a book

* STATE:: the von Neumannesque ACL2 state object

* TIME$:: time an evaluation

* TRACE:: tracing functions in ACL2

This section contains an assortment of top-level functions that fit
into none of the other categories and yet are suffiently useful as to
merit "advertisement" in the :help command.


File: acl2-doc-emacs.info,  Node: ACCUMULATED-PERSISTENCE,  Next: ACL2-DEFAULTS-TABLE,  Prev: OTHER,  Up: OTHER

ACCUMULATED-PERSISTENCE    to get statistics on which runes are being tried

     Useful Forms:
     (accumulated-persistence t)              ; Activate statistics gathering.
     (accumulated-persistence :all)           ; As above, ``enhanced'' (see below)

     (show-accumulated-persistence :frames)   ; Display statistics ordered by
     (show-accumulated-persistence :tries)    ; frames built, times tried,
     (show-accumulated-persistence :ratio)    ; or their ratio.

     (accumulated-persistence nil)            ; Deactivate.

     Advanced forms:
     (show-accumulated-persistence :frames-s) ; The `s', `f', and `a' suffixes
     (show-accumulated-persistence :frames-f) ; stand for `success' (`useful'),
     (show-accumulated-persistence :frames-a) ; `failure' (`useless'), and `all',
     (show-accumulated-persistence :tries-s)  ; respectively.  The only effect of
     (show-accumulated-persistence :tries-f)  ; the `s' and `f' versions is to
     (show-accumulated-persistence :tries-a)  ; sort first by useful or useless
                                              ; applications, respectively (see
                                              ; below).  The `a' versions avoid
                                              ; showing the useful/useless
                                              ; breakdown.

     (show-accumulated-persistence :runes)    ; Just show runes alphabetically.

* Menu:

* ACCUMULATED-PERSISTENCE-SUBTLETIES:: some subtle aspects of the counting done by accumulated-persistence


Related topics other than immediate subtopics:
* DMR:: dynamically monitor rewrites and other prover activity

Note: set-accumulated-persistence is equivalent to
accumulated-persistence.

See the end of this item for a discussion of "enhanced statistics
gathering," which can be useful for more fine-grained proof debugging.

Generally speaking, the more ACL2 knows, the slower it runs.  That is
because the search space grows with the number of alternative rules.
Often, the system tries to apply rules that you have forgotten were
even there, if you knew about them in the first place!
"Accumulated-persistence" is a statistic (originally developed for
Nqthm) that helps you identify the rules that are causing ACL2's search
space to explode.

For other proof debugging utilities, see *note BREAK-REWRITE:: and see
*note DMR::.

Accumulated persistence tracking can be turned on or off.  It is
generally off.  When on, proofs may take perhaps 50% more time than
otherwise!  But some useful numbers are collected.  When it is turned
on, by

     ACL2 !>(accumulated-persistence t)

an accumulation site is initialized and henceforth data about which
rules are being tried is accumulated into that site.  That accumulated
data can be displayed with show-accumulated-persistence, as described
in detail below.  When accumulated persistence is turned off, with
(accumulated-persistence nil), the accumulation site is wiped out and
the data in it is lost.

The "accumulated persistence" of a rune is the number of runes the
system has attempted to apply (since accumulated persistence was last
activated) while the given rune was being tried.

Consider a :rewrite rule named rune.  For simplicity, let us imagine
that rune is tried only once in the period during which accumulated
persistence is being monitored.  Recall that to apply a rewrite rule we
must match the left-hand side of the conclusion to some term we are
trying to rewrite, establish the hypotheses of rune by rewriting, and,
if successful, then rewrite the right-hand side of the conclusion.  We
say rune is "being tried" from the time we have matched its left-hand
side to the time we have either abandoned the attempt or finished
rewriting its right-hand side.  (By "match" we mean to include any
loop-stopper requirement; see *note LOOP-STOPPER::.)  During that
period of time other rules might be tried, e.g., to establish the
hypotheses.  The rules tried while rune is being tried are "billed" to
rune in the sense that they are being considered here only because of
the demands of rune.  Thus, if no other rules are tried during that
period, the accumulated persistence of rune is 1 -- we "bill" rune once
for its own application attempt.  If, on the other hand, we tried 10
rules on behalf of that application of rune, then rune's accumulated
persistence would be 11.

One way to envision accumulated persistence is to imagine that every
time a rune is tried it is pushed onto a stack.  The rules tried on
behalf of a given application of a rune are thus pushed and popped on
the stack above that rune.  A lot of work might be done on its behalf
-- the stack above the rune grows and shrinks repeatedly as the search
continues for a way to use the rune.  All the while, the rune itself
"persists" in the stack, until we finish with the attempt to apply it,
at which time we pop it off.  The accumulated persistence of a rune
application is thus the number of stack frames built while that rune
was on the stack.

Note that accumulated persistence is tallied whether or not the attempt
to apply a rune is successful.  Each of the rules tried on its behalf
might have failed and the attempt to apply the rune might have also
failed.  The ACL2 proof script would make no mention of the rune or the
rules tried on its behalf because they did not contribute to the proof.
But time was spent pursuing the possible application of the rune and
accumulated persistence is a measure of that time.

A high accumulated persistence might come about in two extreme ways.
One is that the rule causes a great deal of work every time it is
tried.  The other is that the rule is "cheap" but is tried very often.
We therefore keep track of the number of times each rule is tried as
well as its persistence.  The ratio between the two is the average
amount of work done on behalf of the rule each time it is tried.

When the accumulated persistence totals are displayed by the function
show-accumulated-persistence we sort them so that the most expensive
runes are shown first.  We can sort according to one of three basic
keys:

     :frames - the number of frames built on behalf of the rune
     :tries  - the number of times the rune was tried
     :ratio  - frames built per try

The key simply determines the order in which the information is
presented.  If no argument is supplied to show-accumulated-persistence,
:frames is used.

The display breaks each total into "useful" and "useless" subtotals.  A
"useful" rule try is one that is viewed as contributing to the progress
of the proof, and the rest are "useless" rule applications.  For
example, if a :rewrite rule is tried but its hypotheses are not
successfully relieved, then that rule application and all work done on
behalf of those hypotheses is "useless" work.  In general, an attempt
to apply a rune is viewed as "useful" unless the attempt fails or the
attempt is on the stack (as described above) for a rune application
that ultimately fails.  A large number of "useless" :frames or :tries
along with correspondingly small "useful" counts may suggest runes to
consider disabling (see *note DISABLE:: and see *note IN-THEORY::).
Thus, here is a more complete list of the arguments that may be
supplied to show-accumulated-persistence.  Suffixes "s", "f", and "a"
are intended to suggest "success" ("useful"), "failure" ("useless"), and
"all".

     :frames     - sort by the number of frames built on behalf of the rune
        :frames-s -   as above, but sort by useful applications
        :frames-f -   as above, but sort by useless applications
        :frames-a -   as above, but inhibit display of ``useful'' and
                      ``useless'' subtotals
     :tries      - sort by the number of times the rune was tried
        :tries-s  -   as above, but sort by useful applications
        :tries-f  -   as above, but sort by useless applications
        :tries-a  -   as above, but inhibit display of ``useful'' and
                      ``useless'' subtotals
     :ratio      - sort by frames built per try
     :useless    - show only the runes tried whose tries were all ``useless''

For a given line of the report, every frame credited to a "useful"
(respectively, "useless") rule application is considered "useful"
(respectively, "useless").  We illustrate with the following example.

     (progn
       (defstub hyp (x) t)
       (defstub concl (x) t)
       (defstub bad (x) t)
       (defstub good (x) t)
       (defaxiom good-ax
         (implies (good x) (hyp x)))
       (defaxiom bad-ax
         (implies (bad x) (hyp x)))
       (defaxiom hyp-implies-concl
         (implies (hyp x) (concl x)))
       )
     (accumulated-persistence t)
     (thm (implies (good x) (concl x)))
     (show-accumulated-persistence)

To prove the thm form, ACL2 attempts to rewrite (concl x) to true by
applying rule hyp-implies-concl.  It then attempts to establish (hyp x)
first by trying rule bad-ax, which fails, and second by trying rule
good-ax, which succeeds.  As expected, the report labels as "useless"
the failure of the attempt to establish the hypothesis, (bad x).

        --------------------------------
              1        1 (    1.00) (:REWRITE BAD-AX)
              0        0    [useful]
              1        1    [useless]
        --------------------------------

Now consider the top-level application of rule hyp-implies-concl.  Even
though the above report shows the application of bad-ax as "useless",
note that this rule was applied on behalf of the successful ("useful")
application of hyp-implies-concl, and hence is incorporated into the
"useful" line for hyp-implies-concl, as follows.

        --------------------------------
              3        1 (    3.00) (:REWRITE HYP-IMPLIES-CONCL)
              3        1    [useful]
              0        0    [useless]
        --------------------------------

In summary: categorization of :frames as "useful" or "useless" is based
on whether they support "useful" or "useless" :tries.

Note that a rune with high accumulated persistence may not actually be
the "culprit."  For example, suppose rune1 is reported to have a :ratio
of 101, meaning that on the average a hundred and one frames were built
each time rune1 was tried.  Suppose rune2 has a :ratio of 100.  It
could be that the attempt to apply rune1 resulted in the attempted
application of rune2 and no other rune.  Thus, in some sense, rune1 is
"cheap" and rune2 is the "culprit" even though it costs less than rune1.

If a proof is aborted, then in general, show-accumulated-persistence
will only display totals for runes whose attempted application is
complete: that is, if the rewriter was in the process of relieving
hypotheses for a rule, then information for that rule will not be
included in the tally.  We say "in general" because, as indicated near
the top of the output from show-accumulated-persistence when such
incomplete information is omitted, you can get this information by
using argument :frames-a or :tries-a.

There are other subtleties in how rune applications are tallied,
documented elsewhere:  see *note ACCUMULATED-PERSISTENCE-SUBTLETIES::.

We conclude with a discussion of "enhanced" statistics gathering, which
is enabled by supplying accumulated-persistence the argument :ALL:

     (accumulated-persistence :all)

At some additional performance expense (but probably well under a
factor of 2 altogether), ACL2 then gathers additional statistics for
individual hypotheses of rules as well as their conclusions.  To
understand how this works, suppose rn is a rune.  Then we prepend the
keyword :CONC to rn to form what we call its "conclusion xrune", and
for its I-th hypothesis we prepend :HYP I to rn to form its I-th
"hypothesis xrune."  Here, "xrune" is pronounced "ex rune", and is
mnemonic for "extended rune."  For example, if (REWRITE FOO) is a rune
then (:CONC REWRITE FOO) is its conclusion xrune, and (:HYP 2 REWRITE
FOO) is a hypothesis xrune corresponding to the second hypothesis of the
corresponding rewrite rule.

With (accumulated-persistence :all), we instruct ACL2 to track not only
runes but also xrunes.  Then, (show-accumulated-persistence) will
display information for all xrunes in a format that we consider to be
"raw", in the sense that data for xrunes are displayed just as for
runes.  But a "merged" format is also available.  Here is a summary of
display commands, followed below by further discussion.

       (show-accumulated-persistence :frames t) ; t is optional, i.e., the default
          ; Display enhanced statistics sorted by frames, in a ``raw'' format.
       (show-accumulated-persistence :frames :merge)
          ; Display enhanced statistics sorted by frames, in a ``merged'' format.
       (show-accumulated-persistence :frames nil)
          ; Display regular statistics sorted by frames, without the enhancements.

       ; More generally, the descriptions just above apply for any legal first
       ; argument:

       (show-accumulated-persistence KEY t)
       (show-accumulated-persistence KEY :merge)
       (show-accumulated-persistence KEY nil)

       ; Note also these alternate forms, equivalent to the first of the two forms
       ; just above, i.e., the form with second argument of t:
       (show-accumulated-persistence KEY :raw)
       (show-accumulated-persistence KEY)

There is a significant difference between how runes are tracked and how
ACL2 tracks hypothesis and conclusion xrunes: unlike regular runes,
these xrunes do not contribute to the accumulated :frames counts.
Rather, they serve as accumulation sites without contributing their
:tries to any accumulation.  Consider for example the snippet below,
taken from a report created with the :merge option (to be discussed
further below), i.e., by evaluating the form
(show-accumulated-persistence :frames :merge).

        :frames   :tries    :ratio  rune
        --------------------------------
            462      211 (    2.18) (:REWRITE PERM-MEM)
             13        6    [useful]
            449      205    [useless]
           .............................
            251       47 (    5.34) (:HYP 2 :REWRITE PERM-MEM)
              6        6    [useful]
            245       41    [useless]
           .............................
              0      211 (    0.00) (:HYP 1 :REWRITE PERM-MEM)
              0        6    [useful]
              0      205    [useless]
           .............................
              0        7 (    0.00) (:CONC :REWRITE PERM-MEM)
              0        6    [useful]
              0        1    [useless]
        --------------------------------

Notice that while :tries are recorded for the xrune (:HYP 1 :REWRITE
PERM-MEM), no :frames are recorded.  This is because no stack frames
were built for runes while this xrune was on the stack -- only for the
xrune itself, which as we explained above is not accumulated into the
total :frames counts.  As it turns out, this lack of stack frames is
explained by the fact that the rewrite rule PERM-MEM has a free
variable in the first hypothesis.

     ACL2 !>:pe perm-mem
              18  (DEFTHM PERM-MEM
                          (IMPLIES (AND (PERM X Y) (MEM A X))
                                   (MEM A Y))
                          :RULE-CLASSES ((:REWRITE :MATCH-FREE :ONCE)))
     ACL2 !>

The second hypothesis, however, does cause additional rewriting in
order to rewrite it to true, resulting in 251 stack frames for runes.
We see that the conclusion does not lead to creation of any rune stack
frames, which might seem to suggest that only 251 stack frames for
runes were created on behalf of this rule application -- yet, we see
that 462 frames were actually created.  The difference is the 211
frames created for the rewrite rule itself.  Even if the total had been
a bit more than 462, one need not be surprised, as there could be some
work recorded during application of the rewrite rule, such as
type-prescription reasoning, that is not done during rewriting of a
hypothesis or the conclusion.

Now suppose we have executed (accumulated-persistence :all) and
attempted some proofs, and now we are ready to see statistics.  The form
(show-accumulated-persistence) displays statistics exactly as described
above, treating these extra xrunes just as though they are runes;
similarly for the form (show-accumulated-persistence KEY), for any
legal KEY.  A second optional argument may however be supplied to
show-accumulated-persistence.  The default for that second argument is
t, and a second argument of :raw is treated the same as t; thus, these
arguments provide the behavior just described, where data for xrunes
are displayed just as for runes.  You may restrict output to runes,
ignoring hypothesis and conclusion xrunes, by giving a second argument
of nil.  (This gives the same behavior as if we had started with the
command (accumulated-persistence t) instead of the command
(accumulated-persistence :all).)  Finally, you may give a second
argument of :merge, in which case output will be sorted and displayed
as though only runes were tracked (not the extra xrunes), but each data
item for a non-rune xrune will be merged so that it is displayed in
suitable order just below its corresponding rune, as in the PERM-MEM
example displayed above.

We close by mentioning two aspects of enhanced statistics display for
:CONC xrunes that have potential to be confusing.  First consider the
following example.

          :frames   :tries    :ratio  rune
        --------------------------------
             14        4 (    3.50) (:REWRITE DEFAULT-+-2)
              0        0    [useful]
             14        4    [useless]
           .............................
             10        4 (    2.50) (:HYP 1 :REWRITE DEFAULT-+-2)
              0        0    [useful]
             10        4    [useless]
        --------------------------------

It may be surprising that no data is displayed for the corresponding
:CONC xrune.  The explanation, however, is simple: the hypothesis never
rewrote to true, so the conclusion was never rewritten.  This is
consistent with the marking as "useless" of all :frames and :tries for
the rune and the hypothesis xrune.  Note by the way, once again, that
the hypothesis xrune does not contribute to any :frames count.

Another reason not to see data displayed for a :CONC xrune is that if a
rule has no hypotheses, then no such data is collected.  This decision
was made because in the case of no hypotheses, we expect it to be very
rare that information for the :CONC xrune will add any useful insight.

On a final note: (show-accumulated-persistence :runes) may be used
simply to see a list of all runes (or xrunes) displayed alphabetically.

Users are encouraged to think about other meters we could install in
ACL2 to help diagnose performance problems.


File: acl2-doc-emacs.info,  Node: ACCUMULATED-PERSISTENCE-SUBTLETIES,  Prev: ACCUMULATED-PERSISTENCE,  Up: ACCUMULATED-PERSISTENCE

ACCUMULATED-PERSISTENCE-SUBTLETIES    some subtle aspects of the counting done by accumulated-persistence

In this topic we cover the overcounting of "useful" and of recursive
rune application attempts, and we describe how "useless" rune
application attempts can actually be critical for a proof's success.

_Overcounting of "useful" and of recursive rune application attempts._
Not every rune application may be necessary for a proof's success.
Consider for example:

     (thm (equal (car (cons a (cdr (cons b x))))
                 a))

Then show-accumulated-persistence will tell us that :rewrite rules
car-cons and cdr-cons each had one useful application.  However, the
rule cdr-cons is used to simplify (cdr (cons b x)) to x, and this
simplification is unecessary for the proof.  Indeed, the proof succeeds
even when preceded by the event: (in-theory (disable cdr-cons)).  We
thus see that a rune application labeled as "useful" may be simplifying
a term that is not relevant to the proof.

As of this writing, we consider every :forward-chaining rule
application to be "useful", for simplicity of the implementation.
Moreover, our counting of these rules is such that a single rule may be
counted more than once.

Next we show how recursive rule applications are overcounted.  Consider
the following example.

     (defun mem (a x)
       (if (atom x)
           nil
         (or (equal a (car x)) (mem a (cdr x)))))

Now suppose we consider the sequence of theorems (mem a (list a)), (mem
a (list 1 a)), (mem a (list 1 2 a)), (mem a (list 1 2 3 a)), and so on.
We will see that the :frames reported for each increases quadratically,
even though the :tries increases linearly; so in this case the :tries
statistics are more appropriate.  Each time the definition of mem is
applied, a new stack frame is pushed (see *note
ACCUMULATED-PERSISTENCE::), and all subsequent applications of that
definition are accumulated into the :frames count for that stack frame.
The final :frames count will be the sum of the counts for those
individual frames, which form a linear sequence whose sum is therefore
quadratic in the number of applications of the definition of mem.

_How "useless" attempts can be critical for a proof's success._  The
command (accumulated-persistence :useless)] will list rules that did not
contribute directly to the proof (see *note ACCUMULATED-PERSISTENCE::,
in particular the discussion of "useless" there).  However, a "useless"
rule can on rare occasions be critical to the success of a proof.  In
the following example, we have a "bad" rule that can take the proof in
the wrong direction, but a "useless" rule does a rewrite that prevents
the succesful relieving of a hypothesis of the "bad" rule.  In summary:

     ; Assume p0.  We want to prove p1.

     ; Key rule:
     p0 -> p1 = t

     ; Bad rule that could ruin the proof:
     p3 -> p1 = p2

     ; But unfortunately, we know p3:
     p0 -> p3

     ; Important ``useless'' rule, preventing ``bad rule'' above from firing:
     p3 = p4

The following event captures the rules described above.

     (encapsulate
      ((p0 (x) t)
       (p1 (x) t)
       (p2 (x) t)
       (p3 (x) t)
       (p4 (x) t))
      (local (defun p0 (x) x))
      (local (defun p1 (x) x))
      (local (defun p2 (x) x))
      (local (defun p3 (x) x))
      (local (defun p4 (x) x))

     ; Key rule:
      (defthm p0-implies-p1
        (implies (p0 x)
                 (p1 x)))

     ; Bad rule that could ruin the proof:
      (defthm p3-implies-p1-is-p2
        (implies (p3 x)
                 (equal (p1 x) (p2 x))))

     ; But unfortunately, we know p3:
      (defthm p0-implies-p3
        (implies (p0 x)
                 (p3 x)))

     ; Important ``useless'' rule, preventing p3-implies-p1-is-p2 from firing:
      (defthm p3-is-p4
        (equal (p3 x) (p4 x))))

Now we can see that p3-is-p4 is labeled as "useless", by evaluating
these commands.

     (accumulated-persistence t)
     (thm (implies (p0 x) (p1 x)))
     (show-accumulated-persistence)

If instead we first evaluate (in-theory (disable p3-is-p4)) before the
thm above, then the proof fails, even though p3-is-p4 was labeled as
"useless"!

Nevertheless, in general it is probably safe to disable rules reported
as "useless" by (show-accumulated-persistence :useless), and doing so
may speed up a proof considerably.

Remark. The example above suggests a surprising fact: on rare
occasions, a proof may fail when you give an :in-theory hint consisting
of exactly the runes reported in a proof that succeeds.  For, imagine a
rule R that is needed in part of the proof but is "bad" in a second
part, and that some other, "useless" rule prevents the application of R
in that second part.  The example above suggests that disabling this
"useless" rule can allow the second application of R, thus preventing
the proof.


File: acl2-doc-emacs.info,  Node: ACL2-DEFAULTS-TABLE,  Next: ACL2-HELP,  Prev: ACCUMULATED-PERSISTENCE,  Up: OTHER

ACL2-DEFAULTS-TABLE    a table specifying certain defaults, e.g., the default defun-mode

     Example Forms:
     (table acl2-defaults-table :defun-mode) ; current default defun-mode
     (table acl2-defaults-table :defun-mode :program)
                ; set default defun-mode to :program

See *note TABLE:: for a discussion of tables in general.  The legal
keys for this table are shown below.  They may be accessed and changed
via the general mechanisms provided by tables.  However, there are
often more convenient ways to access and/or change the defaults.  (See
also the note below.)

     :defun-mode

the default defun-mode, which must be :program or :logic.  See *note
DEFUN-MODE:: for a general discussion of defun-modes.  The :defun-mode
key may be conveniently set by keyword commands naming the new
defun-mode, :program and :logic.  See *note PROGRAM:: and see *note
LOGIC::.

     :enforce-redundancy

if t, cause ACL2 to insist that most events are redundant (see *note
REDUNDANT-EVENTS::); if :warn, cause a warning instead of an error for
such non-redundant events; else, nil.  See *note
SET-ENFORCE-REDUNDANCY::.

     :ignore-doc-string-error

if t, cause ACL2 to ignore ill-formed documentation strings rather than
causing an error; if :warn, cause a warning instead of an error in such
cases; else, nil (the default).  See *note
SET-IGNORE-DOC-STRING-ERROR::.

     :verify-guards-eagerness

an integer between 0 and 2 indicating how eager the system is to verify
the guards of a defun event.  See *note SET-VERIFY-GUARDS-EAGERNESS::.

     :compile-fns

When this key's value is t, functions are compiled when they are
defun'd; otherwise, the value is nil.  (Except, this key's value is
ignored when explicit compilation is suppressed; see *note
COMPILATION::.)  To set the flag, see *note SET-COMPILE-FNS::.

     :measure-function

the default measure function used by defun when no :measure is supplied
in xargs.  The default measure function must be a function symbol of
one argument. Let mfn be the default measure function and suppose no
:measure is supplied with some recursive function definition.  Then
defun finds the first formal, var, that is tested along every branch
and changed in each recursive call.  The system then "guesses" that
(mfn var) is the :measure for that defun.

     :well-founded-relation

the default well-founded relation used by defun when no
:well-founded-relation is supplied in xargs.  The default well-founded
relation must be a function symbol, rel, of two arguments about which a
:well-founded-relation rule has been proved.  See *note
WELL-FOUNDED-RELATION::.

     :bogus-defun-hints-ok

When this key's value is t, ACL2 allows :hints for nonrecursive
function definitions.  Otherwise, the value is the nil (the default) or
:warn (which makes the check but merely warns when the check fails).
See *note SET-BOGUS-DEFUN-HINTS-OK::.

     :bogus-mutual-recursion-ok

When this key's value is t, ACL2 skips the check that every function in
a mutual-recursion (or defuns) "clique" calls at least one other
function in that "clique."  Otherwise, the value is nil (the default)
or :warn (which makes the check but merely warns when the check fails).
See *note SET-BOGUS-MUTUAL-RECURSION-OK::.

     :irrelevant-formals-ok

When this key's value is t, the check for irrelevant formals is
bypassed; otherwise, the value is the keyword nil (the default) or
:warn (which makes the check but merely warns when the check fails).
See *note IRRELEVANT-FORMALS:: and see *note
SET-IRRELEVANT-FORMALS-OK::.

     :ignore-ok

When this key's value is t, the check for ignored variables is
bypassed; otherwise, the value is the keyword nil (the default) or
:warn (which makes the check but merely warns when the check fails).
See *note SET-IGNORE-OK::.

     :bdd-constructors

This key's value is a list of function symbols used to define the
notion of "BDD normal form."  See *note BDD-ALGORITHM:: and see *note
HINTS::.

     :ttag

This key's value, when non-nil, allows certain operations that extend
the trusted code base beyond what is provided by ACL2.  See *note
DEFTTAG::.  See *note DEFTTAG::.

     :state-ok

This key's value is either t or nil and indicates whether the user is
aware of the syntactic restrictions on the variable symbol STATE.  See
*note SET-STATE-OK::.

     :backchain-limit

This key's value is a list of two "numbers."  Either "number" may
optionally be nil, which is treated like positive infinity.  The
numbers control backchaining through hypotheses during type-set
reasoning and rewriting.  See *note BACKCHAIN-LIMIT::.

     :default-backchain-limit

This key's value is a list of two "numbers."  Either "number" may
optionally be nil, which is treated like positive infinity.  The
numbers are used respectively to set the backchain limit of a rule if
one has not been specified. See *note BACKCHAIN-LIMIT::.

     :step-limit

This key's value is either nil or a natural number not exceeding the
value of *default-step-limit*.  If the value is nil or the value of
*default-step-limit*, there is no limit on the number of "steps" that
ACL2 counts during a proof: currently, the number of top-level rewriting
calls.  Otherwise, the value is the maximum number of such calls allowed
during evaluation of any event.  See *note SET-PROVER-STEP-LIMIT::.

     :rewrite-stack-limit

This key's value is a nonnegative integer less than (expt 2 28).  It is
used to limit the depth of calls of ACL2 rewriter functions.  See *note
REWRITE-STACK-LIMIT::.

     :let*-abstractionp

This key affects how the system displays subgoals.  The value is either
t or nil.  When t, let* expressions are introduced before printing to
eliminate common subexpressions.  The actual goal being worked on is
unchanged.

     :nu-rewriter-mode

This key's value is nil, t, or :literals.  When the value is non-nil,
the rewriter gives special treatment to expressions and functions
defined in terms of nth and update-nth.  See set-nu-rewriter-mode.

     :case-split-limitations

This key's value is a list of two "numbers."  Either "number" may
optionally be nil, which is treated like positive infinity.  The
numbers control how the system handles case splits in the simplifier.
See *note SET-CASE-SPLIT-LIMITATIONS::.

     :include-book-dir-alist

This key's value is used by include-book's :DIR argument to associate a
directory with a keyword.  An exception is the keyword :SYSTEM for the
books/ directory; see *note INCLUDE-BOOK::, in particular the section
on "Books Directory."

     :match-free-default

This key's value is either :all, :once, or nil.  See *note
SET-MATCH-FREE-DEFAULT::.

     :match-free-override

This key's value is a list of runes.  See *note
ADD-MATCH-FREE-OVERRIDE::.

     :match-free-override-nume

This key's value is an integer used in the implementation of
add-match-free-override, so that only existing runes are affected by
that event.

     :non-linearp

This key's value is either t or nil and indicates whether the user
wishes ACL2 to extend the linear arithmetic decision procedure to
include non-linear reasoning.  See *note NON-LINEAR-ARITHMETIC::.

     :tau-auto-modep

This key's value is either t or nil and indicates whether the user
wishes ACL2 to look for opportunities to create :tau-system rules from
all suitable defuns and from all suitable defthms (with non-nil
:rule-classes).  See *note SET-TAU-AUTO-MODE::.

     :ruler-extenders

This key's value may be a list of symbols, indicating those function
symbols that are not to block the collection of rulers; see *note
DEFUN::.  Otherwise the value is :all to indicate all function symbols,
i.e., so that no function symbol blocks the collection of rulers.  If a
list is specified (rather than :all), then it may contain the keyword
:lambdas, which has the special role of specifying all lambda
applications.  No other keyword is permitted in the list.  See *note
RULER-EXTENDERS::.

     :memoize-ideal-okp

This key is only legal in an experimental hons version (see *note
HONS-AND-MEMOIZATION::).  Its value must be either t, nil, or :warn.
If the value is nil or not present, then it is illegal by default to
memoize a :logic mode function that has not been guard-verified (see
*note VERIFY-GUARDS::), sometimes called an "ideal-mode" function.
This illegality is the default because such calls of such functions in
the ACL2 loop are generally evaluated in the logic (using so-called
"executable counterpart" definitions), rather than directly by
executing calls of the corresponding (memoized) raw Lisp function.
However, such a raw Lisp call can be made when the function is called
by a :program mode function, so we allow you to override the default
behavior by associating the value t or :warn with the key
:memoize-ideal-okp, where with :warn you get a suitable warning.  Note
that you can also allow memoization of ideal-mode functions by supplying
argument :ideal-okp to your memoization event (see *note MEMOIZE::), in
which case the value of :memoize-ideal-okp in the acl2-defaults-table is
irrelevant.

Note: Unlike all other tables, acl2-defaults-table can affect the
soundness of the system.  The table mechanism therefore enforces on it
a restriction not imposed on other tables: when table is used to update
the acl2-defaults-table, the key and value must be variable-free forms.
Thus, while

     (table acl2-defaults-table :defun-mode :program),

     (table acl2-defaults-table :defun-mode ':program), and

     (table acl2-defaults-table :defun-mode (compute-mode *my-data*))

are all examples of legal events (assuming compute-mode is a function
of one non-state argument that produces a defun-mode as its single
value),

     (table acl2-defaults-table :defun-mode (compute-mode (w state)))

is not legal because the value form is state-sensitive.

Consider for example the following three events which one might make
into the text of a book.

     (in-package "ACL2")

     (table acl2-defaults-table
       :defun-mode
       (if (ld-skip-proofsp state) :logic :program))

     (defun crash-and-burn (x) (car x))

The second event is illegal because its value form is state-sensitive.
If it were not illegal, then it would set the :defun-mode to :program
when the book was being certified but would set the defun-mode to
:logic when the book was being loaded by include-book.  That is because
during certification, ld-skip-proofsp is nil (proof obligations are
generated and proved), but during book inclusion ld-skip-proofsp is
non-nil (those obligations are assumed to have been satisfied.)  Thus,
the above book, when loaded, would create a function in :logic mode that
does not actually meet the conditions for such status.

For similar reasons, table events affecting acl2-defaults-table are
illegal within the scope of local forms.  That is, the text

     (in-package "ACL2")

     (local (table acl2-defaults-table :defun-mode :program))

     (defun crash-and-burn (x) (car x))

is illegal because acl2-defaults-table is changed locally.  If this
text were acceptable as a book, then when the book was certified,
crash-and-burn would be processed in :program mode, but when the
certified book was included later, crash-and-burn would have :logic
mode because the local event would be skipped.

The text

     (in-package "ACL2")

     (program) ;which is (table acl2-defaults-table :defun-mode :program)

     (defun crash-and-burn (x) (car x))

is acceptable and defines crash-and-burn in :program mode, both during
certification and subsequent inclusion.

We conclude with an important observation about the relation between
acl2-defaults-table and include-book, certify-book, and encapsulate.
Including or certifying a book never has an effect on the
acl2-defaults-table, nor does executing an encapsulate event; we always
restore the value of this table as a final act.  (Also see *note
INCLUDE-BOOK::, see *note ENCAPSULATE::, and see *note CERTIFY-BOOK::.)
That is, no matter how a book fiddles with the acl2-defaults-table, its
value immediately after including that book is the same as immediately
before including that book.  If you want to set the acl2-defaults-table
in a way that persists, you need to do so using commands that are not
inside books.  It may be useful to set your favorite defaults in your
acl2-customization file; see *note ACL2-CUSTOMIZATION::.


File: acl2-doc-emacs.info,  Node: ACL2-HELP,  Next: CERTIFY-BOOK!,  Prev: ACL2-DEFAULTS-TABLE,  Up: OTHER

ACL2-HELP    the acl2-help mailing list

You can email questions about ACL2 usage to the acl2-help mailing list:
acl2-help@utlists.utexas.edu.  If you have more general questions about
ACL2, for example, about projects completed using ACL2, you may prefer
the acl2 mailing list, acl2@utlists.utexas.edu, which tends to have
wider distribution.


File: acl2-doc-emacs.info,  Node: CERTIFY-BOOK!,  Next: COMMAND-LINE,  Prev: ACL2-HELP,  Up: OTHER

CERTIFY-BOOK!    a variant of certify-book

     Examples:
     (certify-book! "my-arith" 3)     ;Certify in a world with 3
                                        ; commands, starting in a world
                                        ; with at least 3 commands.
     (certify-book! "my-arith")       ;Certify in the initial world.

     General Form:
     (certify-book! book-name k compile-flg)

where book-name is a book name (see *note BOOK-NAME::), k is a
nonnegative integer used to indicate the "certification world," and
compile-flg indicates whether you wish to compile the (functions in
the) book.

This command is identical to certify-book, except that the second
argument k may not be t in certify-book! and if k exceeds the current
command number, then an appropriate ubt! will be executed first.  See
*note CERTIFY-BOOK:: and see *note UBT!::.


File: acl2-doc-emacs.info,  Node: COMMAND-LINE,  Next: CW-GSTACK,  Prev: CERTIFY-BOOK!,  Up: OTHER

COMMAND-LINE    handling of command-line arguments when ACL2 is invoked

You may provide command-line arguments when invoking ACL2, which are
passed to the host Lisp.  For more information on this topic, along
with a discussion of how to save an ACL2 executable that avoids passing
command-line arguments to the host Lisp, see *note SAVE-EXEC::.

* Menu:


Related topics other than immediate subtopics:
* SAVE-EXEC:: save an executable image and a wrapper script


File: acl2-doc-emacs.info,  Node: CW-GSTACK,  Next: DEAD-EVENTS,  Prev: COMMAND-LINE,  Up: OTHER

CW-GSTACK    debug a rewriting loop or stack overflow

     Example Forms:
     (cw-gstack)
     (cw-gstack :frames 10)       ; show only the top 10 frames
     (cw-gstack :frames '(1 10))  ; same as above:  show only frames 1 through 10
     (cw-gstack :frames '(10 20)) ; show only frames 10 through 20
     (cw-gstack :evisc-tuple (evisc-tuple 3 4 nil nil))
                                  ; print with print-level 3 and print-length 4
     (cw-gstack :evisc-tuple nil) ; print using default ``evisceration'',
                                  ;   essentially the same as just above
     (cw-gstack :evisc-tuple '(nil 3 4 (hide)))
                                  ; same as just above

     General Form:
     (cw-gstack :frames frames :evisc-tuple evisc-tuple)

where :frames and :evisc-tuple are optional, but if they are supplied,
their values are evaluated.  The value of frames should be either a
natural number or a list of two natural numbers, the first less than
the second; and the value of evisc-tuple should be an evisc-tuple (see
*note EVISC-TUPLE::).  If :evisc-tuple is omitted, then substructures
deeper than 3 are replaced by "#" and those longer than 4 are replaced
by "...", and terms of the form (hide ...) are printed as <hidden>.
Also see *note SET-IPRINT:: for an alternative to printing "#" and
"...".

Stack overflows may occur, perhaps caused by looping rewrite rules.  In
some Lisps, stack overflows may manifest themselves as segmentation
faults, causing the entire ACL2 image to crash.  Finding looping
rewrite rules can be tricky, especially if you are using books supplied
by other people.  (However, see *note SET-REWRITE-STACK-LIMIT:: for a
way to avoid stack overflows caused by rewriter loops.)

Normally, a stack overflow will cause the printing of an error message
that suggests how to proceed.  Just follow those instructions, and you
will generally be able to see what is causing the loop.

Suggestion: Once you have found the loop and fixed it, you should
execute the ACL2 command :brr nil, so that you don't slow down
subsequent proof attempts.


File: acl2-doc-emacs.info,  Node: DEAD-EVENTS,  Next: DISASSEMBLE$,  Prev: CW-GSTACK,  Up: OTHER

DEAD-EVENTS    using proof supporters to identify dead code and unused theorems

Below, when we talk about "an event A", we mean an event whose name is
A.

When event A is used in a proof performed to admit event B that you
submit to ACL2, we say that A is a "proof-supporter" of B.  ACL2 stores
an association list such that for every event B with at least one
proof-supporter, B is associated with a list of all of its
proof-supporters, sorted by symbol-<.  The following form evaluates to
that alist, which is called the "proof-supporters-alist".

     (global-val 'proof-supporters-alist (w state))

By "used in a proof" above, we mean: applied as a rule or supplied
explicitly via hints of type :use, :by, or :clause-processor.  That is,
the events "used in a proof" for admitting an event E are those listed
in the summary printed at the conclusion of admitting E.

Note that if proofs are skipped when admitting event E, say because the
last admission of E was done by include-book (or certify-book, which
ends with an include-book), then there will be no entry in that alist
for E.  (An exception is made however for encapsulate events, where
proof-supporters are remembered from the first pass; see below.)  So if
you want the proof-supporters-alist to include supporters for events in
a book, use ld rather than include-book or certify-book to process the
events in that book.  If however you are interested in the
proof-supporters FROM a book that support a later event, then it is
fine to include that book.

The case for encapsulate is slightly tricky.  Consider an example of
the following form.

     A ; event preceding the encapsulate
     (encapsulate
      ()
      B
      (local C) ; uses A and B in a proof
      D ; uses C in a proof
      )

At the conclusion of this encapsulate event, the proof-supporters-alist
associates D with A and B, but not C (which has disappeared, since it
is local).

Note that this sort of "transitive closure" operation is only performed
when necessary due to the disappearance of local events.  For example,
if we replace (local C) above by just C, then D is associated in the
proof-supporters-alist only with C, not with A or B.  If you want the
transitive closure of the relation computed by the
proof-supporters-alist, you have to compute it yourself. (This was a
deliberate design decision, in order to avoid slowing down event
processing.)  However, there is help available on how to do such a
computation:

A community book, books/misc/dead-events.lisp, does such a transitive
closure, and moreover uses that information to find "dead events"
relative to a list of "desired" events.  For example, suppose you use
LD to process the events, with proofs, in a book intended to prove
theorems MAIN-1 and MAIN-2.  (Remember, certify-book will not save such
information.)  Suppose furthermore that the book begins with some
include-book forms followed by (deflabel book-start).  You could
evaluate this form:

     (dead-events '(main-1 main-2) :start 'book-start)

The result is a list of events that you probably can delete from the
book without causing any proofs to fail.  See the dead-events.lisp book
for further documentation.

You might also find the code in the above book to be helpful for
writing your own utilities based on the proof-supporters-alist.


File: acl2-doc-emacs.info,  Node: DISASSEMBLE$,  Next: DMR,  Prev: DEAD-EVENTS,  Up: OTHER

DISASSEMBLE$    disassemble a function

The macro disassemble$ provides a convenient interface to the underlying
disassemble utility of the host Common Lisp implementation, which prints
assembly code for a given function symbol at the terminal.  It works by
including the community book books/misc/disassemble.lisp, which defines
the supporting function disassemble$-fn, and then by calling that
function.  Note that the arguments to disassemble$ are evaluated.  Also
note that disassemble$ is intended as a top-level utility for the ACL2
loop, not to be called in code; for such a purpose, include the above
book and call disassemble$-fn directly.

     Example Forms:

     (disassemble$ 'foo)
     (disassemble$ 'foo :recompile t)

     General Forms:
     (disassemble$ form)
     (disassemble$ form :recompile flg)

where form evaluates to a function symbol and flg evaluates to any
value.  If flg is nil, then the existing definition of that function
symbol is disassembled.  But if flg is supplied and has a value other
than nil or :default, and if that function symbol is defined in the
ACL2 loop (not merely in raw Lisp; for example, see *note
SET-RAW-MODE::), then the disassembly will be based on a recompilation
of that ACL2 definition.  Normally this recompilation is not necessary,
but for some host Lisps, it may be useful; in particular, for CCL the
above book arranges that source code information is saved, so that the
output is annotated with such information.  When recompilation takes
place, the previous definition is restored after disassembly is
complete.  Finally, if flg is omitted or has the value :default --
i.e., in the default case -- then recompilation may take place or not,
depending on the host Lisp.  The values of (@ host-lisp) for which
recompilation takes place by default may be found by looking at the
above book, or by including it and evaluating the constant
*host-lisps-that-recompile-by-default*.  As of this writing, CCL is the
only such Lisp (because that is the one for which we can obtain source
annotation in the output by recompiling).


File: acl2-doc-emacs.info,  Node: DMR,  Next: DYNAMICALLY-MONITOR-REWRITES,  Prev: DISASSEMBLE$,  Up: OTHER

DMR    dynamically monitor rewrites and other prover activity

In addition to utilities that allow you to set breakpoints or print
rewriting information to the screen -- see *note BREAK-REWRITE:: --
ACL2 provides a utility for watching the activity of the rewriter and
some other proof processes, in real time.  This utility is called
"dmr", which is an acronym for "dynamically monitor rewrites".  The
utility comes in two parts: an ACL2 component that frequently updates a
file (the "dmr file") containing the relevant information, and an Emacs
component that frequently updates the an Emacs buffer (the "dmr
buffer") with the contents of that file.  Other editors could, in
principle, be programmed to display that file; anyone developing such a
capability is invited to contribute it to the ACL2 community.

The dmr utility can be extremely helpful for expensive proofs,
especially when ACL2 is not providing any output to the terminal.  The
break-rewrite and accumulated-persistence utilities may be a bit easier
to use, so you might want to try those first.  But the dmr utility can
be a very helpful debugging aide, as it can visually give you a sense of
where ACL2 is spending its time.

The Emacs portion of this utility is already loaded if you load the
distributed Emacs file emacs/emacs-acl2.el.  Otherwise, invoke the
following Emacs command, say by typing Control-X Control-E after the
right parenthesis, where DIR is the directory of your ACL2 distribution.

     (load "<DIR>/emacs/monitor.el") ; absolute pathnames might work best

You only need to do that once.  Then each time you want to observe the
rewriter in action, invoke the following to see it displayed in a
buffer, which we call the "dmr buffer":

     Control-t 1

But first you will need to enable monitoring at the ACL2 level:

     (dmr-start)

Monitoring has some cost.  So if you have started it, then at some
point you may want to turn it off when not using it.  Any time the dmr
buffer (generally called "acl2-dmr-<user_name>") is not visible, Emacs
monitoring is turned off.  You can also turn off Emacs monitoring
explicitly, with:

     Control-t 2

At the ACL2 level you can disable monitoring as follows:

     (dmr-stop)

_Interpreting the dmr buffer display._

We explain the dmr buffer display by way of the following example.  It
is a snapshot of a dmr buffer taken from one of the community books,
books/workshops/2004/legato/support/proof-by-generalization-mult.lisp.

      0. (DEFTHM . WP-ZCOEF-G-MULTIPLIES)
      1. SIMPLIFY-CLAUSE
        2. Rewriting (to simplify) the atom of literal 18; argument(s) 1
        4. Rewriting (to simplify) the expansion; argument(s) 3|2
        7. Applying (:DEFINITION WP-ZCOEF-G)
     *  8. Rewriting (to simplify) the rewritten body; argument(s) 2|1|2|2
     *  13. Applying (:REWRITE MOD-ZERO . 2)
     *    14. Rewriting (to establish) the atom of hypothesis 4
     *    15. Applying (:META META-INTEGERP-CORRECT)

Each line indicates an ACL2 activity that leads to the activity shown
on the line just below it.  Moreover, lines are sometimes collapsed to
make the display more compact.  Consider for example the first few
lines.  Above, we are proving a theorem named WP-ZCOEF-G-MULTIPLIES.
Lines 1 and 2 show the clause simplification process invokes the
rewriter on the 18th literal.  (Recall that a clause is a disjunction
of literals; for example the clause {(NOT A), (NOT B), C} would be
displayed as (IMPLIES (AND A B) C).)  This 18th literal mentioned on
line 2 is a function call (f arg1 ...), and "argument(s) 1" indicates
that the rewriter, which works inside-out, is considering the first
argument ("arg1").  Thus the display could instead have shown the
following.

        2. Rewriting (to simplify) the atom of literal 18
        3. Rewriting (to simplify) the first argument
        4. Rewriting (to simplify) the expansion; argument(s) 3|2

But it saved space to combine lines 2 and 3.  Line 4 suggests that the
above arg1 is a function call that has been opened up because of an
:expand hint or, perhaps, an expansion directed explicitly by the
prover (as can happen during induction).  The annotation "argument(s)
3|2" then indicates that the rewriter is diving into the third argument
of the expansion, and then into the second argument of that.  Let us
call the result term7 (since it is the one to be considered on line 7).

Now consider the next two lines:

        7. Applying (:DEFINITION WP-ZCOEF-G)
     *  8. Rewriting (to simplify) the rewritten body; argument(s) 2|1|2|2

Line 7 is saying that term7 (defined above) is modified by applying the
definition of WP-ZCOEF-G to it.  Line 8 then says that the body of this
definition has been rewritten (with its formals bound to the actuals
from term7) and the rewriter is diving into the subterms of that
rewritten body, as indicated.  Notice also that line 8 is the first
line marked with an asterisk ("*") in the margin.  This line is the
first that is different from what was shown the previous time the
display was updated (about 1/10 second earlier, by default).  When a
line is marked with an asterisk, so are all the lines below it; so the
lines without an asterisk are those that have been stable since the
last display.  In this example we may see line 7 marked without an
asterisk for a while, which suggests that the rule (:DEFINITION
WP-ZCOEF-G) is expensive.  (Also see *note ACCUMULATED-PERSISTENCE::.)
In general, a line that persists for awhile without a leading asterisk
can suggest why the proof is taking a long time.

Finally, note the indentation of line 14 relative to line 13.  Extra
indentation occurs when an attempt is being made to relieve a hypothesis
(i.e., rewrite it to t).  In particular, rewrites that will be
incorporated directly into a (top-level) literal are all indented just
two spaces, starting with the first rewrite directly under a process
such as SIMPLIFY-CLAUSE (shown line 1 above).  If the indentation is at
least the value of raw Lisp variable *dmr-indent-max* (by default, 20),
then indenttion is restricted to that column, but ACL2 prints {n} where
n is the column that would have been used for indentation if there were
no maximum.

You can move the cursor around in the dmr buffer even while it is being
updated.  But emacs will attempt to keep the cursor no later than the
first asterisk ("*") in the margin.  Thus, you can move the cursor
around in the stable part of the display, and emacs will keep the
cursor in that stable part.

WARNING: Things could go terribly wrong if the same user runs two
different ACL2 sessions with dmr active, because the same file will be
written by two different ACL2 processes.

WARNING: For dmr to work, emacs and ACL2 need to be run on the same
machine because the file used to communicate between ACL2 and emacs is
under /tmp.  Except, you can probably hack around that restriction by
changing *dmr-file-name* in ACL2 (in raw Lisp) and correspondingly in
Emacs file monitor.el.

More generally, advanced users are welcome to search for the string

     User-settable dmr variables

in ACL2 files interface-raw.lisp and emacs/monitor.el in order to
customize their dmr environments.

In order to update the dmr file with the latest stack information,
interrupt ACL2 and then evaluate: (dmr-flush).  In order to support
resumption of the interrupted proof (assuming your host Common Lisp
supports resumption), evaluation of (dmr-start) will automatically
enable the debugger if it is not already enabled and not fully disabled
with value :never (see *note SET-DEBUGGER-ENABLE::).  If such automatic
enabling takes place, then (dmr-stop) will restore the old setting of
the debugger unless, after (dmr-start) enables the debugger but before
(dmr-stop) is called, you call set-debugger-enable (or more precisely:
function set-debugger-enable-fn is called).

Note for users of the experimental extension ACL2(p) (see *note
PARALLELISM::): when waterfall-parallelism has been set to a non-nil
value (see *note SET-WATERFALL-PARALLELISM::), statistics about
parallel execution are printed instead of the usual information.


File: acl2-doc-emacs.info,  Node: DYNAMICALLY-MONITOR-REWRITES,  Next: EXIT,  Prev: DMR,  Up: OTHER

DYNAMICALLY-MONITOR-REWRITES    See *note DMR::.


File: acl2-doc-emacs.info,  Node: EXIT,  Next: GOOD-BYE,  Prev: DYNAMICALLY-MONITOR-REWRITES,  Up: OTHER

EXIT    quit entirely out of Lisp

Same as good-bye.


File: acl2-doc-emacs.info,  Node: GOOD-BYE,  Next: GUARD-OBLIGATION,  Prev: EXIT,  Up: OTHER

GOOD-BYE    quit entirely out of Lisp

     Examples:
     ACL2 !>(good-bye)
     ; [ACL2 is exited]

     ACL2 !>(good-bye 3)
     ; [ACL2 is exited with Unix exit status 3]

Note:  Your entire session will disappear forever when you evaluate
(good-bye).

The command (good-bye) quits not only out of the ACL2 command loop, but
in fact quits entirely out of the underlying Lisp.  Thus, there is no
going back!  You will *not* be able to re-enter the command loop after
typing (good-bye)!  All your work will be lost!!!

This command may not work in some underlying Common Lisp
implementations.  In such cases, there is no harm in trying; ACL2 will
let you know how to proceed if it cannot exit.

In some systems, typing control-d at the top-level ACL2 prompt
(control-c control-d if inside emacs) will call this function.

If you give good-bye an argument, it should be a natural number, and it
indicates the Unix (Linux) exit status.

If you merely want to exit the ACL2 command loop, use :q instead (see
*note Q::).


File: acl2-doc-emacs.info,  Node: GUARD-OBLIGATION,  Next: IN-PACKAGE,  Prev: GOOD-BYE,  Up: OTHER

GUARD-OBLIGATION    the guard proof obligation

See *note VERIFY-GUARDS::, and see *note GUARD:: for a discussion of
guards.  Also see *note VERIFY-GUARDS-FORMULA:: for a utility provided
for viewing the guard proof obligation, without proof.
Guard-obligation is a lower level function for use in system programs,
not typically appropriate for most ACL2 users.  If you simply want to
see the guard proof obligations, see *note VERIFY-GUARDS-FORMULA::.

     Example Form:
     (guard-obligation 'foo nil 'top-level state)
     (guard-obligation '(if (consp x) (foo (car x)) t) nil 'my-function state)

     General Forms:
     (guard-obligation name guard-debug ctx state)
     (guard-obligation term guard-debug ctx state)

where the first argument is either the name of a function or theorem or
is a non-variable term that may be in untranslated form; guard-debug is
typically nil but may be t (see *note GUARD-DEBUG::); ctx is a context
(typically, a symbol used in error and warning messages); and state
references the ACL2 state.

If you want to obtain the formula but you don't care about the so-called
"tag tree":

     (mv-let (erp val state)
             (guard-obligation x guard-debug 'top-level state)
             (if erp
                ( .. code for handling error case, e.g., name is undefined .. )
               (let ((cl-set (cadr val))) ; to be proved for guard verification
                 ( .. code using cl-set, which is a list of clauses,
                      implicitly conjoined, each of which is viewed as
                      a disjunction .. ))))

The form (guard-obligation x guard-debug ctx state) evaluates to a
triple (mv erp val state), where erp is nil unless there is an error,
and state is the ACL2 state.  Suppose erp is nil.  Then val is the
keyword :redundant if the corresponding verify-guards event would be
redundant; see *note REDUNDANT-EVENTS::.  Otherwise, val is a tuple
(list* names cl-set ttree), where: names is (cons :term xt) if x is not
a variable, where xt is the translated form of x; and otherwise is a
list containing x along with, if x is defined in a mutual-recursion,
any other functions defined in the same mutual-recursion nest; cl-set
is a list of lists of terms, viewed as a conjunction of clauses (each
viewed (as a disjunction); and ttree is an assumption-free tag-tree
that justifies cl-set.  (The notion of "tag-tree" may probably be
ignored except for system developers.)

Guard-obligation is typically used for function names or non-variable
terms, but as for verify-guards, it may also be applied to theorem
names.

See the source code for verify-guards-formula for an example of how to
use guard-obligation.


File: acl2-doc-emacs.info,  Node: IN-PACKAGE,  Next: LD,  Prev: GUARD-OBLIGATION,  Up: OTHER

IN-PACKAGE    select current package

     Example:
     (in-package "MY-PKG")

     General Form:
     (in-package str)

where str is a string that names an existing ACL2 package, i.e., one of
the initial packages such as "KEYWORD" or "ACL2" or a package
introduced with defpkg.  For a complete list of the known packages
created with defpkg, evaluate

     (strip-cars (known-package-alist state)).

See *note DEFPKG::.  An ACL2 book (see *note BOOKS::) must contain a
single in-package form, which must be the first form in that book.


File: acl2-doc-emacs.info,  Node: LD,  Next: PRINT-GV,  Prev: IN-PACKAGE,  Up: OTHER

LD    the ACL2 read-eval-print loop, file loader, and command processor

     Examples:
     (LD "foo.lisp")              ; read and evaluate each form in file
                                  ; "foo.lisp", in order
     (LD "foo.lisp" :ld-pre-eval-print t)
                                  ; as above, but print each form to standard
                                  ; character output just before it is evaluated

     General Form:
     (LD standard-oi                  ; open obj in channel, stringp file name
                                      ; to open and close, or list of forms
                                      ; Optional keyword arguments:
         :dir                ...      ; use this add-include-book-dir directory
         :standard-co        ...      ; open char out or file to open and close
         :proofs-co          ...      ; open char out or file to open and close
         :current-package    ...      ; known package name
         :ld-skip-proofsp    ...      ; nil, 'include-book, or t
                                      ;   (see *note LD-SKIP-PROOFSP::)
         :ld-redefinition-action ...  ; nil or '(:a . :b)
         :ld-prompt          ...      ; nil, t, or some prompt printer fn
         :ld-missing-input-ok ...     ; nil, t, :warn, or warning message
         :ld-pre-eval-filter ...      ; :all, :query, or some new name
         :ld-pre-eval-print  ...      ; nil, t, or :never
         :ld-post-eval-print ...      ; nil, t, or :command-conventions
         :ld-evisc-tuple     ...      ; nil or '(alist nil nil level length)
         :ld-error-triples   ...      ; nil or t
         :ld-error-action    ...      ; :return!, :return, :continue or :error
         :ld-query-control-alist ...  ; alist supplying default responses
         :ld-verbose         ...)     ; nil or t

     * Menu:

     * CALLING-LD-IN-BAD-CONTEXTS:: errors caused by calling ld in inappropriate contexts


Ld is the top-level ACL2 read-eval-print loop.  (When you call lp, a
little initialization is done in raw Common Lisp and then ld is
called.)  Ld is also a general-purpose ACL2 file loader and a command
interpreter.  Ld is actually a macro that expands to a function call
involving state.  Ld returns an "error triple" (mv erp val state) as
explained below.  (For much more on error triples, see *note
PROGRAMMING-WITH-STATE::.)

See *note REBUILD:: for a variant of ld that skips proofs.  See *note
OUTPUT-TO-FILE:: for examples showing how to redirect output to a file.

The arguments to ld, except for :dir, all happen to be global variables
in state (see *note STATE:: and see *note PROGRAMMING-WITH-STATE::).
For example, 'current-package and 'ld-verbose are global variables,
which may be accessed via (@ current-package) and (@ ld-verbose).  When
ld is called, it "binds" these variables.  By "binds" we actually mean
the variables are globally set but restored to their old values on
exit.  Because ld provides the illusion of state global variables being
bound, they are called "ld specials" (after the Lisp convention of
calling a variable "special" if it is referenced freely after having
been bound).

Note that all arguments but the first are passed via keyword.  Any
variable not explicitly given a value in a call retains its pre-call
value, with the exception of :ld-error-action, which defaults to
:return! if not explicitly specified.

Just as an example to drive the point home: If current-package is
"ACL2" and you typed

     (ld *standard-oi* :current-package "MY-PKG")

you would find yourself in (an inner) read-eval-print loop in which the
current-package was "MY-PKG".  You could operate there as long as you
wished, changing the current package at will.  But when you typed :q
you would return to the outer read-eval-print loop where the current
package would still be "ACL2".

Roughly speaking, ld repeatedly reads a form from standard-oi,
evaluates it, and prints its result to standard-co.  It does this until
the form is :q or evaluates to an error triple whose value component is
:q, or until the input channel or list is emptied.  However, ld has
many bells and whistles controlled by the ld specials.  Each such
special is documented individually.  For example, see the documentation
for standard-oi, current-package, ld-pre-eval-print, etc.

A more precise description of ld is as follows.  In the description
below we use the ld specials as variables, e.g., we say "a form is read
from standard-oi."  By this usage we refer to the current value of the
named state global variable, e.g., we mean "a form is read from the
current value of 'standard-oi." This technicality has an important
implication: If while interacting with ld you change the value of one of
the ld specials, e.g., 'standard-oi, you will change the behavior of
ld, e.g., subsequent input will be taken from the new value.

Three ld specials are treated as channels: standard-oi is treated as an
object input channel and is the source of forms evaluated by ld;
standard-co and proofs-co are treated as character output channels and
various flavors of output are printed to them.  However, the supplied
values of these specials need not actually be channels; several special
cases are recognized.

If the supplied value of one of these is in fact an open channel of the
appropriate type, that channel is used and is not closed by ld.  If the
supplied value of one of these specials is a string, the string is
treated as a file name in (essentially) Unix syntax (see *note
PATHNAME::) and a channel of the appropriate type is opened to/from
that file.  Any channel opened by ld during the binding of the ld
specials is automatically closed by ld upon termination.  If
standard-co and proofs-co are equal strings, only one channel to that
file is opened and is used for both.

As a special convenience, when standard-oi is a string and the :dir
argument provided and not nil, we look up :dir in the table of
directories maintained by add-include-book-dir, and prepend this
directory to standard-oi to create the filename.  (In this case,
however, we require that standard-oi is a relative pathname, not an
absolute pathname.)  For example, one can write (ld
"arithmetic/top-with-meta.lisp" :dir :system) to ld that particular
community books library.  (Of course, you should almost always load
books like arithmetic/top-with-meta using include-book instead of ld.)
If :dir is not specified, then a relative pathname is resolved using
the connected book directory; see *note CBD::.

Several other alternatives are allowed for standard-oi.  If standard-oi
is a true list then it is taken as the list of forms to be processed.
If standard-oi is a list ending in an open channel, then ld processes
the forms in the list and then reads and processes the forms from the
channel.  Analogously, if standard-oi is a list ending a string, an
object input channel from the named file is opened and ld processes the
forms in the list followed by the forms in the file.  That channel is
closed upon termination of ld.

In the cases that a string is to be converted to an object input
channel -- that is, when standard-oi is a string or is a list ending in
a string -- an error occurs by default if the conversion fails,
presumably because the file named by the string does not exist.
However, if keyword argument :ld-missing-input-ok is t, then ld
immediately returns without error in this case, but without reading or
executing any forms, as though standard-oi is nil and keyword arguments
:ld-verbose and ld-prompt both have value nil.  The other legal values
for :ld-missing-input-ok are nil, which gives the default behavior, and
:warn, which behaves the same as t except that a warning is printed,
which contains the same information as would be printed for the default
error described above.

The remaining ld specials are handled more simply and generally have to
be bound to one of a finite number of tokens described in the :doc
entries for each ld special.  Should any ld special be supplied an
inappropriate value, an error message is printed.

Next, if ld-verbose is t, ld prints the message "ACL2 loading name"
where name names the file or channel from which forms are being read.
At the conclusion of ld, it will print "Finished loading name" if
ld-verbose is t.

Finally, ld repeatedly executes the ACL2 read-eval-print step, which may
be described as follows.  A prompt is printed to standard-co if
ld-prompt is non-nil.  The format of the prompt is determined by
ld-prompt.  If it is t, the default ACL2 prompt is used.  If it is any
other non-nil value then it is treated as an ACL2 function that will
print the desired prompt.  See *note LD-PROMPT::.  In the exceptional
case where ld's input is coming from the terminal (*standard-oi*) but
its output is going to a different sink (i.e., standard-co is not
*standard-co*), we also print the prompt to the terminal.

Ld then reads a form from standard-oi.  If the object read is a
keyword, ld constructs a "keyword command form" by possibly reading
several more objects.  See *note KEYWORD-COMMANDS::.  This construction
process is sensitive to the value of ld-keyword-aliases.  See *note
LD-KEYWORD-ALIASES::.  Otherwise, the object read is treated as the
command form.

Ld next decides whether to evaluate or skip this form, depending on
ld-pre-eval-filter.  Initially, the filter must be either :all, :query,
or a new name.  If it is :all, it means all forms are evaluated.  If it
is :query, it means each form that is read is displayed and the user is
queried.  Otherwise, the filter is a name and each form that is read is
evaluated as long as the name remains new, but if the name is ever
introduced then no more forms are read and ld terminates.  See *note
LD-PRE-EVAL-FILTER::.

If the form is to be evaluated, then ld first prints the form to
standard-co, if ld-pre-eval-print is t.  With this feature, ld can
process an input file or form list and construct a script of the
session that appears as though each form was typed in.  See *note
LD-PRE-EVAL-PRINT::.

Ld then evaluates the form, with state bound to the current state.  The
result is some list of (multiple) values.  If a state is among the
values, then ld uses that state as the subsequent current state.

Depending on ld-error-triples, ld may interpret the result as an
"error."  See *note LD-ERROR-TRIPLES::.  We first discuss ld's behavior
if no error signal is detected (either because none was sent or because
ld is ignoring them because ld-error-triples is nil).

In the case of a non-erroneous result, ld does two things: First, if the
logical world in the now current state is different than the world
before execution of the form, ld adds to the world a "command landmark"
containing the form evaluated.  See *note COMMAND-DESCRIPTOR::.
Second, ld prints the result to standard-co, but only if
ld-post-eval-print is not nil.  The result is printed as a list of
(multiple) values unless ld-post-eval-print is :command-conventions,
ld-error-triples is t, and the result is an "error triple", i.e., of
the form (mv * * state) (see *note ERROR-TRIPLES::).  In that case,
only the non-erroneous "value" component of the result is printed.  See
*note LD-POST-EVAL-PRINT::.

Whenever ld prints anything (whether the input form, a query, or some
results) it "eviscerates" it if ld-evisc-tuple is non-nil.
Essentially, evisceration is a generalization of Common Lisp's use of
*print-level* and *print-length* to hide large substructures.  See
*note EVISC-TUPLE:: and also see *note SET-IPRINT::.

We now return to the case of a form whose evaluation signals an error.
In this case, ld first restores the ACL2 logical world to what it was
just before the erroneous form was evaluated.  Thus, a form that
partially changes the world (i.e., begins to store properties) and then
signals an error, has no effect on the world.  You may see this happen
on commands that execute several events (e.g., an encapsulate or a
progn of several defuns): even though the output makes it appear that
the initial events were executed, if an error is signalled by a later
event the entire block of events is discarded.

After rolling back, ld takes an action determined by ld-error-action.
If the action is :continue, ld merely iterates the read-eval-print
step.  Note that nothing suggestive of the value of the "erroneous"
form is printed.  If the action is :return, ld terminates normally;
similarly if the action is :return!, but a special value is returned
that can cause superior ld commands to terminate; see *note
LD-ERROR-ACTION:: for details.  If the action is :error, ld terminates
signalling an error to its caller.  If its caller is in fact another
instance of ld and that instance is watching out for error signals, the
entire world created by the inner ld will be discarded by the outer ld
if the inner ld terminates with an error.

Ld returns an error triple, (mv erp val state).  Erp is t or nil
indicating whether an error is being signalled.  If no error is
signalled, val is the "reason" ld terminated and is one of :exit
(meaning :q was read), :eof (meaning the input source was exhausted),
:error (meaning an error occurred but has been supressed), :filter
(meaning the ld-pre-eval-filter terminated ld), or a cons pair whose
first component is the symbol :STOP-LD, which typically indicates that
an error occurred while the value of variable 'ld-error-action was
:RETURN!.  See *note LD-ERROR-ACTION:: for details of this last case.


File: acl2-doc-emacs.info,  Node: CALLING-LD-IN-BAD-CONTEXTS,  Prev: LD,  Up: LD

CALLING-LD-IN-BAD-CONTEXTS    errors caused by calling ld in inappropriate contexts

The macro ld was designed to be called directly in the top-level ACL2
loop, although there may be a few occasions for calling it from
functions.  ACL2 cannot cope with invocations of ld during the process
of loading a compiled file for a book, so this is an error.

To see how that can happen, consider the following book, where file
const.lsp contains the single form (defconst *foo* '(a b)).

       (in-package "ACL2")
       (defttag t)
       (progn! (ld "const.lsp"))

An attempt to certify this book will cause an error, but that particular
error can be avoided, as discussed below.  If the book is certified,
however, with production of a corresponding compiled file (which is the
default behavior for certify-book), then any subsequent call of
include-book that loads this compiled file will cause an error.  Again,
this error is necessary because of how ACL2 is designed; specifically,
this ld call would interfere with tracking of constant definitions when
loading the compiled file for the book.

Because including such a book (with a compiled file) causes an error,
then as a courtesy to the user, ACL2 arranges that the certification
will fail (thus avoiding a surprise later when trying to include the
book).  The error in that case will look as follows.

       ACL2 Error in LD:  It is illegal to call LD in this context.  See DOC
       calling-ld-in-bad-contexts.

If you really think it is OK to avoid this error, you can get around it
by setting state global variable ld-okp to t:  (assign ld-okp t).  You
can then certify the book in the example above, but you will still not
be able to include it with a compiled file.


File: acl2-doc-emacs.info,  Node: PRINT-GV,  Next: PROPS,  Prev: LD,  Up: OTHER

PRINT-GV    print a form whose evaluation caused a guard violation

By default, ACL2 checks input constraints on functions, known as
guards.  When guards are violated, an informative message is printed;
but sometimes it is useful to investigate why the guard check fails.
The utility print-gv is provided for that purpose.  (Alternatively, you
may prefer to avoid guards entirely with (set-guard-checking :none);
see *note SET-GUARD-CHECKING::.)

     Example Forms:
     (print-gv)
     (print-gv :evisc-tuple (evisc-tuple 4 4 nil nil))
     (print-gv :evisc-tuple (evisc-tuple 4 ; print-level
                                         5 ; print-length
                                         (world-evisceration-alist state nil)
                                         nil ; hiding-cars
                                         ))

     General Form:
     (print-gv :evisc-tuple x)

where the :evisc-tuple argument is optional and defaults to one that
hides only the ACL2 logical world, by printing <world> instead of a
very large structure.  See *note EVISC-TUPLE:: for a discussion of
evisc-tuples.

To see how one might use print-gv, consider the following definition.

     (defun foo (x)
       (declare (xargs :guard (and (my-first-predicate x)
                                   (my-second-predicate x))))
       (cdr x))

Now suppose we evaluate a call of foo and obtain a guard violation.

     ACL2 !>(foo 3)


     ACL2 Error in TOP-LEVEL:  The guard for the function call (FOO X),
     which is (AND (MY-FIRST-PREDICATE X) (MY-SECOND-PREDICATE X)), is violated
     by the arguments in the call (FOO 3).  To debug: See :DOC print-gv,
     see :DOC trace, and see :DOC wet.  See :DOC set-guard-checking for
     information about suppressing this check with (set-guard-checking :none),
     as recommended for new users.

     ACL2 !>

We can obtain (in essence) the guard form that was false, as follows.

     ACL2 !>(print-gv)

     (LET ((X '3))
          (DECLARE (IGNORABLE X))
          (AND (MY-FIRST-PREDICATE X)
               (MY-SECOND-PREDICATE X)))

     ACL2 !>

But which conjunct is to blame?  With a bit of editing we can try each
conjunct in turn.

     ACL2 !>(LET ((X '3))
                 (DECLARE (IGNORABLE X))
                 (MY-FIRST-PREDICATE X))
     T
     ACL2 !>(LET ((X '3))
                 (DECLARE (IGNORABLE X))
                 (MY-SECOND-PREDICATE X))
     NIL
     ACL2 !>

Aha!  Now we can investigate why the second predicate fails for 3.

The following hack will give you access in raw Lisp to the form printed
by (print-gv).  After a guard violation, just submit this form to raw
Lisp:

     (print-gv1 (wormhole-data (cdr (assoc 'ev-fncall-guard-er-wormhole
                                           *wormhole-status-alist*)))
                state)

If you use local stobjs (see *note WITH-LOCAL-STOBJ::) or stobj fields
of stobjs, you may need to edit the output of print-gv in order to
evaluate it.  Consider the following example.

     (defstobj st fld)

     (defun g (x st)
       (declare (xargs :guard (consp x) :stobjs st)
                (ignore x))
       (fld st))

     (defun test ()
       (with-local-stobj
        st
        (mv-let (result st)
                (mv (g 3 st) st)
                result)))

     (test)

Then :print-gv yields the result shown below.

     (FLET ((G{GUARD} (X ST)
                      (DECLARE (IGNORABLE X ST))
                      (AND (STP ST) (CONSP X))))
           (G{GUARD} '3 |<some-stobj>|))

In this example you could replace "|<some-stobj>|" by "st" to obtain a
result of nil.  But similar cases may require the use of a local stobj
that is no longer available, in which case you may need to be creative
in order to take advantage of :print-gv.  Here is such an example.

     (defstobj st2 fld2)

     (defun g2 (st2)
       (declare (xargs :guard (null (fld2 st2)) :stobjs st2))
       (mv 0 st2))

     (defun test2 ()
       (with-local-stobj
        st2
        (mv-let (result st2)
                (let ((st2 (update-fld2 17 st2)))
                  (g2 st2))
                result)))

     (test2)

In this case, :print-gv yields the following.

     (FLET ((G2{GUARD} (ST2)
                       (DECLARE (IGNORABLE ST2))
                       (AND (ST2P ST2) (NULL (FLD2 ST2)))))
           (G2{GUARD} |<some-stobj>|))

But if you replace "|<some-stobj>|" by "st", the guard holds; it is
only the local stobj, which is no longer available, that produced a
guard violation (because its field had been updated to a cons).

     ACL2 !>(FLET ((G2{GUARD} (ST2)
                              (DECLARE (IGNORABLE ST2))
                              (AND (ST2P ST2) (NULL (FLD2 ST2)))))
                  (G2{GUARD} st2))
     T
     ACL2 !>

Finally, we note that while print-gv is a utility for debugging guard
violations, in contrast, see *note GUARD-DEBUG:: for a utility to
assist in debugging failed proofs arising from guard verification.


File: acl2-doc-emacs.info,  Node: PROPS,  Next: PSO,  Prev: PRINT-GV,  Up: OTHER

PROPS    print the ACL2 properties on a symbol

     Example:
     :props assoc-eq

Props takes one argument, a symbol, and prints all of the properties
that are on that symbol in the ACL2 world.


File: acl2-doc-emacs.info,  Node: PSO,  Next: PSO!,  Prev: PROPS,  Up: OTHER

PSO    show the most recently saved output

Evaluate :pso in order to print output that was generated in an
environment where output was being saved;  see *note SET-SAVED-OUTPUT::
for details.  However, proof-tree output will be suppressed; use :pso!
if you want that output to be printed as well.

Also see *note PSOG::, for printing saved output in gag-mode.


File: acl2-doc-emacs.info,  Node: PSO!,  Next: PSOF,  Prev: PSO,  Up: OTHER

PSO!    show the most recently saved output, including proof-tree output

Evaluate :pso! in order to print output that was generated in an
environment where output was being saved; see *note SET-SAVED-OUTPUT::
for details.  Note that proof-tree will be included; use :pso if you
want that output to be suppressed.

Also see *note PSOG::, for printing saved output in gag-mode.


File: acl2-doc-emacs.info,  Node: PSOF,  Next: PSOG,  Prev: PSO!,  Up: OTHER

PSOF    show the most recently saved output

For a similar utility, see *note PSO::.  Like :pso, the :psof command
prints output that was generated in an environment where output was
being saved, typically gag-mode; also see *note SET-SAVED-OUTPUT::.
But unlike :pso, :psof takes a filename argument and saves output to
that file, instead of to the terminal.  For large proofs, :psof may
complete more quickly than :pso.  Note that as with :pso, proof-tree
output will be suppressed.

The first line of output from :psof directs the Emacs editor to use
auto-revert mode.  You can change the frequency of auto-reverting the
buffer connected to a file by evaluating a suitable command in Emacs.
For example, the command (setq auto-revert-interval .1) arranges for
auto-revert mode to update as needed every 1/10 of a second.


File: acl2-doc-emacs.info,  Node: PSOG,  Next: PSTACK,  Prev: PSOF,  Up: OTHER

PSOG    show the most recently saved output in gag-mode

Evaluate :psog in order to print output in gag-mode that was generated
in an environment where output was being saved;  see *note
SET-SAVED-OUTPUT:: for details.

Also see *note PSO:: and see *note PSO!:: for printing the full output.


File: acl2-doc-emacs.info,  Node: PSTACK,  Next: Q,  Prev: PSOG,  Up: OTHER

PSTACK    seeing what the prover is up to

     General Forms:
     (pstack)      ; inspect break
     (pstack t)    ; inspect break, printing all calls in abbreviated form
     (pstack :all) ; as above, but only abbreviating the ACL2 world

When the form (pstack) is executed during a break from a proof, or at
the end of a proof that the user has aborted, a "process stack" (or
"prover stack") will be printed that gives some idea of what the
theorem prover has been doing.  Moreover, by evaluating (verbose-pstack
t) before starting a proof (see *note VERBOSE-PSTACK::) one can get
trace-like information about prover functions, including time
summaries, printed to the screen during a proof.  This feature is
currently quite raw and may be refined considerably as time goes on,
based on user suggestions.  For example, the usual control of printing
given by set-inhibit-output-lst is irrelevant for printing the pstack.

The use of (pstack t) or (pstack :all) should only be used by those who
are comfortable looking at functions in the ACL2 source code.
Otherwise, simply use (pstack).

* Menu:

* VERBOSE-PSTACK:: seeing what the prover is up to (for advanced users)

Entries in the pstack include the following (listed here alphabetically,
except for the first).

preprocess-clause, simplify-clause, etc. (in general,xxx-clause):
top-level processes in the prover "waterfall"

clausify: splitting a goal into subgoals

ev-fncall: evaluating a function on explicit arguments

ev-fncall-meta:  evaluating a metafunction

forward-chain: building a context for the current goal using
forward-chaining rules

induct: finding an induction scheme

pop-clause:  getting the next goal to prove by induction

process-assumptions:  creating forcing rounds

remove-built-in-clauses: removing built-in clauses (see *note
BUILT-IN-CLAUSE::)

process-equational-polys:  deducing interesting equations

remove-trivial-equivalences:  removing trivial equalities (and
equivalences) from the current goal

rewrite-atm:  rewriting a top-level term in the current goal

setup-simplify-clause-pot-lst:  building the linear arithmetic database
for the current goal

strip-branches,  subsumption-replacement-loop:  subroutines of clausify

waterfall: top-level proof control


File: acl2-doc-emacs.info,  Node: VERBOSE-PSTACK,  Prev: PSTACK,  Up: PSTACK

VERBOSE-PSTACK    seeing what the prover is up to (for advanced users)

     General Forms:
     (verbose-pstack t)   ; get trace-like information on prover during proofs
     (verbose-pstack '(fn1 fn2 ...))
                          ; as above, but omit calls of the indicated functions
     (verbose-pstack nil) ; turn off trace-like information on prover

For example, (verbose-pstack '(ev-fncall)) will provide a trace of
various prover functions during proofs, except for the function
ev-fncall.

By evaluating (verbose-pstack t) one can get trace-like information
during subsequent proofs about prover functions, including time
summaries, printed to the screen during a proof.  To turn off this
feature, evaluate (verbose-pstack nil).  Also See *note PSTACK::.


File: acl2-doc-emacs.info,  Node: Q,  Next: QUICK-AND-DIRTY-SUBSUMPTION-REPLACEMENT-STEP,  Prev: PSTACK,  Up: OTHER

Q    quit ACL2 (type :q) -- reenter with (lp)

     Example:
     ACL2 !>:Q

The keyword command :q typed at the top-level of the ACL2 loop will
terminate the loop and return control to the Common Lisp top-level (or,
more precisely, to whatever program invoked lp).  To reenter the ACL2
loop, execute (acl2::lp) in Common Lisp.  You will be in the same state
as you were when you exited with :q, unless during your stay in Common
Lisp you messed the data structures representating the ACL2 state
(including files, property lists, and single-threaded objects).

Unlike all other keyword commands, typing :q is not equivalent to
invoking the function q.  There is no function q.


File: acl2-doc-emacs.info,  Node: QUICK-AND-DIRTY-SUBSUMPTION-REPLACEMENT-STEP,  Next: QUIT,  Prev: Q,  Up: OTHER

QUICK-AND-DIRTY-SUBSUMPTION-REPLACEMENT-STEP    (advanced topic) controlling a heuristic in the prover's clausifier

This topic is probably only of interest to those who are undertaking
particularly complex proof developments.

The ACL2 prover's handling of propositional logic uses a heuristic that
we believe might cause the prover to slow down significantly or even to
trigger a stack overflow.  However, we believe these negative effects
are only felt on very large formulas -- formulas that are likely to
cause similar degradation of many other parts of ACL2.

The following two events turn off that heuristic (by eliminating calls
to source function quick-and-dirty-subsumption-replacement-step, after
which this documentation topic is named).

     (defun quick-and-dirty-srs-off (cl1 ac)
       (declare (ignore cl1 ac)
                (xargs :mode :logic :guard t))
       nil)

     (defattach quick-and-dirty-srs quick-and-dirty-srs-off)

However, if you feel the need to try this out, please remember that the
proof is likely to fail anyway since other parts of ACL2 will probably
be stressed.  A more basic problem with your proof strategy may exist:
the formulas are getting extraordinarily large.  A common approach for
avoiding such problem include disabling functions (see *note
IN-THEORY::).  Other less common approaches might help if you are
sufficiently desperate, such as defining your own IF function to use in
place of the built-in IF.

If you do find an example for which the above two events provide
significant benefit, we (the ACL2 implementors) would be interested in
hearing about it.

To turn the heuristic back on:

     (defattach quick-and-dirty-srs quick-and-dirty-srs-builtin)


File: acl2-doc-emacs.info,  Node: QUIT,  Next: REBUILD,  Prev: QUICK-AND-DIRTY-SUBSUMPTION-REPLACEMENT-STEP,  Up: OTHER

QUIT    quit entirely out of Lisp

Same as good-bye.


File: acl2-doc-emacs.info,  Node: REBUILD,  Next: REDO-FLAT,  Prev: QUIT,  Up: OTHER

REBUILD    a convenient way to reconstruct your old state

     Examples:
     ACL2 !>(rebuild "project.lisp")
     ACL2 !>(rebuild "project.lisp" t)
     ACL2 !>(rebuild "project.lisp" t :dir :system)
     ACL2 !>(rebuild "project.lisp" :all)
     ACL2 !>(rebuild "project.lisp" :query)
     ACL2 !>(rebuild "project.lisp" 'lemma-22)

Rebuild allows you to assume all the commands in a given file or list,
supplied in the first argument.  Because rebuild processes an arbitrary
sequence of commands with ld-skip-proofsp t, it is unsound!  However,
if each of these commands is in fact admissible, then processing them
with rebuild will construct the same logical state that you would be in
if you typed each command and waited through the proofs again.  Thus,
rebuild is a way to reconstruct a state previously obtained by proving
your way through the commands.

The second, optional argument to rebuild is a "filter" (see *note
LD-PRE-EVAL-FILTER::) that lets you specify which commands to process.
You may specify t, :all, :query, or a new logical name.  t and :all
both mean that you expect the entire file or list to be processed.
:query means that you will be asked about each command in turn.  A new
name means that all commands will be processed as long as the name is
new, i.e., rebuild will stop processing commands immediately after
executing a command that introduces name.  Rebuild will also stop if
any command causes an error.  You may therefore wish to plant an
erroneous form in the file, e.g., (mv t nil state), (see *note
LD-ERROR-TRIPLES::), to cause rebuild to stop there.  The form
(i-am-here) is such a pre-defined form.  If you do not specify a
filter, rebuild will query you for one.

Inspection of the definition of rebuild, e.g., via :pc rebuild-fn, will
reveal that it is just a glorified call to the function ld.  See *note
LD:: if you find yourself wishing that rebuild had additional
functionality.

If you supply the above "filter" argument, then you may also supply the
keyword argument :dir, which is then passed to ld; see *note LD::.


File: acl2-doc-emacs.info,  Node: REDO-FLAT,  Next: RESET-LD-SPECIALS,  Prev: REBUILD,  Up: OTHER

REDO-FLAT    redo on failure of a progn, encapsulate, or certify-book

When one submits an encapsulate, progn, or certify-book command and
there is a failure, ACL2 restores its logical world as though the
command had not been run.  But sometimes one would like to debug the
failure by re-executing all sub-events that succeeded up to the point of
failure, and then re-executing the failed sub-event.  Said differently,
imagine that the events under an encapsulate, progn, or certify-book
form were flattened into a list of events that were then submitted to
ACL2 up to the point of failure.  This would put us in the state in
which the original failed event had failed, so we could now replay that
failed event and try modifying it, or first proving additional events,
in order to get it admitted.

Redo-flat is provided for this purpose.  Consider the following (rather
nonsensical) example, in which the defun of f3 fails (the body is y but
the formal parameter list is (x)).

     (encapsulate
      ()
      (defun f1 (x) x)
      (encapsulate ()
                   (local (defthm hack (equal (car (cons x y)) x))))
      (encapsulate ()
                   (local (defthm hack (equal (+ x y) (+ y x)))))
      (encapsulate ()
                   (make-event '(defun f2 (x) x))
                   (progn (defthm foo (equal x x) :rule-classes nil)
                          (defun f3 (x) y)))
      (defun f4 (x) x)
      (defun f5 (x) y))

After this attempt fails, you can evaluate the following form.

     (redo-flat)

This will first lay down a deflabel event, (deflabel r), so that you
can eventually remove your debugging work with (:ubt! r).  Then the
successful sub-events that preceded the failure will be executed with
proofs skipped (so that this execution is fast).  Then, the failed
event will be executed.  Finally, a :pbt command is executed so that
you can see a summary of the events that executed successfully.

You can eliminate some of the steps above by supplying keyword values,
as follows.

     (redo-flat
      :succ  succ ; Skip the successful sub-events if val is nil.
      :fail  fail ; Skip the failed sub-event if val is nil.
      :label lab  ; Skip deflabel if lab or succ is nil, else use (deflabel lab).
      :pbt   val  ; Skip the final :pbt if val, lab, or succ is nil.
      )

Also, you can avoid skipping proofs for the successful sub-events by
supplying keyword :succ-ld-skip-proofsp with a valid value for
ld-skip-proofsp; see *note LD-SKIP-PROOFSP::.  For example, you might
want to execute (redo-flat :succ-ld-skip-proofsp nil) if you use the
must-fail utility from community book make-event/eval.lisp, since for
example (must-fail (thm (equal x y))) normally succeeds but would cause
an error if proofs are skipped.

If you prefer only to see the successful and failed sub-events, without
any events being re-executed, you may evaluate the following form
instead.

     (redo-flat :show t)

For the example above, this command produces the following output.


     List of events preceding the failure:

     ((DEFUN F1 (X) X)
      (ENCAPSULATE NIL
                   (LOCAL (DEFTHM HACK (EQUAL (CAR (CONS X Y)) X))))
      (ENCAPSULATE NIL
                   (LOCAL (DEFTHM HACK (EQUAL (+ X Y) (+ Y X)))))
      (MAKE-EVENT '(DEFUN F2 (X) X))
      (DEFTHM FOO (EQUAL X X)
              :RULE-CLASSES NIL))

     Failed event:

     (DEFUN F3 (X) Y)
     ACL2 !>

Redo-flat uses a scheme that should not cause spurious name conflicts
for local events.  Above, it is mentioned that events are "flattened";
now we clarify this notion.  Each sub-event that succeeds and is an
encapsulate or progn is left intact.  Only such events that fail are
replaced by their component events.  Thus, in the example above, there
is no conflict between the two local sub-events named "hack," because
these are contained in successful encapsulate sub-events, which are
therefore not flattened.  The progn and two encapsulate events
surrounding the definition of f3 are, however, flattened, because that
definition failed to be admitted.

Normally, redo-flat will have the desired effect even if you interrupted
a proof (with control-c).  However, redo-flat will not produce the
desired result after an interrupt if you have enabled the debugger using
(set-debugger-enable t),


File: acl2-doc-emacs.info,  Node: RESET-LD-SPECIALS,  Next: SAVE-EXEC,  Prev: REDO-FLAT,  Up: OTHER

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 *note 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*.


File: acl2-doc-emacs.info,  Node: SAVE-EXEC,  Next: SET-ACCUMULATED-PERSISTENCE,  Prev: RESET-LD-SPECIALS,  Up: OTHER

SAVE-EXEC    save an executable image and a wrapper script

Save-exec saves your ACL2 state so that you can immediately re-start
later in that same state.  This utility can be useful for a project with
books to be included every time ACL2 is started, to avoid time taken to
run include-book.  Another use of save-exec is to save an executable
that takes command-line arguments beyond those normally passed to the
host Lisp executable.  All arguments of a call of save-exec are
evaluated.

     Examples:

     ; Save an executable script named my-saved_acl2, with the indicated message
     ; added to the start-up banner:
     (save-exec "my-saved_acl2"
                "This saved image includes Version 7 of Project Foo.")

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

     ; Arrange that the generated script passes the indicated arguments to be
     ; processed by the Lisp (ACL2) executable (where this example is specific to
     ; the case that CCL is the host Lisp):
     (save-exec "my-saved_acl2" nil
                :host-lisp-args "--no-init -Z 256M")

     ; Arrange that the generated script passes along the indicated arguments
     ; to Lisp (ACL2), but that they are not processed by Lisp other than to
     ; record the additional arguments (see (6) below).
     (save-exec "my-saved_acl2" nil
                :inert-args "abc xyz -i foo")

     ; Combining the preceding two examples:
     (save-exec "my-saved_acl2" nil
                :host-lisp-args "--no-init -Z 256M"
                :inert-args "abc xyz -i foo")

     ; Immediately exit the ACL2 read-eval-print loop after starting up.
     (save-exec "my-acl2" nil
                :return-from-lp t)

     ; Immediately exit the ACL2 read-eval-print loop after starting up and
     ; defining function FOO in the logic.
     (save-exec "my-acl2" "Start with foo defined."
                :return-from-lp '(with-output
                                  :off :all
                                  (defun foo (x) x)))

     ; Immediately exit the ACL2 read-eval-print loop after starting up and
     ; defining variable xxx in raw Lisp.
     (save-exec "my-acl2" "Start with xxx defined."
                :return-from-lp '(with-output
                                  :off :all
                                  (ld '((set-raw-mode-on!)
                                        (defvar xxx (make-list 10))
                                        (set-raw-mode nil)
                                        (u)))))

Each example above generates a file named "my-saved_acl2".  That file is
quite similar in form to the script generated when building ACL2
directly from source code; details are below.  For example, here are
the contents of that generated file if the host Lisp is CCL (but where
dates and pathnames are specific to one's environment).  Here, we break
lines using `\', but the exec command is actually on a single line.

     #!/bin/sh

     # Saved August 16, 2013  23:06:49
     #  then August 17, 2013  11:01:56

     export CCL_DEFAULT_DIRECTORY="/projects/acl2/lisps/ccl/15542/ccl"
     exec "/projects/ccl/lx86cl64" -I "/u/smith/my-saved_acl2.lx86cl64" \
          -Z 64M -K ISO-8859-1 -e "(acl2::acl2-default-restart)" \
          --no-init -Z 256M \
          -- \
          abc xyz -i foo \
          "$@"

     General Form:
     (save-exec exec-filename extra-startup-string
                :host-lisp-args host-lisp-args
                :inert-args inert-args
                :return-from-lp return-from-lp)

where the keyword arguments are optional, and arguments are as follows.

     Exec-filename is the filename of the proposed executable.

     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.

     Host-lisp-args can be nil (the default), but if it is a non-nil
     value, then it is a string to be inserted into the command line in
     the saved script, specifying additional arguments that are to be
     processed by the host Lisp executable.  (Note for SBCL only: these
     are runtime options; for toplevel options, see (8) below.)

     Inert-args can be nil (the default), but if it is a non-nil value,
     then it is a string to be inserted into the command line in the
     saved script, specifying additional arguments that are not to be
     processed by the host Lisp executable.

Return-from-lp is nil by default.  Regardless of the value of
return-from-lp, ACL2 starts up and enters its read-eval-print loop as
usual; see *note LP::.  Normally you'll stay inside that loop, but if
return-from-lp is not nil, then it is evaluated in the loop, which is
then exited, leaving you in raw Lisp.  Evaluation of return-from-lp is
done with ld options that minimize output; also see *note WITH-OUTPUT::
to minimize output.  Suggestion: let return-from-lp be t if you simply
want to exit the read-eval-print loop at startup, without evaluating any
(nontrivial) form.

The remainder of this documentation focuses on the options other than
return-from-lp.

*Details*:

(1) You must first exit the ACL2 read-eval-print loop, typically by
executing :q, before evaluating a save-exec call; otherwise an error
occurs.

(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 *note
LP::) will be the same as their respective values at the time save-exec
is called.

(3) Save-exec generates a small script file (e.g., "my-saved_acl2" in
the examples above), similar in form (see (4) below) to the script
generated when building ACL2 directly from source code, but with a
comment line indicating the time at which the new script is written.
Save-exec also saves an associated binary file.  The binary file's name
is obtained by putting a suffix on the script filename; for example, if
the host Lisp is GCL running on a Linux or Darwin (MacOS) system, then
that binary file has the name my-saved_acl2.gcl in the examples above.

(4) If inert-args is nil (for example if keyword :inert-args is
omitted), then when the generated ACL2 script is invoked with command
line arguments, those arguments will be passed to the host Lisp;
otherwise they will not.  Thus for the example above, suppose we invoke
the generated script as follows.

     my-saved_acl2 -a bcd -e fgh

If my-saved_acl2 was generated using a save-exec command with a non-nil
value specified for keyword :inert-args, then the arguments "-a bcd -e
fgh" will not be passed to the host Lisp; otherwise, they will be.
Note that for ACL2 executable scripts generated by an ordinary ACL2
build from sources, the latter case (i.e., without inert-args) takes
place.

(5) The generated script, which specifies execution with /bin/sh, will
generally contain a line of one of the following forms.  (But for SBCL,
see (8) below.)  In the examples that follow, ACL2_options is a suitable
list of command-line arguments given to the ACL2 executable.  The quoted
string "$@" is intended to allow the user to pass additional
command-line arguments to that executable.

     If host-lisp-args and inert-args are omitted (or nil):

          exec <lisp_executable> <ACL2_options> "$@"

     More generally, host-lisp-args is inserted immediately after
     <ACL2_options>, but only if it is non-nil (hence a string).  If
     inert-args is nil, we thus get:

          exec <lisp_executable> <ACL2_options> host-lisp-args "$@"

     If host-lisp-args redefines a value from <ACL2_options>, then it is
     up to the host lisp which value to use.  For example, experiments
     show that in CCL, if -Z appears twice, each with a legal value,
     then the second value is the one that is used (i.e. it does indeed
     override the original value written out by ACL2 in <ACL2_options>.
     But experiments also show that in LispWorks, where "-init -" is
     included in <ACL2_options>, then inclusion of "-init foo.lisp" in
     host-lisp-args is ignored.

     The remaining cases below are for a non-nil value of inert-args.
     In each case, if host-lisp-args is nil then it should be omitted
     from the displayed command.

     If inert-args is t then an additional argument, `-', indicates
     that when ACL2 is given command line arguments, these should not
     be processed by the host Lisp (other than recording them; see (6)
     below):

          exec <lisp_executable> <ACL2_options> host-lisp-args -- "$@"

     If inert-args is a string then the result is similar to the above,
     except that inert-args is added immediately after `-':

          exec <lisp_executable> <ACL2_options> host-lisp-args -- inert-args "$@"


(6) See community books books/oslib/argv for a utility that returns a
list of all inert-args from an invocation of ACL2.

(7) Suppose that you invoke an ACL2 script, say "my-saved_acl2", that
was generated by save-exec, and then optionally evaluate some forms.
Then you may save a new ACL2 script with save-exec.  The new script will
contain comment lines that extend comment lines in "my-saved_acl2" with
a new write date, but otherwise will be identical to the script that
would have been generated by executing the new save-exec call after
invoking the original ACL2 executable (built directly from ACL2
sources) instead of "my-saved_acl2".  In other words, the options added
by the earlier save-exec call that created "my-saved_acl2" are
discarded by the new save-exec call.  However, the .core file will
built on top of the .core file that was consulted when "my-saved_acl2"
was invoked.

(8) The following note pertains only to the case that the host Lisp is
SBCL.  For SBCL, the scripts written are analogous to, but slightly
different from, those shown above.  Please note that for SBCL, the
host-lisp-args are what the SBCL manual calls "runtime options".  For
SBCL only, an extra keyword argument, :toplevel-args, may be used for
specifying what the SBCL manual calls "toplevel options.  As with
:host-lisp-args, this value, toplevel-args, should be nil (the default)
or a string.  Here is an example.

     (save-exec "my-saved_acl2" nil
                :host-lisp-args "--dynamic-space-size 12000"
                :toplevel-args "--eval '(print \"HELLO\")'"
                :inert-args "--my-option my-value")

The script generated by this example call of save-exec contains a line
such as the following (with the same convention for `\' as before)

     exec "/projects/sbcl-1.1.7-x86-64-linux/src/runtime/sbcl" \
          --dynamic-space-size 2000 --control-stack-size 8 \
          --core "/u/smith/my-saved_acl2.core" --dynamic-space-size 12000 \
          --end-runtime-options \
          --no-userinit --eval '(acl2::sbcl-restart)' \
          --eval '(print "HELLO")' \
          --end-toplevel-options \
          --my-option my-value \
          "$@"

In general, the generated script is of one of the following forms (with
the same convention for `\' as before).

     For the case that inert-args is nil:

          exec <lisp_executable> \
               <ACL2_runtime_options> host-lisp-args --end-runtime-options \
               <ACL2_toplevel_options> host-lisp-args \
               "$@"

     For the case that inert-args is non-nil:

          exec <lisp_executable> \
               <ACL2_runtime_options> host-lisp-args --end-runtime-options \
               <ACL2_toplevel_options> host-lisp-args --end-toplevel-options \
               inert-args "$@"


Notice that as before, when the generated script is invoked (for
example, at the shell), additional command-line arguments provided at
that time are passed to Lisp if and only if inert-args is nil.  For
SBCL, when they are passed to Lisp they are passed as toplevel options,
not as runtime options.


File: acl2-doc-emacs.info,  Node: SET-ACCUMULATED-PERSISTENCE,  Next: SHARP-BANG-READER,  Prev: SAVE-EXEC,  Up: OTHER

SET-ACCUMULATED-PERSISTENCE    See *note ACCUMULATED-PERSISTENCE::.


File: acl2-doc-emacs.info,  Node: SHARP-BANG-READER,  Next: SHARP-COMMA-READER,  Prev: SET-ACCUMULATED-PERSISTENCE,  Up: OTHER

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.


File: acl2-doc-emacs.info,  Node: SHARP-COMMA-READER,  Next: SHARP-DOT-READER,  Prev: SHARP-BANG-READER,  Up: OTHER

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

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


File: acl2-doc-emacs.info,  Node: SHARP-DOT-READER,  Next: SHARP-U-READER,  Prev: SHARP-COMMA-READER,  Up: OTHER

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 *note EVISC-TABLE::.

Remarks.

(1) 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 *note A!::.  For a
related feature that only pops up one level, see *note P!::.

(2) If you call certify-book on a book that contains a form `#.*foo*',
the *foo* must already be defined in the world in which you issue the
certify-book command.  The reason is that certify-book reads the entire
book before evaluating its forms.


File: acl2-doc-emacs.info,  Node: SHARP-U-READER,  Next: SHOW-ACCUMULATED-PERSISTENCE,  Prev: SHARP-DOT-READER,  Up: OTHER

SHARP-U-READER    allow underscore characters in numbers

     Example:

     ACL2 !>#ub1000_1000_1000_
     2184
     ACL2 !>#b100010001000
     2184
     ACL2 !>#uo1_1
     9
     ACL2 !>#o11
     9
     ACL2 !>#u34_5
     345
     ACL2 !>#u345
     345
     ACL2 !>345
     345
     ACL2 !>#ux12_a
     298
     ACL2 !>#ux12a
     298
     ACL2 !>#u x12a
     298
     ACL2 !>#x12a
     298
     ACL2 !>#u123_456/7_919
     123456/7919
     ACL2 !>

The ACL2 reader supports the use of #ub, #uo, and #ux where one would
otherwise write #b, #o, and #x, respectively (for binary, octal, and
hexadecimal numerals), but where underscore characters (`_') are
allowed but ignored.  Also supported is the prefix #u in front of a an
expression that is a decimal numeral except that underscore characteres
are allowed but ignored.

The precise specification of #u is as follows.  The Lisp reader reads
one expression after the #u.  If the result is a number, then that
number is returned by the reader.  Otherwise the result must be a
symbol whose name begins with one of the characters `B', `O', or `X',
or else a decimal digit (one of the characters `0, 1, ..., 9').  All
underscores are removed from the name of that symbol to obtain a string
and in the first three cases only, a `#' character is prepended to that
string.  The resulting string is then handed to the Lisp reader in
order to obtain the final result, which must be a number or else an
error occurs.


File: acl2-doc-emacs.info,  Node: SHOW-ACCUMULATED-PERSISTENCE,  Next: SKIP-PROOFS,  Prev: SHARP-U-READER,  Up: OTHER

SHOW-ACCUMULATED-PERSISTENCE    See *note ACCUMULATED-PERSISTENCE::.


File: acl2-doc-emacs.info,  Node: SKIP-PROOFS,  Next: THM,  Prev: SHOW-ACCUMULATED-PERSISTENCE,  Up: OTHER

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 *note EVENTS::.  If you want to put
skip-proofs around more than one event, consider the following (see
*note 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 *note 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 *note 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 *note
INCLUDE-BOOK::.

We conclude with a technical note.  Skip-proofs works by binding the ld
special ld-skip-proofsp to t unless it is already bound to a non-nil
value; see *note LD-SKIP-PROOFSP::.


File: acl2-doc-emacs.info,  Node: THM,  Next: TOP-LEVEL,  Prev: SKIP-PROOFS,  Up: OTHER

THM    prove a theorem

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

Also see *note 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.


File: acl2-doc-emacs.info,  Node: TOP-LEVEL,  Next: TRANS,  Prev: THM,  Up: OTHER

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.

Top-level generates a call of ld, so that the value returned is printed
in the normal way.  The call of top-level itself actually evaluates to
(mv erp :invisible state), where erp is t if and only evaluation of the
call of top-level-fn caused an error, which normally results in no
additional output.  (For details about "caused an error", see the
definition of top-level in the ACL2 source code, and see *note
LD-ERROR-ACTION::.)


File: acl2-doc-emacs.info,  Node: TRANS,  Next: TRANS!,  Prev: TOP-LEVEL,  Up: OTHER

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 *note 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 *note 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 *note TERM::.


File: acl2-doc-emacs.info,  Node: TRANS!,  Next: TRANS1,  Prev: TRANS,  Up: OTHER

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 *note TRANS:: and see *note TRANS1::.


File: acl2-doc-emacs.info,  Node: TRANS1,  Next: VERIFY-GUARDS-FORMULA,  Prev: TRANS!,  Up: OTHER

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 *note TRANS::, which translates the given form
completely.


File: acl2-doc-emacs.info,  Node: VERIFY-GUARDS-FORMULA,  Next: WALKABOUT,  Prev: TRANS1,  Up: OTHER

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

See *note VERIFY-GUARDS:: and see *note 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 *note
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,
then it is treated as the body of a defthm event for which you want the
guard proof obligation.

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


File: acl2-doc-emacs.info,  Node: WALKABOUT,  Next: WITH-PROVER-STEP-LIMIT,  Prev: VERIFY-GUARDS-FORMULA,  Up: OTHER

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 *note 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
     :


File: acl2-doc-emacs.info,  Node: WITH-PROVER-STEP-LIMIT,  Next: WITH-PROVER-TIME-LIMIT,  Prev: WALKABOUT,  Up: OTHER

WITH-PROVER-STEP-LIMIT    limit the number of steps for proofs

Logically, (with-prover-step-limit expr form) is equivalent to form,
except that if the number of "prover steps" executed during evaluation
of form exceeds a bound specified by the value of expr, then that proof
will abort.  See *note SET-PROVER-STEP-LIMIT:: for a related utility
that sets the limit on prover steps globally instead of setting it for
just one form, and for a discussion of the notion of "prover steps",
which could change in future ACL2 releases.  For a related utility
based on time instead of prover steps, see *note
WITH-PROVER-TIME-LIMIT::; but as discussed in the documentation for
set-prover-step-limit, there is at best a loose connection between the
counting of steps and with-prover-time-limit.

The arguments of (with-prover-step-limit expr form) are evaluated.
However, the (optional) argument flg is not evaluated in
(with-prover-step-limit expr flg form).

Depending on the machine you are using, you may have less than a
half-hour of time before the number of prover steps exceeds the maximum
limit on prover steps that may be imposed, which is one less than the
value of *default-step-limit*.  But there is no limit unless you
explicitly call with-prover-step-limit or set-prover-step-limit.

For examples of how step-limits work besides those presented below, see
the community book books/misc/misc2/step-limits.lisp.

For a utility that returns an indicator of the number of prover steps
most recently taken, see *note LAST-PROVER-STEPS::.

Note that with-prover-step-limit may not be called inside definitions,
and that it is simply the identity macro in raw Lisp.  However,
with-prover-step-limit! may be called in place of
with-prover-step-limit, with the effect described here even in raw Lisp.

     Examples:

     ; Limit (mini-proveall) to 100,000 prover steps (which happens to suffice)
     (with-prover-step-limit 100000 (mini-proveall))

     ; Same as above for the inner call of with-prover-step-limit; so the
     ; mini-proveall call completes, but then we get an error because the second
     ; argument of the outer with-prover-step-limit call took more than 200
     ; steps.
     (with-prover-step-limit
      200
      (with-prover-step-limit 100000 (mini-proveall)))

     ; Same as preceding form just above, except that this time there is no error,
     ; because the inner call of with-prover-step-limit has an extra argument
     ; of t inserted into the second argument position, which specifies that this
     ; entire inner call is treated as though it uses no prover steps.
     (with-prover-step-limit
      200
      (with-prover-step-limit 100000 t (mini-proveall)))

     ; The inner call limits (mini-proveall) to 200 prover steps, which fails
     ; almost immediately.
     (with-prover-step-limit 100000 (with-prover-step-limit 200 (mini-proveall)))

     ; Do not limit the number of prover steps, regardless of such a limit imposed
     ; globally or by the surrounding context.
     (with-prover-step-limit nil (mini-proveall))

     ; Same as just above (indeed, nil above is converted to
     ; *default-step-limit*):
     (with-prover-step-limit *default-step-limit* (mini-proveall))

     ; Advanced example: Limit the indicated theorem to 100 steps, and when the
     ; proof does not complete, then put down a label instead.
     (mv-let (erp val state)
             (with-prover-step-limit
              100
              (thm (equal (append (append x x) x)
                          (append x x x))))
             (if erp
                 (deflabel foo :doc "Attempt failed.")
               (value (list :succeeded-with val))))

     ; Use extra argument of t to avoid ``charging'' steps for the indicated
     ; form.
     (with-prover-step-limit
      500
      (encapsulate
       ()
       (with-prover-step-limit
        500
        t ; Don't charge prover steps for this first defthm.
        (defthm test1
          (equal (append x (append y z))
                 (append (append x y) z))
          :rule-classes nil))
       (defthm test2
         (equal (append x (append y z))
                (append (append x y) z))
         :rule-classes nil)))

     General Forms:
     (with-prover-step-limit expr form)
     (with-prover-step-limit expr flg form)

where form is an arbitrary form to evaluate, and expr evaluates to one
of the following: nil; a natural number not exceeding the value of
*default-step-limit*; or the special value, :START.  The optional extra
argument in the second position, flg, must be Boolean if supplied.

If the value of expr is a natural number less than the value of
*default-step-limit*, then that value is the maximum number of prover
steps permitted during evaluation of form before an error occurs.  If
however the value of expr is nil or is the value of
*default-step-limit*, then no limit is placed on the number of prover
steps during processing of form.  Otherwise, the value of expr should
be the keyword :START, which is intended for use by the ACL2
implementation and may have semantics that change with new ACL2
versions.

Finally we describe the optional extra Boolean argument, flg.  If flg
is nil or omitted, then a running count of prover steps is maintained
after form is evaluated; otherwise, that count is not affected by
evaluation of form.  To see how this works when flg is nil or omitted,
consider an event of shape (progn form1 form2), where we are tracking
prover steps (say, because of a superior call of
with-prover-step-limit).  If n is the number of prover steps available
when the progn form is entered, and if s prover steps are executed
while evaluating form1, then n-s steps are available for evaluation of
form2 provided s does not exceed n; otherwise, an error occurs.  In
particular, this is the case if form1 is an event
(with-prover-step-limit k form1').  However, if form1 is an event
(with-prover-step-limit k t form1'), then because of the extra argument
of t, no steps are "charged" to form; that is, all n steps, rather than
n-s steps, are available for evaluation of form2.


File: acl2-doc-emacs.info,  Node: WITH-PROVER-TIME-LIMIT,  Next: WOF,  Prev: WITH-PROVER-STEP-LIMIT,  Up: OTHER

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

Note that by default, the time used is runtime (cpu time); to switch to
realtime (elapsed time), see *note GET-INTERNAL-TIME::.

For a related utility based on prover steps instead of time, see *note
WITH-PROVER-STEP-LIMIT::; also see *note SET-PROVER-STEP-LIMIT::.  Those
utilities have the advantage of having platform-independent behavior,
unlike time limits, which of course are generally less restrictive for
faster processors.  But note that the prover steps counted need not
correspond closely to prover time.

Although with-prover-time-limit behaves like an ACL2 function in the
sense that it evaluates both its arguments, it is however actually a
macro that behaves as follows.  (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
*note 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,
it may be because the prover only checks the time elapsed at certain
points during the proof process, for example at entry to the rewriter.
For example, if you write your own clause-processor that does an
expensive computation, the time is unlikely to be checked during its
execution.  If however you find the time limit seems to be ignored even
during ordinary prover operation, you are encouraged to email an
example to the ACL2 implementors with instructions on how to observe
the undesirable behavior.  This information can perhaps 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 *note 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.


File: acl2-doc-emacs.info,  Node: WOF,  Prev: WITH-PROVER-TIME-LIMIT,  Up: OTHER

WOF    direct standard output and proofs output to a file

     Example Form:
     (wof "tmp" (pso)) ; same as (psof "tmp")

     General Form:
     (wof filename form)

where filename is a writable filename and form is any form that
evaluates to an error triple (see *note PROGRAMMING-WITH-STATE::), that
is, a multiple value of the form (mv erp val state).  All output to
channels standard-co and proofs-co will be directed to the indicated
file.  It is acceptable to replace filename with (quote filename).

Note that so-called comment-window output (see *note CW:: and see *note
OBSERVATION-CW::) is not redirected by wof to a file, nor is printing
from a wormhole.


File: acl2-doc-emacs.info,  Node: PARALLELISM,  Next: PROGRAMMING,  Prev: OTHER,  Up: Top

PARALLELISM    experimental extension for parallel execution and proofs

This documentation topic relates to an experimental extension of ACL2,
ACL2(p), created initially by David L. Rager.  See *note
COMPILING-ACL2P:: for how to build an executable image that supports
parallel execution.  Also see community books directory books/parallel/
for examples.  For a completely different sort of parallelism, at the
system level, see *note PROVISIONAL-CERTIFICATION::.

* Menu:

* COMPILING-ACL2P:: compiling ACL2(p)

* PARALLEL-PROGRAMMING:: parallel programming in ACL2(p)

* PARALLEL-PROOF:: parallel proof in ACL2(p)

* UNSUPPORTED-PARALLELISM-FEATURES:: ACL2 features not supported in ACL2(p)

* WATERFALL-PARALLELISM-FOR-BOOK-CERTIFICATION:: for ACL2(p): using waterfall parallelism during book certification

IMPORTANT NOTE.  We hope and expect that every evaluation result is
correctly computed by ACL2(p), and that every formula proved using
ACL2(p) is a theorem of the ACL2 logic (and in fact is provable using
ACL2).  However, we do not guarantee these properties.  Since ACL2(p)
is intended to be an aid in efficient evaluation and proof development,
we focus less on ironclad soundness and more on providing an efficient
and working implementation.  Nevertheless, if you encounter a case
where ACL2(p) computes an incorrect result, or produces a proof where
ACL2 fails to do so (and this failure is not discussed in
unsupported-waterfall-parallelism-features), please notify the
implementors.

The ACL2 source code provides experimental parallel execution and proof
capabilities.  For example, one of ACL2's strengths lies in its ability
to simulate industrial models efficiently, and it can also decrease the
time required for proofs about such models both by making use of
parallel evaluation and by dispatching proof subgoals in parallel.

While we aim to support Clozure Common Lisp (CCL), Steel Bank Common
Lisp (SBCL), and Lispworks, SBCL and Lispworks both currently sometimes
experience problems when evaluating the ACL2 proof process (the
"waterfall") in parallel.  Therefore, CCL is the recommend Lisp for
anyone that wants to use parallelism and isn't working on fixing those
problems.


File: acl2-doc-emacs.info,  Node: COMPILING-ACL2P,  Next: PARALLEL-PROGRAMMING,  Prev: PARALLELISM,  Up: PARALLELISM

COMPILING-ACL2P    compiling ACL2(p)

This documentation topic relates to the experimental extension of ACL2
supporting parallel execution and proof; see *note PARALLELISM::.  See
*note PARALLELISM-TUTORIAL:: for an introduction to parallel
programming in ACL2.

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

     * CCL (OpenMCL)

     * Lispworks 6.0

     * SBCL with threads (feature :sb-thread)

The command below will compile ACL2 to support parallel execution,
including parallel execution during proofs.  Any non-empty string may
be used in place of t, and the value of LISP (shown here as ccl) is any
Lisp executable on which one can build ACL2(p) (see *note
PARALLELISM::).

     make ACL2_PAR=t LISP=ccl

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

     make large DOC ACL2_PAR=t LISP=ccl

