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: HONS-ASSOC-EQUAL,  Next: HONS-CLEAR,  Prev: HONS-ACONS!,  Up: HONS-AND-MEMOIZATION

HONS-ASSOC-EQUAL    (hons-assoc-equal key alist) is *not fast*; it serves as the logical
definition for hons-get.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

The definition of hons-assoc-equal is similar to that of assoc-equal,
except that (1) it does not require alistp as a guard, and (2) it "skips
over" any non-conses when its alist argument is malformed.

We typically leave hons-get enabled and reason about hons-assoc-equal
instead.  One benefit of this approach is that it avoids certain "false"
discipline warnings that might arise from execution during theorem
proving.


File: acl2-doc-emacs.info,  Node: HONS-CLEAR,  Next: HONS-COPY,  Prev: HONS-ASSOC-EQUAL,  Up: HONS-AND-MEMOIZATION

HONS-CLEAR    (hons-clear gc) is a drastic garbage collection mechanism that clears out
the underlying Hons Space.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

Logically, hons-clear just returns nil; we leave it enabled and would
think it odd to ever prove a theorem about it.

Under the hood, hons-clear brutally (1) clears all the tables that
govern which conses are normed, then (2) optionally garbage collects,
per the gc argument, then finally (3) re-norms the keys of fast-alists
and persistently normed conses; see *note HONS-COPY-PERSISTENT::.

Note.  The hash tables making up the Hons Space retain their sizes
after being cleared.  If you want to shrink them, see hons-resize.

Note.  CCL users might prefer hons-wash, which is relatively efficient
and allows for the garbage collection of normed conses without
impacting their normed status.

Note.  It is not recommended to interrupt this function.  Doing so may
cause persistently normed conses and fast alist keys to become
un-normed, which might lead to less efficient re-norming and/or
violations of the fast-alist discipline.


File: acl2-doc-emacs.info,  Node: HONS-COPY,  Next: HONS-COPY-PERSISTENT,  Prev: HONS-CLEAR,  Up: HONS-AND-MEMOIZATION

HONS-COPY    (hons-copy x) returns a normed object that is equal to X.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

In the logic, hons-copy is just the identity function; we leave it
enabled and would think it odd to ever prove a theorem about it.

Under the hood, hons-copy does whatever is necessary to produce a
normed version of X.

What might this involve?

If X is a symbol, character, or number, then it is already normed and
nothing is done.

If X is a string, we check if any normed version of X already exists.
If so, we return the already-normed version; otherwise, we install X as
the normed version for all strings that are equal to X.

If X is a cons, we must determine if there is a normed version of X, or
recursively construct and install one.  Norming large cons trees can
become expensive, but there are a couple of cheap cases.  In
particular, if X is already normed, or if large subtrees of X are
already normed, then not much needs to be done.  The slowest case is
norming some large ACL2 cons structure that has no subtrees which are
already normed.

Note that running hons-copy on an object that was created with cons is
often slower than just using hons directly when constructing the object.


File: acl2-doc-emacs.info,  Node: HONS-COPY-PERSISTENT,  Next: HONS-EQUAL,  Prev: HONS-COPY,  Up: HONS-AND-MEMOIZATION

HONS-COPY-PERSISTENT    (hons-copy-persistent x) returns a normed object that is equal to X
and which will be re-normed after any calls to hons-clear.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

Logically hons-copy-persistent is the identity; we leave it enabled and
would think it odd to ever prove a theorem about it.

Under the hood, hons-copy-persistent is virtually identical to
hons-copy.

The only difference is that when hons-clear is used, any persistently
normed conses are automatically re-normed, and this re-norming can be
carried out more efficiently than, say, an ordinary hons-copy.


File: acl2-doc-emacs.info,  Node: HONS-EQUAL,  Next: HONS-EQUAL-LITE,  Prev: HONS-COPY-PERSISTENT,  Up: HONS-AND-MEMOIZATION

HONS-EQUAL    (hons-equal x y) is a recursive equality check that optimizes when parts of
its arguments are normed.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

In the logic, hons-equal is just equal; we leave it enabled and would
think it odd to ever prove a theorem about it.

Under the hood, when hons-equal encounters two arguments that are both
normed, it becomes a mere eql check, and hence avoids the overhead of
recursively checking large cons structures for equality.

Note.  If hons-equal is given arguments that do not contain many normed
objects, it can actually be much slower than equal!  This is because it
checks to see whether its arguments are normed at each recursive step,
and so you are repeatedly paying the price of such checks.  Also see
*note HONS-EQUAL-LITE::, which only checks at the top level whether its
arguments are normed.


File: acl2-doc-emacs.info,  Node: HONS-EQUAL-LITE,  Next: HONS-GET,  Prev: HONS-EQUAL,  Up: HONS-AND-MEMOIZATION

HONS-EQUAL-LITE    (hons-equal-lite x y) is a non-recursive equality check that optimizes if
its arguments are normed.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

In the logic, hons-equal-lite is just equal; we leave it enabled and
would think it odd to ever prove a theorem about it.

Under the hood, hons-equal-lite checks whether its arguments are normed,
and if so it effectively becomes a eql check.  Otherwise, it immediately
calls equal to determine if its arguments are equal.

The idea here is to strike a useful balance between equal and
hons-equal.  If both arguments happen to be normed, we get to use a very
fast equality comparison.  Otherwise, we just get out of the way and let
equal do its work, without the extra overhead of recursively checking
whether the subtrees of x and y are normed.


File: acl2-doc-emacs.info,  Node: HONS-GET,  Next: HONS-NOTE,  Prev: HONS-EQUAL-LITE,  Up: HONS-AND-MEMOIZATION

HONS-GET    (hons-get key alist) is the efficient lookup operation for
fast-alists.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

Logically, hons-get is just an alias for hons-assoc-equal; we typically
leave it enabled and prefer to reason about hons-assoc-equal instead.
One benefit of this approach is that it helps to avoids "false"
discipline warnings that might arise from execution during theorem
proving.

Under the hood, when alist is a fast alist that is associated with a
valid hash table, hons-get first norms key using hons-copy, then
becomes a gethash operation on the hidden hash table.


File: acl2-doc-emacs.info,  Node: HONS-NOTE,  Next: HONS-RESIZE,  Prev: HONS-GET,  Up: HONS-AND-MEMOIZATION

HONS-NOTE    notes about HONS, especially pertaining to expensive resizing operations

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

Certain "Hons-Notes" are printed to the terminal to report
implementation-level information about the management of HONS
structures.  Some of these may be low-level and of interest mainly to
system developers.  But below we discuss what users can learn from a
particular hons-note, "ADDR-LIMIT reached".  In short: If you are
seeing a lot of such hons-notes, then you may be using a lot of memory.
(Maybe you can reduce that memory; for certain BDD operations, for
example (as defined in community books books/centaur/ubdds/), variable
ordering can make a big difference.)

By way of background:

     The ADDR-HT is the main hash table that lets us look up normed
     conses, i.e., honses.  It is an ordinary Common Lisp hash table,
     so when it starts to get too full the Lisp will grow it.  It can
     get really big.  (It has been seen to take more than 10 GB of
     memory just for the hash table's array, not to mention the actual
     conses!)

     Hons-Notes may be printed when the ADDR-HT is getting really full.
     This growth can be expensive and can lead to memory problems.
     Think about what it takes to resize a hash table:

     (1) allocate a new, bigger array
     (2) rehash elements, copying them into the new array
     (3) free the old array

     Until you reach step (3) and a garbage collection takes place, you
     have to have enough memory to have both the old and new arrays
     allocated.  If the old array was 10 GB and we want to allocate a
     new one that's 15 GB, this can get pretty bad.  Also, rehashing
     the elements is expensive time-wise when there are lots of
     elements.

     Since resizing a hash table is expensive, we want to avoid it.
     There's a hons-resize command for this.  You may want your books
     to start with something like the following.

            (value-triple (set-max-mem (* 30 (expt 2 30))))      ; 30 GB heap
            (value-triple (hons-resize :addr-ht #u_100_000_000)) ; 100M honses

     Basically, if you roughly know how many honses your book will
     need, you can just get them up front and then never to resize.

The Hons-Notes about "ADDR-LIMIT reached" are basically there to warn
you that the ADDR-HT is being resized.  This can help you realize that
your hons-resize command had too small of an ADDR-HT size, or might
suggest that your book should have a hons-resize command.  There are
also commands like (hons-summary) and, defined in community book
books/centaur/misc/memory-mgmt-logic.lisp, (hons-analyze-memory nil).
These can show you how many honses you currently have, how much space
they are taking, and that sort of thing.  (A nice trick is to call
hons-summary at the end of a book, to get an idea of how many honses
you should ask for in your hons-resize command).


File: acl2-doc-emacs.info,  Node: HONS-RESIZE,  Next: HONS-SHRINK-ALIST,  Prev: HONS-NOTE,  Up: HONS-AND-MEMOIZATION

HONS-RESIZE    (hons-resize ...) can be used to manually adjust the sizes of the hash
tables that govern which ACL2 Objects are considered normed.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

General form:

      (hons-resize [:str-ht size]
                   [:nil-ht size]
                   [:cdr-ht size]
                   [:cdr-ht-eql size]
                   [:addr-ht size]
                   [:other-ht size]
                   [:sbits size]
                   [:fal-ht size]
                   [:persist-ht size])

Example:

      (hons-resize :str-ht 100000
                   :addr-ht (expt 2 27))

Logically, hons-resize just returns nil; we leave it enabled and would
think it odd to ever prove a theorem about it.

Under the hood, hons-resize can be used to change the sizes of certain
hash tables in the Hons Space.

All arguments are optional.  The size given to each argument should
either be nil (the default) or a natural number.  A natural number
indicates the newly desired size for the hash table, whereas nil means
"don't resize this table."  Any non-natural argument is regarded as nil.

You may wish to call this function for two reasons.

1.  Improving Performance by Resizing Up

Since the hash tables in the Hons Space automatically grow as new
objects are normed, hons-resize is unnecessary.  But automatic growth
can be slow because it is incremental: a particular hash table might be
grown dozens of times over the course of your application.  Using
hons-resize to pick a more appropriate initial size may help to reduce
this overhead.

2.  Reducing Memory Usage by Resizing Down

Resizing can also be used to shrink the hash tables.  This might
possibly be useful immediately after a hons-clear to free up memory
taken by the hash tables themselves.  (Of course, the tables will grow
again as you create new normed objects.)

Advice for using hons-resize.

Note that hash tables that are already close to the desired size, or
which have too many elements to fit into the desired size, will not
actually be resized.  This makes resizing relatively "safe."

Note that the hons-summary function can be used to see how large and how
full your hash tables are.  This may be useful in deciding what sizes
you want to give to hons-resize.

Note that hons-resize operates by (1) allocating new hash tables, then
(2) copying everything from the old hash table into the new table.
Because of this, for best performance you should ideally call it when
the hash tables involved are minimally populated, i.e., at the start of
your application, or soon after a hons-clear.


File: acl2-doc-emacs.info,  Node: HONS-SHRINK-ALIST,  Next: HONS-SHRINK-ALIST!,  Prev: HONS-RESIZE,  Up: HONS-AND-MEMOIZATION

HONS-SHRINK-ALIST    (hons-shrink-alist alist ans) can be used to eliminate "shadowed pairs"
from an alist or to copy fast-alists.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.  It assumes familiarity with fast alists; see
*note FAST-ALISTS::.

Logically, (hons-shrink-alist alist ans) is defined as follows:

      (cond ((atom alist)
             ans)
            ((atom (car alist))
             (hons-shrink-alist (cdr alist) ans))
            ((hons-assoc-equal (car (car alist)) ans)
             (hons-shrink-alist (cdr alist) ans))
            (t
             (hons-shrink-alist (cdr alist) (cons (car alist) ans))))

The alist argument need not be a fast alist.

Typically ans is set to nil or some other atom.  In this case, shrinking
produces a new, fast alist which is like alist except that (1) any
"malformed," atomic entries have been removed, (2) all "shadowed pairs"
have been removed, and (3) incidentally, the surviving elements have
been reversed.  This can be useful as a way to clean up any unnecessary
bindings in alist, or as a way to obtain a "deep copy" of a fast alist
that can extended independently from the original while maintaining
discipline.

Note that hons-shrink-alist is potentially expensive, for the following
two reasons.

     o The alist is copied, dropping any shadowed pairs.  This process
     will require a hash table lookup for each entry in the alist; and
     it will require creating a new alist, which uses additional memory.

     o Unless ans is a fast alist that is stolen (see below), a new
     hash table is created, which uses additional memory.  This hash
     table is populated in time that is linear in the number of unique
     keys in the alist.


When ans is not an atom, good discipline requires that it is a fast
alist.  In this case, hons-shrink-alist steals the hash table for ans
and extends it with all of the bindings in alist that are not in ans.
From the perspective of hons-assoc-equal, you can think of the
resulting alist as being basically similar to (append ans alist), but
in a different order.

Note that when ans is not a fast alist (e.g., ans is an atom) then such
stealing does not take place.

A common idiom is to replace an alist by the result of shrinking it, in
which case it is best to free the input alist, for example as follows.

       (let ((alist (fast-alist-free-on-exit alist
                                             (hons-shrink-alist alist nil))))
         ...)

See *note FAST-ALIST-FREE-ON-EXIT:: and see *note FAST-ALIST-FREE::.


File: acl2-doc-emacs.info,  Node: HONS-SHRINK-ALIST!,  Next: HONS-SUMMARY,  Prev: HONS-SHRINK-ALIST,  Up: HONS-AND-MEMOIZATION

HONS-SHRINK-ALIST!    (hons-shrink-alist! alist ans) is an alternative to hons-shrink-alist
that produces a normed result.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

Logically this function is just hons-shrink-alist; we leave it enabled
and would think it odd to ever prove a theorem about it.

Under the hood, this is the same as hons-shrink-alist except that it
uses something like hons-acons! instead of hons-acons.  You generally
*should not use* this function unless you really know what you're doing
and understand the drawbacks discussed in hons-acons!.


File: acl2-doc-emacs.info,  Node: HONS-SUMMARY,  Next: HONS-WASH,  Prev: HONS-SHRINK-ALIST!,  Up: HONS-AND-MEMOIZATION

HONS-SUMMARY    (hons-summary) prints basic information about the sizes of the tables in
the current Hons Space.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

Logically, hons-summary just returns nil; we leave it enabled and would
think it odd to ever prove a theorem about it.

Under the hood, this function gathers and prints some basic information
about the sizes of the tables in the Hons Space.

This information may be useful for deciding if you want to garbage
collect using functions such as hons-clear or hons-wash.  It may also be
useful for determining good initial sizes for the Hons Space hash
tables for your particular computation; see *note HONS-RESIZE::.


File: acl2-doc-emacs.info,  Node: HONS-WASH,  Next: MAKE-FAST-ALIST,  Prev: HONS-SUMMARY,  Up: HONS-AND-MEMOIZATION

HONS-WASH    (hons-wash) is like gc$ but can also garbage collect normed
objects (CCL Only).

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

Logically, hons-wash just returns nil; we leave it enabled and would
think it odd to ever prove a theorem about it.

Under the hood, in CCL, hons-wash runs a garbage collection after taking
special measures to allow normed conses to be collected.  In Lisps
other than CCL, hons-wash does nothing.  This is because the efficient
implementation of hons-wash is specific to the "static honsing" scheme
which requires CCL-specific features.

Why is this function needed?  Ordinarily, it is not possible to garbage
collect any normed conses.  This is because the Hons Space includes
pointers to any normed conses, and hence Lisp's garbage collector
thinks these objects are live.  To correct for this, hons-wash (1)
clears out these pointers, (2) runs a garbage collection, then (3)
re-norms any previously-normed conses which have survived the garbage
collection.

Note.  It is not recommended to interrupt this function.  Doing so may
cause persistently normed conses and fast alist keys to become
un-normed, which might lead to less efficient re-norming and/or
violations of the fast-alist discipline.


File: acl2-doc-emacs.info,  Node: MAKE-FAST-ALIST,  Next: MEMOIZE-SUMMARY,  Prev: HONS-WASH,  Up: HONS-AND-MEMOIZATION

MAKE-FAST-ALIST    (make-fast-alist alist) creates a fast-alist from the input alist,
returning alist itself or, in some cases, a new object equal to it.

Note: it is often better to use with-fast-alist; see *note
WITH-FAST-ALIST::.

Logically, make-fast-alist is the identity function.

Under the hood, we construct and return an object that is equal to
alist and which is a fast alist.  If alist is already a fast alist,
almost no work is required: we simply return it unchanged.

When alist is not fast, we must minimally construct a hash table for its
bindings.  It is often possible to bind this new hash table to alist
itself.  But in certain cases when the alist keys are not normed, a new
alist must be constructed, also, and so we may return an equal but not
eq alist.  (In these cases, we still try to avoid at least some consing
by reusing the "longest normed tail" of the alist.)


File: acl2-doc-emacs.info,  Node: MEMOIZE-SUMMARY,  Next: MEMSUM,  Prev: MAKE-FAST-ALIST,  Up: HONS-AND-MEMOIZATION

MEMOIZE-SUMMARY    display all collected profiling and memoization table info

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

Logically, this function just returns nil, but it displays profiling and
memoization table information.  The profiling statistics may be cleared
with (clear-memoize-statistics).


File: acl2-doc-emacs.info,  Node: MEMSUM,  Next: NEVER-MEMOIZE,  Prev: MEMOIZE-SUMMARY,  Up: HONS-AND-MEMOIZATION

MEMSUM    display all collected profiling and memoization info

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

This macro is an abbreviation for memoize-summary.  Logically, it just
returns nil.


File: acl2-doc-emacs.info,  Node: NEVER-MEMOIZE,  Next: NORMED,  Prev: MEMSUM,  Up: HONS-AND-MEMOIZATION

NEVER-MEMOIZE    Mark a function as unsafe to memoize.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

Logically, this function just returns nil.  But execution of
(never-memoize fn) records that fn must never be memoized, so that any
attempt to memoize fn will fail.

Any function can be marked as unsafe to memoize; in fact, fn need not
even be defined at the time it is marked.

This is useful for prohibiting the memoization of functions that are
known to involve destructive functions like nreverse.


File: acl2-doc-emacs.info,  Node: NORMED,  Next: NUMBER-SUBTREES,  Prev: NEVER-MEMOIZE,  Up: HONS-AND-MEMOIZATION

NORMED    Normed objects are ACL2 Objects that are "canonical" or "unique" in a
certain sense.

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

In Common Lisp, we can tell whether an ACL2 object is *normed* or not,
but there is no way for an ordinary ACL2 function to see whether an
object is normed.  Hence, whether or not an object is normed is an
implementation-level concept.

The fundamental property of normed objects is that if A and B are both
normed, then (equal A B) holds if and only if (eql A B) holds.  For
strings and conses, (eql A B) holds only when (eq A B), so any normed
conses or strings are equal precisely when they are eq.  The potential
benefits of having normed objects include:  constant-time equality
comparisons, reduced memory usage, fast association lists, and function
memoization.

Note that in our implementation, all symbols, characters, and numbers
are automatically normed, and whenever a cons is normed its car and cdr
must also be normed.

The Meaning of Normed in Common Lisp.

Recall that the ACL2 Objects are certain "good" Common Lisp symbols,
characters, strings, and numbers, and the conses which can be
recursively formed from these good atoms.

Not all properties of these objects are visible in the ACL2 logic.  An
example of an invisible property is the pointer identity of an object.
For example, suppose we write the following.

      (defconst *x* (cons 1 2))
      (defconst *y* (cons 1 2))

In Common Lisp, cons is guaranteed to provide a new pair that is
distinct from any previously created pair, so we know that *x* and *y*
will be distinct objects and we will be able to tell them apart from
one another using eq.  But this difference is not visible in the ACL2
logic, and no ACL2 function can tell *x* apart from *y*.

The normed-ness of an object is a similarly invisible property.  In
Common Lisp, invisible to ACL2, we maintain a data structure called a
"Hons Space" that records which objects are normed.  So, being normed
is not an intrinsic property of an object, but instead is determined by
whether the object is mentioned in this Hons Space.

Notes about Garbage Collection.

The Hons Space includes tables with pointers to every normed cons and
string.  One consequence of this is that normed objects cannot be
reclaimed by Lisp's ordinary garbage collector, even after they have
become unreachable from the perspective of an ACL2 program.

For CCL users only, hons-wash is a special kind of garbage collection
that allows normed conses to be reclaimed.  For other Lisps, the only
option is to occasionally, manually clear out these Hons Space tables
with hons-clear.


File: acl2-doc-emacs.info,  Node: NUMBER-SUBTREES,  Next: SLOW-ALIST-WARNING,  Prev: NORMED,  Up: HONS-AND-MEMOIZATION

NUMBER-SUBTREES    (number-subtrees x) returns the number of distinct subtrees of X, in the
sense of equal

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

In the logic, number-subtrees is defined as the length of cons-subtrees.

Under the hood, we first hons-copy X to obtain a normed version, then
count the number of unique conses in X using an EQ hash table.


File: acl2-doc-emacs.info,  Node: SLOW-ALIST-WARNING,  Next: WITH-FAST-ALIST,  Prev: NUMBER-SUBTREES,  Up: HONS-AND-MEMOIZATION

SLOW-ALIST-WARNING    warnings issued when fast-alists are used inefficiently

This documentation topic relates to the experimental extension of ACL2
supporting hash cons, fast alists, and memoization; see *note
HONS-AND-MEMOIZATION::.

Obtaining hash-table performance from hons-get requires one to follow a
certain discipline.  If this discipline is violated, you may see a "slow
alist warning".  This warning means that the alist you are extending or
accessing does not have a valid hash table associated with it, and
hence any accesses must be carried out with hons-assoc-equal instead of
gethash.

You can control whether or not you get a warning and, if so, whether or
not a break (an error from which you can continue) ensues.  For
instance:

      (set-slow-alist-action :warning)  ; warn on slow access (default)
      (set-slow-alist-action :break)    ; warn and also call break$
      (set-slow-alist-action nil)       ; do not warn or break

The above forms expand to table events, so they can be embedded in
encapsulates and books, wrapped in local, and so on.


File: acl2-doc-emacs.info,  Node: WITH-FAST-ALIST,  Next: WITH-STOLEN-ALIST,  Prev: SLOW-ALIST-WARNING,  Up: HONS-AND-MEMOIZATION

WITH-FAST-ALIST    (with-fast-alist name form) causes name to be a fast alist for the
execution of form.

Logically, with-fast-alist just returns form.

Under the hood, we cause alist to become a fast alist before executing
form.  If doing so caused us to introduce a new hash table, the hash
table is automatically freed after form completes.

More accurately, under the hood (with-fast-alist name form) essentially
expands to something like:

      (if (already-fast-alist-p name)
          form
        (let ((<temp> (make-fast-alist name)))
          (prog1 form
                 (fast-alist-free <temp>))))

Practically speaking, with-fast-alist is frequently a better choice then
just using make-fast-alist, and is particularly useful for writing
functions that can take either fast or slow alists as arguments.  That
is, consider the difference between:

      (defun bad (alist ...)
        (let* ((fast-alist (make-fast-alist alist))
               (answer     (expensive-computation fast-alist ...)))
         (prog2$ (fast-alist-free fast-alist)
                 answer)))

      (defun good (alist ...)
         (with-fast-alist alist
           (expensive-computation alist ...)))

Either approach is fine if the caller provides a slow alist.  But if the
input alist is already fast, bad will (perhaps unexpectedly) free it!
On the other hand, good is able to take advantage of an already-fast
argument and will not cause it to be inadvertently freed.

See also the macro with-fast-alists defined in the community book
"books/centaur/misc/hons-extra.lisp", which allows you to call
with-fast-alist on several alists simultaneously.

The community book "books/centaur/misc/hons-extra.lisp" extends the b*
macro (defined in the community book "books/tools/bstar.lisp") with the
with-fast pattern binder.  That is, after executing (include-book
"centaur/misc/hons-extra.lisp" :dir :system) you may write something
like this:

      (b* (...
           ((with-fast a b c ...))
           ...)
        ...)

which causes a, b, and c to become fast alists until the completion of
the b* form.

Note that with-fast-alist will cause logically tail-recursive functions
not to execute tail-recursively if its cleanup phase happens after the
tail-recursive call returns.


File: acl2-doc-emacs.info,  Node: WITH-STOLEN-ALIST,  Prev: WITH-FAST-ALIST,  Up: HONS-AND-MEMOIZATION

WITH-STOLEN-ALIST    (with-stolen-alist name form) ensures that name is a fast alist at the
start of the execution of form.  At the end of execution, it ensures that
name is a fast alist if and only if it was originally.  That is, if
name was not a fast alist originally, its hash table link is freed, and if
it was a fast alist originally but its table was modified during the execution
of form, that table is restored.  Note that any extended table created from
the original fast alist during form must be manually freed.

Logically, with-stolen-alist just returns form.

Under the hood, we cause alist to become a fast alist before executing
form, and we check the various conditions outlined above before
returning the final value.

Note that with-stolen-alist will cause logically tail-recursive
functions not to execute tail-recursively if its cleanup phase happens
after the tail-recursive call returns.


File: acl2-doc-emacs.info,  Node: INTRODUCTION-TO-THE-TAU-SYSTEM,  Next: IO,  Prev: HONS-AND-MEMOIZATION,  Up: Top

INTRODUCTION-TO-THE-TAU-SYSTEM    a decision procedure for runtime types

This doc topic is the main source of information about the tau system
and discusses the general idea behind the procedure and how to exploit
it.

A "Type-Checker" for an Untyped Language

Because ACL2 is an untyped language it is impossible to type check it.
All functions are total.  An n-ary function may be applied to any
combination of n ACL2 objects.  The syntax of ACL2 stipulates that (fn
a1...an) is a well-formed term if fn is a function symbol of n
arguments and the ai are well-formed terms.  No mention is made of the
"types" of terms.  That is what is meant by saying ACL2 is an untyped
language.

Nevertheless, the system provides a variety of monadic Boolean function
symbols, like natp, integerp, alistp, etc., that recognize different
"types" of objects at runtime.  Users typically define many more such
recognizers for domain-specific "types."  Because of the prevalence of
such "types," ACL2 must frequently reason about the inclusion of one
"type" in another.  It must also reason about the consequences of
functions being defined so as to produce objects of certain "types"
when given arguments of certain other "types."

Because the word "type" in computer science tends to imply syntactic or
semantic restrictions on functions, we avoid using that word henceforth.
Instead, we just reason about monadic Boolean predicates.  You may wish
to think of "tau" as synonymous with "type" but without any suggestion
of syntactic or semantic restrictions.

* Menu:

* DEALING-WITH-TAU-PROBLEMS:: some advice on dealing with problems caused by the tau system

* FUTURE-WORK-RELATED-TO-THE-TAU-SYSTEM:: some tau system problems that we hope someone will address


Related topics other than immediate subtopics:
* REGENERATE-TAU-DATABASE:: regenerate the tau database relative to the current enabled theory

* SET-TAU-AUTO-MODE:: turn on or off automatic (``greedy'') generation of :tau-system rules

* TAU-DATA:: to see what tau knows about a function symbol

* TAU-DATABASE:: to see the tau database as a (very large) object

* TAU-STATUS:: query or set tau system status

* TAU-SYSTEM:: make a rule for the ACL2 ``type checker''

Design Philosophy

The following basic principles were kept in mind when developing tau
checker and may help you exploit it.

(1) The tau system is supposed to be a lightweight, fast, and helpful
decision procedure for an elementary subset of the logic focused on
monadic predicates and function signatures.

(2) Most subgoals produced by the theorem prover are not in any
decidable subset of the logic!  Thus, decision procedures fail to prove
the vast majority of the formulas they see and will be net time-sinks
if tried too often no matter how fast they are.

Tau reasoning is used by the prover as part of preprocess-clause, one of
the first proof techniques the system tries.  The tau system filters out
"obvious" subgoals.  The tau system is only tried when subgoals first
enter the waterfall and when they are stable under simplification.

(3) The tau system is "benign" in the sense that the only way it
contributes to a proof is to eliminate (prove!) subgoals.  It does not
rewrite, simplify, or change formulas.  Tau reasoning is not used by the
rewriter.  The tau system either eliminates a subgoal by proving it or
leaves it unchanged.

(4) It is impossible to infer automatically the relations between
arbitrary recursively defined predicates and functions.  Thus, the tau
system's knowledge of tau relationships and function signatures is
gleaned from theorems stated by the user and proved by the system.

(5) Users wishing to build effective "type-checkers" for their models
must learn how rules affect the tau system's behavior.  There are two
main forms of tau rules: those that reveal inclusion/exclusion
relations between named tau predicates, e.g., that 16-bit naturals are
also 32-bit naturals,

     (implies (n16p x) (n32p x)),

and signatures for all relevant functions, e.g., writing a 32-bit
natural to a legal slot in a register file produces a register file:

     (implies (and (natp n)
                   (< n 16)
                   (n32p val)
                   (register-filep regs))
              (register-filep (update-nth n val regs))).

For a complete description of acceptable forms see :tau-system.

(6) The tau system is "greedy" in its efforts to augment its database.
Its database is potentially augmented when rules of any :rule-class (see
:rule-classes) are proved.  For example, if you make a :rewrite or
:type-prescription rule which expresses a relationship between one tau
and another (e.g., that (P x) implies (Q x)), ACL2 will build it into
the tau database.  The rule-class :tau-system can be used to add a rule
to the tau database without adding any other kind of rule.

(7) Greediness is forced into the design by benignity: the tau system
may "know" some fact that the rewriter does not, and because tau
reasoning is not used in rewriting, that missing fact must be conveyed
to the rewriter through some other class of rule, e.g., a :rewrite or
:type-prescription or :forward-chaining rule.  By making the tau system
greedy, we allow the user to program the rewriter and the tau system
simultaneously while keeping them separate.  However, this means you
must keep in mind the effects of a rule on both the rewriter and the tau
system and use :tau-system rules explicitly when you want to "talk"
just to the tau system.

(8) Tau rules are built into the database with as much preprocessing as
possible (e.g., the system transitively closes inclusion/exclusion
relationships at rule-storage time) so the checker can be fast.

(9) For speed, tau does not track dependencies and is not sensitive to
the enabled/disabled status (see enable and disable) of rules.  Once a
fact has been built into the tau database, the only way to prevent that
fact from being used is by disabling the entire tau system, by disabling
(:executable-counterpart tau-system).  If any tau reasoning is used in
a proof, the rune (:executable-counterpart tau-system) is reported in
the summary.  For a complete list of all the runes in the tau database,
evaluate (global-val 'tau-runes (w state)).  Any of these associated
theorems could have been used.

These design criteria are not always achieved!  For example, the tau
system's "greediness" can be turned off (see set-tau-auto-mode), the tau
database can be regenerated from scratch to ignore disabled rules (see
regenerate-tau-database), and disabling the executable-counterpart of a
tau predicate symbol will prevent the tau system from trying to run the
predicate on constants.  The tau system's benignity can be frustrating
since it might "know" something the rewriter does not.  More
problematically, the tau system is not always "fast" and not always
"benign!"  The typical way tau reasoning can slow a proof down is by
evaulating expensive tau predicates on constants.  The typical way tau
reasoning can hurt a previously successful proof is by proving some
subgoals (!) and thus causing the remaining subgoals to have different
clause-identifiers, thus making explicit hints no longer applicable.  We
deal with such problems in dealing-with-tau-problems.

Technical Details

The tau system consists of both a database and an algorithm for using
the database.  The database contains theorems that match certain
schemas allowing them to be stored in the tau database.  Roughly
speaking the schemas encode "inclusion" and "exclusion" relations,
e.g., that natp implies integerp and that integerp implies not consp,
and they encode "signatures" of functions, e.g., theorems that relate
the output of a function to the input, provided only tau predicates are
involved.

By "tau predicates" we mean the application of a monadic Boolean-valued
function symbol, the equality of something to a quoted constant, an
arithmetic ordering relation between something and a rational constant,
or the logical negation of such a term.  Here are some examples of tau
predicates:

     (natp i)
     (not (consp x))
     (equal y 'MONDAY)
     (not (eql 23 k))
     (< 8 max)
     (<= max 24)

Synonyms for equal include =, eq, and eql.  Note that negated equalites
are also allowed.  The arithmetic ordering relations that may be used
are <, <=, >=, and >.  One of the arguments to every arithmetic
ordering relation must be an integer or rational constant for the term
to be treated as a tau predicate.

A "tau" is a data object representing a set of signed (positive or
negative) tau predicates whose meaning is the conjunction of the
literals in the set.

When we say that a term "has" a given tau we mean the term satisfies
all of the recognizers in that tau.

The tau algorithm is a decision procedure for the logical theory
described (only) by the rules in the database.  The algorithm takes a
term and a list of assumptions mapping subterms (typically variable
symbols) to tau, and returns the tau of the given term.

When the system is called upon to decide whether a term satisfies a
given monadic predicate, it computes the tau of the term and asks
whether the predicate is in that set.  More generally, to determine if
a term satisfies a tau, s, we compute a tau, r, for the term and ask
whether s is a subset of r.  To determine whether a constant, c,
satisfies tau s we apply each of the literals in s to c.  Evaluation
might, of course, be time-consuming for complex user-defined predicates.

The tau database contains rules derived from definitions and theorems
stated by the user.  See :tau-system for a description of the acceptable
forms of tau rules.

To shut off the greedy augmentation of the tau database, see *note
SET-TAU-AUTO-MODE::.  This may be of use to users who wish to tightly
control the rules in the tau database.  To add a rule to the tau
database without adding any other kind of rule, use the rule class
:tau-system.

There are some slight complexities in the design related to how we
handle events with both :tau-system corollaries and corollaries of other
:rule-classes, see set-tau-auto-mode.

To prevent tau reasoning from being used, disable the
:executable-counterpart of tau-system, i.e., execute

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

or, equivalently,

     (in-theory (disable (tau-system)))

To prevent tau from being used in the proof of a particular subgoal,
locally disable the :executable-counterpart of tau-system with a local
:in-theory hint (see *note HINTS::).

The event command tau-status is a macro that can be used to toggle both
whether tau reasoning is globally enabled and whether the tau database
is augmented greedily.  For example, the event

     (tau-status :system nil :auto-mode nil)

prevents the tau system from being used in proofs and prevents the
augmentation of the tau database by rules other than those explicitly
labeled :tau-system.

To see what the tau system "knows" about a given function symbol see
*note TAU-DATA::.  To see the entire tau database, see *note
TAU-DATABASE::.  To regenerate the tau database using only the runes
listed in the current enabled theory, see *note
REGENERATE-TAU-DATABASE::.


File: acl2-doc-emacs.info,  Node: DEALING-WITH-TAU-PROBLEMS,  Next: FUTURE-WORK-RELATED-TO-THE-TAU-SYSTEM,  Prev: INTRODUCTION-TO-THE-TAU-SYSTEM,  Up: INTRODUCTION-TO-THE-TAU-SYSTEM

DEALING-WITH-TAU-PROBLEMS    some advice on dealing with problems caused by the tau system

For background on the tau system, see *note
INTRODUCTION-TO-THE-TAU-SYSTEM::.  The two most common problems caused
by the tau system have to do with the system's interaction with
"legacy" proof scripts.  Such scripts may suffer because they were not
designed to exploit tau reasoning and which may configure the tau
database in quite incomplete and arbitrary ways.  The two most common
problems we have seen are (a) significant slow downs in a few proofs
and (b) failed proof attempts due to hints being misapplied because the
tau system caused subgoals to be renumbered.

We discuss the rather limited means of dealing with these problems
here.  In future-work-related-to-the-tau-system we list some major
inadequacies of the tau system.

If the tau system contributes to a proof, the rune
(:executable-counterpart tau-system) will be listed among the Rules in
the Summary.  However, merely by being attempted the tau system can
slow down proofs in which it makes no contribution.

The most brutal and fool-proof way to isolate a proof from the tau
system is to disable the entire system.  This can be done globally by

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

or locally with a subgoal specific hint:

     ...
     :hints (("...subgoal id..." :in-theory (disable (tau-system))))

Conducting a proof with and without the participation of the tau system
can help you determine whether tau reasoning is helping or hurting.

Dealing with Slowdowns

The time-tracker utility was added to allow users to investigate
whether excessive amounts of time are being spent in a given function.
It was then used to annotate the code for the tau system as described in
time-tracker-tau.  The result is that if "excessive" time is spent in
tau reasoning, messages to that effect will be printed to the proof
log.  The question is: aside from disabling the tau system how can the
proof be sped up?

There are two common causes of slowdown in the tau system.  The first
stems from the system's use of :executable-counterparts to determine
whether a constant has a given tau.  Recall that a tau is a conjunction
of monadic predicates.  To determine whether some constant satisfies
the tau, the predicates are executed.  If you have a hard-to-compute
predicate this can be very slow.  The most typical such predicates in
ACL2 applications are those that check invariants, e.g., that recognize
"good states" or "well-formed data."  These are often written
inefficiently because they are intended only for used in theorems and,
before the tau system was added, they may have never been applied to
constants.  The most common constants tau predicates are applied to are
0, T, and NIL, although different models may stress other constants.
To understand why NIL for example is frequently tested, if the test of
an IF-expression is computed to have tau s then the next question we
ask is "does nil satisfy s?"

You may determine whether the tau system is spending time executing tau
predicates by observing the rewriter -- see *note DMR:: -- or by
interrupting the system and getting a backtrace (see *note
SET-DEBUGGER-ENABLE::).

If excessive time is being spent in a tau predicate, a draconian
solution is to disable the :executable-counterpart of that predicate,
for example in either of these equivalent ways.  The tau system does
not execute disabled :executable-counterparts.

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

In either case above, you may prefer to provide local :in-theory :hints
rather than :in-theory events.

Disabling the executable counterpart of expensive tau predicates will
weaken the tau system, probably only negligibly, because it can no
longer run the predicates to determine whether they admits given
constants.

A more sophisticated solution is to make the tau system record values
of the :logic-mode function in question, so that the system will look up
the necessary values rather than running the function every time the
question arises.  It will look up recorded values whether the
executable counterpart of the tau predicate is enabled or disabled.
Here is an example of a lemma that can provide such a solution.  See
the discussion of the Eval form of :tau-system rules.

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

It might be difficult to determine which constants are being repeatedly
tested, although tracing (trace$) suspected tau predicates will show
what they are being called on.

At the moment there are no better user-level tools to discover this.
However, some users may wish to consider the following hack: In the ACL2
source file tau.lisp, immediately after the definition of the system
function ev-fncall-w-tau-recog, there is a comment which contains some
raw Lisp code that can be used to investigate whether tau's use of
evaluation on constants is causing a problem and to determine which
constants are involved.

The second main cause of slowdowns by the tau system is that the system
contains "too many" conjunctive rules (see the Conjunctive form in
tau-system).  Unfortunately, we have no tools for either identifying
the problem or addressing it!  That said, let us tell you what we do
know!

Conjunctive rules are used to "complete" each tau as it is built.
Referring to the weekdayp example in tau-system, if a tau is
constructed that recognizes weekdays but not MON, TUE, THU, or FRI, it
is completed by adding that the tau recognizes (only) WED.  This means
that when we construct a tau we scan all known conjunctive rules and
see whether all but one of the literals of any conjunctive rule are
present.  This can be expensive.  To mitigate this expense, the tau
system caches the computation on a per proof basis (the cache is
cleared after every proof).

To learn what conjunctive rules there are in your system, evaluate

     (assoc 'tau-conjunctive-rules (tau-database (w state)))

Perhaps by sending the implementors that list, we can think of ways to
index the conjunctive rules to save time.

Dealing with Misapplied Hints

The second common problem caused by the tau system in legacy proof
scripts is that it can cause subgoals to be renumbered and thus cause
hints to be missed.  The only ways to address this problem is either to
disable the tau system (locally or globally by disabling
(:executable-counterpart tau-system)) or change the legacy hints to use
the new subgoal names.


File: acl2-doc-emacs.info,  Node: FUTURE-WORK-RELATED-TO-THE-TAU-SYSTEM,  Prev: DEALING-WITH-TAU-PROBLEMS,  Up: INTRODUCTION-TO-THE-TAU-SYSTEM

FUTURE-WORK-RELATED-TO-THE-TAU-SYSTEM    some tau system problems that we hope someone will address

The tau system is inexpressive compared to modern polymorphic type
systems -- something that may be unavoidable in an untyped first-order
language.  However, we believe its effectiveness could be greatly
increased by the development of some additional tools.  We also believe
that most of these tools could be provided by ACL2 users creating
certified community books that exploit the basic tools already
provided.  It is likely the initial attempts to create such books will
show the inadequacy of some of the current algorithms and data
structures in the tau system and might point the way to improvements.

As implementors of ACL2 our preference is to support the improvement of
the core algorithms and data structures and provide customizable hooks
allowing users to exploit them by developing effective and convenient
interfaces.  However, we want the further elaboration and optimization
of the tau system to be based on user experience not just speculation.

Some tools we think might help are listed below.  We invite volunteers
and further suggestions.

A tau-centric signature notation for use in function definitions,
exploited by a macro replacing defun so that input-output relationships
phrased in tau terms are proved as :tau-system rules immediately after
functions are introduced:

We have, for example, experimented with a book defining a macro that
allows the definition of the function ap (append) accompanied by a
signature rule.  Subsequent defsig events can add other signatures in
the same notation.

     (defsig ap (true-listp * true-listp ==> true-listp) (x y)
        (if (consp x)
            (cons (car x) (ap (cdr x) y))
            y))

     (defsig ap (integer-listp * integer-listp ==> integer-listp))

This experimental book provides succinct syntax for all tau signatures.
For example, that book parses the signature

     (NATP (/= 3 5 7) (< 16) * TRUE-LISTP ==> BOOLEANP * INTEGER-LISTP * NATP)
 to be the signature of a function with two inputs and three outputs.
The first input must be a natural number, different from 3, 5, and 7,
and less than 16.  The second input must be a true list.  The first
output is a boolean, the second a list of integers, and the third a
natural.

To express this signature for function fn as a formula requires
significantly more typing by the user:

     (IMPLIES (AND (NATP X)
                   (NOT (EQUAL X 3))
                   (NOT (EQUAL X 5))
                   (NOT (EQUAL X 7))
                   (< X 16)
                   (TRUE-LISTP Y))
              (AND (BOOLEANP (MV-NTH 0 (FN X Y)))
                   (INTEGER-LISP (MV-NTH 1 (FN X Y)))
                   (NATP (MV-NTH 2 (FN X Y)))))

We suspect that the provision of some succinct tau-centric notation (not
necessarily the one above) for signatures at definition-time will mean
users get more benefit from the tau system.

Some tau inference mechanisms: This phrase suggests two different
improvements.  One is to implement a mechanism that adds or completes
signatures for function definitions by exploiting knowledge of commonly
used recursive schemas and the signatures of the subroutines in the
body.  For example, the definition of ap above rather obviously has the
signature

     (integer-listp * integer-listp ==> integer-listp)

and many others just based on the two recursive schemas that (a) collect
certain elements from lists and (b) check that all elements have a
certain property.

The other "tau inference" improvement is to implement a mechanism for
inferring relations between user-defined Booleans, perhaps by exploiting
example generation, testing, and knowledge of recursive schemas.  For
example, it is fairly obvious that symbol-alistp implies alistp.
Making the user state these relations invites omissions that render the
tau system very unpredictable.

A tau assistant: It would be useful to have a way to find out what tau
rules are missing.  Given a term that the user believes should
"obviously" have some tau ("type") what rules might be added to make
the tau algorithm compute that expected tau?  For example, if (g x) is
known to satisfy P and (f x) is known to satisfy R when its argument
satisfies S:

     g : T ==> P
     f : S ==> R

then if the user asserts that (f (g x)) "ought" to have tau R, one
plausible suggestion is the simple tau rule that (P x) implies (S x).
Such assistance -- while still confronting an undecidable problem --
might be easier to implement within the tau framework than more
generally in ACL2.  (Many users have wanted such an assistant to
suggest lemmas for the rewriter.)


File: acl2-doc-emacs.info,  Node: IO,  Next: MISCELLANEOUS,  Prev: INTRODUCTION-TO-THE-TAU-SYSTEM,  Up: Top

IO    input/output facilities in ACL2

     Example:
     (mv-let
       (channel state)
       (open-input-channel "foo.lisp" :object state)
       (mv-let (eofp obj state)
               (read-object channel state)
               (.
                 .
                  (let ((state (close-input-channel channel state)))
                        (mv final-ans state))..)))

Also see *note FILE-READING-EXAMPLE::.

For advanced ways to control printing, see *note PRINT-CONTROL::.

For a discussion of formatted printing, see *note FMT::.

To control ACL2 abbreviation ("evisceration") of objects before printing
them, see *note SET-EVISC-TUPLE::, see *note WITHOUT-EVISC::, and see
*note SET-IPRINT::.

To redirect output to a file, see *note OUTPUT-TO-FILE::.

* Menu:

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

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

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

* CHARACTER-ENCODING:: how bytes are parsed into characters

* EVISC-TUPLE:: control suppression of details when printing

* EVISCERATE-HIDE-TERMS:: to print (hide ...) as <hidden>

* EXTERNAL-FORMAT:: See *note CHARACTER-ENCODING::.

* IPRINT:: See *note SET-IPRINT::.

* IPRINTING:: See *note SET-IPRINT::.

* OPEN-OUTPUT-CHANNEL!:: when trust tags are needed to open output channels

* OUTPUT-TO-FILE:: redirecting output to a file

* PRINT-CONTROL:: advanced controls of ACL2 printing

* PRINTING-TO-STRINGS:: printing to strings instead of files or standard output

* RESET-PRINT-CONTROL:: See *note PRINT-CONTROL::.

* SET-EVISC-TUPLE:: control suppression of details when printing

* SET-FMT-HARD-RIGHT-MARGIN:: set the right margin for formatted output

* SET-FMT-SOFT-RIGHT-MARGIN:: set the soft right margin for formatted output

* SET-IPRINT:: control whether abbreviated output can be read back in

* SET-PRINT-BASE:: control radix in which numbers are printed

* SET-PRINT-CASE:: control whether symbols are printed in upper case or in lower case

* SET-PRINT-CIRCLE:: See *note PRINT-CONTROL::.

* SET-PRINT-ESCAPE:: See *note PRINT-CONTROL::.

* SET-PRINT-LENGTH:: See *note PRINT-CONTROL::.

* SET-PRINT-LEVEL:: See *note PRINT-CONTROL::.

* SET-PRINT-LINES:: See *note PRINT-CONTROL::.

* SET-PRINT-RADIX:: control printing of the radix for numbers

* SET-PRINT-READABLY:: See *note PRINT-CONTROL::.

* SET-PRINT-RIGHT-MARGIN:: See *note PRINT-CONTROL::.

* WITHOUT-EVISC:: print output in full


Related topics other than immediate subtopics:
* PRINC$:: print an atom

ACL2 supports input and output facilities equivalent to a subset of
those found in Common Lisp.  ACL2 does not support random access to
files or bidirectional streams.  In Common Lisp, input and output are
to or from objects of type stream.  In ACL2, input and output are to or
from objects called "channels," which are actually symbols.  Although a
channel is a symbol, one may think of it intuitively as corresponding
to a Common Lisp stream.  Channels are in one of two ACL2 packages,
"ACL2-INPUT-CHANNEL" and "ACL2-OUTPUT-CHANNEL".  When one "opens" a
file one gets back a channel whose symbol-name is the file name passed
to "open," postfixed with -n, where n is a counter that is incremented
every time an open or close occurs.

There are three channels which are open from the beginning and which
cannot be closed:

       acl2-input-channel::standard-character-input-0
       acl2-input-channel::standard-object-input-0
       acl2-input-channel::standard-character-output-0

All three of these are really Common Lisp's *standard-input* or
*standard-output*, appropriately.

For convenience, three global variables are bound to these rather
tedious channel names:

       *standard-ci*
       *standard-oi*
       *standard-co*

Common Lisp permits one to open a stream for several different kinds of
io, e.g. character or byte.  ACL2 permits an additional type called
"object".  In ACL2 an "io-type" is a keyword, either :character, :byte,
or :object.  When one opens a file, one specifies a type, which
determines the kind of io operations that can be done on the channel
returned.  The types :character and :byte are familiar.  Type :object
is an abstraction not found in Common Lisp.  An :object file is a file
of Lisp objects.  One uses read-object to read from :object files and
print-object$ (or print-object$-ser) to print to :object files.  (The
reading and printing are really done with the Common Lisp read and
print functions.  For those familiar with read, we note that the
recursive-p argument is nil.)  The function read-object-suppress is
logically the same as read-object except that read-object-suppress
throws away the second returned value, i.e. the value that would
normally be read, simply returning (mv eof state); under the hood,
read-object-suppress avoids errors, for example those caused by
encountering symbols in packages unknown to ACL2.

File-names are strings.  ACL2 does not support the Common Lisp type
pathname.  However, for the file-name argument of the output-related
functions listed below, ACL2 supports a special value, :STRING.  For
this value, the channel connects (by way of a Common Lisp output string
stream) to a string rather than to a file: as characters are written to
the channel they can be retrieved by using get-output-stream-string$.

Here are the names, formals and output descriptions of the ACL2 io
functions.

     Input Functions:
       (open-input-channel (file-name io-type state) (mv channel state))
       (open-input-channel-p (channel io-type state) boolean)
       (close-input-channel (channel state) state)
       (read-char$ (channel state) (mv char/nil state)) ; nil for EOF
       (peek-char$ (channel state) boolean)
       (read-byte$ (channel state) (mv byte/nil state)) ; nil for EOF
       (read-object (channel state) (mv eof-read-flg obj-read state))
       (read-object-suppress (channel state) (mv eof-read-flg state))

     Output Functions:
       (open-output-channel  (file-name io-type state) (mv channel state))
       (open-output-channel! (file-name io-type state) (mv channel state))
       (open-output-channel-p (channel io-type state) boolean)
       (close-output-channel (channel state) state)
       (princ$ (obj channel state) state)
       (write-byte$ (byte channel state) state)
       (print-object$ (obj channel state) state)
       (print-object$-ser (obj serialize-character channel state) state)
       (fms  (string alist channel state evisc-tuple) state)
       (fms! (string alist channel state evisc-tuple) state)
       (fmt  (string alist channel state evisc-tuple) (mv col state))
       (fmt! (string alist channel state evisc-tuple) (mv col state))
       (fmt1 (string alist col channel state evisc-tuple) (mv col state))
       (fmt1! (string alist col channel state evisc-tuple) (mv col state))
       (cw (string arg0 arg1 ... argn) nil)
       (get-output-stream-string$ (channel state
                                   &optional (close-p 't)
                                             (ctx ''get-output-stream-string$))
                                  (mv erp string state))

The "formatting" functions are particularly useful; see *note FMT:: and
see *note CW::.  In particular, cw prints to a "comment window" and
does not involve the ACL2 state, so many may find it easier to use than
fmt and its variants.  The functions fms!, fmt!, and fmt1! are the same
as their respective functions without the "!," except that the "!"
functions are guaranteed to print forms that can be read back in (at a
slight readability cost).

When one enters ACL2 with (lp), input and output are taken from
*standard-oi* to *standard-co*.  Because these are synonyms for
*standard-input* and *standard-output*, one can drive ACL2 io off of
arbitrary Common Lisp streams, bound to *standard-input* and
*standard-output* before entry to ACL2.

The macro get-output-stream-string$ returns the string accumulated into
the given channel.  By default, a call of this macro closes the supplied
output channel.  However, a third argument is optional (default t), and
if it evaluates to nil then the channel remains open.  The fourth
argument is an optional context, which generally evaluates to a symbol,
for error reporting.  The following example illustrates.

     ACL2 !>
     (mv-let
        (channel state)
        (open-output-channel :string :object state)
        (pprogn (print-object$-ser 17 nil channel state)
                (print-object$-ser '(a b (c d)) nil channel state)
                (er-let*
                  ((str1 (get-output-stream-string$
                          channel state
                          nil))) ; keep the channel open
                  (pprogn (print-object$-ser 23 nil channel state)
                          (print-object$-ser '((e f)) nil channel state)
                          (er-let* ; close the channel
                            ((str2 (get-output-stream-string$ channel state)))
                            (value (cons str1 str2)))))))
      ("
     17
     (A B (C D))" . "
     23
     ((E F))")
     ACL2 !>

Also see *note PRINTING-TO-STRINGS:: for a discussion of formatted
printing functions such as fmt-to-string that do not take a channel or
state argument and return a string.

By default, symbols are printed in upper case when vertical bars are not
required, as specified by Common Lisp.  See *note SET-PRINT-CASE:: for
how to get ACL2 to print symbols in lower case.

By default, numbers are printed in radix 10 (base 10).  See *note
SET-PRINT-BASE:: for how to get ACL2 to print numbers in radix 2, 8, or
16.

To see the guard of an IO function, or indeed any function, see *note
ARGS:: or call the function guard; but some built-in functions
(including some IO functions) will print the result using the variable
STATE-STATE.  While that is logically correct, if you want to execute
the guard then you should replace that variable by STATE and also
replace each built-in function symbol of the form xxx-p1 by
corresponding function symbol xxx-p.  Consider the following example.

     ACL2 !>:args princ$

     Function         PRINC$
     Formals:         (X CHANNEL STATE-STATE)
     Signature:       (PRINC$ * * STATE)
                      => STATE
     Guard:           (AND (OR (ACL2-NUMBERP X)
                               (CHARACTERP X)
                               (STRINGP X)
                               (SYMBOLP X))
                           (STATE-P1 STATE-STATE)
                           (SYMBOLP CHANNEL)
                           (OPEN-OUTPUT-CHANNEL-P1 CHANNEL
                                                   :CHARACTER STATE-STATE))
     Guards Verified: T
     Defun-Mode:      :logic
     Type:            (CONSP (PRINC$ X CHANNEL STATE-STATE))
     Documentation available via :DOC
      PRINC$
     ACL2 !>(untranslate (guard 'princ$ nil (w state)) t (w state))
     (AND (OR (ACL2-NUMBERP X)
              (CHARACTERP X)
              (STRINGP X)
              (SYMBOLP X))
          (STATE-P1 STATE-STATE)
          (SYMBOLP CHANNEL)
          (OPEN-OUTPUT-CHANNEL-P1 CHANNEL
                                  :CHARACTER STATE-STATE))
     ACL2 !>

If you want to execute the guard for princ$, then according to the
suggestion above, you should consider the guard for (princ$ x channel
state) to be as follows.

     (AND (OR (ACL2-NUMBERP X)
              (CHARACTERP X)
              (STRINGP X)
              (SYMBOLP X))
          (STATE-P STATE)
          (SYMBOLP CHANNEL)
          (OPEN-OUTPUT-CHANNEL-P CHANNEL :CHARACTER STATE))

For example, we can check the guard for a given value and channel as
follows.

     ACL2 !>(let ((x 3) (channel *standard-co*))
              (AND (OR (ACL2-NUMBERP X)
                       (CHARACTERP X)
                       (STRINGP X)
                       (SYMBOLP X))
                   (STATE-P STATE)
                   (SYMBOLP CHANNEL)
                   (OPEN-OUTPUT-CHANNEL-P CHANNEL :CHARACTER STATE)))
     T
     ACL2 !>

Comment for advanced users: Function open-output-channel! is identical
as a function to open-output-channel, except that the former may be
called even during make-event expansion and clause-processor hints, but
requires that there is an active trust tag (see *note DEFTTAG::).

Finally, we note that the community book books/misc/file-io.lisp
contains useful file io functions whose definitions illustrate some of
the features described above.


File: acl2-doc-emacs.info,  Node: *STANDARD-CI*,  Next: *STANDARD-CO*,  Prev: IO,  Up: IO

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

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

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


File: acl2-doc-emacs.info,  Node: *STANDARD-CO*,  Next: *STANDARD-OI*,  Prev: *STANDARD-CI*,  Up: IO

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

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

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

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

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


File: acl2-doc-emacs.info,  Node: *STANDARD-OI*,  Next: CHARACTER-ENCODING,  Prev: *STANDARD-CO*,  Up: IO

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

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

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


File: acl2-doc-emacs.info,  Node: CHARACTER-ENCODING,  Next: EVISC-TUPLE,  Prev: *STANDARD-OI*,  Up: IO

CHARACTER-ENCODING    how bytes are parsed into characters

When the Common Lisp reader comes across bytes in a file or at the
terminal, they are parsed into characters.  The simplest case is when
each byte that is read is a standard character (see *note
STANDARD-CHAR-P::).  It is actually quite common that each byte that is
read corresponds to a single character.  The parsing of bytes into
characters is based on a _character encoding_, that is, a mapping that
associates one or more bytes with each legal character.

In order to help guarantee the portability of files (including books),
ACL2 installs a common character encoding for reading files, often
known as iso-8859-1 or latin-1.  For some host Lisps this character
encoding is also used for reading from the terminal; but, sadly, this
may not hold for all host Lisps, and may not even be possible for some
of them.

The use of the above encoding could in principle cause problems if one's
editor produces files using an encoding other than iso-8859-1, at least
if one uses non-standard characters.  In particular, the default Emacs
buffer encoding may be utf-8.  If your file has non-standard
characters, then in Emacs you can evaluate the form

     (setq save-buffer-coding-system 'iso-8859-1)

before saving the buffer into a file.  This will happen automatically
for users who load distributed file emacs/emacs-acl2.el into their Emacs
sessions.

For an example of character encodings in action, see the community book
books/misc/character-encoding-test.lisp.


File: acl2-doc-emacs.info,  Node: EVISC-TUPLE,  Next: EVISCERATE-HIDE-TERMS,  Prev: CHARACTER-ENCODING,  Up: IO

EVISC-TUPLE    control suppression of details when printing

ACL2 output is generally printed in full.  However, ACL2 can be
directed to abbreviate, or "eviscerate", objects before printing them.
To "eviscerate" an object we replace certain substructures within it by
strings that are printed in their stead.  Such replacement is made
relative to a so-called "evisc-tuple", which has four components:
(evisc-tuple print-level print-length alist hiding-cars) is the same as
the value of (list alist print-level print-length hiding-cars), and the
components are used as follows (with priority order as discussed
below).  The alist component is used to replace any substructure
occurring as a key by the corresponding string.  The print-level and
print-length are analogous to Common Lisp variables *print-level* and
*print-length*, respectively, and cause replacement of substructures
deeper than print-level by `#' and those longer than print-length by
`...'.  Finally, any consp x that starts with one of the symbols in
hiding-cars is printed as <hidden>.

The following example illustrates the use of an evisc-tuple that limits
the print-level to 3 -- only three descents into list structures are
permitted before replacing a subexpression by `#' -- and limits the
print-length to 4 -- only the first four elements of any list structure
will be printed before replacing its tail by `...'.

     ACL2 !>(fms "~x0~%"
                 (list (cons #\0 '((a b ((c d)) e f g) u v w x y)))
                 *standard-co*
                 state
                 (evisc-tuple 3 4 nil nil))

     ((A B (#) E ...) U V W ...)
     <state>
     ACL2 !>

Notice that it is impossible to read the printed value back into ACL2,
since there is no way for the ACL2 reader to interpret `#' or `...'.  To
solve this problem, see *note SET-IPRINT::.

In the above example we pass an evisc-tuple explicitly to a printing
function, in this case, fms (see *note FMT::).  But ACL2 also does its
own printing, for example during a proof attempt.  There are global
evisc-tuples that control ACL2's printing; see *note SET-EVISC-TUPLE::
and see *note WITHOUT-EVISC::.


File: acl2-doc-emacs.info,  Node: EVISCERATE-HIDE-TERMS,  Next: EXTERNAL-FORMAT,  Prev: EVISC-TUPLE,  Up: IO

EVISCERATE-HIDE-TERMS    to print (hide ...) as <hidden>

     Example:
     (assign eviscerate-hide-terms t)
     (assign eviscerate-hide-terms nil)

Eviscerate-hide-terms is a state global variable whose value is either
t or nil.  The variable affects how terms are displayed by default (but
not if you have set the term-evisc-tuple to other than its default; see
*note SET-EVISC-TUPLE::).  If t, terms of the form (hide ...)  are
printed as <hidden>.  Otherwise, they are printed normally.


File: acl2-doc-emacs.info,  Node: EXTERNAL-FORMAT,  Next: IPRINT,  Prev: EVISCERATE-HIDE-TERMS,  Up: IO

EXTERNAL-FORMAT    See *note CHARACTER-ENCODING::.


File: acl2-doc-emacs.info,  Node: IPRINT,  Next: IPRINTING,  Prev: EXTERNAL-FORMAT,  Up: IO

IPRINT    See *note SET-IPRINT::.


File: acl2-doc-emacs.info,  Node: IPRINTING,  Next: OPEN-OUTPUT-CHANNEL!,  Prev: IPRINT,  Up: IO

IPRINTING    See *note SET-IPRINT::.


File: acl2-doc-emacs.info,  Node: OPEN-OUTPUT-CHANNEL!,  Next: OUTPUT-TO-FILE,  Prev: IPRINTING,  Up: IO

OPEN-OUTPUT-CHANNEL!    when trust tags are needed to open output channels

Use this function in place of open-output-channel if you want to open a
channel for output at times this would otherwise be prohibited, for
example during make-event expansion and clause-processor hints.  If
this functionality doesn't quite seem like what you need, take a look
at the definition of open-output-channel! in axioms.lisp, specifically
the binding of state global variable writes-okp.  The following
example, taken from community book books/hons-archive/hons-archive.lisp,
illustrates the latter approach.

     (defmacro har-zip! (x filename &key sortp)
       "See :doc hons-archive"
       `(mv-let (erp val state)
                (progn!
                 :state-global-bindings
                 ((temp-touchable-vars t set-temp-touchable-vars))
                 (state-global-let*
                  ((writes-okp t))
                  (let ((state (har-zip-fn ,x ,filename ,sortp state)))
                    (mv nil nil state))))
                (declare (ignore erp val))
                state))

The book below illustrates the soundness loophole plugged in ACL2
Version_3.2 related to file writes during book certification.

     ; The following example is adapted (with only very slight changes)
     ; from one written by Peter Dillinger.  It illustrates the prohibition
     ; against writing files enforced by with-output-channel during book
     ; certification (more specifically, during make-event expansion).

     ; This book certifies in ACL2 Version_3.1 before the fix discussed in the
     ; paragraph about it being ``possible to write files during book
     ; certification'' in :DOC NOTE-3-2.  The fix was actually made to ACL2
     ; function open-output-channel.

     ; After the fix, in order for certification to succeed one needs to do
     ; two things.  First, in raw lisp:
     ;   (push :after-writes-okp-fix *features*)
     ; Second, certify with this command:
     ;   (certify-book "writes-okp" 0 nil :ttags (:writes-okp))

     (in-package "ACL2")

     (local
      (defun write-objects-to-channel (obj-lst chan state)
        (declare (xargs :mode :program
                        :stobjs state
                        :guard (true-listp obj-lst)))
        (if (consp obj-lst)
            (pprogn (print-object$ (car obj-lst) chan state)
                    (write-objects-to-channel (cdr obj-lst) chan state)
                    state)
          state)))

     #+after-writes-okp-fix
     (defttag :writes-okp)

     (local
      (defun write-objects-to-file (obj-lst filename state)
        (declare (xargs :mode :program
                        :stobjs state
                        :guard (and (stringp filename)
                                    (true-listp obj-lst))))
        (mv-let (chan state)
                #-after-writes-okp-fix
                (open-output-channel filename :object state)
                #+after-writes-okp-fix
                (open-output-channel! filename :object state)
                (if chan
                    (pprogn (write-objects-to-channel obj-lst chan state)
                            (close-output-channel chan state)
                            (value :done))
                  (er soft 'write-object-to-file
                      "Could not open for writing: ~x0"
                      filename)))))

     (local
      (defconst *nil.lisp*
        '((in-package "ACL2")
          (defthm bad nil :rule-classes nil))))

     (local
      (defconst *nil.cert*
        '((IN-PACKAGE "ACL2")
          "ACL2 Version 3.1"
          :BEGIN-PORTCULLIS-CMDS
          :END-PORTCULLIS-CMDS
          NIL
          (("/home/peterd/test/nil.lisp" "nil" "nil"
            ((:SKIPPED-PROOFSP) (:AXIOMSP) (:TTAGS)) . 134094174))
          62589544
          )))

     (local
      (make-event (er-progn
                   (write-objects-to-file *nil.lisp* "nil.lisp" state)
                   (write-objects-to-file *nil.cert* "nil.cert" state)
                   (value '(value-triple :invisible)))))

     (local (include-book
             "nil" :load-compiled-file nil))

     (defthm bad nil :rule-classes nil)


File: acl2-doc-emacs.info,  Node: OUTPUT-TO-FILE,  Next: PRINT-CONTROL,  Prev: OPEN-OUTPUT-CHANNEL!,  Up: IO

OUTPUT-TO-FILE    redirecting output to a file

For a general discussion of ACL2 input/output and of the ACL2
read-eval-print loop, see *note IO:: and see *note LD:: (respectively).
Here we use an example to illustrate how to use some of the options
provided by ld to redirect ACL2 output to a file, other than the
printing of the prompt (which continues to go to the terminal).

There are two ld specials that control output from the ld command:
proofs-co for proof output and standard-co for other output.  The
following example shows how to use these to redirect output to a file
"tmp.out".  The following command opens a character output channel to
to the file "tmp.out" and redirects proof output to that channel, i.e.,
to file "tmp.out".

     (mv-let (chan state)
             (open-output-channel "tmp.out" :character state)
             (set-proofs-co chan state))

Next, we redirect standard output to that same channel.

     (set-standard-co (proofs-co state) state)

Now we can load an input file, in this case file "tmp.lisp", and output
will be redirected to file "tmp.out".  (The use of :ld-pre-eval-print t
is optional; see *note LD::.)

     (ld "tmp.lisp" :ld-pre-eval-print t)

Having completed our load operation, we restore both proof output and
standard output to the terminal, as follows.

     (set-standard-co *standard-co* state)
     (close-output-channel (proofs-co state) state)
     (set-proofs-co *standard-co* state)

The following variant of the above example shows how to redirect output
as above except without changing the global settings of the two ld
specials, proofs-co and standard-co.  This approach uses a notion of
"global variables" stored in the ACL2 state; see *note ASSIGN:: and see
*note @: atsign.

     (mv-let (chan state)
             (open-output-channel "tmp.out" :character state)
             (assign tmp-channel chan))
     (ld "tmp.lisp" :ld-pre-eval-print t
                    :proofs-co (@ tmp-channel)
                    :standard-co (@ tmp-channel))
     (close-output-channel (@ tmp-channel) state)


File: acl2-doc-emacs.info,  Node: PRINT-CONTROL,  Next: PRINTING-TO-STRINGS,  Prev: OUTPUT-TO-FILE,  Up: IO

PRINT-CONTROL    advanced controls of ACL2 printing

See *note IO:: for a summary of printing in ACL2.  Here we document
some advanced ways to control what is printed by ACL2's primary
printing routines.

See *note SET-PRINT-BASE::, see *note SET-PRINT-RADIX::, and see *note
SET-PRINT-CASE:: for discussions of the most common ways to control
what is printed.  Indeed, these are the only ways to control the
behavior of princ$ and prin1$.

The rest of this topic is for advanced users of ACL2.  We refer to
Common Lisp behavior, as described in any good Common Lisp
documentation.

*Print-control variables*.  Set-print-base, set-print-radix, and
set-print-case assign to corresponding so-called "state global
variables" 'print-base, 'print-radix, and 'print-case, which can be
accessed using the expressions (@ print-base), (@ print-radix), and (@
print-case), respectively; see *note ASSIGN::.  Here is a table showing
all print-control variables, their setters, and their defaults.

     print-base          set-print-base          10
     print-case          set-print-case          :upcase
     print-circle        set-print-circle        nil
       [but see remark on print-circle-files, below]
     print-escape        set-print-escape        t
     print-length        set-print-length        nil
     print-level         set-print-level         nil
     print-lines         set-print-lines         nil
     print-pretty        set-print-pretty        nil
     print-radix         set-print-radix         nil
     print-readably      set-print-readably      nil
     print-right-margin  set-print-right-margin  nil

Each ACL2 print-control variable print-xxx can correspond in function to
Common Lisp variable *PRINT-XXX*.  Specifically, the evaluation of forms
(set-print-base t), (set-print-radix t), and (set-print-case t) affects
ACL2 printing functions in much the same way that setting to t Common
Lisp variables *PRINT-BASE*, *PRINT-RADIX*, and *PRINT-CASE*,
respectively, affects Common Lisp printing.  The same is true for
print-escape, except that this does not affect princ$ or prin1$, which
correspond to Common Lisp functions princ and prin1: princ treats
*PRINT-ESCAPE* as nil while prin1 treats *PRINT-ESCAPE* as t.
Moreover, all print-control variables not mentioned in this paragraph
are set to their defaults in princ$ and prin1$, as indicated by ACL2
constant *print-control-defaults*, except that print-readably is set to
nil in princ$.

Fmt and its related functions are sensitive to state globals
'print-base, 'print-radix, 'print-case, 'print-escape, and
'print-readably, in analogy with Common Lisp functions that don't fix
*PRINT-ESCAPE* or *PRINT-READABLY*.  But the fmt functions do not
respect settings of other print-control variables; for example, they act
as though 'print-circle is nil.  Since ACL2 output is produced using
the same underlying print routines as the fmt functions, it also is
insensitive to all print-control variables except for the five above.
To control the print-level and print-length used for producing ACL2
output, see *note SET-EVISC-TUPLE::.

Print-object$ is sensitive to all of the print-control variables.

Remark on print-circle-files: ACL2 typically binds 'print-circle to t
before writing certificate files, or auxiliary files that are compiled
when make-event forms are present in a book, or files in support of
:comp commands.  This binding allows for structure sharing that can
keep these files from growing large.  However, this behavior is
defeated in GCL (Gnu Common Lisp), because of the small number of
indices n available by default (1024) for the #n= reader macro.  For the
files described above, what actually happens is that 'print-circle is
bound to the value of 'print-circle-files, which by default is t unless
the underlying Lisp is GCL, in which case it is set to nil.  See *note
ASSIGN:: for how to set state globals such as 'print-circle-files.  For
example, if you build GCL with a larger number of #n= indices
available, you may wish to restore the print-circle behavior for
certificate files by following these instructions from Camm Maguire:

     This can trivially be revised to any larger constant by editing the
     following line of read.d and recompiling:

     #ifndef SHARP_EQ_CONTEXT_SIZE
     #define SHARP_EQ_CONTEXT_SIZE 500
     #endif

End of Remark.

Evaluate (reset-print-control) to restore all print-control variables to
their original settings, as stored in constant *print-control-defaults*.

(Remark for those using ACL2 built on Gnu Common Lisp (GCL) versions
that are non-ANSI, which as of October 2008 is all GCL versions
recommended for ACL2: Note that Common Lisp variables *PRINT-LINES*,
*PRINT-MISER-WIDTH*, *PRINT-READABLY*, *PRINT-PPRINT-DISPATCH*, and
*PRINT-RIGHT-MARGIN* do not have any effect for such GCL versions.)


File: acl2-doc-emacs.info,  Node: PRINTING-TO-STRINGS,  Next: RESET-PRINT-CONTROL,  Prev: PRINT-CONTROL,  Up: IO

PRINTING-TO-STRINGS    printing to strings instead of files or standard output

Each of ACL2's formatted printing functions, FM*, has an analoguous
macro FM*-TO-STRING indicated below.  These functions do not include a
channel or state as an argument, and FM*-TO-STRING returns the string
that FM* would print to the state, in place of state; see *note FMT::.
The legal keyword arguments are described below.

     General Forms:                                 result
     (fms-to-string string alist &key ...)          ; string
     (fmt-to-string string alist &key ...)          ; (mv col string)
     (fmt1-to-string string alist column &key ...)  ; (mv col string)
     (fms!-to-string string alist &key ...)         ; string
     (fmt!-to-string string alist &key ...)         ; (mv col string)
     (fmt1!-to-string string alist column &key ...) ; (mv col string)

The legal keyword arguments are as follows.  They are all optional with
a default of nil.

     Evisc-tuple is evaluated, and corresponds exactly to the
     evisc-tuple argument of the corresponding FM* function; see *note
     FMT::.

     Fmt-control-alist should typically evaluate to an alist that maps
     print-control variables to values; see *note PRINT-CONTROL::.  Any
     alist mapping variables to values is legal, however.  By default
     the print controls are set according to the value of constant
     *fmt-control-defaults*; fmt-control-alist overrides these
     defaults.  For example, *fmt-control-defaults* sets the right
     margin just as it is set in the initial ACL2 state, by binding
     fmt-soft-right-margin and fmt-hard-right-margin to their
     respective defaults of *fmt-soft-right-margin-default* and
     *fmt-hard-right-margin-default*.  The following example shows how
     you can override those defaults, in this case arranging to print
     flat by setting the right margin to a large number.

          (fmt-to-string "~x0"
                         (list (cons #\0 (make-list 30)))
                         :fmt-control-alist
                         `((fmt-soft-right-margin . 10000)
                           (fmt-hard-right-margin . 10000)))

     Iprint is typically nil, but t is also a legal value.  See *note
     SET-IPRINT:: for the effect of value t, which however is local to
     this call of a FM*-TO-STRING function; the behavior if iprinting
     afterwards is not affected by this call.  In particular, you will
     not be able to look at the values of iprint tokens printed by this
     call, so the value t is probably of limited utility at best.

Also see *note IO:: for a discussion of the utility
get-output-stream-string$, which allows for accumulating the results of
more than one printing call into a single string but requires the use
of state.


File: acl2-doc-emacs.info,  Node: RESET-PRINT-CONTROL,  Next: SET-EVISC-TUPLE,  Prev: PRINTING-TO-STRINGS,  Up: IO

RESET-PRINT-CONTROL    See *note PRINT-CONTROL::.


File: acl2-doc-emacs.info,  Node: SET-EVISC-TUPLE,  Next: SET-FMT-HARD-RIGHT-MARGIN,  Prev: RESET-PRINT-CONTROL,  Up: IO

SET-EVISC-TUPLE    control suppression of details when printing

ACL2 output is generally printed in full.  However, ACL2 can be
directed to abbreviate, or "eviscerate", objects before printing them,
though the use of a so-called "evisc-tuple".  See *note EVISC-TUPLE::
for a discussion of evisc-tuples.  The utility set-evisc-tuple modifies
certain global evisc-tuples, as explained below, to affect the extent
to which ACL2 eviscerates objects during printing, for example during
proof output or when printing top-level evaluation results.

     General Form:
     (set-evisc-tuple evisc-tuple ; a legal evisc-tuple, or :DEFAULT
                     :iprint val  ; one of *iprint-actions*
                     :sites sites ; either :ALL, or an element or a subset of the
                                  ;   list (:TERM :LD :TRACE :ABBREV)

where the value of :iprint is passed to set-iprint, :sites :all
abbreviates :sites '(:TERM :LD :TRACE :ABBREV), and other documentation
is provided below.  Note that all arguments are evaluated.

See *note WITHOUT-EVISC:: for how to avoid evisceration for ACL2 output.

The following example illustrates an invocation of set-evisc-tuple that
limits the print-level to 3 -- only three descents into list structures
are permitted before eviscerating a subterm -- and limits the
print-length to 4 -- only the first four elements of any list structure
will be printed.

     ACL2 !>(set-evisc-tuple (evisc-tuple 3   ; print-level
                                          4   ; print-length
                                          nil ; alist
                                          nil ; hiding-cars
                                          )
                             :iprint :same ; better yet, T
                             :sites :all)
      (:TERM :LD :TRACE :ABBREV)
     ACL2 !>'((a b ((c d)) e f g) u v w x y)
     ((A B (#) E ...) U V W ...)
     ACL2 !>

We recommend however using :iprint t so that eviscerated terms may be
read back in; see *note SET-IPRINT::.  Indeed, the :iprint argument is
required as a reminder to the user to consider that issue, unless
iprinting has been enabled at least once.  If :sites or a required
:iprint argument is omitted, however, ACL2 will query the user for the
missing arguments rather than causing an error.

ACL2 eviscerates by default only in a few cases, primarily in
informational messages for errors, warnings, and queries (i.e., in the
:EVISC case below).  Users can modify the default behavior by supplying
a suitable argument to set-evisc-tuple.  The argument may be :default,
which denotes the evisceration provided when ACL2 starts up.  Otherwise
that argument is an evisc-tuple, which is either nil (no evisceration)
or as described above.  Moreover, there are four evisc-tuple
"evisceration contexts", each with its own evisceration control.  The
value returned by set-evisc-tuple indicates the evisceration contexts
whose evisc-tuple has been set.  The evisceration contexts are as
follows, all of which use a default value of nil for the hiding-cars.
Accessors are also shown for retrieving the corresponding evisc-tuple.

     o :TERM -- used for printing terms.  The accessor is
     (term-evisc-tuple flg state), where flg is ignored if
     set-evisc-tuple has been called for :term with value other than
     :default, and otherwise (hence initially): a flg of nil indicates
     an evisc-tuple of nil, and otherwise the term-evisc-tuple has a
     print-level of 3 and print-length of 4.

     o :ABBREV -- used for printing informational messages for errors,
     warnings, and queries.  Initially, the alist abbreviates the ACL2
     world, print-level is 5, and print-level is 7.  The accessor is
     (abbrev-evisc-tuple state).

     o :GAG-MODE -- used for printing induction schemes (and perhaps,
     in the future, for other printing) when gag-mode is on.  If
     gag-mode is off, the value used for this evisc-tuple is
     (term-evisc-tuple nil state).  But if gag-mode is on (i.e.,
     (gag-mode) evaluates to a non-nil value), then with one exception,
     the value is an evisc-tuple or nil, to be used in gag-mode for
     printing of induction schemes and, during proofs, the "The
     non-trivial part of the guard conjecture".  The exceptional value
     is t, which indicates that in gag-mode, no printing of induction
     schemes should be and the guard conjecture should be printed using
     (term-evisc-tuple t state).  The accessor is (gag-mode-evisc-tuple
     state).

     o :LD -- used by the ACL2 read-eval-print loop.  The accessor is
     (ld-evisc-tuple state).

     o :TRACE -- used for printing trace output.  No accessor is
     available (though in raw Lisp, (trace-evisc-tuple) returns the
     trace-evisc-tuple).

Each context ectx also has an updater, (set-ectx-evisc-tuple val
state), where val is a legal value for set-evisc-tuple as described
above: :default or an evisc-tuple (possibly nil).

Note that the break-rewrite commands and the proof-checker generally do
their printing using the term-evisc-tuple.


File: acl2-doc-emacs.info,  Node: SET-FMT-HARD-RIGHT-MARGIN,  Next: SET-FMT-SOFT-RIGHT-MARGIN,  Prev: SET-EVISC-TUPLE,  Up: IO

SET-FMT-HARD-RIGHT-MARGIN    set the right margin for formatted output

In this documentation topic we discuss setting of both a "soft" and a
"hard" right margin.

     Example Forms:
     (set-fmt-soft-right-margin 55 state) ; set soft right margin to 55
     (set-fmt-hard-right-margin 68 state) ; set hard right margin to 68

Fmt and related functions insert linebreaks when lines get too long.  A
linebreak is inserted at an aesthetically appropriate point once the
column exceeds the value of (@ fmt-soft-right-margin).  If however the
column exceeds the value of (@ fmt-hard-right-margin), then a linebreak
is soon inserted.  Such a "hard" linebreak follows the insertion of a
backslash (\) character unless fmt!, fms!, or fmt1! is used, or state
global write-for-read is true.


File: acl2-doc-emacs.info,  Node: SET-FMT-SOFT-RIGHT-MARGIN,  Next: SET-IPRINT,  Prev: SET-FMT-HARD-RIGHT-MARGIN,  Up: IO

SET-FMT-SOFT-RIGHT-MARGIN    set the soft right margin for formatted output

See *note SET-FMT-HARD-RIGHT-MARGIN:: for a discussion of the soft and
hard right margin for formatted output.


File: acl2-doc-emacs.info,  Node: SET-IPRINT,  Next: SET-PRINT-BASE,  Prev: SET-FMT-SOFT-RIGHT-MARGIN,  Up: IO

SET-IPRINT    control whether abbreviated output can be read back in

When ACL2 pretty-prints large expressions using formatted printing (see
*note FMT::), it may save time and space by printing tokens `#' or
`...' in place of certain subexpressions.  By default this only happens
for a few settings such as error and warning messages; see *note
SET-EVISC-TUPLE:: for controlling such elision in general.  The full
expression is unavailable to the user when `#' or `...' is printed, but
that is easily solved by evaluating the form

       (set-iprint t)

to enable a mode called "iprinting".  Then, instead of printing `#' or
`...', ACL2 prints `#@i#' for i = 1,2,3,... -- all in base 10.  ACL2
can read back in such `#@i#' because under the hood, i is associated
with its corresponding elided form.  Thus the term "iprint" can be
viewed as suggesting "interactive print" or "index print".  We also
think of "iprint" as suggesting "i printing", to suggest the printing
of token `#@i#'.  We call i the "iprint index" of that token.

The following example should suffice to illustrate how to recover elided
subexpressions.  (Below this example we provide details that may be of
interest only to advanced users.)  Here we cause an error by defining a
macro of one argument and then calling it with two arguments.  By
default, error messages abbreviate subexpressions deeper than level 5
with `#' and past the 7th element of a list with `...'.  We see this
behavior below.

     ACL2 !>(defmacro foo (x) x)

     Summary
     Form:  ( DEFMACRO FOO ...)
     Rules: NIL
     Warnings:  None
     Time:  0.02 seconds (prove: 0.00, print: 0.00, other: 0.02)
      FOO
     ACL2 !>(foo arg1 (a (b (c (d (e (f (g)))))) h i j k l m n))


     ACL2 Error in macro expansion:  Wrong number of args in macro expansion
     of (FOO ARG1 (A (B (C (D #))) H I J K L ...)).  (See :DOC set-iprint
     to be able to see elided values in this message.)

     ACL2 !>(set-iprint t)

     ACL2 Observation in SET-IPRINT:  Iprinting has been enabled.
     ACL2 !>(foo arg1 (a (b (c (d (e (f (g)))))) h i j k l m n))


     ACL2 Error in macro expansion:  Wrong number of args in macro expansion
     of (FOO ARG1 (A (B (C (D #@1#))) H I J K L . #@2#)).

     ACL2 !>(acl2-count '(FOO ARG1 (A (B (C (D #@1#))) H I J K L . #@2#)))
     23
     ACL2 !>

Sometimes you may want to supply the abbreviated form not to compute
with it, as in the acl2-count example just above, but so that you can
see it.  The macro without-evisc eliminates elision during printing.
Below we show two ways to use this utility: first, we use it to print
the elided form, and then, we use it instead on the original input form
to print the entire error message.

     ACL2 !>(without-evisc '(FOO ARG1 (A (B (C (D #@1#))) H I J K L . #@2#)))
     (FOO ARG1
          (A (B (C (D (E (F (G))))))
             H I J K L M N))
     ACL2 !>(without-evisc (foo arg1 (a (b (c (d (e (f (g)))))) h i j k l m n)))


     ACL2 Error in macro expansion:  Wrong number of args in macro expansion
     of (FOO ARG1 (A (B (C (D (E (F (G)))))) H I J K L M N)).

     ACL2 !>

The documentation above probably suffices for most users.  For those
who want more details, below we detail all the ways to use the
set-iprint utility.

     Example Forms:
     (set-iprint t)   ; enable iprinting (elision with #@i@)
     (set-iprint nil) ; disable iprinting

     General Form:
     (set-iprint action        ; t, nil, :reset, :reset-enable, or :same
                 :soft-bound s ; initially  1000
                 :hard-bound h ; initially 10000)

where all arguments are optional, but ACL2 queries for action if it is
omitted.   We defer the explanations of :soft-bound and :hard-bound.
The values for action are as follows:

     T -- Enable iprinting.

     NIL -- Disable iprinting.

     :RESET -- Reset iprinting to its initial disabled state, so that
     when enabled, the first index i for which `#@i# is printed will be
     1.  Note that all stored information for existing iprint indices
     will be erased.

     :RESET-ENABLE -- Reset iprinting as with :reset, and then enable
     iprinting.

     :SAME -- Make no change to the iprinting state (other than setting
     the :soft-bound and/or :hard-bound if specified, as explained
     below).

Immediately after a top-level form is read, hence before it is
evaluated, a check is made for whether the latest iprint index exceeds
a certain bound, (iprint-soft-bound state) -- 1000, by default.  If so,
then the (iprint-last-index state) is set back to 0.  This soft bound
can be changed to any positive integer k by calling set-iprint with
:soft-bound k, typically (set-iprint :same :soft-bound k)].

The above "soft bound" is applied once for each top-level form, but you
may want finer control by applying a bound after the pretty-printing of
each individual form (since many forms may be pretty-printed between
successive evaluations of top-level forms).  That bound is
(iprint-hard-bound state), and can be set with the :hard-bound argument
in analogy to how :soft-bound is set, as described above.

A "rollover" is the detection that the soft or hard bound has been
exceeded, along with a state update so that the next iprint index will
be 1.  When a rollover occurs, any index beyond the latest iprint index
is no longer available for reading.  At the top level of the ACL2
read-eval-print loop, this works as follows: ACL2 reads the next
top-level form according to the current iprint state, then handles a
rollover if the latest iprint index exceeded the current soft bound.
The following log illustrates a rollover, which follows the description
above.

     ACL2 !>(set-iprint t :soft-bound 3)

     ACL2 Observation in SET-IPRINT:  The soft-bound for iprinting has been
     set to 3.

     ACL2 Observation in SET-IPRINT:  Iprinting has been enabled.
     ACL2 !>(set-evisc-tuple (evisc-tuple 2 3 nil nil) :sites :ld)
      (:LD)
     ACL2 !>'((a b c d e f g) (a b c d e f g) (a b c d e f g))
     ((A B C . #@1#) (A B C . #@2#) (A B C . #@3#))
     ACL2 !>'((a b c d e f g) (a b c d e f g) (a b c d e f g))
     ((A B C . #@4#) (A B C . #@5#) (A B C . #@6#))
     ACL2 !>(without-evisc '((A B C . #@4#) (A B C . #@5#) (A B C . #@6#)))
     ((A B C D E F G)
      (A B C D E F G)
      (A B C D E F G))
     ACL2 !>'(1 2 3 4 5)
     (1 2 3 . #@1#)
     ACL2 !>'((a b c d e f g) (a b c d e f g) (a b c d e f g))
     ((A B C . #@2#) (A B C . #@3#) (A B C . #@4#))
     ACL2 !>(without-evisc '((A B C . #@4#) (A B C . #@5#) (A B C . #@6#)))
     ((A B C D E F G)
      (A B C D E F G)
      (A B C D E F G))
     ACL2 !>(without-evisc '((A B C . #@4#) (A B C . #@5#) (A B C . #@6#)))

     ***********************************************
     ************ ABORTING from raw Lisp ***********
     Error:  Out-of-bounds index in #@5#.  See :DOC set-iprint.
     ***********************************************

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

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

We conclude by mentioning two cases where iprinting and evisc-tuples are
ignored.  (1) This is typically the case when printing results in raw
Lisp outside the ACL2 loop.  To use iprinting and evisc-tuples in raw
Lisp, use raw-mode; see *note SET-RAW-MODE::.  In raw-mode, results
that are ACL2 objects will be printed in the same way that ACL2 would
print those results if not in raw-mode.  (2) Iprinting and evisc-tuples
are ignored by print-object$, which however is sensitive to many
settings that do not affect formatted (fmt etc.) printing; see *note
PRINT-CONTROL::.

The reader interested in design and implementation issues considered
during the addition of iprinting to ACL2 is invited to read the paper
"Abbreviated Output for Input in ACL2: An Implementation Case Study";
see the proceedings of ACL2 Workshop 2009,
`http://www.cs.utexas.edu/users/moore/acl2/workshop-2009/'.


File: acl2-doc-emacs.info,  Node: SET-PRINT-BASE,  Next: SET-PRINT-CASE,  Prev: SET-IPRINT,  Up: IO

SET-PRINT-BASE    control radix in which numbers are printed

By default, integers and ratios are printed in base 10.  ACL2 also
supports printing in radix 2, 8, or 16 by calling set-print-base with
the desired radix (base).

       (set-print-base 10 state) ; Default printing
       (set-print-base 16 state) ; Print integers and ratios in hex

Here is a sample log.

       ACL2 !>(list 25 25/3)
       (25 25/3)
       ACL2 !>(set-print-base 16 state)
       <state>
       ACL2 !>(list 25 25/3)
       (19 19/3)
       ACL2 !>

See *note SET-PRINT-RADIX:: for how to print the radix, for example,
printing the decimal number 25 in print-base 16 as "#x25" rather than
"25".  Also see *note PRINT-CONTROL:: for other user-settable print
controls.

Note: ACL2 events and some other top-level commands (for example, thm,
verify, and history commands such as :pe and :pbt) set the print base
to 10 during their evaluation.  So set-print-base has no effect while
these forms are being processed.


File: acl2-doc-emacs.info,  Node: SET-PRINT-CASE,  Next: SET-PRINT-CIRCLE,  Prev: SET-PRINT-BASE,  Up: IO

SET-PRINT-CASE    control whether symbols are printed in upper case or in lower case

By default, symbols are printed in upper case when vertical bars are
not required, as specified by Common Lisp.  As with Common Lisp, ACL2
supports printing in a "downcase" mode, where symbols are printed in
lower case.  Many printing functions (some details below) print
characters in lower case for a symbol when the ACL2 state global
variable print-case has value :downcase and vertical bars are not
necessary for printing that symbol.  (Thus, this state global functions
in complete analogy to the Common Lisp global *print-case*.)  The value
print-case is returned by (print-case), and may be set using the
function set-print-case as follows.

       (set-print-case :upcase   state) ; Default printing
       (set-print-case :downcase state) ; Print symbols in lower case when
                                        ; vertical bars are not required

The ACL2 user can expect that the :downcase setting will have an effect
for formatted output (see *note FMT:: and see *note FMS::) when the
directives are ~p, ~P, ~q, or ~Q, for built-in functions princ$ and
prin1$, and the ppr family of functions, and _not_ for built-in
function print-object$.  For other printing functions, the effect of
:downcase is unspecified.

Also see *note PRINT-CONTROL:: for other user-settable print controls.


File: acl2-doc-emacs.info,  Node: SET-PRINT-CIRCLE,  Next: SET-PRINT-ESCAPE,  Prev: SET-PRINT-CASE,  Up: IO

SET-PRINT-CIRCLE    See *note PRINT-CONTROL::.


File: acl2-doc-emacs.info,  Node: SET-PRINT-ESCAPE,  Next: SET-PRINT-LENGTH,  Prev: SET-PRINT-CIRCLE,  Up: IO

SET-PRINT-ESCAPE    See *note PRINT-CONTROL::.


File: acl2-doc-emacs.info,  Node: SET-PRINT-LENGTH,  Next: SET-PRINT-LEVEL,  Prev: SET-PRINT-ESCAPE,  Up: IO

SET-PRINT-LENGTH    See *note PRINT-CONTROL::.


File: acl2-doc-emacs.info,  Node: SET-PRINT-LEVEL,  Next: SET-PRINT-LINES,  Prev: SET-PRINT-LENGTH,  Up: IO

SET-PRINT-LEVEL    See *note PRINT-CONTROL::.


File: acl2-doc-emacs.info,  Node: SET-PRINT-LINES,  Next: SET-PRINT-RADIX,  Prev: SET-PRINT-LEVEL,  Up: IO

SET-PRINT-LINES    See *note PRINT-CONTROL::.


File: acl2-doc-emacs.info,  Node: SET-PRINT-RADIX,  Next: SET-PRINT-READABLY,  Prev: SET-PRINT-LINES,  Up: IO

SET-PRINT-RADIX    control printing of the radix for numbers

See *note SET-PRINT-BASE:: for background on how the print base affects
the printing of numbers.  set-print-radix affects whether a radix
indicated when a number is printed.  The radix is not indicated by
default, or after evaluating (set-print-radix nil state).  But if
set-print-radix is called with a first argument that evaluates to a
nonnil value -- for example, (set-print-radix t state) -- then the
radix is shown when printing.  (This behavior is consistent with the
handling of Common Lisp global *print-radix*.)  The following log
illustrates how this works.

     ACL2 !>(list 25 25/3)
     (25 25/3)
     ACL2 !>(set-print-base 16 state)
     <state>
     ACL2 !>(list 25 25/3)
     (19 19/3)
     ACL2 !>(set-print-radix t state)
     <state>
     ACL2 !>(list 25 25/3)
     (#x19 #x19/3)
     ACL2 !>(set-print-base 10 state)
     <state>
     ACL2 !>(list 25 25/3)
     (25. #10r25/3)
     ACL2 !>(set-print-radix nil state)
     <state>
     ACL2 !>(list 25 25/3)
     (25 25/3)
     ACL2 !>


File: acl2-doc-emacs.info,  Node: SET-PRINT-READABLY,  Next: SET-PRINT-RIGHT-MARGIN,  Prev: SET-PRINT-RADIX,  Up: IO

SET-PRINT-READABLY    See *note PRINT-CONTROL::.


File: acl2-doc-emacs.info,  Node: SET-PRINT-RIGHT-MARGIN,  Next: WITHOUT-EVISC,  Prev: SET-PRINT-READABLY,  Up: IO

SET-PRINT-RIGHT-MARGIN    See *note PRINT-CONTROL::.


File: acl2-doc-emacs.info,  Node: WITHOUT-EVISC,  Prev: SET-PRINT-RIGHT-MARGIN,  Up: IO

WITHOUT-EVISC    print output in full

     General Form:
     (without-evisc form)

where form is any expression to evaluate.  The effect is to evaluate
form as though the without-evisc wrapper were absent, except that
expressions are printed in full for the ensuing output, regardless of
the current evisc-tuples (see *note SET-EVISC-TUPLE::).  See *note
SET-IPRINT:: for an example.

More precisely, without-evisc binds each of the term-evisc-tuple,
ld-evisc-tuple, abbrev-evisc-tuple and gag-mode-evisc-tuple to nil (see
*note SET-EVISC-TUPLE::).  It does not modify the trace evisc-tuple, so
trace output is not modified by without-evisc.  Also note that calls of
printing functions such as fmt that include explicit evisc-tuples will
not have those evisc-tuples overridden.  The following example
illustrates this point.

     ACL2 !>(without-evisc
             (fms "~x0~%"
                  (list (cons #0 '((a b ((c d)) e f g) u v w x y)))
                  *standard-co*
                  state
                  (evisc-tuple 2 3 nil nil)))

     ((A B # ...) U V ...)
     <state>
     ACL2 !>

We conclude with two remarks.  (1) A call of without-evisc on expression
exp actually invokes a specialized call of ld on a one-element list
containing exp, which prints the value returned by evaluation of exp
but actually returns the useless value (mv nil :invisible state).  So do
not use without-evisc in programs; just use it at the top level of the
ACL2 read-eval-print loop, or at least the top level of ld.  (2) Even
when using without-evisc, if the ACL2 logical world is part of the value
returned, it will be printed in abbreviated form because the ACL2
read-eval-print loop always arranges for this to be the case,
regardless of the ld-evisc-tuple.  For example:

     ACL2 !>(without-evisc (w state))
     <world>
     ACL2 !>

An alternative to the use of without-evisc is to explore large objects
using the ACL2 function (walkabout object state).  Some brief
documentation is printed when you enter an interactive loop upon
evaluating a call of walkabout.  We may add documentation for walkabout
if that is requested.


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

MISCELLANEOUS    a miscellany of documented functions and concepts
               (often cited in more accessible documentation)

* Menu:

* &ALLOW-OTHER-KEYS:: See *note MACRO-ARGS::.

* &BODY:: See *note MACRO-ARGS::.

* &KEY:: See *note MACRO-ARGS::.

* &OPTIONAL:: See *note MACRO-ARGS::.

* &REST:: See *note MACRO-ARGS::.

* &WHOLE:: See *note MACRO-ARGS::.

* A!:: to return to the top-level of ACL2's command loop

* ABORT!:: to return to the top-level of ACL2's command loop

* ACKNOWLEDGMENTS:: some contributors to the well-being of ACL2

* ACL2S:: See *note ACL2-SEDAN::.

* APROPOS:: See *note FINDING-DOCUMENTATION::.

* BACKCHAIN-LIMIT:: limiting the effort expended on relieving hypotheses

* BACKCHAIN-LIMIT-RW:: hints keyword :BACKCHAIN-LIMIT-RW

* BACKTRACK:: hints keyword :BACKTRACK

* BIBLIOGRAPHY:: reports about ACL2

* BIND-FREE:: to bind free variables of a rewrite, definition, or linear rule

* BY:: hints keyword :BY

* CASE-SPLIT:: like force but immediately splits the top-level goal on the hypothesis

* CASE-SPLIT-LIMITATIONS:: a list of two ``numbers'' limiting the number of cases produced at once

* CASES:: hints keyword :CASES

* CLAUSE-IDENTIFIER:: the internal form of a goal-spec

* COMMAND:: forms you type at the top-level, but...

* COMMAND-DESCRIPTOR:: an object describing a particular command typed by the user

* COMMON-LISP:: relation to Common Lisp, including deviations from the spec

* COMPUTED-HINTS:: computing advice to the theorem proving process

* CONSTRAINT:: restrictions on certain functions introduced in encapsulate events

* COPYRIGHT:: ACL2 copyright, license, sponsorship

* COROLLARY:: the corollary formula of a rune

* CURRENT-PACKAGE:: the package used for reading and printing

* CUSTOM-KEYWORD-HINTS:: user-defined hints

* DEFAULT-BACKCHAIN-LIMIT:: specifying the backchain limit for a rule

* DEFAULT-DEFUN-MODE:: the default defun-mode of defun'd functions

* DEFAULT-HINTS:: a list of hints added to every proof attempt

* DEFAULT-PRINT-PROMPT:: the default prompt printed by ld

* DEFAULT-RULER-EXTENDERS:: the default ruler-extenders for defun'd functions

* DEFUN-MODE:: determines whether a function definition is a logical act

* DEFUNS:: an alternative to mutual-recursion

* DISABLE-FORCING:: to disallow forced case-splits

* DISABLE-IMMEDIATE-FORCE-MODEP:: forced hypotheses are not attacked immediately

* DISABLEDP:: determine whether a given name or rune is disabled

* DO-NOT:: hints keyword :DO-NOT

* DO-NOT-INDUCT:: hints keyword :DO-NOT-INDUCT

* DOUBLE-REWRITE:: cause a term to be rewritten twice

* EMBEDDED-EVENT-FORM:: forms that may be embedded in other events

* ENABLE-FORCING:: to allow forced splits

* ENABLE-IMMEDIATE-FORCE-MODEP:: forced hypotheses are attacked immediately

* ENTER-BOOT-STRAP-MODE:: The first millisecond of the Big Bang

* ESCAPE-TO-COMMON-LISP:: escaping to Common Lisp

* EXECUTABLE-COUNTERPART:: a rule for computing the value of a function

* EXIT-BOOT-STRAP-MODE:: the end of pre-history

* EXPAND:: hints keyword :EXPAND

* EXTENDED-METAFUNCTIONS:: state and context sensitive metafunctions

* FAILED-FORCING:: how to deal with a proof failure in a forcing round

* FAILURE:: how to deal with a proof failure

* FIND-RULES-OF-RUNE:: find the rules named rune

* FINDING-DOCUMENTATION:: searching the documentation

* FNCALL-TERM:: See *note META-EXTRACT::.

* FORCE:: identity function used to force a hypothesis

* FORCED:: See *note FORCE::.

* FORCING-ROUND:: a section of a proof dealing with forced assumptions

* FUNCTIONAL-INSTANTIATION-IN-ACL2R:: additional requirements for :functional-instance hints in ACL2(r)

* GAG-MODE:: verbosity of proof output

* GC$:: invoke the garbage collector

* GC-VERBOSE:: control printing from the garbage collector

* GCL:: tips on building and using ACL2 based on Gnu Common Lisp

* GET-INTERNAL-TIME:: runtime vs. realtime in ACL2 timings

* GET-WORMHOLE-STATUS:: make a wormhole's status visible outside the wormhole

* GOAL-SPEC:: to indicate where a hint is to be used

* GUARD:: restricting the domain of a function

* GUARD-HINTS:: xargs keyword :GUARD-HINTS

* HANDS-OFF:: hints keyword :HANDS-OFF

* HIDE:: hide a term from the rewriter

* HINTS:: advice to the theorem proving process

* HINTS-AND-THE-WATERFALL:: how hints fit into the ACL2 proof waterfall

* I-AM-HERE:: a convenient marker for use with rebuild

* IF-INTRO:: See *note SPLITTER::.

* IGNORED-ATTACHMENT:: why attachments are sometimes not used

* IMMED-FORCED:: See *note SPLITTER::.

* IMMEDIATE-FORCE-MODEP:: when executable counterpart is enabled,
 forced hypotheses are attacked immediately

* INDUCT:: hints keyword :INDUCT

* KEYWORD:: See *note KEYWORDP::.

* KEYWORD-COMMANDS:: how keyword commands are processed

* LAMBDA:: See *note TERM::.

* LAST-PROVER-STEPS:: the number of prover steps most recently taken

* LD-ERROR-ACTION:: determines ld's response to an error

* LD-ERROR-TRIPLES:: determines whether a form caused an error during ld

* LD-EVISC-TUPLE:: determines whether ld suppresses details when printing

* LD-MISSING-INPUT-OK:: determines which forms ld evaluates

* LD-POST-EVAL-PRINT:: determines whether and how ld prints the result of evaluation

* LD-PRE-EVAL-FILTER:: determines which forms ld evaluates

* LD-PRE-EVAL-PRINT:: determines whether ld prints the forms to be eval'd

* LD-PROMPT:: determines the prompt printed by ld

* LD-QUERY-CONTROL-ALIST:: how to default answers to queries

* LD-REDEFINITION-ACTION:: to allow redefinition without undoing

* LD-SKIP-PROOFSP:: how carefully ACL2 processes your commands

* LD-VERBOSE:: determines whether ld prints ``ACL2 Loading ...''

* LEMMA-INSTANCE:: an object denoting an instance of a theorem

* LINEAR-ARITHMETIC:: A description of the linear arithmetic decision procedure

* LOCAL-INCOMPATIBILITY:: when non-local events won't replay in isolation

* LOGICAL-NAME:: a name created by a logical event

* LOOP-STOPPER:: limit application of permutative rewrite rules

* LP:: the Common Lisp entry to ACL2

* MACRO-ARGS:: the formals list of a macro definition

* MAKE-WORMHOLE-STATUS:: creates a wormhole status object from given status, entry code, and data

* MEASURE:: xargs keyword :MEASURE

* META-EXTRACT:: meta reasoning using valid terms extracted from context or world

* META-EXTRACT-CONTEXTUAL-FACT:: See *note META-EXTRACT::.

* META-EXTRACT-FORMULA:: See *note META-EXTRACT::.

* META-EXTRACT-GLOBAL-FACT:: See *note META-EXTRACT::.

* META-EXTRACT-GLOBAL-FACT+:: See *note META-EXTRACT::.

* META-EXTRACT-RW+-TERM:: See *note META-EXTRACT::.

* MODE:: xargs keyword :MODE

* NAME:: syntactic rules on logical names

* NIL-GOAL:: how to proceed when the prover generates a goal of nil

* NO-THANKS:: hints keyword :NO-THANKS

* NON-EXECUTABLE:: xargs keyword :NON-EXECUTABLE

* NON-LINEAR-ARITHMETIC:: Non-linear Arithmetic

* NONLINEARP:: hints keyword :NONLINEARP

* NORMALIZE:: xargs keyword :NORMALIZE

* NU-REWRITER:: rewriting NTH/UPDATE-NTH expressions

* OBDD:: ordered binary decision diagrams with rewriting

* ORDINALS:: ordinals in ACL2

* OTF-FLG:: allow more than one initial subgoal to be pushed for induction

* OVERRIDE-HINTS:: a list of hints given priority in every proof attempt

* P!:: to pop up (at least) one level of ACL2's command loop

* PACKAGE-REINCARNATION-IMPORT-RESTRICTIONS:: re-defining undone defpkgs

* PARALLEL:: evaluating forms in parallel

* PARALLELISM-BUILD:: building an ACL2 executable with parallel execution enabled

* PRINT-DOC-START-COLUMN:: printing the one-liner

* PROMPT:: the prompt printed by ld

* PROOF-OF-WELL-FOUNDEDNESS:: a proof that o< is well-founded on o-ps

* PROOF-SUPPORTERS-ALIST:: See *note DEAD-EVENTS::.

* REDEF:: a common way to set ld-redefinition-action

* REDEF!:: a common way to set ld-redefinition-action

* REDEF+:: system hacker's redefinition command

* REDEF-:: turn off system hacker's redefinition command

* REDEFINED-NAMES:: to collect the names that have been redefined

* REDUNDANT-EVENTS:: allowing a name to be introduced ``twice''

* REORDER:: hints keyword :REORDER

* RESTRICT:: hints keyword :RESTRICT

* REWRITE-STACK-LIMIT:: limiting the stack depth of the ACL2 rewriter

* SAVING-AND-RESTORING:: See *note SAVE-EXEC::.

* SET-WORMHOLE-DATA:: sets the wormhole data object in a wormhole status object

* SET-WORMHOLE-ENTRY-CODE:: sets the wormhole entry code in a wormhole status object

* SHOW-BODIES:: show the potential definition bodies

* SIGNATURE:: how to specify the arity of a constrained function

* SIMPLE:: :definition and :rewrite rules used in preprocessing

* SPECIOUS-SIMPLIFICATION:: nonproductive proof steps

* SPLITTER:: reporting of rules whose application may have caused case splits

* SPLITTER-OUTPUT:: status for reporting of splitter rules

* STOBJS:: xargs keyword :STOBJS

* SUBVERSIVE-INDUCTIONS:: why we restrict encapsulated recursive functions

* SUBVERSIVE-RECURSIONS:: why we restrict encapsulated recursive functions

* SYNTAX:: the syntax of ACL2 is that of Common Lisp

* SYNTAXP:: attach a heuristic filter on a rule

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

* THE-METHOD:: how to find proofs

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

* TRUST-TAG:: See *note DEFTTAG::.

* TTAGS-SEEN:: list some declared trust tags (ttags)

* TTREE:: tag-trees

* TYPE-SET:: how type information is encoded in ACL2

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

* USE:: hints keyword :USE

* USING-COMPUTED-HINTS:: how to use computed 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

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

* VERSION:: ACL2 Version Number

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

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

* WORLD:: ACL2 property lists and the ACL2 logical database

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

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

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

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

* WORMHOLE-IMPLEMENTATION:: notes on how wormholes are implemented

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

* WORMHOLE-STATUSP:: predicate recognizing well-formed wormhole status object

* XARGS:: extra arguments, for example to give hints to defun

Perhaps as the system matures this section will become more structured.


File: acl2-doc-emacs.info,  Node: &ALLOW-OTHER-KEYS,  Next: &BODY,  Prev: MISCELLANEOUS,  Up: MISCELLANEOUS

&ALLOW-OTHER-KEYS    See *note MACRO-ARGS::.


File: acl2-doc-emacs.info,  Node: &BODY,  Next: &KEY,  Prev: &ALLOW-OTHER-KEYS,  Up: MISCELLANEOUS

&BODY    See *note MACRO-ARGS::.


File: acl2-doc-emacs.info,  Node: &KEY,  Next: &OPTIONAL,  Prev: &BODY,  Up: MISCELLANEOUS

&KEY    See *note MACRO-ARGS::.


File: acl2-doc-emacs.info,  Node: &OPTIONAL,  Next: &REST,  Prev: &KEY,  Up: MISCELLANEOUS

&OPTIONAL    See *note MACRO-ARGS::.


File: acl2-doc-emacs.info,  Node: &REST,  Next: &WHOLE,  Prev: &OPTIONAL,  Up: MISCELLANEOUS

&REST    See *note MACRO-ARGS::.


File: acl2-doc-emacs.info,  Node: &WHOLE,  Next: A!,  Prev: &REST,  Up: MISCELLANEOUS

&WHOLE    See *note MACRO-ARGS::.


File: acl2-doc-emacs.info,  Node: A!,  Next: ABORT!,  Prev: &WHOLE,  Up: MISCELLANEOUS

A!    to return to the top-level of ACL2's command loop

When (a!) is evaluated inside of ACL2's command loop, the current
computation is aborted and control returns to the top of the command
loop, exactly as though the user had interrupted and aborted the current
computation.  (Note: Versions of ACL2 up to Version_3.4 provided `#.'
for this purpose, but no longer; see *note SHARP-DOT-READER::.)

If you are at an ACL2 prompt (as opposed to a raw Lisp break), then you
may type :a! in place of (a!); see *note KEYWORD-COMMANDS::.

For a related feature that only pops up one level, see *note P!::.

Logically speaking, (a!) = nil.  But imagine that it is defined in such
a way that it causes a stack overflow or other resource exhaustion when
called.


File: acl2-doc-emacs.info,  Node: ABORT!,  Next: ACKNOWLEDGMENTS,  Prev: A!,  Up: MISCELLANEOUS

ABORT!    to return to the top-level of ACL2's command loop

This is an alias for a!; see *note A!::.  For a related feature that
only pops up one level, see *note P!::.


File: acl2-doc-emacs.info,  Node: ACKNOWLEDGMENTS,  Next: ACL2S,  Prev: ABORT!,  Up: MISCELLANEOUS

ACKNOWLEDGMENTS    some contributors to the well-being of ACL2

The development of ACL2 was initially made possible by funding from the
U. S. Department of Defense, including ARPA and ONR.  We thank all the
organizations that have contributed support, including the following (in
alphabetical order).

     o AMD, for providing significant time over several years for Matt
     Kaufmann to carry out ACL2 research, support, and development
     o Computational Logic, Inc. and its president, Don Good, where the
     first eight years of ACL2 development occurred
     o Centaur Technology
     o DARPA
     o Digital Equipment Corporation
     o EDS, which provided some time for Matt Kaufmann's ACL2 work
     1998-1999
     o ForrestHunt and, more generally, Warren A. Hunt, Jr. (see below)
     o IBM
     o NSF
     o ONR
     o Rockwell Collins
     o SRC
     o Sun Microsystems
     o University of Texas at Austin (in particular support to J Moore
     through the Admiral B. R.  Inman Chair of Computing Theory)

We are especially grateful to Warren A. Hunt, Jr. for his unrivaled
efforts in securing support for the entire ACL2 research group at both
Computational Logic, Inc., and the University of Texas at Austin.
Without his efforts, we would have spent less time working on the
system and fewer students would have been funded to apply it.

ACL2 was started in August, 1989 by Boyer and Moore working together.
They co-authored the first versions of axioms.lisp and basis.lisp, with
Boyer taking the lead in the formalization of "state" and the most
primitive io functions.  Boyer also had a significant hand in the
development of the early versions of the files interface-raw.lisp and
translate.lisp.  For several years, Moore alone was responsible for
developing the ACL2 system code, though he consulted often with both
Boyer and Kaufmann.  In August, 1993, Kaufmann became jointly
responsible with Moore for developing the system.  Boyer has continued
to provide valuable consulting on an informal basis.

Bishop Brock was the heaviest early user of ACL2, and provided many
suggestions for improvements.  In particular, the :cases and :restrict
hints were his idea; he developed an early version of congruence-based
reasoning for Nqthm; and he helped in the development of some early
books about arithmetic.  In a demonstration of his courage and faith in
us, he pushed for Computational Logic, Inc., to agree to the Motorola
CAP contract - which required formalizing a commercial DSP in the
untested ACL2 - and moved to Scottsdale, AZ, to do the work with the
Motorola design team.  His demonstration of ACL2's utility was an
inspiration, even to those of us designing ACL2.

John Cowles also helped in the development of some early books about
arithmetic, and also provided valuable feedback and bug reports.

Other early users of ACL2 at Computational Logic, Inc. helped influence
its development.  In particular, Warren Hunt helped with the port to
Macintosh Common Lisp, and Art Flatau and Mike Smith provided useful
general feedback.

Mike Smith helped develop the Emacs portion of the implementation of
proof trees.

Bill Schelter made some enhancements to akcl (now gcl) that helped to
enhance ACL2 performance in that Common Lisp implementation, and more
generally, responded helpfully to our bug reports.  Camm Maguire has
since provided wonderful gcl support, and has created a Debian package
for ACL2 built on GCL.  We are also grateful to developers of other
Common Lisp implementations.

Kent Pitman helped in our interaction with the ANSI Common Lisp
standardization committee, X3J13.

John Cowles helped with the port to Windows (98) by answering questions
and running tests.

Ruben Gamboa created a modification of ACL2 to allow reasoning about
the real numbers using non-standard analysis.  His work has been
incorporated into the ACL2 distribution; see *note REAL::.

Rob Sumners has made numerous useful suggestions.  In particular, he has
designed and implemented improvements for stobjs and been key in our
development of locally-bound stobjs; see *note NOTE-2-6::.

Robert Krug has designed and implemented many changes in the vicinity
of the linear arithmetic package and its connection to type-set and
rewrite.  He was also instrumental in the development of
extended-metafunctions.

Pete Manolios has made numerous useful suggestions.  In particular, Pete
helped us to organize the first workshop and was a wonderful equal
partner with the two of us (Kaufmann and Moore) in producing the books
that arose from that workshop.  Pete and his student, Daron Vroon,
provided the current implementation of ordinals.

Jared Davis and Sol Swords have our gratitude for starting the
acl2-books repository, `http://acl2-books.googlecode.com/'.

We thank David L. Rager for contributing an initial version of the
support for parallelism in an experimental extension of ACL2.

Bob Boyer and Warren A. Hunt, Jr. developed a canonical representation
for ACL2 data objects and a function memoization mechanism to
facilitate reuse of previously computed results.  We thank them for
their extensive efforts for the corresponding experimental (as of 2008
and 2009) extension of ACL2; see *note HONS-AND-MEMOIZATION::.

We also thank the contributors to the ACL2 workshops for some suggested
improvements and for the extensive collection of publicly distributed
benchmark problems.  And we thank participants at the ACL2 seminar at
the University of Texas for useful feedback.  More generally, we thank
the ACL2 community for feedback, contributed books (see *note
COMMUNITY-BOOKS::), and their interest in the ACL2 project.

_Regarding the documentation:_

     Bill Young wrote significant portions of the original acl2-tutorial
     section of the ACL2 documentation, including what is now called
     alternative-introduction.  This was an especially important task
     in the early years when there was no guide for how to use ACL2 and
     we are very grateful.  He, Bishop Brock, Rich Cohen, and Noah
     Friedman read over considerable amounts of the documentation, and
     made many useful comments.  Others, particularly Bill Bevier and
     John Cowles, have also made useful comments on the documentation.

     Art Flatau helped develop the ACL2 markup language and translators
     from that language to Texinfo and HTML.  Michael "Bogo" Bogomolny
     created a search engine, beginning with Version 2.6, and for that
     purpose modified the HTML translator to create one file per topic
     (a good idea in any case).

     Laura Lawless provided many hours of help in marking up
     appropriate parts of the documentation in typewriter font.

     Noah Friedman developed an Emacs tool that helped us insert
     "invisible links" into the documentation, which improve the
     usability of that documentation under HTML readers such as Mosaic.

     Richard Stallman contributed a texinfo patch, to be found in the
     file doc/texinfo.tex.


File: acl2-doc-emacs.info,  Node: ACL2S,  Next: APROPOS,  Prev: ACKNOWLEDGMENTS,  Up: MISCELLANEOUS

ACL2S    See *note ACL2-SEDAN::.


File: acl2-doc-emacs.info,  Node: APROPOS,  Next: BACKCHAIN-LIMIT,  Prev: ACL2S,  Up: MISCELLANEOUS

APROPOS    See *note FINDING-DOCUMENTATION::.


File: acl2-doc-emacs.info,  Node: BACKCHAIN-LIMIT,  Next: BACKCHAIN-LIMIT-RW,  Prev: APROPOS,  Up: MISCELLANEOUS

BACKCHAIN-LIMIT    limiting the effort expended on relieving hypotheses

Before ACL2 can apply a rule with hypotheses, it must establish that the
hypotheses are true.  (We ignore the relaxing of this requirement
afforded by case-splits and forced hypotheses.)  ACL2 typically
establishes each hypothesis by backchaining -- instantiating the
hypothesis and then rewriting it recursively.  Here we describe how
ACL2 allows the user to limit backchaining.  At the end, below, we
describe the function backchain-limit.

Each hypothesis of a rewrite, meta, linear, or type-prescription rule
is assigned a backchain-limit when the rule is stored.  By default,
this limit is nil, denoting infinity (no limit).  However, the value
used for the default may be set to a non-negative integer (or to nil)
by the user; see *note SET-DEFAULT-BACKCHAIN-LIMIT::.  The default is
overridden when a :backchain-limit-lst is supplied explicitly with the
rule; see *note RULE-CLASSES::.  The number of recursive applications of
backchaining starting with the hypothesis of a rule is limited to the
backchain-limit associated with that hypothesis.

Moreover, the user may set global backchain-limits that limit the total
backchaining depth.  See *note SET-BACKCHAIN-LIMIT::.  One limit is for
the use of rewrite, meta, and linear rules, while the other limit is
for so-called "type-set reasoning", which uses rules of class
type-prescription rules.  The two limits operate independently.  Below,
we discuss the first kind of backchain limits, i.e., for other than
type-prescription rules, except as otherwise indicated; but the
mechanism for those rules is similar.

Below we lay out the precise sense in which a global backchain-limit
interacts with the backchain-limits of individual rules in order to
limit backchaining.  But first we note that when further backchaining is
disallowed, ACL2 can still prove a hypothesis in a given context by
using that contextual information.  In fact, type-set reasoning may be
used (except that a weaker version of it is used in the second case
above, i.e., where we are already doing type-set reasoning).  Thus, the
relieving of hypotheses may be limited to the use of contextual
information (without backchaining, i.e., without recursively rewriting
hypotheses) by executing :set-backchain-limit 0.

Recall that there are two sorts of backchain limits: those applied to
hypotheses of individual rules, as assigned by their :rule-classes or
else taken from the default (see *note SET-DEFAULT-BACKCHAIN-LIMIT::);
and the global limit, initially nil (no limit) but settable with
:set-backchain-limit.  Here is how these two types of limits interact
to limit backchaining, i.e., recursive rewriting of hypotheses.  ACL2
maintains a current backchain limit, which is the limit on the depth of
recursive calls to the rewriter, as well as a current backchain depth,
which is initially 0 and is incremented each time ACL2 backchains (and
is decremented when a backchain completes).  When ACL2 begins to
rewrite a literal (crudely, one of the "top-level" terms of the goal
currently being worked on), it sets the current backchain-limit to the
global value, which is initially nil but can be set using
:set-backchain-limit.  When ACL2 is preparing to relieve a hypothesis
by backchaining (hence, after it has already tried type-set reasoning),
it first makes sure that the current backchain limit is greater than
the current backchain depth.  If not, then it refuses to relieve that
hypothesis.  Otherwise, it increments the current backchain depth and
calculates a new current backchain-limit by taking the minimum of two
values: the existing current backchain-limit, and the sum of the
current backchain depth and the backchain-limit associated with the
hypothesis.  Thus, ACL2 only modifies the current backchain-limit if it
is necessary to decrease that limit in order to respect the backchain
limit associated with the hypothesis.

We illustrate with the following examples.

     ; We stub out some functions so that we can reason about them.

     (defstub p0 (x) t)
     (defstub p1 (x) t)
     (defstub p2 (x) t)
     (defstub p3 (x) t)

     ; Initially, the default-backchain-limit is nil, or infinite.

     (defaxiom p2-implies-p1-limitless
       (implies (p2 x)
                (p1 x)))

     ; The following rule will have a backchain-limit of 0.

     (defaxiom p1-implies-p0-limit-0
       (implies (p1 x)
                (p0 x))
       :rule-classes ((:rewrite :backchain-limit-lst 0)))

     ; We have (p2 x) ==> (p1 x) ==> (p0 x).  We wish to establish that
     ; (p2 x) ==> (p0 x).  Normally, this would be no problem, but here
     ; we fail because ACL2 cannot establish (p0 x) by type-set reasoning
     ; alone.

     (thm
       (implies (p2 x)
                (p0 x)))

     ; We set the default-backchain-limit (for rewriting) to 1.

     :set-default-backchain-limit 1

     ; The following is more powerful than p1-implies-p0-limit-0
     ; because it can use rewrite rules to establish (p1 x).

     (defaxiom p1-implies-p0-limit-1
       (implies (p1 x)
                (p0 x)))

     ; This theorem will succeed:

     (thm
       (implies (p2 x)
                (p0 x)))

     ; We return the default-backchain-limit to its initial value.

     :set-default-backchain-limit nil

     ; Here is our last axiom.

     (defaxiom p3-implies-p2-limitless
       (implies (p3 x)
                (p2 x)))

     ; We now have (p3 x) ==> (p2 x) ==> (p1 x) ==> (p0 x).  However the
     ; rule p1-implies-p0-limit-1 has a backchain-limit of 1; hence we
     ; are not allowed to backchain far enough back to use
     ; p3-implies-p2-limitless.  We therefore lose.

     (defthm will-fail
       (implies (p3 x)
                (p0 x)))

Finally, we remark that to see the current global backchain-limits,
issue the following commands.

     (backchain-limit wrld :ts) ; backchain limit for type-set reasoning
     (backchain-limit wrld :rewrite) ; backchain limit for rewriting


File: acl2-doc-emacs.info,  Node: BACKCHAIN-LIMIT-RW,  Next: BACKTRACK,  Prev: BACKCHAIN-LIMIT,  Up: MISCELLANEOUS

BACKCHAIN-LIMIT-RW    hints keyword :BACKCHAIN-LIMIT-RW

See *note HINTS::.


File: acl2-doc-emacs.info,  Node: BACKTRACK,  Next: BIBLIOGRAPHY,  Prev: BACKCHAIN-LIMIT-RW,  Up: MISCELLANEOUS

BACKTRACK    hints keyword :BACKTRACK

See *note HINTS::.


File: acl2-doc-emacs.info,  Node: BIBLIOGRAPHY,  Next: BIND-FREE,  Prev: BACKTRACK,  Up: MISCELLANEOUS

BIBLIOGRAPHY    reports about ACL2

For a list of notes and reports about ACL2, see
`http://www.cs.utexas.edu/users/moore/publications/acl2-papers.html'.


File: acl2-doc-emacs.info,  Node: BIND-FREE,  Next: BY,  Prev: BIBLIOGRAPHY,  Up: MISCELLANEOUS

BIND-FREE    to bind free variables of a rewrite, definition, or linear rule

     Examples:
     (IMPLIES (AND (RATIONALP LHS)
                   (RATIONALP RHS)
                   (BIND-FREE (FIND-MATCH-IN-PLUS-NESTS LHS RHS) (X)))
              (EQUAL (EQUAL LHS RHS)
                     (EQUAL (+ (- X) LHS) (+ (- X) RHS))))

     (IMPLIES (AND (BIND-FREE
                     (FIND-RATIONAL-MATCH-IN-TIMES-NESTS LHS RHS MFC STATE)
                     (X))
                   (RATIONALP X)
                   (CASE-SPLIT (NOT (EQUAL X 0))))
              (EQUAL (< LHS RHS)
                     (IF (< 0 X)
                         (< (* (/ X) LHS) (* (/ X) RHS))
                        (< (* (/ X) RHS) (* (/ X) LHS)))))

* Menu:

* BIND-FREE-EXAMPLES:: examples pertaining to bind-free hypotheses

General Forms:

     (BIND-FREE term var-list)
     (BIND-FREE term t)
     (BIND-FREE term)

A rule which uses a bind-free hypothesis has similarities to both a rule
which uses a syntaxp hypothesis and to a :meta rule.  Bind-free is like
syntaxp, in that it logically always returns t but may affect the
application of a :rewrite, :definition, or :linear rule when it is
called at the top-level of a hypothesis.  It is like a :meta rule, in
that it allows the user to perform transformations of terms under
progammatic control.

Note that a bind-free hypothesis does not, in general, deal with the
meaning or semantics or values of the terms, but rather with their
syntactic forms.  Before attempting to write a rule which uses
bind-free, the user should be familiar with syntaxp and the internal
form that ACL2 uses for terms.  This internal form is similar to what
the user sees, but there are subtle and important differences.  Trans
can be used to view this internal form.

Just as for a syntaxp hypothesis, there are two basic types of
bind-free hypotheses.  The simpler type of bind-free hypothesis may be
used as the nth hypothesis in a :rewrite, :definition, or :linear rule
whose :corollary is (implies (and hyp1 ... hypn ... hypk) (equiv lhs
rhs)) provided term is a term, term contains at least one variable, and
every variable occuring freely in term occurs freely in lhs or in some
hypi, i<n.  In addition, term must not use any stobjs.  Later below we
will describe the second type, an _extended_ bind-free hypothesis, which
may use state.  Whether simple or extended, a bind-free hypothesis may
return an alist that binds free variables, as explained below, or it may
return a list of such alists.  We focus on the first of these cases:
return of a single binding alist.  We conclude our discussion with a
section that covers the other case: return of a list of alists.

We begin our description of bind-free by examining the first example
above in some detail.

We wish to write a rule which will cancel "like" addends from both
sides of an equality.  Clearly, one could write a series of rules such
as

     (DEFTHM THE-HARD-WAY-2-1
        (EQUAL (EQUAL (+ A X B)
                      (+ X C))
               (EQUAL (+ A B)
                      (FIX C))))

with one rule for each combination of positions the matching addends
might be found in (if one knew before-hand the maximum number of
addends that would appear in a sum).  But there is a better way.  (In
what follows, we assume the presence of an appropriate set of rules for
simplifying sums.)

Consider the following definitions and theorem:

     (DEFUN INTERSECTION-EQUAL (X Y)
       (COND ((ENDP X)
              NIL)
             ((MEMBER-EQUAL (CAR X) Y)
              (CONS (CAR X) (INTERSECTION-EQUAL (CDR X) Y)))
             (T
              (INTERSECTION-EQUAL (CDR X) Y))))

     (DEFUN PLUS-LEAVES (TERM)
       (IF (EQ (FN-SYMB TERM) 'BINARY-+)
           (CONS (FARGN TERM 1)
                 (PLUS-LEAVES (FARGN TERM 2)))
         (LIST TERM)))

     (DEFUN FIND-MATCH-IN-PLUS-NESTS (LHS RHS)
       (IF (AND (EQ (FN-SYMB LHS) 'BINARY-+)
                (EQ (FN-SYMB RHS) 'BINARY-+))
           (LET ((COMMON-ADDENDS (INTERSECTION-EQUAL (PLUS-LEAVES LHS)
                                                     (PLUS-LEAVES RHS))))
             (IF COMMON-ADDENDS
                 (LIST (CONS 'X (CAR COMMON-ADDENDS)))
               NIL))
         NIL))

     (DEFTHM CANCEL-MATCHING-ADDENDS-EQUAL
       (IMPLIES (AND (RATIONALP LHS)
                     (RATIONALP RHS)
                     (BIND-FREE (FIND-MATCH-IN-PLUS-NESTS LHS RHS) (X)))
                (EQUAL (EQUAL LHS RHS)
                       (EQUAL (+ (- X) LHS) (+ (- X) RHS)))))

How is this rule applied to the following term?

     (equal (+ 3 (expt a n) (foo a c))
            (+ (bar b) (expt a n)))

As mentioned above, the internal form of an ACL2 term is not always
what one sees printed out by ACL2.  In this case, by using :trans one
can see that the term is stored internally as

     (equal (binary-+ '3
                      (binary-+ (expt a n) (foo a c)))
            (binary-+ (bar b) (expt a n))).

When ACL2 attempts to apply cancel-matching-addends-equal to the term
under discussion, it first forms a substitution that instantiates the
left-hand side of the conclusion so that it is identical to the target
term.  This substitution is kept track of by the substitution alist:

     ((LHS . (binary-+ '3
                        (binary-+ (expt a n) (foo a c))))
      (RHS . (binary-+ (bar b) (expt a n)))).

ACL2 then attempts to relieve the hypotheses in the order they were
given.  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, we rewrite:

     (RATIONALP (binary-+ '3
                           (binary-+ (expt a n) (foo a c)))).

Let us assume that the first two hypotheses rewrite to t.  How do we
relieve the bind-free hypothesis?  Just as for a syntaxp hypothesis,
ACL2 evaluates (find-match-in-plus-nests lhs rhs) in an environment
where lhs and rhs are instantiated as determined by the substitution.
In this case we evaluate

     (FIND-MATCH-IN-PLUS-NESTS '(binary-+ '3
                                           (binary-+ (expt a n) (foo a c)))
                               '(binary-+ (bar b) (expt a n))).

Observe that, just as in the case of a syntaxp hypothesis, we
substitute the quotation of the variables bindings into the term to be
evaluated.  See *note SYNTAXP:: for the reasons for this.  The result
of this evaluation, ((X . (EXPT A N))), is then used to extend the
substitution alist:

     ((X . (EXPT A N))
      (LHS . (binary-+ '3
                        (binary-+ (expt a n) (foo a c))))
      (RHS . (binary-+ (bar b) (expt a n)))),

and this extended substitution determines
cancel-matching-addends-equal's result:

     (EQUAL (+ (- X) LHS) (+ (- X) RHS))
     ==>
     (EQUAL (+ (- (EXPT A N)) 3 (EXPT A N) (FOO A C))
            (+ (- (EXPT A N)) (BAR B) (EXPT A N))).

Question: What is the internal form of this result?
Hint: Use :trans.

When this rule fires, it adds the negation of a common term to both
sides of the equality by selecting a binding for the otherwise-free
variable x, under programmatic control.  Note that other mechanisms
such as the binding of free-variables may also extend the substitution
alist.

Just as for a syntaxp test, a bind-free form signals failure by
returning nil.  However, while a syntaxp test signals success by
returning true, a bind-free form signals success by returning an alist
which is used to extend the current substitution alist.  Because of
this use of the alist, there are several restrictions on it -- in
particular the alist must only bind variables, these variables must not
be already bound by the substitution alist, and the variables must be
bound to ACL2 terms.  If term returns an alist and the alist meets
these restrictions, we append the alist to the substitution alist and
use the result as the new current substitution alist.  This new current
substitution alist is then used when we attempt to relieve the next
hypothesis or, if there are no more, instantiate the right hand side of
the rule.

There is also a second, optional, var-list argument to a bind-free
hypothesis.  If provided, it must be either t or a list of variables.
If it is not provided, it defaults to t.  If it is a list of variables,
this second argument is used to place a further restriction on the
possible values of the alist to be returned by term: any variables
bound in the alist must be present in the list of variables.  We
strongly recommend the use of this list of variables, as it allows some
consistency checks to be performed at the time of the rule's admittance
which are not possible otherwise.

An extended bind-free 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 term: 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 BIND-FREE-EXAMPLES:: for examples of the use of these extended
bind-free hypotheses.

*SECTION*: Returning a list of alists.

As promised above, we conclude with a discussion of the case that
evaluation of the bind-free term produces a list of alists, x, rather
than a single alist.  In this case each member b of x is considered in
turn, starting with the first and proceeding through the list.  Each
such b is handled exactly as discussed above, as though it were the
result of evaluating the bind-free term.  Thus, each b extends the
current variable binding alist, and all remaining hypotheses are then
relieved, as though b had been the value obtained by evaluating the
bind-free term.  As soon as one such b leads to successful relieving of
all remaining hypotheses, the process of relieving hypotheses
concludes, so no further members of x are considered.

We illustrate with a simple pedagogical example.  First introduce
functions p1 and p2 such that a rewrite rule specifies that p2 implies
p1, but with a free variable.


     (defstub p1 (x) t)
     (defstub p2 (x y) t)

     (defaxiom p2-implies-p1
       (implies (p2 x y)
                (p1 x)))

If we add the following axiom, then (p1 x) follows logically for all x.


     (defaxiom p2-instance
       (p2 v (cons v 4)))

Unfortunately, evaluation of (thm (p1 a)) fails, because ACL2 fails to
bind the free variable y in order to apply the rule p2-instance.

Let's define a function that produces a list of alists, each binding the
variable y.  Of course, we know that only the middle one below is
necessary in this simple example.  In more complex examples, one might
use heuristics to construct such a list of alists.


     (defun my-alists (x)
       (list (list (cons 'y (fcons-term* 'cons x ''3)))
             (list (cons 'y (fcons-term* 'cons x ''4)))
             (list (cons 'y (fcons-term* 'cons x ''5)))))

The following rewrite rule uses bind-free to return a list of candidate
alists binding y.


     (defthm p2-implies-p1-better
       (implies (and (bind-free (my-alists x)
                                (y)) ; the second argument, (y), is optional
                     (p2 x y))
                (p1 x)))

Now the proof succeeds for (thm (p1 a)).  Why?  When ACL2 applies the
rewrite rule p2-implies-p1-better, it evaluates my-alists, as we can
see from the following trace, to bind y in three different alists.


     ACL2 !>(thm (p1 a))
     1> (ACL2_*1*_ACL2::MY-ALISTS A)
     <1 (ACL2_*1*_ACL2::MY-ALISTS (((Y CONS A '3))
                                   ((Y CONS A '4))
                                   ((Y CONS A '5))))

     Q.E.D.

The first alist, binding y to (cons a '3), fails to allow the
hypothesis (p2 x y) to be proved.  But the next binding of y, to (cons
a '4), succeeds: then the current binding alist is ((x . a) (y . (cons
a '4))), for which the hypothesis (p2 x y) rewrites to true using the
rewrite rule p2-instance.


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

BIND-FREE-EXAMPLES    examples pertaining to bind-free hypotheses

See *note BIND-FREE:: for a basic discussion of the use of bind-free to
control rewriting.

Note that the examples below all illustrate the common case in which a
bind-free hypothesis generates a binding alist.  See *note BIND-FREE::,
in particular the final section, for a discussion of the case that
instead a list of binding alists is generated.

We give examples of the use of bind-free hypotheses from the
perspective of a user interested in reasoning about arithmetic, but it
should be clear that bind-free can be used for many other purposes also.

EXAMPLE 1:  Cancel a common factor.

     (defun bind-divisor (a b)

     ; If a and b are polynomials with a common factor c, we return a
     ; binding for x.  We could imagine writing get-factor to compute the
     ; gcd, or simply to return a single non-invertible factor.

       (let ((c (get-factor a b)))
         (and c (list (cons 'x c)))))

     (defthm cancel-factor
       ;; We use case-split here to ensure that, once we have selected
       ;; a binding for x, the rest of the hypotheses will be relieved.
       (implies (and (acl2-numberp a)
                     (acl2-numberp b)
                     (bind-free (bind-divisor a b) (x))
                     (case-split (not (equal x 0)))
                     (case-split (acl2-numberp x)))
                (iff (equal a b)
                     (equal (/ a x) (/ b x)))))

EXAMPLE 2:  Pull integer summand out of floor.  Note:  This example has
an _extended_ bind-free hypothesis, which uses the term
(find-int-in-sum sum mfc state).

     (defun fl (x)
       ;; This function is defined, and used, in the IHS books.
       (floor x 1))

     (defun int-binding (term mfc state)
       ;; The call to mfc-ts returns the encoded type of term. ;
       ;; Thus, we are asking if term is known by type reasoning to ;
       ;; be an integer. ;
       (declare (xargs :stobjs (state) :mode :program))
       (if (ts-subsetp (mfc-ts term mfc state)
                       *ts-integer*)
           (list (cons 'int term))
         nil))

     (defun find-int-in-sum (sum mfc state)
       (declare (xargs :stobjs (state) :mode :program))
       (if (and (nvariablep sum)
                (not (fquotep sum))
                (eq (ffn-symb sum) 'binary-+))
           (or (int-binding (fargn sum 1) mfc state)
               (find-int-in-sum (fargn sum 2) mfc state))
         (int-binding sum mfc state)))

     ; Some additional work is required to prove the following.  So for
     ; purposes of illustration, we wrap skip-proofs around the defthm.

     (skip-proofs
      (defthm cancel-fl-int
       ;; The use of case-split is probably not needed, since we should
       ;; know that int is an integer by the way we selected it.  But this
       ;; is safer.
        (implies (and (acl2-numberp sum)
                      (bind-free (find-int-in-sum sum mfc state) (int))
                      (case-split (integerp int)))
                 (equal (fl sum)
                        (+ int (fl (- sum int)))))
        :rule-classes ((:rewrite :match-free :all)))
     )

     ; Arithmetic libraries will have this sort of lemma.
     (defthm hack (equal (+ (- x) x y) (fix y)))

     (in-theory (disable fl))

     (thm (implies (and (integerp x) (acl2-numberp y))
                   (equal (fl (+ x y)) (+ x (fl y)))))

EXAMPLE 3:  Simplify terms such as (equal (+ a (* a b)) 0)

     (defun factors (product)
       ;; We return a list of all the factors of product.  We do not
       ;; require that product actually be a product.
       (if (eq (fn-symb product) 'BINARY-*)
           (cons (fargn product 1)
                 (factors (fargn product 2)))
         (list product)))

     (defun make-product (factors)
       ;; Factors is assumed to be a list of ACL2 terms.  We return an
       ;; ACL2 term which is the product of all the ellements of the
       ;; list factors.
       (cond ((atom factors)
              ''1)
             ((null (cdr factors))
              (car factors))
             ((null (cddr factors))
              (list 'BINARY-* (car factors) (cadr factors)))
             (t
              (list 'BINARY-* (car factors) (make-product (cdr factors))))))

     (defun quotient (common-factors sum)
       ;; Common-factors is a list of ACL2 terms.   Sum is an ACL2 term each
       ;; of whose addends have common-factors as factors.  We return
       ;; (/ sum (make-product common-factors)).
       (if (eq (fn-symb sum) 'BINARY-+)
           (let ((first (make-product (set-difference-equal (factors (fargn sum 1))
                                                            common-factors))))
             (list 'BINARY-+ first (quotient common-factors (fargn sum 2))))
         (make-product (set-difference-equal (factors sum)
                                             common-factors))))

     (defun intersection-equal (x y)
       (cond ((endp x)
              nil)
             ((member-equal (car x) y)
              (cons (car x) (intersection-equal (cdr x) y)))
             (t
              (intersection-equal (cdr x) y))))

     (defun common-factors (factors sum)
       ;; Factors is a list of the factors common to all of the addends
       ;; examined so far.  On entry, factors is a list of the factors in
       ;; the first addend of the original sum, and sum is the rest of the
       ;; addends.  We sweep through sum, trying to find a set of factors
       ;; common to all the addends of sum.
       (declare (xargs :measure (acl2-count sum)))
       (cond ((null factors)
              nil)
             ((eq (fn-symb sum) 'BINARY-+)
              (common-factors (intersection-equal factors (factors (fargn sum 1)))
                              (fargn sum 2)))
             (t
              (intersection-equal factors (factors sum)))))

     (defun simplify-terms-such-as-a+ab-rel-0-fn (sum)
       ;; If we can find a set of factors common to all the addends of sum,
       ;; we return an alist binding common to the product of these common
       ;; factors and binding quotient to (/ sum common).
       (if (eq (fn-symb sum) 'BINARY-+)
           (let ((common-factors (common-factors (factors (fargn sum 1))
                                                 (fargn sum 2))))
             (if common-factors
                 (let ((common (make-product common-factors))
                       (quotient (quotient common-factors sum)))
                   (list (cons 'common common)
                         (cons 'quotient quotient)))
               nil))
         nil))

     (defthm simplify-terms-such-as-a+ab-=-0
       (implies (and (bind-free
                      (simplify-terms-such-as-a+ab-rel-0-fn sum)
                      (common quotient))
                     (case-split (acl2-numberp common))
                     (case-split (acl2-numberp quotient))
                     (case-split (equal sum
                                        (* common quotient))))
                (equal (equal sum 0)
                       (or (equal common 0)
                           (equal quotient 0)))))

     (thm (equal (equal (+ u (* u v)) 0)
           (or (equal u 0) (equal v -1))))


File: acl2-doc-emacs.info,  Node: BY,  Next: CASE-SPLIT,  Prev: BIND-FREE,  Up: MISCELLANEOUS

BY    hints keyword :BY

See *note HINTS::.


File: acl2-doc-emacs.info,  Node: CASE-SPLIT,  Next: CASE-SPLIT-LIMITATIONS,  Prev: BY,  Up: MISCELLANEOUS

CASE-SPLIT    like force but immediately splits the top-level goal on the hypothesis

Case-split is an variant of force, which has similar special treatment
in hypotheses of rules for the same rule-classes as for force (see
*note FORCE::).  This treatment takes place for rule classes :rewrite,
:linear, :type-prescription, :definition, :meta (actually in that case,
the result of evaluating the hypothesis metafunction call), and
:forward-chaining.

When a hypothesis of a conditional rule (of one of the classes listed
above) has the form (case-split hyp) it is logically equivalent to hyp.
However it affects the application of the rule generated as follows: if
ACL2 attempts to apply the rule but cannot establish that the required
instance of hyp holds in the current context, it considers the
hypothesis true anyhow, but (assuming all hypotheses are seen to be
true and the rule is applied) creates a subgoal in which that instance
of hyp is assumed false.  (There are exceptions, noted below.)

For example, given the rule

     (defthm p1->p2
       (implies (case-split (p1 x))
                (p2 x)))

then an attempt to prove

     (implies (p3 x) (p2 (car x)))

can give rise to a single subgoal:

     (IMPLIES (AND (NOT (P1 (CAR X))) (P3 X))
              (P2 (CAR X))).

Unlike force, case-split does not delay the "false case" to a forcing
round but tackles it more or less immediately.

The special "split" treatment of case-split can be disabled by
disabling forcing: see *note FORCE:: for a discussion of disabling
forcing, and also see *note DISABLE-FORCING::.  Finally, we should
mention that the rewriter is never willing to split when there is an if
term present in the goal being simplified.  Since and terms and or
terms are merely abbreviations for if terms, they also prevent
splitting.  Note that if terms are ultimately eliminated using the
ordinary flow of the proof (but see *note
SET-CASE-SPLIT-LIMITATIONS::), so case-split will ultimately function
as intended.

When in the proof checker, case-split behaves like force.


File: acl2-doc-emacs.info,  Node: CASE-SPLIT-LIMITATIONS,  Next: CASES,  Prev: CASE-SPLIT,  Up: MISCELLANEOUS

CASE-SPLIT-LIMITATIONS    a list of two "numbers" limiting the number of cases produced at once

     Examples:
     ACL2 !>(case-split-limitations (w state))
     (500 100)

With the setting above, clausify will not try subsumption/replacement
if more than 500 clauses are involved.  Furthermore, the simplifier, as
it sweeps over a clause, will inhibit further case splits when it has
accumulated 100 subgoals.  This inhibition is implemented by continuing
to rewrite subsequent literals but not splitting out their cases.  This
can produce literals containing IFs.

See *note SET-CASE-SPLIT-LIMITATIONS:: for a more general discussion.


File: acl2-doc-emacs.info,  Node: CASES,  Next: CLAUSE-IDENTIFIER,  Prev: CASE-SPLIT-LIMITATIONS,  Up: MISCELLANEOUS

CASES    hints keyword :CASES

See *note HINTS::.


File: acl2-doc-emacs.info,  Node: CLAUSE-IDENTIFIER,  Next: COMMAND,  Prev: CASES,  Up: MISCELLANEOUS

CLAUSE-IDENTIFIER    the internal form of a goal-spec

To each goal-spec, str, there corresponds a clause-identifier produced
by (parse-clause-id str).  For example,

     (parse-clause-id "[2]Subgoal *4.5.6/7.8.9'''")

returns ((2 4 5 6) (7 8 9) . 3).

The function string-for-tilde-@-clause-id-phrase inverts
parse-clause-id in the sense that given a clause identifier it returns
the corresponding goal-spec.

As noted in the documentation for goal-spec, each clause printed in the
theorem prover's proof attempt is identified by a name.  When these
names are represented as strings they are called "goal specs."  Such
strings are used to specify where in the proof attempt a given hint is
to be applied.  The function parse-clause-id converts goal-specs into
clause identifiers, which are cons-trees containing natural numbers.

Examples of goal-specs and their corresponding clause identifiers are
shown below.

                  parse-clause-id
                        -->

     "Goal"                       ((0) NIL . 0)
     "Subgoal 3.2.1'"             ((0) (3 2 1) . 1)
     "[2]Subgoal *4.5.6/7.8.9'''" ((2 4 5 6) (7 8 9) . 3)

                        <--
           string-for-tilde-@-clause-id-phrase

The caar of a clause id specifies the forcing round, the cdar specifies
the goal being proved by induction, the cadr specifies the particular
subgoal, and the cddr is the number of primes in that subgoal.

Internally, the system maintains clause ids, not goal-specs.  The
system prints clause ids in the form shown by goal-specs.  When a
goal-spec is used in a hint, it is parsed (before the proof attempt
begins) into a clause id.  During the proof attempt, the system watches
for the clause id and uses the corresponding hint when the id arises.
(Because of the expense of creating and garbage collecting a lot of
strings, this design is more efficient than the alternative.)


File: acl2-doc-emacs.info,  Node: COMMAND,  Next: COMMAND-DESCRIPTOR,  Prev: CLAUSE-IDENTIFIER,  Up: MISCELLANEOUS

COMMAND    forms you type at the top-level, but...

...the word "command" usually refers to a top-level form whose
evaluation produces a new logical world.

     Typical commands are:
     (defun foo (x) (cons x x))
     (defthm consp-foo (consp (foo x)))
     (defrec pair (hd . tl) nil)

The first two forms are examples of commands that are in fact primitive
events.  See *note EVENTS::.  Defrec, on the other hand, is a macro
that expands into a progn of several primitive events.  In general, a
world extending command generates one or more events.

Both events and commands leave landmarks on the world that enable us to
determine how the given world was created from the previous one.  Most
of your interactions will occur at the command level, i.e., you type
commands, you print previous commands, and you undo back through
commands.  Commands are denoted by command descriptors.  See *note
COMMAND-DESCRIPTOR::.


File: acl2-doc-emacs.info,  Node: COMMAND-DESCRIPTOR,  Next: COMMON-LISP,  Prev: COMMAND,  Up: MISCELLANEOUS

COMMAND-DESCRIPTOR    an object describing a particular command typed by the user

     Examples:

     :max      ; the command most recently typed by the user
     :x        ; synonymous with :max
     (:x -1)   ; the command before the most recent one
     (:x -2)   ; the command before that
     :x-2      ; synonymous with (:x -2)
     5         ; the fifth command typed by the user
     1         ; the first command typed by the user
     0         ; the last command of the system initialization
     -1        ; the next-to-last initialization command
     :min      ; the first command of the initialization
     :start    ; the last command of the initial ACL2 logical world
     fn        ; the command that introduced the logical name fn
     (:search (defmacro foo-bar))
               ; the first command encountered in a search from :max to
               ; 0 that either contains defmacro and foo-bar in the
               ; command form or contains defmacro and foo-bar in some
               ; event within its block.

The recorded history of your interactions with the top-level ACL2
command loop is marked by the commands you typed that changed the
logical world.  Each such command generated one or more events, since
the only way for you to change the logical world is to execute an event
function.  See *note COMMAND:: and see *note EVENTS::.  We divide
history into "command blocks," grouping together each world changing
command and its events.  A "command descriptor" is an object that can
be used to describe a particular command in the history of the ongoing
session.

Each command is assigned a unique integer called its "command number"
which indicates the command's position in the chronological ordering of
all of the commands ever executed in this session (including those
executed to initialize the system).  We assign the number 1 to the
first command you type to ACL2.  We assign 2 to the second and so on.
The non-positive integers are assigned to "prehistoric" commands, i.e.,
the commands used to initialize the ACL2 system: 0 is the last command
of the initialization, -1 is the one before that, etc.

The legal command descriptors are described below.  We use n to denote
any integer, sym to denote any logical name (see *note LOGICAL-NAME::),
and cd to denote, recursively, any command descriptor.

      command                   command
     descriptor                described

     :max   -- the most recently executed command (i.e., the one with
               the largest command number)
     :x     -- synonymous with :max
     :x-k   -- synonymous with (:x -k), if k is an integer and k>0
     :min   -- the earliest command (i.e., the one with the smallest
               command number and hence the first command of the system
               initialization)
     :start -- the last command when ACL2 starts up
     n      -- command number n  (If n is not in the
               range :min<=n<=:max, n is replaced by the nearest of :min
               and :max.)
     sym    -- the command that introduced the logical name sym
     (cd n) -- the command whose number is n plus the command number of
               the command described by cd
     (:search pat cd1 cd2)
               In this command descriptor, pat must be either an atom or
               a true list of atoms and cd1 and cd2 must be command
               descriptors.  We search the interval from cd1 through cd2
               for the first command that matches pat.  Note that if cd1
               occurs chronologically after cd2, the search is
               ``backwards'' through history while if cd1 occurs
               chronologically before cd2, the search is ``forwards''.  A
               backwards search will find the most recent match; a
               forward search will find the chronologically earliest
               match.  A command matches pat if either the command form
               itself or one of the events in the block contains pat (or
               all of the atoms in pat if pat is a list).
     (:search pat)
               the command found by (:search pat :max 0), i.e., the most
               recent command matching pat that was part of the user's
               session, not part of the system initialization.


File: acl2-doc-emacs.info,  Node: COMMON-LISP,  Next: COMPUTED-HINTS,  Prev: COMMAND-DESCRIPTOR,  Up: MISCELLANEOUS

COMMON-LISP    relation to Common Lisp, including deviations from the spec

ACL2 is a logic, a theorem prover, and a programming language based on
Common Lisp.  A connection with Common Lisp is established with guards
(see *note GUARD::).

However, here we document potential deviations from Common Lisp
semantics even in the presence of verified guards.  Our view is that
these deviations are extremely unlikely to manifest; indeed, as of this
writing we are unaware of any cases in which these issues arise in
practice.  However, we feel obligated to acknowledge their possibility,
which could result in surprises during evaluation or even proof.

* Menu:

* DEFUN-MODE-CAVEAT:: potential soundness issue for functions with defun-mode :program

* GENERALIZED-BOOLEANS:: potential soundness issues related to ACL2 predicates

The Common Lisp spec allows certain predicates to return what it calls
"generalized Booleans," which are really arbitrary values that are to be
viewed as either nil or non-nil.  However, in ACL2 these functions are
assumed to return nil or t.  For details,see *note
GENERALIZED-BOOLEANS::.

The execution of forms with :program mode functions can result in calls
of functions on arguments that do not satisfy their guards.  In
practice, this simply causes hard Lisp errors.  But in principle one
could imagine a damaged Lisp image that operates incorrectly.  See
*note DEFUN-MODE-CAVEAT::.

The Common Lisp spec, specifically Section 3.2.2.3 of the Common Lisp
HyperSpec, allows for undefined results when a function is "multiply
defined" in a compiled file.  ACL2 allows redundant defuns in a book,
and in general books are compiled by certify-book (but see *note
CERTIFY-BOOK:: and see *note COMPILATION:: for how to control such
compilation).  Moreover, ACL2 provides a redefinition capability (see
*note LD-REDEFINITION-ACTION:: and see *note REDEF::), and the above
section also allows for undefined results when a function is defined in
a compiled file and then redefined, presumably (for example) because of
inlining.


File: acl2-doc-emacs.info,  Node: DEFUN-MODE-CAVEAT,  Next: GENERALIZED-BOOLEANS,  Prev: COMMON-LISP,  Up: COMMON-LISP

DEFUN-MODE-CAVEAT    potential soundness issue for functions with defun-mode :program

Technically speaking, in the current implementation, the execution of
functions having defun-mode :program may damage the ACL2 system in a
way that renders it unsound.  In practice, we have never seen this
happen; so, the explanations below can be viewed as extremely paranoid.
Nevertheless, here we document this concern, even if it should be taken
with more than a grain of salt.

See *note DEFUN-MODE:: for a discussion of defun-modes.  That discussion
describes an imagined implementation that is slightly different from
this one.  This note explains that the current implementation is open to
unsoundness.

For discussion of a different soundness issue that is also related to
function execution, see *note GENERALIZED-BOOLEANS::.

The execution of a function having defun-mode :program may violate
Common Lisp guards on the subroutines used.  (This may be true even for
calls of a function on arguments that satisfy its guard, because ACL2
has not verified that its guard is sufficient to protect its
subroutines.)  When a guard is violated at runtime all bets are off.
That is, no guarantees are made either about the answer being "right"
or about the continued rationality of the ACL2 system itself.

For example, suppose you make the following defun:


     (defun crash (i)
       (declare (xargs :mode :program :guard (integerp i)))
       (car i))

Note that the declared guard does not in fact adequately protect the
subroutines in the body of crash; indeed, satisfying the guard to crash
will guarantee that the car expression is in violation of its guard.
Because this function is admitted in :program-mode, no checks are made
concerning the suitability of the guard.  Furthermore, in the current
ACL2 implementation, crash is executed directly in Common Lisp.  Thus
if you call crash on an argument satisfying its guard you will cause an
erroneous computation to take place.

     ACL2 !>(crash 7)

     Error: Caught fatal error [memory may be damaged]
     ...

There is no telling how much damage is done by this errant computation.
In some lisps your ACL2 job may actually crash back to the operating
system.  In other lisps you may be able to recover from the "hard
error" and resume ACL2 in a damaged but apparently functional image.

THUS, HAVING A FUNCTION WITH DEFUN-MODE :PROGRAM IN YOUR SYSTEM
ABSOLVES US, THE ACL2 IMPLEMENTORS, FROM RESPONSIBILITY FOR THE
SOUNDNESS OF OUR SYSTEM.

Furthermore

ACL2 DOES NOT YET PROVIDE ANY MEANS OF REGAINING ASSURANCES OF
SOUNDNESS AFTER THE INTRODUCTION OF A FUNCTION IN :PROGRAM MODE, EVEN
IF IT IS ULTIMATELY CONVERTED TO :LOGIC MODE (since its execution could
have damaged the system in a way that makes it possible to verify its
termination and guards unsoundly).

Finally,

THE VAST MAJORITY OF ACL2 SYSTEM CODE IS IN :PROGRAM MODE AND SO ALL
BETS ARE OFF FROM BEFORE YOU START!

This hopeless state of current affairs will change, we think.  We think
we have defined our functions "correctly" in the sense that they can be
converted, without "essential" modification, to :logic mode.  We think
it very unlikely that a mis-guarded function in :program mode (whether
ours or yours) will cause unsoundness without some sort of hard lisp
error accompanying it.  We think that ultimately we can make it
possible to execute your functions (interpretively) without risk to the
system, even when some have :program mode.  In that imagined
implementation, code using functions having :program mode would run
more slowly, but safely.  These functions could be introduced into the
logic ex post facto, whereupon the code's execution would speed up
because Common Lisp would be allowed to execute it directly.  We
therefore ask that you simply pretend that this is that imagined
implementation, introduce functions in :program mode, use them as
convenient and perhaps ultimately introduce some of them in :logic mode
and prove their properties.  If you use the system this way we can
develop (or dismiss) this style of formal system development.  BUT BE
ON THE LOOKOUT FOR SCREWUPS DUE TO DAMAGE CAUSED BY THE EXECUTION OF
YOUR FUNCTIONS HAVING :PROGRAM MODE!


File: acl2-doc-emacs.info,  Node: GENERALIZED-BOOLEANS,  Prev: DEFUN-MODE-CAVEAT,  Up: COMMON-LISP

GENERALIZED-BOOLEANS    potential soundness issues related to ACL2 predicates

The discussion below outlines a potential source of unsoundness in
ACL2.  Although to our knowledge there is no existing Lisp
implementation in which this problem can arise, nevertheless we feel
compelled to explain this situation.

Consider for example the question:  What is the value of (equal 3 3)?
According to the ACL2 axioms, it's t.  And as far as we know, based on
considerable testing, the value is t in every Common Lisp
implementation.  However, according the Common Lisp draft proposed ANSI
standard, any non-nil value could result.  Thus for example, (equal 3
3) is allowed by the standard to be 17.

The Common Lisp standard specifies (or soon will) that a number of
Common Lisp functions that one might expect to return Boolean values
may, in fact, return arbitrary values.  Examples of such functions are
equal, rationalp, and <; a much more complete list is given below.
Indeed, we dare to say that every Common Lisp function that one may
believe returns only Booleans is, nevertheless, not specified by the
standard to have that property, with the exceptions of the functions
not and null.  The standard refers to such arbitrary values as
"generalized Booleans," but in fact this terminology makes no
restriction on those values.  Rather, it merely specifies that they are
to be viewed, in an informal sense, as being either nil or not nil.

This situation is problematic for ACL2, which axiomatizes these
functions to return Booleans.  The problem is that because (for
efficiency and simplicity) ACL2 makes very direct use of compiled
Common Lisp functions to support the execution of its functions, there
is in principle a potential for unsoundness due to these "generalized
Booleans."  For example, ACL2's equal function is defined to be Common
Lisp's equal.  Hence if in Common Lisp the form (equal 3 3) were to
evaluate to 17, then in ACL2 we could prove (using the
:executable-counterpart of equal) (equal (equal 3 3) 17).  However,
ACL2 can also prove (equal (equal x x) t), and these two terms together
are contradictory, since they imply (instantiating x in the second term
by 3) that (equal 3 3) is both equal to 17 and to t.

To make matters worse, the standard allows (equal 3 3) to evaluate to
_different_ non-nil values every time.  That is:  equal need not even
be a function!

Fortunately, no existing Lisp implementation takes advantage of the
flexibility to have (most of) its predicates return generalized
Booleans, as far as we know.  We may implement appropriate safeguards
in future releases of ACL2, in analogy to (indeed, probably extending)
the existing safeguards by way of guards (see *note GUARD::).  For now,
we'll sleep a bit better knowing that we have been up-front about this
potential problem.

The following list of functions contains all those that are defined in
Common Lisp to return generalized Booleans but are assumed by ACL2 to
return Booleans.  In addition, the functions acl2-numberp and
complex-rationalp are directly defined in terms of respective Common
Lisp functions numberp and complexp.

     /=
     <
     =
     alpha-char-p
     atom
     char-equal
     char<
     char<=
     char>
     char>=
     characterp
     consp
     digit-char-p
     endp
     eq
     eql
     equal
     evenp
     integerp
     keywordp
     listp
     logbitp
     logtest
     lower-case-p
     minusp
     oddp
     plusp
     rationalp
     standard-char-p
     string-equal
     string<
     string<=
     string>
     string>=
     stringp
     subsetp
     symbolp
     upper-case-p
     zerop


File: acl2-doc-emacs.info,  Node: COMPUTED-HINTS,  Next: CONSTRAINT,  Prev: COMMON-LISP,  Up: MISCELLANEOUS

COMPUTED-HINTS    computing advice to the theorem proving process

     General Form of :hints:
     (hint1 hint2 ... hintk)

Each element, hinti, must be either a common hint or a computed hint.

A common hint is of the form

     (goal-spec :key1 val1 ... :keyn valn)

where goal-spec is as specified in goal-spec and each :keyi and vali is
as specified in hints.  Among the "common hints" we include both the
primitive hints and user-defined custom keyword hints (see *note
CUSTOM-KEYWORD-HINTS::).

A computed hint may be a function symbol, fn, of three, four or seven
arguments.  Otherwise, a computed hint is a term with the following
properties:

(a) the only free variables allowed in the term are ID, CLAUSE, WORLD,
STABLE-UNDER-SIMPLIFICATIONP, HIST, PSPV, CTX, and STATE;

(b) the output signature of the term is either (MV * * STATE), which is
to be treated as an error triple (see below), or is *, denoting a single
non-stobj value; and

(c) in the former case of (b) above, the term is single-threaded in
STATE.

If a computed hint is a function symbol fn, whose arity n is therefore
three, four, or seven, then it is treated as the term resulting from
applying that fn to the first n variables shown in (a) above.  Notice
that it must then return a single non-stobj value, not an error triple,
since state is not one of the first seven variables shown in (a).

Note: Error triples are an ACL2 idiom for implementing "errors"; see
*note ERROR-TRIPLES::.  If a computation returns (mv erp val state) in a
context in which ACL2 is respecting the error triple convention (see
*note LD-ERROR-TRIPLES:: and see *note LD-ERROR-ACTION::), then an
error is deemed to have occurred if erp is non-nil.  The computation is
expected to have printed an appropriate error message to state and
further computation is aborted.  On the other hand, if a computation
returns an error triple in which erp is nil, then "value" of the
computation is taken to be the second component, val, of the triple
(along with the possibly modified state), and computation continues.
For more information about programming with error triples, see *note
PROGRAMMING-WITH-STATE::.

The function symbol cases are treated as abbreviations of the term (fn
ID CLAUSE WORLD), (fn ID CLAUSE WORLD STABLE-UNDER-SIMPLIFICATIONP), or
(fn ID CLAUSE WORLD STABLE-UNDER-SIMPLIFICATIONP HIST PSPV CTX) as
appropriate for the arity of fn.  (Note that this tells you which
argument of fn is which.)  Moreover, in these cases the value returned
must be a single ordinary (non-stobj) value, not an error triple.  In
the discussion below we assume all computed hints are of the term form.
Indeed, we almost assume all computed hints are of the 3 and 4 argument
forms.  We only comment briefly on the 7 argument form in
using-computed-hints-8.

The semantics of a computed hint term is as follows.  On every subgoal,
the term is evaluated in an environment in which the variables
mentioned in (a) above are bound to context-sensitive values explained
below.  Either the computed hint signals an error, in which the proof
attempt aborts, or else it returns a value, val and a new state, state.
Any changes to those parts of state that affect logical soundness are
undone; more specifically, the values of symbols (sometimes called
"state global variables") in the list *protected-system-state-globals*
in the global table of the state (see *note STATE::) are restored when
changed during evaluation.  The value, val, of a non-erroneous computed
hint calculation is either nil, which means the computed hint did not
apply to the subgoal in question, or it is an alternating list of :keyi
vali pairs as specified in hints.  With one exception, those new hints
are applied to the given subgoal as though the user had typed them
explicitly.

The exception is that the first keyword in the returned val is allowed
to be :COMPUTED-HINT-REPLACEMENT.  Its value should be nil, t, or a
list of terms.  If this keyword is not present, the default value of nil
is provided.  We explain :COMPUTED-HINT-REPLACEMENT below.

The evaluation of a hint term is done with guard checking turned off
(see *note SET-GUARD-CHECKING::); e.g., the form (car 23) in a computed
hint returns nil as per the axioms.

When a non-nil value is returned, the keyword/value pairs (other than
the optional :COMPUTED-HINT-REPLACEMENT) are used as the hint for the
subgoal in question.  Thus, your job as the programmer of computed
hints is either to cause an error, typically by invoking er, or to
return a non-erroneous value triple whose value is the list of keys and
values you would have typed had you supplied a common hint for the
subgoal. (In particular, any theory expressions in it are evaluated
with respect to the global current-theory, not whatever theory is
active at the subgoal in question.)  If the generated list of keywords
and values is illegal, an error will be signaled and the proof attempt
will be aborted.

The purpose of the :COMPUTED-HINT-REPLACEMENT keyword and its value,
chr, is to change the list of hints.  If chr is nil, then the hint
which was applied is removed from the list of hints that is passed down
to the children of the subgoal in question.  This is the default.  If
chr is t, then the hint is left in the list of hints.  This means that
the same hint may act on the children of the subgoal.  Otherwise, chr
must be a list of terms, each of which is treated as a computed hint.
The hint which was applied is deleted from the list of hints and the
hints in chr are added to the list of hints passed to the children of
the subgoal.  The ability to compute new hints and pass them down
allows strange and wonderful behavior.

For these purposes, the goals produced by induction and the top-level
goals of forcing rounds are not considered children; all original hints
are available to them.

Only the first hint applicable to a goal, as specified in the
user-supplied list of :hints followed by the default-hints-table, will
be applied to that goal.  (For an advanced exception, see *note
OVERRIDE-HINTS::.)

It remains only to describe the bindings of the free variables.

Suppose the theorem prover is working on some clause, clause, named by
some goal-spec, e.g., "Subgoal *1/2"'" in some logical world, world.
Corresponding to the printed goal-spec is an internal data structure
called a "clause identifier" id.  See *note CLAUSE-IDENTIFIER::.

In the case of a common hint, the hint applies if the goal-spec of the
hint is the same as the goal-spec of the clause in question.

In the case of a computed hint, the variable ID is bound to the clause
id, the variable CLAUSE is bound to the (translated form of the) clause,
and the variable WORLD is bound to the current ACL2 world.  The variable
STABLE-UNDER-SIMPLIFICATIONP is bound to t or nil.  It is bound to t
only if the clause is known to be stable under simplification.  That
is, the simplifier has been applied to the clause and did not change it.
Such a clause is sometimes known as a "simplification checkpoint."  It
is frequently useful to inject hints (e.g., to enable a rule or provide
a :use hint) only when the goal in question has stabilized.  If a hint
is provided, the processing of the clause starts over with
simplification.

As for CTX and STATE, they are provided so that you can pass them to
the er macro to print error messages.  We recommend not writing
computed hints that otherwise change STATE!

The remaining variables, HIST and PSPV are not documented yet.  Only
users familiar with the internals of ACL2 are likely to need them or
understand their values.

For some instruction about how to use computed hints, see *note
USING-COMPUTED-HINTS::.


File: acl2-doc-emacs.info,  Node: CONSTRAINT,  Next: COPYRIGHT,  Prev: COMPUTED-HINTS,  Up: MISCELLANEOUS

CONSTRAINT    restrictions on certain functions introduced in encapsulate events

Suppose that a given theorem, thm, is to be functionally instantiated
using a given functional substitution, alist.  (See *note
LEMMA-INSTANCE::, or for an example, see *note
FUNCTIONAL-INSTANTIATION-EXAMPLE::.)  What is the set of proof
obligations generated?  It is the set obtained by applying alist to all
terms, tm, such that (a) tm mentions some function symbol in the domain
of alist, and (b) either (i) tm arises from the "constraint" on a
function symbol ancestral in thm or in some defaxiom or (ii) tm is the
body of a defaxiom.  Here, a function symbol is "ancestral" in thm if
either it occurs in thm, or it occurs in the definition of some
function symbol that occurs in thm, and so on.

The remainder of this note explains what we mean by "constraint" in the
words above.

In a certain sense, function symbols are introduced in essentially two
ways.  The most common way is to use defun (or when there is mutual
recursion, mutual-recursion or defuns).  There is also a mechanism for
introducing "witness functions"; see *note DEFCHOOSE::.  The
documentation for these events describes the axioms they introduce,
which we will call here their "definitional axioms."  These
definitional axioms are generally the constraints on the function
symbols that these axioms introduce.

However, when a function symbol is introduced in the scope of an
encapsulate event, its constraints may differ from the definitional
axioms introduced for it.  For example, suppose that a function's
definition is local to the encapsulate; that is, suppose the function is
introduced in the signature of the encapsulate.  Then its constraints
include, at the least, those non-local theorems and definitions in the
encapsulate that mention the function symbol.

Actually, it will follow from the discussion below that if the
signature is empty for an encapsulate, then the constraint on each of
its new function symbols is exactly the definitional axiom introduced
for it.  Intuitively, we view such encapsulates just as we view
include-book events.  But the general case, where the signature is not
empty, is more complicated.

In the discussion that follows we describe in detail exactly which
constraints are associated with which function symbols that are
introduced in the scope of an encapsulate event.  In order to simplify
the exposition we make two cuts at it.  In the first cut we present an
over-simplified explanation that nevertheless captures the main ideas.
In the second cut we complete our explanation by explaining how we view
certain events as being "lifted" out of the encapsulate, resulting in a
possibly smaller encapsulate, which becomes the target of the algorithm
described in the first cut.

At the end of this note we present an example showing why a more naive
approach is unsound.

Finally, before we start our "first cut," we note that any information
you want "exported" outside an encapsulate event must be there as an
explicit definition or theorem.  For example, even if a function foo has
output type (mv t t) in its signature, the system will not know
(true-listp (foo x)) merely on account of this information.  Thus, if
you are using functions like foo (constrained mv functions), then you
may find it useful to prove (inside the encapsulate, to be exported) a
:type-prescription rule for the constrained function, for example, the
:type-prescription rule (true-listp (foo x)).

_First cut at constraint-assigning algorithm._  Quite simply, the
formulas introduced in the scope of an encapsulate are conjoined, and
each function symbol introduced by the encapsulate is assigned that
conjunction as its constraint.

Clearly this is a rather severe algorithm.  Let us consider two possible
optimizations in an informal manner before presenting our second cut.

Consider the (rather artificial) event below.  The function before1 does
not refer at all, even indirectly, to the locally-introduced function
sig-fn, so it is unfortunate to saddle it with constraints about sig-fn.

     (encapsulate
      (((sig-fn *) => *))

      (defun before1 (x)
        (if (consp x)
            (before1 (cdr x))
          x))

      (local (defun sig-fn (x) (cons x x)))

      (defthm sig-fn-prop
        (consp (sig-fn x)))
      )

We would like to imagine moving the definition of before1 to just in
front of this encapsulate, as follows.

     (defun before1 (x)
       (if (consp x)
           (before1 (cdr x))
         x))

     (encapsulate
      (((sig-fn *) => *))

      (local (defun sig-fn (x) (cons x x)))

      (defthm sig-fn-prop
        (consp (sig-fn x)))
      )

Thus, we will only assign the constraint (consp (sig-fn x)), from the
theorem sig-fn-prop, to the function sig-fn, not to the function
before1.

More generally, suppose an event in an encapsulate event does not
mention any function symbol in the signature of the encapsulate, nor
any function symbol that mentions any such function symbol, and so on.
(We might say that no function symbol from the signature is an
"ancestor" of any function symbol occurring in the event.)  Then we
imagine moving the event, so that it appears in front of the
encapsulate.  We don't actually move it, but we pretend we do when it
comes time to assign constraints.  Thus, such definitions only
introduce definitional axioms as the constraints on the function
symbols being defined.  In the example above, the event sig-fn-prop
introduces no constraints on function before1.

Once this first optimization is performed, we have in mind a set of
"constrained functions."  These are the functions introduced in the
encapsulate that would remain after moving some of them in front, as
indicated above.  Consider the collection of all formulas introduced by
the encapsulate, except the definitional axioms, that mention these
constrained functions.  So for example, in the event below, no such
formula mentions the function symbol after1.

     (encapsulate
      (((sig-fn *) => *))

      (local (defun sig-fn (x) (cons x x)))

      (defthm sig-fn-prop
        (consp (sig-fn x)))

      (defun after1 (x)
        (sig-fn x))
      )

We can see that there is really no harm in imagining that we move the
definition of after1 out of the encapsulate, to just after the
encapsulate.

Many subtle aspects of this rearrangement process have been omitted.
For example, suppose the function fn uses sig-fn, the latter being a
function in the signature of the encapsulation.  Suppose a formula about
fn is proved in the encapsulation.  Then from the discussion above fn
is among the constrained functions of the encapsulate: it cannot be
moved before the encapsulate and it cannot be moved after the
encapsulation.  But why is fn constrained?  The reason is that the
theorem proved about fn may impose or express constraints on sig-fn.
That is, the theorem proved about fn may depend upon properties of the
witness used for sig-fn.  Here is a simple example:

     (encapsulate
      (((sig-fn *) => *))

      (local (defun sig-fn (x) (declare (ignore x)) 0))

      (defun fn (lst)
        (if (endp lst)
            t
            (and (integerp (sig-fn (car lst)))
                 (fn (cdr lst)))))

      (defthm fn-always-true
        (fn lst)))

In this example, there are no defthm events that mention sig-fn
explicitly.  One might therefore conclude that it is completely
unconstrained.  But the witness we chose for it always returns an
integer.  The function fn uses sig-fn and we prove that fn always
returns true.  Of course, the proof of this theorem depends upon the
properties of the witness for sig-fn, even though those properties were
not explicitly "called out" in theorems proved about sig-fn.  It would
be unsound to move fn-always-true after the encapsulate.  It would also
be unsound to constrain sig-fn to satisfy just fn-always-true without
including in the constraint the relation between sig-fn and fn.  Hence
both sig-fn and fn are constrained by this encapsulation and the
constraint imposed on each is the same and states the relation between
the two as characterized by the equation defining fn as well as the
property that fn always returns true.  Suppose, later, one proved a
theorem about sig-fn and wished to functionally instantiate it.  Then
one must also functionally instantiate fn, even if it is not involved
in the theorem, because it is only through fn that sig-fn inherits its
constrained properties.

This is a pathological example that illustrate a trap into which one may
easily fall: rather than identify the key properties of the constrained
function the user has foreshadowed its intended application and
constrained those notions.  Clearly, the user wishing to introduce the
sig-fn above would be well-advised to use the following instead:

     (encapsulate
      (((sig-fn *) => *))
      (local (defun sig-fn (x) (declare (ignore x)) 0))
      (defthm integerp-sig-fn
        (integerp (sig-fn x))))

     (defun fn (lst)
       (if (endp lst)
           t
         (and (integerp (sig-fn (car lst)))
              (fn (cdr lst)))))

     (defthm fn-always-true
        (fn lst)))

Note that sig-fn is constrained merely to be an integer.  It is the only
constrained function.  Now fn is introduced after the encapsulation, as
a simple function that uses sig-fn.  We prove that fn always returns
true, but this fact does not constrain sig-fn.  Future uses of sig-fn
do not have to consider fn at all.

Sometimes it is necessary to introduce a function such as fn within the
encapsulate merely to state the key properties of the undefined function
sig-fn.  But that is unusual and the user should understand that both
functions are being constrained.

Another subtle aspect of encapsulation that has been brushed over so
far has to do with exactly how functions defined within the
encapsulation use the signature functions.  For example, above we say
"Consider the collection of all formulas introduced by the encapsulate,
_except the definitional axioms_, that mention these constrained
functions."  We seem to suggest that a definitional axiom which
mentions a constrained function can be moved out of the encapsulation
and considered part of the "post-encapsulation" extension of the
logical world, if the defined function is not used in any
non-definitional formula proved in the encapsulation.  For example, in
the encapsulation above that constrained sig-fn and introduced fn
within the encapsulation, fn was constrained because we proved the
formula fn-always-true within the encapsulation.  Had we not proved
fn-always-true within the encapsulation, fn could have been moved after
the encapsulation.  But this suggests an unsound rule because whether
such a function can be moved after the encapsulate depend on whether
its _admission_ used properties of the witnesses!  In particular, we
say a function is "subversive" if any of its governing tests or the
actuals in any recursive call involve a function in which the signature
functions are ancestral.  See *note SUBVERSIVE-RECURSIONS::.

(Aside: The definition of fn in the first enapsulation above that
defines fn, i.e., the encapsulation with fn-always-true inside, is
subversive because the call of the macro AND expands to a call of IF
that governs a recursive call of fn, in this case:

     (defun fn (lst)
       (if (endp lst)
           t
           (if (integerp (sig-fn (car lst)))
               (fn (cdr lst))
             nil))).

If we switch the order of conjuncts in fn, then the definition of fn is
no longer subversive, but it still "infects" the constraint generated
for the encapsulation, hence for sig-fn, because fn-always-true blocks
the definition of fn from being moved back (to after the
encapsulation).  If we both switch the order of conjuncts and drop
fn-always-true from the encapsulation, then the definition of fn is in
essence moved back to after the encapsulation, and the constraint for
sig-fn no longer includes the definition of fn.  End of aside.)

Another aspect we have not discussed is what happens to nested
encapsulations when each introduces constrained functions.  We say an
encapsulate event is "trivial" if it introduces no constrained
functions, i.e., if its signatures is nil.  Trivial encapsulations are
just a way to wrap up a collection of events into a single event.

From the foregoing discussion we see we are interested in exactly how
we can "rearrange" the events in a non-trivial encapsulation - moving
some "before" the encapsulation and others "after" the encapsulation.
We are also interested in which functions introduced by the
encapsulation are "constrained" and what the "constraints" on each are.
We may summarize the observations above as follows, after which we
conclude with a more elaborate example.

_Second cut at constraint-assigning algorithm._  First, we focus only on
non-trivial encapsulations that neither contain nor are contained in
non-trivial encapsulations.  (Nested non-trivial encapsulations are not
rearranged at all: do not put anything in such a nest unless you mean
for it to become part of the constraints generated.)  Second, in what
follows we only consider the non-local events of such an encapsulate,
assuming that they satisfy the restriction of using no locally defined
function symbols other than the signature functions.  Given such an
encapsulate event, move, to just in front of it and in the same order,
all definitions and theorems for which none of the signature functions
is ancestral.  Now collect up all formulas (theorems) introduced in the
encapsulate other than definitional axioms.  Add to this set any of
those definitional equations that is either subversive or defines a
function used in a formula in the set.  The conjunction of the
resulting set of formulas is called the "constraint" and the set of all
the signature functions of the encapsulate together with all function
symbols defined in the encapsulate and mentioned in the constraint is
called the "constrained functions."  Assign the constraint to each of
the constrained functions.  Move, to just after the encapsulate, the
definitions of all function symbols defined in the encapsulate that
have been omitted from the constraint.

Implementation note.  In the implementation we do not actually move
events, but we create constraints that pretend that we did.

Here is an example illustrating our constraint-assigning algorithm.  It
builds on the preceding examples.

     (encapsulate
      (((sig-fn *) => *))

      (defun before1 (x)
        (if (consp x)
            (before1 (cdr x))
          x))

      (local (defun sig-fn (x) (cons x x)))

      (defthm sig-fn-prop
        (consp (sig-fn x)))

      (defun during (x)
        (if (consp x)
            x
          (cons (car (sig-fn x))
                17)))

      (defun before2 (x)
        (before1 x))

      (defthm before2-prop
        (atom (before2 x)))

      (defthm during-prop
        (implies (and (atom x)
                      (before2 x))
                 (equal (car (during x))
                        (car (sig-fn x)))))

      (defun after1 (x)
        (sig-fn x))

      (defchoose after2 (x) (u)
        (and (< u x) (during x)))
      )

Only the functions sig-fn and during receive extra constraints.  The
functions before1 and before2 are viewed as moving in front of the
encapsulate, as is the theorem before2-prop.  The functions after1 and
after2 are viewed as being moved past the encapsulate.  The
implementation reports the following.

     In addition to SIG-FN, we export AFTER2, AFTER1, BEFORE2, DURING and
     BEFORE1.

     The following constraint is associated with both of the functions DURING and
     SIG-FN:

     (AND (EQUAL (DURING X)
                 (IF (CONSP X)
                     X (CONS (CAR (SIG-FN X)) 17)))
          (CONSP (SIG-FN X))
          (IMPLIES (AND (ATOM X) (BEFORE2 X))
                   (EQUAL (CAR (DURING X))
                          (CAR (SIG-FN X)))))

Notice that the formula (consp (during x)) is not a conjunct of the
constraint.  During the first pass of the encapsulate, this formula is
stored as a :type-prescription rule deduced during the definition of
the function during.  However, the rule is not exported because of a
rather subtle soundness issue.  (If you are interested in details, see
the comments in source function putprop-type-prescription-lst.)

We conclude by asking (and to a certain extent, answering) the following
question: Isn't there an approach to assigning constraints that avoids
over-constraining more simply than our "second cut" above?  Perhaps it
seems that given an encapsulate, we should simply assign to each
locally defined function the theorems exported about that function.  If
we adopted that simple approach the events below would be admissible.

     (encapsulate
      (((foo *) => *))
      (local (defun foo (x) x))
      (defun bar (x)
        (foo x))
      (defthm bar-prop
        (equal (bar x) x)
        :rule-classes nil))

     (defthm foo-id
       (equal (foo x) x)
       :hints (("Goal" :use bar-prop)))

     ; The following event is not admissible in ACL2.

     (defthm ouch!
       nil
       :rule-classes nil
       :hints
       (("Goal" :use
         ((:functional-instance foo-id
                                (foo (lambda (x) (cons x x))))))))

Under the simple approach we have in mind, bar is constrained to satisfy
both its definition and bar-prop because bar mentions a function
declared in the signature list of the encapsulation.  In fact, bar is
so-constrained in the ACL2 semantics of encapsulation and the first two
events above (the encapsulate and the consequence that foo must be the
identity function) are actually admissible.  But under the simple
approach to assigning constraints, foo is unconstrained because no
theorem about it is exported.  Under that approach, ouch! is provable
because foo can be instantiated in foo-id to a function other than the
identity function.

It's tempting to think we can fix this by including definitions, not
just theorems, in constraints.  But consider the following slightly
more elaborate example.  The problem is that we need to include as a
constraint on foo not only the definition of bar, which mentions foo
explicitly, but also abc, which has foo as an ancestor.

     (encapsulate
      (((foo *) => *))
      (local (defun foo (x) x))
      (local (defthm foo-prop
               (equal (foo x) x)))
      (defun bar (x)
        (foo x))
      (defun abc (x)
        (bar x))
      (defthm abc-prop
        (equal (abc x) x)
        :rule-classes nil))

     (defthm foo-id
       (equal (foo x) x)
       :hints (("Goal" :use abc-prop)))

     ; The following event is not admissible in ACL2.

     (defthm ouch!
       nil
       :rule-classes nil
       :hints
       (("Goal" :use
         ((:functional-instance foo-id
                                (foo (lambda (x) (cons x x)))
                                (bar (lambda (x) (cons x x))))))))


File: acl2-doc-emacs.info,  Node: COPYRIGHT,  Next: COROLLARY,  Prev: CONSTRAINT,  Up: MISCELLANEOUS

COPYRIGHT    ACL2 copyright, license, sponsorship

ACL2 Version 6.3 - A Computational Logic for Applicative Common Lisp
Copyright (C) 2013, Regents of the University of Texas

This version of ACL2 is a descendent of ACL2 Version 1.9, Copyright (C)
1997 Computational Logic, Inc.  See the documentation topic NOTE-2-0.

This program is free software; you can redistribute it and/or modify it
under the terms of the LICENSE file distributed with ACL2.

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 LICENSE
for more details.

Written by:  Matt Kaufmann               and J Strother Moore email:
  Kaufmann@cs.utexas.edu      and Moore@cs.utexas.edu Department of
Computer Science University of Texas at Austin Austin, TX 78701 U.S.A.

Please also see *note ACKNOWLEDGMENTS::.


File: acl2-doc-emacs.info,  Node: COROLLARY,  Next: CURRENT-PACKAGE,  Prev: COPYRIGHT,  Up: MISCELLANEOUS

COROLLARY    the corollary formula of a rune

This is a low-level system function at the present time.  See *note
PR:: and see *note PR!:: instead.  Also see *note RULE-CLASSES:: for
the use of the symbol :corollary in specifying a rule class.


File: acl2-doc-emacs.info,  Node: CURRENT-PACKAGE,  Next: CUSTOM-KEYWORD-HINTS,  Prev: COROLLARY,  Up: MISCELLANEOUS

CURRENT-PACKAGE    the package used for reading and printing

Current-package is an ld special (see *note LD::).  The accessor is
(current-package state) and the updater is (set-current-package val
state), or more conventionally, (in-package val).  The value of
current-package is actually the string that names the package.  (Common
Lisp's "package" objects do not exist in ACL2.)  The current package
must be known to ACL2, i.e., it must be one of the initial packages or
a package defined with defpkg by the user.

When printing symbols, the package prefix is displayed if it is not the
current-package and may be optionally displayed otherwise.  Thus, if
current-package is "ACL2" then the symbol 'ACL2::SYMB may be printed as
SYMB or ACL2::SYMB, while 'MY-PKG::SYMB must be printed as
MY-PKG::SYMB.  But if current-package is "MY-PKG" then the former
symbol must be printed as ACL2::SYMB while the latter may be printed as
SYMB.

In Common Lisp, current-package also affects how objects are read from
character streams.  Roughly speaking, read and print are inverses if
the current-package is fixed, so reading from a stream produced by
printing an object must produce an equal object.

In ACL2, the situation is more complicated because we never read
objects from character streams, we only read them from object "streams"
(channels).  Logically speaking, the objects in such a channel are
fixed regardless of the setting of current-package.  However, our host
file systems do not support the idea of Lisp object files and instead
only support character files.  So when you open an object input channel
to a given (character file) we must somehow convert it to a list of
ACL2 objects.  This is done by a deus ex machina ("a person or thing
that appears or is introduced suddenly and unexpectedly and provides a
contrived solution to an apparently insoluble difficulty," Webster's
Ninth New Collegiate Dictionary).  Roughly speaking, the deus ex
machina determines what sequence of calls to read-object will occur in
the future and what the current-package will be during each of those
calls, and then produces a channel containing the sequence of objects
produced by an analogous sequence of Common Lisp reads with
*current-package* bound appropriately for each.

A simple rule suffices to make sane file io possible:  before you read
an object from an object channel to a file created by printing to a
character channel, make sure the current-package at read-time is the
same as it was at print-time.


File: acl2-doc-emacs.info,  Node: CUSTOM-KEYWORD-HINTS,  Next: DEFAULT-BACKCHAIN-LIMIT,  Prev: CURRENT-PACKAGE,  Up: MISCELLANEOUS

CUSTOM-KEYWORD-HINTS    user-defined hints

See *note ADD-CUSTOM-KEYWORD-HINT:: for a discussion of how advanced
users can define their own hint keywords.  For examples, see the
community books directory books/hints/, in particular basic-tests.lisp.

* Menu:

* SHOW-CUSTOM-KEYWORD-HINT-EXPANSION:: print out custom keyword hints when they are expanded


File: acl2-doc-emacs.info,  Node: SHOW-CUSTOM-KEYWORD-HINT-EXPANSION,  Prev: CUSTOM-KEYWORD-HINTS,  Up: CUSTOM-KEYWORD-HINTS

SHOW-CUSTOM-KEYWORD-HINT-EXPANSION    print out custom keyword hints when they are expanded

       Examples:
       (show-custom-keyword-hint-expansion t)
       (show-custom-keyword-hint-expansion nil)

       General Form:
       (show-custom-keyword-hint-expansion flg)

If the value of flg is non-nil, then when custom keyword hints are
expanded, the system prints the results of each expansion.  This is
sometimes   useful for debugging custom keyword hints and, from time to
time, may be   useful in understanding how a custom hint affects some
proof attempt.

The default setting is nil.

For an explanation of how custom keyword hints are processed,   see
*note CUSTOM-KEYWORD-HINTS::.


File: acl2-doc-emacs.info,  Node: DEFAULT-BACKCHAIN-LIMIT,  Next: DEFAULT-DEFUN-MODE,  Prev: CUSTOM-KEYWORD-HINTS,  Up: MISCELLANEOUS

DEFAULT-BACKCHAIN-LIMIT    specifying the backchain limit for a rule

See *note BACKCHAIN-LIMIT::.

The initial value is (nil nil).  To inspect the current value (as
explained elsewhere; see *note BACKCHAIN-LIMIT::):

     (default-backchain-limit wrld :ts) ; for type-set reasoning
     (default-backchain-limit wrld :rewrite) ; for rewriting


File: acl2-doc-emacs.info,  Node: DEFAULT-DEFUN-MODE,  Next: DEFAULT-HINTS,  Prev: DEFAULT-BACKCHAIN-LIMIT,  Up: MISCELLANEOUS

DEFAULT-DEFUN-MODE    the default defun-mode of defun'd functions

When a defun is processed and no :mode xarg is supplied, the function
default-defun-mode is used.  To find the default defun-mode of the
current ACL2 world, type (default-defun-mode (w state)).  See *note
DEFUN-MODE:: for a discussion of defun-modes.  To change the default
defun-mode of the ACL2 world, type one of the keywords :program or
:logic.

The default ACL2 prompt displays the current default defun-mode by
showing the character p for :program mode, and omitting it for :logic
mode; see *note DEFAULT-PRINT-PROMPT::.  The default defun-mode may be
changed using the keyword commands :program and :logic, which are
equivalent to the commands (program) and (logic).  Each of these names
is documented separately:  see *note PROGRAM:: and see *note LOGIC::.
The default defun-mode is stored in the table acl2-defaults-table and
hence may also be changed by a table command.  See *note TABLE:: and
also see *note ACL2-DEFAULTS-TABLE::.  Both mode-changing commands are
events.

While events that change the default defun-mode are permitted within an
encapsulate or the text of a book, their effects are local in scope to
the duration of the encapsulation or inclusion.  For example, if the
default defun-mode is :logic and a book is included that contains the
event (program), then subsequent events within the book are processed
with the default defun-mode :program; but when the include-book event
completes, the default defun-mode will still be :logic.  Commands that
change the default defun-mode are not permitted inside local forms.


File: acl2-doc-emacs.info,  Node: DEFAULT-HINTS,  Next: DEFAULT-PRINT-PROMPT,  Prev: DEFAULT-DEFUN-MODE,  Up: MISCELLANEOUS

DEFAULT-HINTS    a list of hints added to every proof attempt

     Examples:
     ACL2 !>(default-hints (w state))
     ((computed-hint-1 clause)
      (computed-hint-2 clause stable-under-simplificationp))

The value returned by this function is added to the right of the :hints
argument of every defthm and thm command, and to hints provided to
defuns as well (:hints, :guard-hints, and (for ACL2(r)) :std-hints).

See *note SET-DEFAULT-HINTS:: for a more general discussion.  Advanced
users only: see *note OVERRIDE-HINTS:: for an advanced variant of
default hints that are not superseded by :hints arguments.


File: acl2-doc-emacs.info,  Node: DEFAULT-PRINT-PROMPT,  Next: DEFAULT-RULER-EXTENDERS,  Prev: DEFAULT-HINTS,  Up: MISCELLANEOUS

DEFAULT-PRINT-PROMPT    the default prompt printed by ld

     Example prompt:
     ACL2 p!s>

The prompt printed by ACL2 displays the current package, followed by a
space, followed by zero or more of the three characters as specified
below, followed by the character > printed one or more times,
reflecting the number of recursive calls of ld.  The three characters
in the middle are as follows:

     p     ; when (default-defun-mode (w state)) is :program
     !     ; when guard checking is on
     s     ; when (ld-skip-proofsp state) is t

See *note DEFAULT-DEFUN-MODE::, see *note SET-GUARD-CHECKING::, and see
*note LD-SKIP-PROOFSP::.

Also see *note LD-PROMPT:: to see how to install your own prompt.

Here are some examples with ld-skip-proofsp nil.

     ACL2 !>    ; logic mode with guard checking on
     ACL2 >     ; logic mode with guard checking off
     ACL2 p!>   ; program mode with guard checking on
     ACL2 p>    ; program mode with guard checking off

Here are some examples with default-defun-mode of :logic.

     ACL2 >     ; guard checking off, ld-skip-proofsp nil
     ACL2 s>    ; guard checking off, ld-skip-proofsp t
     ACL2 !>    ; guard checking on, ld-skip-proofsp nil
     ACL2 !s>   ; guard checking on, ld-skip-proofsp t

Finally, here is the prompt in raw mode (see *note SET-RAW-MODE::),
regardless of the settings above:

     ACL2 P>


File: acl2-doc-emacs.info,  Node: DEFAULT-RULER-EXTENDERS,  Next: DEFUN-MODE,  Prev: DEFAULT-PRINT-PROMPT,  Up: MISCELLANEOUS

DEFAULT-RULER-EXTENDERS    the default ruler-extenders for defun'd functions

When a defun is processed and no :ruler-extenders xarg is supplied, the
function default-ruler-extenders is used to obtain the current
ruler-extenders; see *note RULER-EXTENDERS::.  To find the default
ruler-extenders of the current ACL2 world, type
(default-ruler-extenders (w state)).

While events that change the default ruler-extenders are permitted
within an encapsulate or the text of a book, their effects are local in
scope to the duration of the encapsulation or inclusion.  See *note
DEFAULT-DEFUN-MODE:: for an analogous discussion for defun-modes.


File: acl2-doc-emacs.info,  Node: DEFUN-MODE,  Next: DEFUNS,  Prev: DEFAULT-RULER-EXTENDERS,  Up: MISCELLANEOUS

DEFUN-MODE    determines whether a function definition is a logical act

Two "defun-modes" are supported, :program and :logic.  Roughly
speaking, :program mode allows you to prototype a function for
execution without any proof burdens, while :logic mode allows you to
add a new definitional axiom to the logic.  The system comes up in
:logic mode.  Execution of functions whose defun-mode is :program may
render ACL2 unsound!  See *note DEFUN-MODE-CAVEAT::.

Note that calls of local and of many events are skipped in :program
mode; see *note PROGRAM::.

When you define a function in the ACL2 logic, that function can be run
on concrete data.  But it is also possible to reason deductively about
the function because each definition extends the underlying logic with
a definitional axiom.  To ensure that the logic is sound after the
addition of this axiom, certain restrictions have to be met, namely
that the recursion terminates.  This can be quite challenging.

Because ACL2 is a programming language, you often may wish simply to
program in ACL2.  For example, you may wish to define your system and
test it, without any logical burden.  Or, you may wish to define
"utility" functions -- functions that are executed to help manage the
task of building your system but functions whose logical properties are
of no immediate concern.  Such functions might be used to generate test
data or help interpret the results of tests.  They might create files
or explore the ACL2 database.  The termination arguments for such
functions are an unnecessary burden provided no axioms about the
functions are ever used in deductions.

Thus, ACL2 introduces the idea of the "defun-mode" of a function.  The
:mode keyword of defun's declare xarg allows you to specify the
defun-mode of a given definition.  If no :mode keyword is supplied, the
default defun-mode is used; see *note DEFAULT-DEFUN-MODE::.

There are two defun-modes, each of which is written as a keyword:

:program -- logically undefined but executable outside deductive
contexts.

:logic -- axiomatically defined as per the ACL2 definitional principle.

It is possible to change the defun-mode of a function from :program to
:logic.  We discuss this below.

We think of functions having :program mode as "dangerous" functions,
while functions having :logic mode are "safe."  The only requirement
enforced on :program mode functions is the syntactic one:  each
definition must be well-formed ACL2.  Naively speaking, if a :program
mode function fails to terminate then no harm is done because no axiom
is added (so inconsistency is avoided) and some invocations of the
function may simply never return.  This simplistic justification of
:program mode execution is faulty because it ignores the damage that
might be caused by "mis-guarded" functions.  See *note
DEFUN-MODE-CAVEAT::.

We therefore implicitly describe an imagined implementation of
defun-modes that is safe and, we think, effective.  But please see
*note DEFUN-MODE-CAVEAT::.

The default defun-mode is :logic.  This means that when you defun a
function the system will try to prove termination.  If you wish to
introduce a function of a different defun-mode use the :mode xargs
keyword.  Below we show fact introduced as a function in :program mode.

     (defun fact (n)
       (declare (xargs :mode :program))
       (if (or (not (integerp n)) (= n 0))
           1
         (* n (fact (1- n)))))

No axiom is added to the logic as a result of this definition.  By
introducing fact in :program mode we avoid the burden of a termination
proof, while still having the option of executing the function.  For
example, you can type

     ACL2 !>(fact 3)

and get the answer 6.  If you type (fact -1) you will get a hard lisp
error due to "infinite recursion."

However, the ACL2 theorem prover knows no axioms about fact.  In
particular, if the term (fact 3) arises in a proof, the theorem prover
is unable to deduce that it is 6.  From the perspective of the theorem
prover it is as though fact were an undefined function symbol of arity
1.  Thus, modulo certain important issues (see *note
DEFUN-MODE-CAVEAT::), the introduction of this function in :program
mode does not imperil the soundness of the system -- despite the fact
that the termination argument for fact was omitted -- because nothing
of interest can be proved about fact.  Indeed, we do not allow fact to
be used in logical contexts such as conjectures submitted for proof.

It is possible to convert a function from :program mode to :logic mode
at the cost of proving that it is admissible.  This can be done by
invoking

     (verify-termination fact)

which is equivalent to submitting the defun of fact, again, but in
:logic mode.

     (defun fact (n)
       (declare (xargs :mode :logic))
       (if (or (not (integerp n)) (= n 0))
           1
         (* n (fact (1- n)))))

This particular event will fail because the termination argument
requires that n be nonnegative.  A repaired defun, for example with =
replaced by <=, will succeed, and an axiom about fact will henceforth
be available.

Technically, verify-termination submits a redefinition of the :program
mode function.  This is permitted, even when ld-redefinition-action is
nil, because the new definition is identical to the old (except for its
:mode and, possibly, other non-logical properties).

See *note GUARD:: for a discussion of how to restrict the execution of
functions.  Guards may be "verified" for functions in :logic mode; see
*note VERIFY-GUARDS::.


File: acl2-doc-emacs.info,  Node: DEFUNS,  Next: DISABLE-FORCING,  Prev: DEFUN-MODE,  Up: MISCELLANEOUS

DEFUNS    an alternative to mutual-recursion

     Example:
     (DEFUNS
      (evenlp (x)
        (if (consp x) (oddlp (cdr x)) t))
      (oddlp (x)
        (if (consp x) (evenlp (cdr x)) nil)))

     General Form:
     (DEFUNS defuns-tuple1 ... defuns-tuplen)

is equivalent to

     (MUTUAL-RECURSION
       (DEFUN . defuns-tuple1)
       ...
       (DEFUN . defuns-tuplen))

In fact, defuns is the more primitive of the two and mutual-recursion
is just a macro that expands to a call of defun after stripping off the
defun at the car of each argument to mutual-recursion.  We provide and
use mutual-recursion rather than defuns because by leaving the defuns
in place, mutual-recursion forms can be processed by the Emacs tags
program.  See *note MUTUAL-RECURSION::.


File: acl2-doc-emacs.info,  Node: DISABLE-FORCING,  Next: DISABLE-IMMEDIATE-FORCE-MODEP,  Prev: DEFUNS,  Up: MISCELLANEOUS

DISABLE-FORCING    to disallow forced case-splits

     General Form:
     ACL2 !>:disable-forcing   ; disallow forced case splits

See *note FORCE:: and see *note CASE-SPLIT:: for a discussion of forced
case splits, which are inhibited by this command.

Disable-forcing is actually a macro that disables the executable
counterpart of the function symbol force; see *note FORCE::.  When you
want to use hints to turn off forced case splits, use a form such as
one of the following (these are equivalent).

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


File: acl2-doc-emacs.info,  Node: DISABLE-IMMEDIATE-FORCE-MODEP,  Next: DISABLEDP,  Prev: DISABLE-FORCING,  Up: MISCELLANEOUS

DISABLE-IMMEDIATE-FORCE-MODEP    forced hypotheses are not attacked immediately

     General Form:
     ACL2 !>:disable-immediate-force-modep

This event causes ACL2 to delay forced hypotheses to the next forcing
round, rather than attacking them immediately.  See *note
IMMEDIATE-FORCE-MODEP::.  Or for more basic information, first see
*note FORCE:: for a discussion of forced case splits.

Disable-immediate-force-modep is a macro that disables the executable
counterpart of the function symbol immediate-force-modep.  When you
want to disable this mode in hints, use a form such as one of the
following (these are equivalent).

     :in-theory (disable (:executable-counterpart immediate-force-modep))
     :in-theory (disable (immediate-force-modep))


File: acl2-doc-emacs.info,  Node: DISABLEDP,  Next: DO-NOT,  Prev: DISABLE-IMMEDIATE-FORCE-MODEP,  Up: MISCELLANEOUS

DISABLEDP    determine whether a given name or rune is disabled

     Examples:

     :disabledp foo   ; returns a list of all disabled runes whose base
                      ; symbol is foo (see *note RUNE::)
     (disabledp 'foo) ; same as above (i.e., :disabledp foo)
     :disabledp (:rewrite bar . 1) ; returns t if the indicated rune is
                                   ; disabled, else nil
     (disabledp (:rewrite bar . 1)); same as immediately above

Also see *note PR::, which gives much more information about the rules
associated with a given event.

Disabledp takes one argument, an event name (see *note EVENTS::) other
than nil or a rune.  In the former case it returns the list of disabled
runes associated with that name, in the sense that the rune's "base
symbol" is that name (see *note RUNE::) or, if the event named is a
defmacro event, then the list of disabled runes associated with the
function corresponding to that macro name, if any (see *note
MACRO-ALIASES-TABLE::).  In the latter case, where the argument is a
rune, disabledp returns t if the rune is disabled, and nil otherwise.


File: acl2-doc-emacs.info,  Node: DO-NOT,  Next: DO-NOT-INDUCT,  Prev: DISABLEDP,  Up: MISCELLANEOUS

DO-NOT    hints keyword :DO-NOT

See *note HINTS::.


File: acl2-doc-emacs.info,  Node: DO-NOT-INDUCT,  Next: DOUBLE-REWRITE,  Prev: DO-NOT,  Up: MISCELLANEOUS

DO-NOT-INDUCT    hints keyword :DO-NOT-INDUCT

See *note HINTS::.


File: acl2-doc-emacs.info,  Node: DOUBLE-REWRITE,  Next: EMBEDDED-EVENT-FORM,  Prev: DO-NOT-INDUCT,  Up: MISCELLANEOUS

DOUBLE-REWRITE    cause a term to be rewritten twice

Logically, double-rewrite is the identity function: (double-rewrite x)
is equal to x.  However, the ACL2 rewriter treats calls of
double-rewrite in the following special manner.  When it encounters a
term (double-rewrite u), it first rewrites u in the current context,
and then the rewriter rewrites the result.

Such double-rewriting is rarely necessary, but it can be useful when
rewriting under non-trivial equivalence relations (see *note
EQUIVALENCE::).  The following example will illustrate the issue.

     ; Define an equivalence relation.
     (defun my-equiv (x y)
       (equal x y))
     (defequiv my-equiv)

     ; Define a unary function whose argument is preserved by my-equiv.
     (defun foo (x)
       (declare (ignore x))
       t)
     (defcong my-equiv equal (foo x) 1)

     ; Define some other unary functions.
     (defun g (x) x)
     (defun h1 (x) x)
     (defun h2 (x) x)

     ; Prove some lemmas and then disable the functions above.
     (defthm lemma-1
       (my-equiv (h1 x) (h2 x)))
     (defthm lemma-2
       (foo (h2 x)))
     (defthm lemma-3
       (implies (foo x)
                (equal (g x) x)))
     (in-theory (union-theories (theory 'minimal-theory)
                                '(lemma-1 lemma-2 lemma-3
                                  my-equiv-implies-equal-foo-1)))

     ; Attempt to prove a simple theorem that follows ``obviously'' from the
     ; events above.
     (thm (equal (g (h1 a)) (h1 a)))

We might expect the proof of this final thm to succeed by the following
reasoning.  It is immediate from lemma-3 provided we can establish (foo
(h1 a)).  By the defcong event above, we know that (foo (h1 a)) equals
(foo (h2 a)) provided (my-equiv (h1 a) (h2 a)); but this is immediate
from lemma-1.  And finally, (foo (h2 a)) is true by lemma-2.

Unfortunately, the proof fails.  But fortunately, ACL2 gives the
following useful warning when lemma-3 is submitted:

     ACL2 Warning [Double-rewrite] in ( DEFTHM LEMMA-3 ...):  In the :REWRITE
     rule generated from LEMMA-3, equivalence relation MY-EQUIV is maintained
     at one problematic occurrence of variable X in hypothesis (FOO X),
     but not at any binding occurrence of X.  Consider replacing that occurrence
     of X in this hypothesis with (DOUBLE-REWRITE X).  See :doc double-
     rewrite for more information on this issue.

We can follow the warning's advice by changing lemma-3 to the following.

     (defthm lemma-3
       (implies (foo (double-rewrite x))
                (equal (g x) x)))

With this change, the proof succeeds for the final thm above.

In practice, it should suffice for users to follow the advice given in
the "Double-rewrite" warnings, by adding calls of double-rewrite around
certain variable occurrences.  But this can cause inefficiency in large
proof efforts.  For that reason, and for completeness, it seems prudent
to explain more carefully what is going on; and that is what we do for
the remainder of this documentation topic.  Optionally, also see the
paper "Double Rewriting for Equivalential Reasoning in ACL2" by Matt
Kaufmann and J Strother Moore, in the proceedings of the 2006 ACL2
Workshop (paper is published in ACM Digital Library,
`http://portal.acm.org/toc.cfm?id=1217975').

*Suggesting congruence rules.*

Sometimes the best way to respond to a "Double-rewrite" warning may be
to prove a congruence rule.  Consider for example this rule.

     (defthm insert-sort-is-id
       (perm (insert-sort x) x))

Assuming that perm has been identified as an equivalence relation (see
*note DEFEQUIV::), we will get the following warning.

     ACL2 Warning [Double-rewrite] in ( DEFTHM INSERT-SORT-IS-ID ...):
     In a :REWRITE rule generated from INSERT-SORT-IS-ID, equivalence relation
     PERM is maintained at one problematic occurrence of variable X in the
     right-hand side, but not at any binding occurrence of X.  Consider
     replacing that occurrence of X in the right-hand side with
     (DOUBLE-REWRITE X).  See :doc double-rewrite for more information on
     this issue.

The problem is that the second occurrence of x (the right-hand side of
the rule insert-sort-is-id) is in a context where perm is to be
maintained, yet in this example, the argument x of insert-sort on the
left-hand side of that rule is in a context where perm will not be
maintained.  This can lead one to consider the possibility that perm
could be maintained in that left-hand side occurrence of x, and if so,
to prove the following congruence rule.

     (defcong perm perm (insert-sort x) 1)

This will eliminate the above warning for insert-sort-is-id.  More
important, this defcong event would probably be useful, since it would
allow rewrite rules with equivalence relation perm to operate on the
first argument of any call of insert-sort whose context calls for
maintaining perm.

*Details on double-rewrite.*

The reader who wants these details may first wish to see *note
EQUIVALENCE:: for relevant review.

The ACL2 rewriter takes a number of contextual arguments, including the
generated equivalence relation being maintained (see *note
CONGRUENCE::) and an association list that maps variables to terms.  We
call the latter alist the unify-subst because it is produced by unifying
(actually matching) a pattern against a current term; let us explain
this point by returning to the example above.  Consider what happens
when the rewriter is given the top-level goal of the thm above.

     (equal (g (h1 a)) (h1 a))

This rewrite is performed with the empty alist (unify-subst), and is
begun by rewriting the first argument (in that same empty unify-subst):

     (g (h1 a))

Note that the only equivalence relation being maintained at this point
is equal.  Now, the rewriter notices that the left-hand side of lemma-3,
which is (g x), matches (g (h1 a)).  The rewriter thus creates a
unify-subst binding x to (h1 a): ((x . (h1 a))).  It now attempts to
rewrite the hypothesis of lemma-3 to t under this unify-subst.

Consider what happens now if the hypothesis of lemma-3 is (foo x).  To
rewrite this hypothesis under a unify-subst of ((x . (h1 a))), it will
first rewrite x under this unify-subst.  The key observation here is
that this rewrite takes place simply by returning the value of x in the
unify-subst, namely (h1 a).  No further rewriting is done!  The
efficiency of the ACL2 rewriter depends on such caching of previous
rewriting results.

But suppose that, instead, the hypothesis of lemma-3 is (foo
(double-rewrite x)).  As before, the rewriter dives to the first
argument of this call of foo.  But this time the rewriter sees the call
(double-rewrite x), which it handles as follows.  First, x is rewritten
as before, yielding (h1 a).  But now, because of the call of
double-rewrite, the rewriter takes (h1 a) and rewrites it under the
empty unify-subst.  What's more, because of the defcong event above,
this rewrite takes place in a context where it suffices to maintain the
equivalence relation my-equiv.  This allows for the application of
lemma-1, hence (h1 a) is rewritten (under unify-subst = nil) to (h2 a).
Popping back up, the rewriter will now rewrite the call of foo to t
using lemma-2.

The example above explains how the rewriter treats calls of
double-rewrite, but it may leave the unfortunate impression that the
user needs to consider each :rewrite or :linear rule carefully, just in
case a call of double-rewrite may be appropriate.  Fortunately, ACL2
provides a "[Double-rewrite]" warning to inform the user of just this
sort of situation.  If you don't see this warning when you submit a
(:rewrite or :linear) rule, then the issue described here shouldn't
come up for that rule.  Such warnings may appear for hypotheses or
right-hand side of a :rewrite rule, and for hypotheses or full
conclusion (as opposed to just the trigger term) of a :linear rule.

If you do see a "[Double-rewrite]" warning, then should you add the
indicated call(s) of double-rewrite?  At the time of writing this
documentation, the answer is not clear.  Early experiments with double
rewriting suggested that it may be too expensive to call double-rewrite
in every instance where a warning indicates that there could be an
advantage to doing so.  And at the time of this writing, the ACL2
regression suite has about 1900 such warnings (but note that books were
developed before double-rewrite or the "[Double-rewrite]" warning were
implemented), which suggests that one can often do fine just ignoring
such warnings.  However, it seems advisable to go ahead and add the
calls of double-rewrite indicated by the warnings unless you run across
efficiency problems caused by doing so.  Of course, if you decide to
ignore all such warnings you can execute the event:
(set-inhibit-warnings "Double-rewrite").

Finally, we note that it is generally not necessary to call
double-rewrite in order to get its effect in the following case, where
the discussion above might have led one to consider a call of
double-rewrite: a hypothesis is a variable, or more generally, we are
considering a variable occurrence that is a branch of the top-level IF
structure of a hypothesis.  The automatic handling of this case, by a
form of double rewriting, was instituted in ACL2 Version_2.9 and
remains in place with the introduction of double-rewrite.  Here is a
simple illustrative example.  Notice that foo-holds applies to prove
the final thm below, even without a call of double-rewrite in the
hypothesis of foo-holds, and that there is no "[Double-rewrite]"
warning when submitting foo-holds.

     (encapsulate
      (((foo *) => *)
       ((bar *) => *))

      (local (defun foo (x) (declare (ignore x)) t))
      (local (defun bar (x) (declare (ignore x)) t))

      (defthm foo-holds
        (implies x
                 (equal (foo x) t)))
      (defthm bar-holds-propositionally
        (iff (bar x) t)))

     (thm (foo (bar y)))


File: acl2-doc-emacs.info,  Node: EMBEDDED-EVENT-FORM,  Next: ENABLE-FORCING,  Prev: DOUBLE-REWRITE,  Up: MISCELLANEOUS

EMBEDDED-EVENT-FORM    forms that may be embedded in other events

     Examples:
     (defun hd (x) (if (consp x) (car x) 0))
     (local (defthm lemma23 ...))
     (progn (defun fn1 ...)
            (local (defun fn2 ...))
            ...)

     General Form:
     An embedded event form is a term, x, such that:

     o x is a call of an event function other than DEFPKG (see *note
     EVENTS:: for a listing of the event functions);

     o x is of the form (LOCAL x1) where x1 is an embedded event form;

     o x is of the form (SKIP-PROOFS x1) where x1 is an embedded event
     form;

     o x is of the form (MAKE-EVENT &), where & is any term whose
     expansion is an embedded event (see *note MAKE-EVENT::);

     o x is of the form (WITH-OUTPUT ... x1), (WITH-PROVER-STEP-LIMIT
     ... x1 ...), or (WITH-PROVER-TIME-LIMIT ... x1), where x1 is an
     embedded event form;

     o x is a call of ENCAPSULATE, PROGN, PROGN!, or INCLUDE-BOOK;

     o x macroexpands to one of the forms above; or

     o [intended only for the implementation] x is (RECORD-EXPANSION x1
     x2), where x1 and x2 are embedded event forms.


An exception: an embedded event form may not set the
acl2-defaults-table when in the context of local.  Thus for example,
the form

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

is not an embedded event form, nor is the form (local (program)), since
the latter sets the acl2-defaults-table implicitly.  An example at the
end of the discussion below illustrates why there is this restriction.

Only embedded event forms are allowed in a book after its initial
in-package form.  See *note BOOKS::.  However, you may find that
make-event allows you to get the effect you want for a form that is not
an embedded event form.  For example, you can put the following into a
book, which assigns the value 17 to state global variable x:

     (make-event (er-progn (assign x 17)
                           (value '(value-triple nil)))
                 :check-expansion t)

When an embedded event is executed while ld-skip-proofsp is
'include-book, those parts of it inside local forms are ignored.  Thus,

        (progn (defun f1 () 1)
               (local (defun f2 () 2))
               (defun f3 () 3))

will define f1, f2, and f3 when ld-skip-proofsp is nil or t, but will
define only f1 and f3 when ld-skip-proofsp is 'include-book.

_Discussion:_

Encapsulate, progn, and include-book place restrictions on the kinds of
forms that may be processed.  These restrictions ensure that the
non-local events are indeed admissible provided that the sequence of
local and non-local events is admissible when proofs are done, i.e.,
when ld-skip-proofs is nil.  But progn! places no such restrictions,
hence is potentially dangerous and should be avoided unless you
understand the ramifications; so it is illegal unless there is an active
trust tag (see *note DEFTTAG::).

Local permits the hiding of an event or group of events in the sense
that local events are processed when we are trying to establish the
admissibility of a sequence of events embedded in encapsulate forms or
in books, but are ignored when we are constructing the world produced
by assuming that sequence.  Thus, for example, a particularly ugly and
inefficient :rewrite rule might be made local to an encapsulate that
"exports" a desirable theorem whose proof requires the ugly lemma.

To see why we can't allow just anything as an embedded event, consider
allowing the form

     (if (ld-skip-proofsp state)
         (defun foo () 2)
         (defun foo () 1))

followed by

     (defthm foo-is-1 (equal (foo) 1)).

When we process the events with ld-skip-proofsp is nil, the second
defun is executed and the defthm succeeds.  But when we process the
events with ld-skip-proofsp 'include-book, the second defun is
executed, so that foo no longer has the same definition it did when we
proved foo-is-1.  Thus, an invalid formula is assumed when we process
the defthm while skipping proofs.  Thus, the first form above is not a
legal embedded event form.

If you encounter a situation where these restrictions seem to prevent
you from doing what you want to do, then you may find make-event to be
helpful.  See *note MAKE-EVENT::.

Defpkg is not allowed because it affects how things are read after it
is executed.  But all the forms embedded in an event are read before
any are executed.  That is,

     (encapsulate nil
                  (defpkg "MY-PKG" nil)
                  (defun foo () 'my-pkg::bar))

makes no sense since my-pkg::bar must have been read before the defpkg
for "MY-PKG" was executed.

Finally, let us elaborate on the restriction mentioned earlier related
to the acl2-defaults-table.  Consider the following form.

     (encapsulate
      ()
      (local (program))
      (defun foo (x)
        (if (equal 0 x)
            0
          (1+ (foo (- x))))))

See *note LOCAL-INCOMPATIBILITY:: for a discussion of how encapsulate
processes event forms.  Briefly, on the first pass through the events
the definition of foo will be accepted in defun mode :program, and
hence accepted.  But on the second pass the form (local (program)) is
skipped because it is marked as local, and hence foo is accepted in
defun mode :logic.  Yet, no proof has been performed in order to admit
foo, and in fact, it is not hard to prove a contradiction from this
definition!


File: acl2-doc-emacs.info,  Node: ENABLE-FORCING,  Next: ENABLE-IMMEDIATE-FORCE-MODEP,  Prev: EMBEDDED-EVENT-FORM,  Up: MISCELLANEOUS

ENABLE-FORCING    to allow forced splits

     General Form:
     ACL2 !>:enable-forcing    ; allowed forced case splits

See *note FORCE:: and see *note CASE-SPLIT:: for a discussion of forced
case splits, which are turned back on by this command.  (See *note
DISABLE-FORCING:: for how to turn them off.)

Enable-forcing is actually a macro that enables the executable
counterpart of the function symbol force; see *note FORCE::.  When you
want to use hints to turn on forced case splits, use a form such as one
of the following (these are equivalent).

     :in-theory (enable (:executable-counterpart force))
     :in-theory (enable (force))


File: acl2-doc-emacs.info,  Node: ENABLE-IMMEDIATE-FORCE-MODEP,  Next: ENTER-BOOT-STRAP-MODE,  Prev: ENABLE-FORCING,  Up: MISCELLANEOUS

ENABLE-IMMEDIATE-FORCE-MODEP    forced hypotheses are attacked immediately

     General Form:
     ACL2 !>:enable-immediate-force-modep

This event causes ACL2 to attack forced hypotheses immediately instead
of delaying them to the next forcing round.  See *note
IMMEDIATE-FORCE-MODEP::.  Or for more basic information, first see
*note FORCE:: for a discussion of forced case splits.

Enable-immediate-force-modep is a macro that enables the executable
counterpart of the function symbol immediate-force-modep.  When you
want to enable this mode in hints, use a form such as one of the
following (these are equivalent).

     :in-theory (enable (:executable-counterpart immediate-force-modep))
     :in-theory (enable (immediate-force-modep))


File: acl2-doc-emacs.info,  Node: ENTER-BOOT-STRAP-MODE,  Next: ESCAPE-TO-COMMON-LISP,  Prev: ENABLE-IMMEDIATE-FORCE-MODEP,  Up: MISCELLANEOUS

ENTER-BOOT-STRAP-MODE    The first millisecond of the Big Bang

ACL2 functions, e.g., if, that show enter-boot-strap-mode as their
defining command are in fact primitives.  It is impossible for the
system to display defining axioms about these symbols.

Enter-boot-strap-mode is a Common Lisp function but not an ACL2
function.  It magically creates from nil an ACL2 property list world
that lets us start the boot-strapping process.  That is, once
enter-boot-strap-mode has created its world, it is possible to process
the defconsts, defuns, and defaxioms, necessary to bring up the rest of
the system.  Before that world is created, the attempt by ACL2 even to
translate a defun form, say, would produce an error because defun is
undefined.

Several ACL2 functions show enter-boot-strap-mode as their defining
command.  Among them are if, cons, car, and cdr.  These functions are
characterized by axioms rather than definitional equations -- axioms
that in most cases are built into our code and hence do not have any
explicit representation among the rules and formulas in the system.


File: acl2-doc-emacs.info,  Node: ESCAPE-TO-COMMON-LISP,  Next: EXECUTABLE-COUNTERPART,  Prev: ENTER-BOOT-STRAP-MODE,  Up: MISCELLANEOUS

ESCAPE-TO-COMMON-LISP    escaping to Common Lisp

     Example:
     ACL2 !>:Q

There is no Common Lisp escape feature in the lp.  This is part of the
price of purity.  To execute a form in Common Lisp as opposed to ACL2,
exit lp with :q, submit the desired forms to the Common Lisp
read-eval-print loop, and reenter ACL2 with (lp).


File: acl2-doc-emacs.info,  Node: EXECUTABLE-COUNTERPART,  Next: EXIT-BOOT-STRAP-MODE,  Prev: ESCAPE-TO-COMMON-LISP,  Up: MISCELLANEOUS

EXECUTABLE-COUNTERPART    a rule for computing the value of a function

     Examples:
     (:executable-counterpart length)

which may be abbreviated in theories as

     (length)

Every defun introduces at least two rules used by the theorem prover.
Suppose fn is the name of a defun'd function.  Then (:definition fn) is
the rune (see *note RUNE::) naming the rule that allows the simplifier
to replace calls of fn by its instantiated body.
(:executable-counterpart fn) is the rune for the rule for how to
evaluate the function on known constants.

When typing theories it is convenient to know that (fn) is a runic
designator that denotes (:executable-counterpart fn).  See *note
THEORIES::.

If (:executable-counterpart fn) is enabled, then when applications of
fn to known constants are seen by the simplifier they are computed out
by executing the Common Lisp code for fn (with the appropriate handling
of guards).  Suppose fact is defined as the factorial function.  If the
executable counterpart rune of fact, (:executable-counterpart fact), is
enabled when the simplifier encounters (fact 12), then that term will
be "immediately" expanded to 479001600.  Note that even if subroutines
of fn have disabled executable counterparts, fn will call their Lisp
code nonetheless:  once an executable counterpart function is applied,
no subsidiary enable checks are made.

Such one-step expansions are sometimes counterproductive because they
prevent the anticipated application of certain lemmas about the
subroutines of the expanded function.  Such computed expansions can be
prevented by disabling the executable counterpart rune of the relevant
function.  For example, if (:executable-counterpart fact) is disabled,
(fact 12) will not be expanded by computation.  In this situation,
(fact 12) may be rewritten to (* 12 (fact 11)), using the rule named
(:definition fact), provided the system's heuristics permit the
introduction of the term (fact 11).  Note that lemmas about
multiplication may then be applicable (while such lemmas would be
inapplicable to 479001600).  In many proofs it is desirable to disable
the executable counterpart runes of certain functions to prevent their
expansion by computation.  See *note EXECUTABLE-COUNTERPART-THEORY::.

Finally:  What do we do about functions that are "constrained" rather
than defined, such as the following?  (See *note ENCAPSULATE::.)

     (encapsulate (((foo *) => *))
                  (local (defun foo (x) x)))

Does foo have an executable counterpart?  Yes:  since the vast majority
of functions have sensible executable counterparts, it was decided that
*all* functions, even such "constrained" ones, have executable
counterparts.  We essentially "trap" when such calls are inappropriate.
Thus, consider for example:

     (defun bar (x)
       (if (rationalp x)
           (+ x 1)
         (foo x)))

If the term (bar '3) is encountered by the ACL2 rewriter during a
proof, and if the :executable-counterpart of bar is enabled, then it
will be invoked to reduce this term to '4.  However, if the term (bar
'a) is encountered during a proof, then since 'a is not a rationalp and
since the :executable-counterpart of foo is only a "trap," then this
call of the :executable-counterpart of bar will result in a "trap." In
that case, the rewriter will return the term (hide (bar 'a)) so that it
never has to go through this process again.  See *note HIDE::.


File: acl2-doc-emacs.info,  Node: EXIT-BOOT-STRAP-MODE,  Next: EXPAND,  Prev: EXECUTABLE-COUNTERPART,  Up: MISCELLANEOUS

EXIT-BOOT-STRAP-MODE    the end of pre-history

Exit-boot-strap-mode is the last step in creating the ACL2 world in
which the user lives.  It has command number 0.  Commands before it are
part of the system initialization and extend all the way back to :min.
Commands after it are those of the user.

Exit-boot-strap-mode is a Common Lisp function but not an ACL2
function.  It is called when every defconst, defun, etc., in our source
code has been processed under ACL2 and the world is all but complete.
exit-boot-strap-mode has only one job: to signal the completion of the
boot-strapping.


File: acl2-doc-emacs.info,  Node: EXPAND,  Next: EXTENDED-METAFUNCTIONS,  Prev: EXIT-BOOT-STRAP-MODE,  Up: MISCELLANEOUS

EXPAND    hints keyword :EXPAND

See *note HINTS::.


File: acl2-doc-emacs.info,  Node: EXTENDED-METAFUNCTIONS,  Next: FAILED-FORCING,  Prev: EXPAND,  Up: MISCELLANEOUS

EXTENDED-METAFUNCTIONS    state and context sensitive metafunctions

     General Form of an Extended :Meta theorem:
     (implies (and (pseudo-termp x)              ; this hyp is optional
                   (alistp a)                    ; this hyp is optional
                   (ev (hyp-fn x mfc state) a)   ; this hyp is optional
                   ; meta-extract hyps may also be included (see below)
                   )
              (equiv (ev x a)
                     (ev (fn x mfc state) a)))

where the restrictions are as described in the documentation for meta
where state is literally the symbol STATE, and x, a, mfc, and state are
distinct variable symbols.  A :meta theorem of the above form installs
fn as a metatheoretic simplifier with hypothesis function hyp-fn,
exactly as for vanilla metafunctions.  The only difference is that when
the metafunctions are applied, some contextual information is passed in
via the mfc argument and the ACL2 state is made available.

See *note META:: for a discussion of vanilla flavored metafunctions.
This documentation assumes you are familiar with the simpler situation,
in particular, how to define a vanilla flavored metafunction, fn, and
its associated hypothesis metafunction, hyp-fn, and how to state and
prove metatheorems installing such functions.  Defining extended
metafunctions requires that you also be familiar with many ACL2
implementation details.  This documentation is sketchy on these
details; see the ACL2 source code or email the acl2-help list if you
need more help.

Additional hypotheses are supported, called "meta-extract hypotheses",
that allow metafunctions to depend on the validity of certain terms
extracted from the context or the logical world.  These hypotheses
provide an even more advanced form of metatheorem so we explain them
elsewhere; see *note META-EXTRACT::.

The metafunction context, mfc, is a list containing many different data
structures used by various internal ACL2 functions.  We do not document
the form of mfc.  Your extended metafunction should just take mfc as its
second formal and pass it into the functions mentioned below.  The ACL2
state is well-documented (see *note STATE::).  Below we present
expressions below that can be useful in defining extended
metafunctions.  Some of these expressions involve keyword arguments,
:forcep and :ttree, which are optional and in most cases are fine to
omit, and which we explain after we present the useful expressions.

(mfc-clause mfc): returns the current goal, in clausal form.  A clause
is a list of ACL2 terms, implicitly denoting the disjunction of the
listed terms.  The clause returned by mfc-clause is the clausal form of
the translation (see *note TRANS::) of the goal or subgoal on which the
rewriter is working.  When a metafunction calls mfc-clause, the term
being rewritten by the metafunction either occurs somewhere in this
clause or, perhaps more commonly, is being rewritten on behalf of some
lemma to which the rewriter has backchained while trying to rewrite a
term in the clause.

(mfc-ancestors mfc): returns an alist whose keys are the negations of
the backchaining hypotheses being pursued.  In particular, (null
(mfc-ancestors mfc)) will be true exactly when rewriting is on part of
the current goal.  Exception: An element of this alist whose key is of
the form (:binding-hyp hyp unify-subst) indicates that hyp has been
encountered as a hypothesis of the form (equal var term) or (equiv var
(double-rewrite-term)), in each case binding variable var to the result
of rewriting term under unify-subst.

(mfc-rdepth mfc): returns the remaining stack depth for calls of the
rewriter (by default, *default-rewrite-stack-limit* at the top level;
see *note REWRITE-STACK-LIMIT::).  When this is 0, no further calls of
the rewriter can be made without error.

(mfc-type-alist mfc): returns the type-alist governing the occurrence of
the term, x, being rewritten by the metafunction.  A type-alist is an
association list, each element of which is of the form (term ts .
ttree).  Such an element means that the term term has the type-set ts.
The ttree component is probably irrelevant here.  All the terms in the
type-alist are in translated form (see *note TRANS::).  The ts are
numbers denoting finite Boolean combinations of ACL2's primitive types
(see *note TYPE-SET::).  The type-alist includes not only information
gleaned from the conditions governing the term being rewritten but also
that gleaned from forward chaining from the (negations of the) other
literals in the clause returned by mfc-clause.

(mfc-unify-subst mfc): returns nil except when evaluating a syntaxp or
bind-free hypothesis, in which case, returns the unifying substitution
present at the start of that evaluation.

(mfc-world mfc): returns the ACL2 logical world.

(mfc-ts term mfc state :forcep forcep :ttreep ttreep): returns the
type-set of term in the current context; see *note TYPE-SET::.

(mfc-rw term obj equiv-info mfc state): returns the result of rewriting
term in the current context, mfc, with objective obj and the
equivalence relation described by equiv-info.  Obj should be t, nil, or
?, and describes your objective: try to show that term is true, false,
or anything.  Equiv-info is either nil, t, a function symbol fn naming
a known equivalence relation, or a list of congruence rules.  Nil means
return a term that is equal to term.  T means return a term that is
propositionally equivalent (i.e., in the iff sense) to term, while fn
means return a term fn-equivalent to term.  The final case, which is
intended only for advanced users, allows the specification of generated
equivalence relations, as supplied to the geneqv argument of rewrite.
Generally, if you wish to establish that term is true in the current
context, use the idiom

     (equal (mfc-rw term t t mfc state) *t*)

The constant *t* is set to the internal form of the constant term t,
i.e., 't.

(mfc-rw+ term alist obj equiv-info mfc state): if alist is nil then
this is equivalent to (mfc-rw term obj equiv-info mfc state).  However,
the former takes an argument, alist, that binds variables to terms, and
returns the result of rewriting term under that alist, where this
rewriting is as described for mfc-rw above.  The function mfc-rw+ can
be more efficient than mfc-rw, because the terms in the binding alist
have generally already been rewritten, and it can be inefficient to
rewrite them again.  For example, consider a rewrite rule of the
following form.

     (implies (and ...
                   (syntaxp (... (mfc-rw `(bar ,x) ...) ...))
                   ...)
              (equal (... x ...) ...))

Here, x is bound in the conclusion to the result of rewriting some term,
say, tm.  Then the above call of mfc-rw will rewrite tm, which is
probably unnecessary.  So a preferable form of the rule above may be as
follows, so that tm is not further rewritten by mfc-rw+.

     (implies (and ...
                   (syntaxp (... (mfc-rw+ '(bar v) `((v . ,x)) ...) ...))
                   ...)
              (equal (... x ...) ...))

However, you may find that the additional rewriting done by mfc-rw is
useful in some cases.

(mfc-ap term mfc state): returns t or nil according to whether linear
arithmetic can determine that term is false.  To the cognoscenti:
returns the contradiction flag produced by linearizing term and adding
it to the linear-pot-lst.

(mfc-relieve-hyp hyp alist rune target bkptr mfc state): returns t or
nil according to whether the indicated hypothesis term, hyp, can be
relieved (proved) under the giving variable bindings, alist.  Note that
this function returns nil if hyp has free variables (see *note
FREE-VARIABLES::).  Here, hyp is the hypothesis of the indicated rune
at (one-based) position bkptr, and target is an instantiated term to
which rune is being applied.  Note that no indication is returned for
whether any assumptions have been generated by force or case-split.
(If you need such a feature, feel free to request it of the ACL2
implementors.)

We explain the :forcep and :ttreep keyword arguments provided in some
expressions, as promised above.  Their defaults are :same and nil,
respectively.  A value of :same for :forcep means that forcing will be
allowed if and only if it is allowed in the current rewriting
environment; see *note FORCE::.  A value of t or nil for :forcep
overrides this default and allows or disallows forcing, respectively.
By default these functions return a single value, val, but if :ttreep
is t then they return (mv val ttree), where ttree is the tag-tree (see
*note TTREE::) returned by the indicated operation, with an input
tag-tree of nil).

During the execution of a metafunction by the theorem prover, the
expressions above compute the results specified.  Typically, you should
imagine that there are no axioms about the mfc- function symbols: treat
them as uninterpreted function symbols.  There is an advanced feature,
meta-extract hypotheses, that can avoid this logical weakness in some
cases when proving :meta rules; see *note META-EXTRACT::.  But we
assume for the rest of the present documentation topic that you do not
use meta-extract hypotheses.  Thus, in the proof of the correctness of
a metafunction, no information is available about the results of these
functions: you should _use these functions for heuristic purposes only_.

For example, your metafunction may use these functions to decide
whether to perform a given transformation, but the transformation must
be sound regardless of the value that your metafunction returns.  We
illustrate this below.  It is sometimes possible to use the hypothesis
metafunction, hyp-fn, to generate a sufficient hypothesis to justify the
transformation.  The generated hypothesis might have already been
"proved" internally by your use of mfc-ts or mfc-rw, but the system
will have to prove it "officially" by relieving it.  We illustrate this
below also.

We conclude with a script that defines, verifies, and uses several
extended metafunctions.  This script is based on one provided by Robert
Krug, who was instrumental in the development of this style of
metafunction and whose help we gratefully acknowledge.


     ; Here is an example.  I will define (foo i j) simply to be (+ i j).
     ; But I will keep its definition disabled so the theorem prover
     ; doesn't know that.  Then I will define an extended metafunction
     ; that reduces (foo i (- i)) to 0 provided i has integer type and the
     ; expression (< 10 i) occurs as a hypothesis in the clause.

     ; Note that (foo i (- i)) is 0 in any case.

     (defun foo (i j) (+ i j))

     (defevaluator eva eva-lst ((foo i j)
                                (unary-- i)

     ; I won't need these two cases until the last example below, but I
     ; include them now.

                                (if x y z)
                                (integerp x)))

     (set-state-ok t)

     (defun metafn (x mfc state)
       (cond
        ((and (consp x)
              (equal (car x) 'foo)
              (equal (caddr x) (list 'unary-- (cadr x))))

     ; So x is of the form (foo i (- i)).  Now I want to check some other
     ; conditions.

         (cond ((and (ts-subsetp (mfc-ts (cadr x) mfc state)
                                 *ts-integer*)
                     (member-equal `(NOT (< '10 ,(cadr x)))
                                   (mfc-clause mfc)))
                (quote (quote 0)))
               (t x)))
        (t x)))

     (defthm metafn-correct
       (equal (eva x a) (eva (metafn x mfc state) a))
       :rule-classes ((:meta :trigger-fns (foo))))

     (in-theory (disable foo))

     ; The following will fail because the metafunction won't fire.
     ; We don't know enough about i.

     (thm (equal (foo i (- i)) 0))

     ; Same here.

     (thm (implies (and (integerp i) (< 0 i)) (equal (foo i (- i)) 0)))

     ; But this will work.

     (thm (implies (and (integerp i) (< 10 i))
                   (equal (foo i (- i)) 0)))

     ; This won't, because the metafunction looks for (< 10 i) literally,
     ; not just something that implies it.

     (thm (implies (and (integerp i) (< 11 i))
                   (equal (foo i (- i)) 0)))

     ; Now I will undo the defun of metafn and repeat the exercise, but
     ; this time check the weaker condition that (< 10 i) is provable
     ; (by rewriting it) rather than explicitly present.

     (ubt 'metafn)

     (defun metafn (x mfc state)
       (cond
        ((and (consp x)
              (equal (car x) 'foo)
              (equal (caddr x) (list 'unary-- (cadr x))))
         (cond ((and (ts-subsetp (mfc-ts (cadr x) mfc state)
                                 *ts-integer*)
                     (equal (mfc-rw `(< '10 ,(cadr x)) t t mfc state)
                            *t*))

     ; The mfc-rw above rewrites (< 10 i) with objective t and iffp t.  The
     ; objective means the theorem prover will try to establish it.  The
     ; iffp means the theorem prover can rewrite maintaining propositional
     ; equivalence instead of strict equality.

                (quote (quote 0)))
               (t x)))
        (t x)))

     (defthm metafn-correct
       (equal (eva x a) (eva (metafn x mfc state) a))
       :rule-classes ((:meta :trigger-fns (foo))))

     (in-theory (disable foo))

     ; Now it will prove both:

     (thm (implies (and (integerp i) (< 10 i))
                   (equal (foo i (- i)) 0)))

     (thm (implies (and (integerp i) (< 11 i))
                   (equal (foo i (- i)) 0)))

     ; Now I undo the defun of metafn and change the problem entirely.
     ; This time I will rewrite (integerp (foo i j)) to t.  Note that
     ; this is true if i and j are integers.  I can check this
     ; internally, but have to generate a hyp-fn to make it official.

     (ubt 'metafn)

     (defun metafn (x mfc state)
       (cond
        ((and (consp x)
              (equal (car x) 'integerp)
              (consp (cadr x))
              (equal (car (cadr x)) 'foo))

     ; So x is (integerp (foo i j)).  Now check that i and j are
     ; ``probably'' integers.

         (cond ((and (ts-subsetp (mfc-ts (cadr (cadr x)) mfc state)
                                 *ts-integer*)
                     (ts-subsetp (mfc-ts (caddr (cadr x)) mfc state)
                                 *ts-integer*))
                *t*)
               (t x)))
        (t x)))

     ; To justify this transformation, I generate the appropriate hyps.

     (defun hyp-fn (x mfc state)

       (declare (ignore mfc state))

     ; The hyp-fn is run only if the metafn produces an answer different
     ; from its input.  Thus, we know at execution time that x is of the
     ; form (integerp (foo i j)) and we know that metafn rewrote
     ; (integerp i) and (integerp j) both to t.  So we just produce their
     ; conjunction.  Note that we must produce a translated term; we
     ; cannot use the macro AND and must quote constants!  Sometimes you
     ; must do tests in the hyp-fn to figure out which case the metafn
     ; produced, but not in this example.

                `(if (integerp ,(cadr (cadr x)))
                     (integerp ,(caddr (cadr x)))
                     'nil))

     (defthm metafn-correct
       (implies (eva (hyp-fn x mfc state) a)
                (equal (eva x a) (eva (metafn x mfc state) a)))
       :rule-classes ((:meta :trigger-fns (integerp))))

     (in-theory (disable foo))

     ; This will not be proved.

     (thm (implies (and (rationalp x) (integerp i)) (integerp (foo i j))))

     ; But this will be.

     (thm (implies (and (rationalp x)
                        (integerp i)
                        (integerp j))
                   (integerp (foo i j))))


File: acl2-doc-emacs.info,  Node: FAILED-FORCING,  Next: FAILURE,  Prev: EXTENDED-METAFUNCTIONS,  Up: MISCELLANEOUS

FAILED-FORCING    how to deal with a proof failure in a forcing round

See *note FORCING-ROUND:: for a background discussion of the notion of
forcing rounds.  When a proof fails during a forcing round it means
that the "gist" of the proof succeeded but some "technical detail"
failed.  The first question you must ask yourself is whether the forced
goals are indeed theorems.  We discuss the possibilities below.

If you believe the forced goals are theorems, you should follow the
usual methodology for "fixing" failed ACL2 proofs, e.g., the
identification of key lemmas and their timely and proper use as rules.
See *note FAILURE::, see *note GAG-MODE::, and see *note PROOF-TREE::.

The rules designed for the goals of forcing rounds are often just what
is needed to prove the forced hypothesis at the time it is forced.
Thus, you may find that when the system has been "taught" how to prove
the goals of the forcing round no forcing round is needed.  This is
intended as a feature to help structure the discovery of the necessary
rules.

If a hint must be provided to prove a goal in a forcing round, the
appropriate "goal specifier" (the string used to identify the goal to
which the hint is to be applied) is just the text printed on the line
above the formula, e.g., "[1]Subgoal *1/3"".  See *note GOAL-SPEC::.

If you solve a forcing problem by giving explicit hints for the goals
of forcing rounds, you might consider whether you could avoid forcing
the assumption in the first place by giving those hints in the
appropriate places of the main proof.  This is one reason that we print
out the origins of each forced assumption.  An argument against this
style, however, is that an assumption might be forced in hundreds of
places in the main goal and proved only once in the forcing round, so
that by delaying the proof you actually save time.

We now turn to the possibility that some goal in the forcing round is
not a theorem.

There are two possibilities to consider.  The first is that the
original theorem has insufficient hypotheses to ensure that all the
forced hypotheses are in fact always true.  The "fix" in this case is
to amend the original conjecture so that it has adequate hypotheses.

A more difficult situation can arise and that is when the conjecture
has sufficient hypotheses but they are not present in the forcing round
goal.  This can be caused by what we call "premature" forcing.

Because ACL2 rewrites from the inside out, it is possible that it will
force hypotheses while the context is insufficient to establish them.
Consider trying to prove (p x (foo x)).  We first rewrite the formula
in an empty context, i.e., assuming nothing.  Thus, we rewrite (foo x)
in an empty context.  If rewriting (foo x) forces anything, that forced
assumption will have to be proved in an empty context.  This will
likely be impossible.

On the other hand, suppose we did not attack (foo x) until after we had
expanded p.  We might find that the value of its second argument, (foo
x), is relevant only in some cases and in those cases we might be able
to establish the hypotheses forced by (foo x).  Our premature forcing
is thus seen to be a consequence of our "over eager" rewriting.

Here, just for concreteness, is an example you can try.  In this
example, (foo x) rewrites to x but has a forced hypothesis of
(rationalp x).  P does a case split on that very hypothesis and uses
its second argument only when x is known to be rational.  Thus, the
hypothesis for the (foo x) rewrite is satisfied.  On the false branch
of its case split, p simplies to (p1 x) which can be proved under the
assumption that x is not rational.

     (defun p1 (x) (not (rationalp x)))
     (defun p (x y)(if (rationalp x) (equal x y) (p1 x)))
     (defun foo (x) x)
     (defthm foo-rewrite (implies (force (rationalp x)) (equal (foo x) x)))
     (in-theory (disable foo))

The attempt then to do (thm (p x (foo x))) forces the unprovable goal
(rationalp x).

Since all "formulas" are presented to the theorem prover as single
terms with no hypotheses (e.g., since implies is a function), this
problem would occur routinely were it not for the fact that the theorem
prover expands certain "simple" definitions immediately without doing
anything that can cause a hypothesis to be forced.  See *note SIMPLE::.
This does not solve the problem, since it is possible to hide the
propositional structure arbitrarily deeply.  For example, one could
define p, above, recursively so that the test that x is rational and
the subsequent first "real" use of y occurred arbitrarily deeply.

Therefore, the problem remains: what do you do if an impossible goal is
forced and yet you know that the original conjecture was adequately
protected by hypotheses?

One alternative is to disable forcing entirely.  See *note
DISABLE-FORCING::.  Another is to disable the rule that caused the
force.

A third alternative is to prove that the negation of the main goal
implies the forced hypothesis.  For example,

     (defthm not-p-implies-rationalp
       (implies (not (p x (foo x))) (rationalp x))
       :rule-classes nil)

Observe that we make no rules from this formula.  Instead, we merely
:use it in the subgoal where we must establish (rationalp x).

     (thm (p x (foo x))
          :hints (("Goal" :use not-p-implies-rationalp)))

When we said, above, that (p x (foo x)) is first rewritten in an empty
context we were misrepresenting the situation slightly.  When we
rewrite a literal we know what literal we are rewriting and we
implicitly assume it false.  This assumption is "dangerous" in that it
can lead us to simplify our goal to nil and give up -- we have even
seen people make the mistake of assuming the negation of what they
wished to prove and then via a very complicated series of
transformations convince themselves that the formula is false.  Because
of this "tail biting" we make very weak use of the negation of our
goal.  But the use we make of it is sufficient to establish the forced
hypothesis above.

A fourth alternative is to weaken your desired theorem so as to make
explicit the required hypotheses, e.g., to prove

     (defthm rationalp-implies-main
       (implies (rationalp x) (p x (foo x)))
       :rule-classes nil)

This of course is unsatisfying because it is not what you originally
intended.  But all is not lost.  You can now prove your main theorem
from this one, letting the implies here provide the necessary case
split.

     (thm (p x (foo x))
          :hints (("Goal" :use rationalp-implies-main)))


File: acl2-doc-emacs.info,  Node: FAILURE,  Next: FIND-RULES-OF-RUNE,  Prev: FAILED-FORCING,  Up: MISCELLANEOUS

FAILURE    how to deal with a proof failure

When ACL2 gives up it does not mean that the submitted conjecture is
invalid, even if the last formula ACL2 printed in its proof attempt is
manifestly false.  Since ACL2 sometimes generalizes the goal being
proved, it is possible it adopted an invalid subgoal as a legitimate
(but doomed) strategy for proving a valid goal.  Nevertheless,
conjectures submitted to ACL2 are often invalid and the proof attempt
often leads the careful reader to the realization that a hypothesis has
been omitted or that some special case has been forgotten.  It is good
practice to ask yourself, when you see a proof attempt fail, whether
the conjecture submitted is actually a theorem.

If you think the conjecture is a theorem, then you must figure out from
ACL2's output what you know that ACL2 doesn't about the functions in the
conjecture and how to impart that knowledge to ACL2 in the form of
rules.  The "key checkpoint" information printed at the end of the
summary provides a fine place to start.  See *note THE-METHOD:: for a
general discussion of how to prove theorems with ACL2, and see *note
INTRODUCTION-TO-THE-THEOREM-PROVER:: for a more detailed tutorial.
Also see *note SET-GAG-MODE:: for discussion of key checkpoints and an
abbreviated output mode that focuses attention on them.  You may find
it most useful to start by focusing on key checkpoints that are not
under a proof by induction, if any, both because these are more likely
to suggest useful lemmas and because they are more likely to be
theorems; for example, generalization may have occurred before a proof
by induction has begun.  If you need more information than is provided
by the key checkpoints -- although this should rarely be necessary --
then you can look at the full proof, perhaps with the aid of certain
utilities: see *note PROOF-TREE::, see *note SET-GAG-MODE::, and see
*note SET-SAVED-OUTPUT::.

For information on a tool to help debug failures of encapsulate and
progn events, as well as certify-book failures, see *note REDO-FLAT::.

Again, see *note THE-METHOD:: for a general discussion of how to prove
theorems with ACL2, and see *note INTRODUCTION-TO-THE-THEOREM-PROVER::
for a more detailed tutorial.  See also the book "Computer-Aided
Reasoning: An Approach" (Kaufmann, Manolios, Moore), as well as the
discussion of how to read Nqthm proofs and how to use Nqthm rules in "A
Computational Logic Handbook" by Boyer and Moore (Academic Press, 1988).

If the failure occurred during a forcing round, see *note
FAILED-FORCING::.


File: acl2-doc-emacs.info,  Node: FIND-RULES-OF-RUNE,  Next: FINDING-DOCUMENTATION,  Prev: FAILURE,  Up: MISCELLANEOUS

FIND-RULES-OF-RUNE    find the rules named rune

     General Form:
     (find-rules-of-rune rune wrld)

This function finds all the rules in wrld with :rune rune.  It returns
a list of rules in their internal form (generally as described by the
corresponding defrec).  Decyphering these rules is difficult since one
cannot always look at a rule object and decide what kind of record it
is without exploiting many system invariants (e.g., that :rewrite runes
only name rewrite-rules).

At the moment this function returns nil if the rune in question is a
:refinement rune, because there is no object representing :refinement
rules.  (:refinement rules cause changes in the 'coarsenings
properties.)  In addition, if the rune is an :equivalence rune, then
congruence rules with that rune will be returned -- because
:equivalence lemmas generate some congruence rules -- but the fact that
a certain function is now known to be an equivalence relation is not
represented by any rule object and so no such rule is returned.  (The
fact that the function is an equivalence relation is encoded entirely
in its presence as a 'coarsening of equal.)


File: acl2-doc-emacs.info,  Node: FINDING-DOCUMENTATION,  Next: FNCALL-TERM,  Prev: FIND-RULES-OF-RUNE,  Up: MISCELLANEOUS

FINDING-DOCUMENTATION    searching the documentation

The :doc and :doc! commands will display, at the terminal,
documentation topics defined in ACL2 or in books that have already been
included.  The :docs command allows you to search the documentation at
the terminal.  See *note DOCS::.

But how can you find documentation for books that are not included in
the current ACL2 session?

The xdoc manual is a combined manual for the ACL2 sources and the
community books.  It is built using documentation not only from the
ACL2 sources (which is rearranged) but also from the community books
(whether included in the current session or not), using an "xdoc
processor" created by Jared Davis.  The ACL2 home page
(`http://www.cs.utexas.edu/users/moore/acl2/') has a link to this
manual, which as of this writing may be found directly by visiting the
following web page: `http://fv.centtech.com/acl2/latest/doc/'.  You can
build a local copy of this manual from the ACL2 Community Books,
following instructions in their Makefile.


File: acl2-doc-emacs.info,  Node: FNCALL-TERM,  Next: FORCE,  Prev: FINDING-DOCUMENTATION,  Up: MISCELLANEOUS

FNCALL-TERM    See *note META-EXTRACT::.


File: acl2-doc-emacs.info,  Node: FORCE,  Next: FORCED,  Prev: FNCALL-TERM,  Up: MISCELLANEOUS

FORCE    identity function used to force a hypothesis

Force is the identity function: (force x) is equal to x.  However, for
rules of many classes (see *note RULE-CLASSES::), a hypothesis of the
form (force term) is given special treatment, as described below.  This
treatment takes place for rule classes :rewrite, :linear,
:type-prescription, :definition, :meta (actually in that case, the
result of evaluating the hypothesis metafunction call), and
:forward-chaining.

When a hypothesis of a conditional rule (of one of the classes listed
above) has the form (force hyp), it is logically equivalent to hyp but
has a pragmatic effect.  In particular, when the rule is considered,
the needed instance of the hypothesis, hyp', may be assumed if the
usual process fails to prove it or its negation.  In that situation, if
the rule is eventually applied, then a special case is generated,
requiring the system to prove that hyp' is true in the current context.
The proofs of all such "forced assumptions" are, by default, delayed
until the successful completion of the main goal.  See *note
FORCING-ROUND:: and see *note IMMEDIATE-FORCE-MODEP::.

Forcing is generally used on hypotheses that are always expected to be
true, as is commonly the case for guards of functions.  All the power
of the theorem prover is brought to bear on a forced hypothesis and no
backtracking is possible.  Forced goals can be attacked immediately
(see *note IMMEDIATE-FORCE-MODEP::) or in a subsequent forcing round
(see *note FORCING-ROUND::).  Also see *note CASE-SPLIT:: for a related
utility.  If the :executable-counterpart of the function force is
disabled, then no hypothesis is forced.  For more on enabling and
disabling forcing, see *note ENABLE-FORCING:: and see *note
DISABLE-FORCING::.

It sometimes happens that a conditional rule is not applied because
some hypothesis, hyp, could not be relieved, even though the required
instance of hyp, hyp', can be shown true in the context.  This happens
when insufficient resources are brought to bear on hyp' at the time we
try to relieve it.  A sometimes desirable alternative behavior is for
the system to assume hyp', apply the rule, and to generate explicitly a
special case to show that hyp' is true in the context.  This is called
"forcing" hyp.  It can be arranged by restating the rule so that the
offending hypothesis, hyp, is embedded in a call of force, as in (force
hyp).  By using the :corollary field of the rule-classes entry, a
hypothesis can be forced without changing the statement of the theorem
from which the rule is derived.

Technically, force is just a function of one argument that returns that
argument.  It is generally enabled and hence evaporates during
simplification.  But its presence among the hypotheses of a conditional
rule causes case splitting to occur if the hypothesis cannot be
conventionally relieved.

Since a forced hypothesis must be provable whenever the rule is
otherwise applicable, forcing should be used only on hypotheses that
are expected always to be true.

A particularly common situation in which some hypotheses should be
forced is in "most general" type-prescription lemmas.  If a single
lemma describes the "expected" type of a function, for all "expected"
arguments, then it is probably a good idea to force the hypotheses of
the lemma.  Thus, every time a term involving the function arises, the
term will be given the expected type and its arguments will be required
to be of the expected type.  In applying this advice it might be wise
to avoid forcing those hypotheses that are in fact just type predicates
on the arguments, since the routine that applies type-prescription
lemmas has fairly thorough knowledge of the types of all terms.

Force can have the additional benefit of causing the ACL2 typing
mechanism to interact with the ACL2 rewriter to establish the
hypotheses of type-prescription rules.  To understand this remark,
think of the ACL2 type reasoning system as a rather primitive
rule-based theorem prover for questions about Common Lisp types, e.g.,
"does this expression produce a consp?"  "does this expression produce
some kind of ACL2 number, e.g., an integerp, a rationalp, or a
complex-rationalp?" etc.  It is driven by type-prescription rules.  To
relieve the hypotheses of such rules, the type system recursively
invokes itself.  This can be done for any hypothesis, whether it is
"type-like" or not, since any proposition, p, can be phrased as the
type-like question "does p produce an object of type nil?"  However, as
you might expect, the type system is not very good at establishing
hypotheses that are not type-like, unless they happen to be assumed
explicitly in the context in which the question is posed, e.g., "If p
produces a consp then does p produce nil?"  If type reasoning alone is
insufficient to prove some instance of a hypothesis, then the instance
will not be proved by the type system and a type-prescription rule with
that hypothesis will be inapplicable in that case.  But by embedding
such hypotheses in force expressions you can effectively cause the type
system to "punt" them to the rest of the theorem prover.  Of course, as
already noted, this should only be done on hypotheses that are "always
true."  In particular, if rewriting is required to establish some
hypothesis of a type-prescription rule, then the rule will be found
inapplicable because the hypothesis will not be established by type
reasoning alone.

The ACL2 rewriter uses the type reasoning system as a subsystem.  It is
therefore possible that the type system will force a hypothesis that
the rewriter could establish.  Before a forced hypothesis is reported
out of the rewriter, we try to establish it by rewriting.

This makes the following surprising behavior possible: A
type-prescription rule fails to apply because some true hypothesis is
not being relieved.  The user changes the rule so as to *force* the
hypothesis.  The system then applies the rule but reports no forcing.
How can this happen?  The type system "punted" the forced hypothesis to
the rewriter, which established it.

Finally, we should mention that the rewriter is never willing to force
when there is an if term present in the goal being simplified.  Since
and terms and or terms are merely abbreviations for if terms, they also
prevent forcing.  Note that if terms are ultimately eliminated using
the ordinary flow of the proof (but see *note
SET-CASE-SPLIT-LIMITATIONS::), allowing force ultimately to function as
intended.  Moreover, forcing can be disabled, as described above; also
see *note DISABLE-FORCING::.


File: acl2-doc-emacs.info,  Node: FORCED,  Next: FORCING-ROUND,  Prev: FORCE,  Up: MISCELLANEOUS

FORCED    See *note FORCE::.


File: acl2-doc-emacs.info,  Node: FORCING-ROUND,  Next: FUNCTIONAL-INSTANTIATION-IN-ACL2R,  Prev: FORCED,  Up: MISCELLANEOUS

FORCING-ROUND    a section of a proof dealing with forced assumptions

If ACL2 "forces" some hypothesis of some rule to be true, it is obliged
later to prove the hypothesis.  See *note FORCE::.  ACL2 delays the
consideration of forced hypotheses until the main goal has been proved.
It then undertakes a new round of proofs in which the main goal is
essentially the conjunction of all hypotheses forced in the preceding
proof.  Call this round of proofs the "Forcing Round."  Additional
hypotheses may be forced by the proofs in the Forcing Round.  The
attempt to prove these hypotheses is delayed until the Forcing Round
has been successfully completed.  Then a new Forcing Round is
undertaken to prove the recently forced hypotheses and this continues
until no hypotheses are forced.  Thus, there is a succession of Forcing
Rounds.

The Forcing Rounds are enumerated starting from 1.  The Goals and
Subgoals of a Forcing Round are printed with the round's number
displayed in square brackets.  Thus, "[1]Subgoal 1.3" means that the
goal in question is Subgoal 1.3 of the 1st forcing round.  To supply a
hint for use in the proof of that subgoal, you should use the goal
specifier "[1]Subgoal 1.3".  See *note GOAL-SPEC::.

When a round is successfully completed -- and for these purposes you
may think of the proof of the main goal as being the 0th forcing round
-- the system collects all of the assumptions forced by the
just-completed round.  Here, an assumption should be thought of as an
implication, (implies context hyp), where context describes the context
in which hyp was assumed true.  Before undertaking the proofs of these
assumptions, we try to "clean them up" in an effort to reduce the
amount of work required.  This is often possible because the forced
assumptions are generated by the same rule being applied repeatedly in
a given context.

By delaying and collecting the forced assumptions until the completion
of the "main goal" we gain two advantages.  First, the user gets
confirmation that the "gist" of the proof is complete and that all that
remains are "technical details."  Second, by delaying the proofs of the
forced assumptions ACL2 can undertake the proof of each assumption only
once, no matter how many times it was forced in the main goal.

In order to indicate which proof steps of the previous round were
responsible for which forced assumptions, we print a sentence
explaining the origins of each newly forced goal.  For example,

     [1]Subgoal 1, below, will focus on
     (GOOD-INPUTP (XTRANS I)),
     which was forced in
      Subgoal 14, above,
       by applying (:REWRITE PRED-CRUNCHER) to
       (PRED (XTRANS I) I),
      and
      Subgoal 28, above,
       by applying (:REWRITE PRED-CRUNCHER) to
       (PRED (XTRANS I) I).

In this entry, "[1]Subgoal 1" is the name of a goal which will be
proved in the next forcing round.  On the next line we display the
forced hypothesis, call it x, which is (good-inputp (xtrans i)) in this
example.  This term will be the conclusion of the new subgoal.  Since
the new subgoal will be printed in its entirety when its proof is
undertaken, we do not here exhibit the context in which x was forced.
The sentence then lists (possibly a succession of) a goal name from the
just-completed round and some step in the proof of that goal that
forced x.  In the example above we see that Subgoals 14 and 28 of the
just-completed proof forced (good-inputp (xtrans i)) by applying
(:rewrite pred-cruncher) to the term (pred (xtrans i) i).

If one were to inspect the theorem prover's description of the proof
steps applied to Subgoals 14 and 28 one would find the word "forced"
(or sometimes "forcibly") occurring in the commentary.  Whenever you
see that word in the output, you know you will get a subsequent forcing
round to deal with the hypotheses forced.  Similarly, if at the
beginning of a forcing round a rune is blamed for causing a force in
some subgoal, inspection of the commentary for that subgoal will reveal
the word "forced" after the rule name blamed.

Most forced hypotheses come from within the prover's simplifier.  When
the simplifier encounters a hypothesis of the form (force hyp) it first
attempts to establish it by rewriting hyp to, say, hyp'.  If the truth
or falsity of hyp' is known, forcing is not required.  Otherwise, the
simplifier actually forces hyp'.  That is, the x mentioned above is
hyp', not hyp, when the forced subgoal was generated by the simplifier.

Once the system has printed out the origins of the newly forced goals,
it proceeds to the next forcing round, where those goals are
individually displayed and attacked.

At the beginning of a forcing round, the enabled structure defaults to
the global enabled structure.  For example, suppose some rune, rune, is
globally enabled.  Suppose in some event you disable the rune at "Goal"
and successfully prove the goal but force "[1]Goal".  Then during the
proof of "[1]Goal", rune is enabled "again."  The right way to think
about this is that the rune is "still" enabled.  That is, it is enabled
globally and each forcing round resumes with the global enabled
structure.


File: acl2-doc-emacs.info,  Node: FUNCTIONAL-INSTANTIATION-IN-ACL2R,  Next: GAG-MODE,  Prev: FORCING-ROUND,  Up: MISCELLANEOUS

FUNCTIONAL-INSTANTIATION-IN-ACL2R    additional requirements for :functional-instance hints in ACL2(r)

This documentation topic relates to ACL2(r), the modification of ACL2
that supports the real numbers (see *note REAL::).

See *note HINTS:: and see *note LEMMA-INSTANCE:: for a discussion of
:use hints that employ the :functional-instance keyword.  Here, we
document additional requirements for such hints that applies to
ACL2(r).  We assume familiarity with lemma instances; see *note
LEMMA-INSTANCE::.

(1) When functionally instantiating a non-classical formula, it is
illegal to use pseudo-lambda expressions in a lemma instance.

(2) A classical function symbol must be bound either to a classical
function symbol or to a lambda (or, if allowed, pseudo-lambda)
expression with a classical body.  Similarly, a non-classical function
symbol must be bound either to a non-classical function symbol or to a
lambda (or, if allowed, pseudo-lambda) expression with a non-classical
body.


File: acl2-doc-emacs.info,  Node: GAG-MODE,  Next: GC$,  Prev: FUNCTIONAL-INSTANTIATION-IN-ACL2R,  Up: MISCELLANEOUS

GAG-MODE    verbosity of proof output

Please see *note SET-GAG-MODE:: for an explanation of gag-mode, which
can take any of the following values:

     (gag-mode) ; generally evaluates to t, nil, or :goals


File: acl2-doc-emacs.info,  Node: GC$,  Next: GC-VERBOSE,  Prev: GAG-MODE,  Up: MISCELLANEOUS

GC$    invoke the garbage collector

This function is provided so that the user can call the garbage
collector of the host Lisp from inside the ACL2 loop.  Specifically, a
call of gc$ is translated into a call of a function below on the same
arguments.

     Allegro CL:            excl:gc
     CCL                    ccl::gc
     CLISP                  ext:gc
     CMU Common Lisp        system::gc
     GCL                    si::gbc
     LispWorks              hcl::gc-generation [default argument list:
                                                (7) for 64-bit OS, else (3)]
     SBCL                   sb-ext:gc

The arguments, if any, are as documented in the underlying Common Lisp.
It is up to the user to pass in the right arguments, although we may do
some rudimentary checks.

Also see *note GC-VERBOSE::.

Evaluation of a call of this macro always returns nil.


File: acl2-doc-emacs.info,  Node: GC-VERBOSE,  Next: GCL,  Prev: GC$,  Up: MISCELLANEOUS

GC-VERBOSE    control printing from the garbage collector

     General Form:
     (gc-verbose arg)

Garbage collection (gc) is performed by every Lisp implementation; see
*note GC$::.  However, different ACL2 builds might see more or fewer
messages.  This macro is intended to provide an interface for
controlling the verbosity, which is off if the argument evaluates to
nil and otherwise is on.

The above functionality is only supported for the following host Common
Lisp implementations: CCL, CMUCL, and GCL.  Otherwise, the only effect
of this macro is to print a notice that it is not supported.  You are
welcome to contact the ACL2 developers if you would like to help in
adding such support for another host Common Lisp.

Evaluation of a call of this macro always returns nil.


File: acl2-doc-emacs.info,  Node: GCL,  Next: GET-INTERNAL-TIME,  Prev: GC-VERBOSE,  Up: MISCELLANEOUS

GCL    tips on building and using ACL2 based on Gnu Common Lisp

See the installation instructions for basic information about building
ACL2 on top of GCL, including information about where to fetch GCL.
Here, we provide some tips that may be useful.

1. You can place forms to evaluate at start-up into file init.lsp in the
directory where you are starting ACL2 (GCL), or into file acl2-init.lsp
in your home directory.  For example, in order to evaluate both of the
lisp forms mentioned in 2 below, you could put them both into init.lsp
in the current directory or in ~/acl2-init.lsp (either way, without
(lp) or :q):

     (setq si::*optimize-maximum-pages* nil)
     (si::allocate 'cons 75000 t)

Note that if you want to put ACL2 patches in this file, you should
precede them with (in-package "ACL2").

2. Suppose you run out of space, for example with an error like this:

        Error: The storage for CONS is exhausted.
          Currently, 59470 pages are allocated.
          Use ALLOCATE to expand the space.

The following suggestion from Camm Maguire will minimize the heap size,
at the cost of more garbage collection time.

     :q   ; exit the ACL2 loop
     (setq si::*optimize-maximum-pages* nil)
     (lp) ; re-enter the ACL2 loop

A second thing to try, suggested by several people, is to preallocate
more pages before the run, e.g.:

     :q   ; exit the ACL2 loop
     (si::allocate 'cons 75000 t)
     (lp) ; re-enter the ACL2 loop

Also see *note RESET-KILL-RING:: for a suggestion on how to free up
space.

3. Windows users have seen this error:

     cc1.exe: unrecognized option `-fno-zero-initialized-in-bss'

Camm Maguire suggests that a solution may be to evaluate the following
in GCL before building ACL2.

     (in-package 'compiler)
     (let* ((x `-fno-zero-initialized-in-bss')
            (i (search x *cc*)))
             (setq *cc* (concatenate 'string
                                     (subseq *cc* 0 i)
                                     (subseq *cc* (+ i (length x))))))

4. It is possible to profile using ACL2 built on GCL.  See file
save-gprof.lsp in the ACL2 source directory.

5. Some versions of GCL may have garbage-collector bugs that, on rare
occasions, cause ACL2 (when built on GCL) to break.  If you run into
this, a solution may be to execute the following:

     :q
     (si::sgc-on nil)
     (lp)

Alternatively, put (si::sgc-on nil) in your ~/acl2-init.lsp file.

A full regression test and found that this decreased performance by
about 10%.  But even with that, GCL is probably one of the faster
Common Lisp implementations for ACL2 on Linux.  Performance figures may
often be found by following the "Recent changes" link on the ACL2 home
page.

6. GCL operations on numbers can sometimes be sped up, perhaps by up to
two orders of magnitude, by suitable declare forms (also see *note
TYPE-SPEC::).  The following example, developed with Warren Hunt and
Serita Nelesen, illustrates the use of such declarations.

     ; File iplus.lisp:
     ; Operations on naturals together with positive infinity (represented as -1).

     ; After (ld "iplus.lisp"), escape to raw Lisp with :q and then eavluate
     ; (disassemble 'big-test).  You should see lots of arithmetic operations
     ; in C code, but no calls of C functions CMPmake_fixnum or number_plus.

     (in-package "ACL2")

     (defmacro i-max ()
       (expt 2 (1- 28)))

     (defmacro i+ (x y)
       `(the (signed-byte 28)
             (let ((x ,x)
                   (y ,y))
               (declare (type (signed-byte 28) x y))
               (cond ((or (< x 0)
                          (< y 0))
                      -1)
                     (t (let ((result
                               (the (signed-byte 29) (+ x y))))
                          (declare (type (signed-byte 29) result))
                          (cond ((>= result (i-max)) -1)
                                (t (the (signed-byte 28) result)))))))))

     (defmacro imin (x y)
       `(the (signed-byte 28)
             (let ((x ,x)
                   (y ,y))
               (declare (type (signed-byte 28) x y))
               (cond ((< x 0)
                      (cond ((< y 0) -1)
                            (t y)))
                     ((< y 0)
                      x)
                     (t
                      (the (signed-byte 28) (min x y)))))))

     (defun big-test (x y z)
       (declare (type (signed-byte 28) x y z))
       (imin (i+ x y)
             (i+ y (imin x z))))


File: acl2-doc-emacs.info,  Node: GET-INTERNAL-TIME,  Next: GET-WORMHOLE-STATUS,  Prev: GCL,  Up: MISCELLANEOUS

GET-INTERNAL-TIME    runtime vs. realtime in ACL2 timings

The ACL2 system provides utilities that deal with elapsed time.  The
most visible of these is in the time summaries printed when completing
evaluation of events.  For others, see *note WITH-PROVER-TIME-LIMIT::,
see *note READ-RUN-TIME::, see *note TIME-TRACKER::, see *note
TIME-TRACKER-TAU::, and see *note PSTACK::.

By default, these utilities all use an underlying notion of run time
provided by the host Common Lisp implementation: specifically, Common
Lisp function get-internal-run-time.  However, Common Lisp also
provides function get-internal-run-time, which returns the real time
(wall clock time).  While the latter is specified to measure elapsed
time, the former is left to the implementation, which might well only
measure time spent in the Lisp process.  Consider the following
example, which is a bit arcane but basically sleeps for 2 seconds.

       (defttag t) ; to allow sys-call
       (make-event
        (prog2$ (sys-call "sleep" '("2"))
                (value '(value-triple nil))))

A typical time summary might be as follows, drastically under-reporting
the elapsed time.

       Time:  0.01 seconds (prove: 0.00, print: 0.00, other: 0.01)

However, you can instruct ACL2 to switch to using elapsed time (run
time), in summaries and elsewhere, by evaluating the following form.

       (assign get-internal-time-as-realtime t)

To return to using runtime:

       (assign get-internal-time-as-realtime nil)

While the above example is rather silly, the issue becomes significant
in time summaries for proofs that call out to external tools (see *note
SYS-CALL:: and see *note CLAUSE-PROCESSOR::).

Note that a function get-internal-time is defined in raw Lisp but is not
available inside the ACL2 loop.  However, the expression (read-run-time
state) provides an interface to this function that is available inside
the ACL2 loop; see *note READ-RUN-TIME::.

We are open to changing the default to elapsed wall-clock time
(realtime), and may do so in future ACL2 releases.


File: acl2-doc-emacs.info,  Node: GET-WORMHOLE-STATUS,  Next: GOAL-SPEC,  Prev: GET-INTERNAL-TIME,  Up: MISCELLANEOUS

GET-WORMHOLE-STATUS    make a wormhole's status visible outside the wormhole

General Form: (get-wormhole-status name state)

Name should be the name of a wormhole (see *note WORMHOLE::).  This
function returns an error triple (see *note ERROR-TRIPLES::) of the form
(mv nil s state), where s is the status of the named wormhole.  The
status is obtained by reading the oracle in the ACL2 state.

This function makes the status of a wormhole visible outside the
wormhole.  But since this function takes state and modifies it, the
function may only be used in contexts in which you may change state.
Otherwise, the wormhole status may stay in the wormhole.  See
wormhole-eval and wormhole.

