Major Section: MISCELLANEOUS
Examples: ACL2 !>(set-ld-skip-proofsp t state) T ACL2 !s>(set-ld-skip-proofsp nil state) NIL ACL2 !>(set-ld-skip-proofsp 'include-book state) INCLUDE-BOOK ACL2 !s>
A global variable in the ACL2 state
, called 'ld-skip-proofsp
,
determines the thoroughness with which ACL2 processes your commands.
This variable may take on one of three values: t
, nil
or
'
include-book
. When ld-skip-proofsp
is non-nil
, the system assumes
that which ought to be proved and is thus unsound. The form
(set-ld-skip-proofsp flg state)
is the general-purpose way of
setting ld-skip-proofsp
. This global variable is an ``ld
special,''
which is to say, you may call ld
in such a way as to ``bind'' this
variable for the dynamic extent of the ld
.
When ld-skip-proofsp
is non-nil
, the default prompt displays the
character s
. Thus, the prompt
ACL2 !s>means that the default defun-mode is
:
logic
(otherwise the
character p
, for :
program
, would also be printed;
see default-print-prompt) but ``proofs are being skipped.''
Observe that there are two legal non-nil
values, t
and
'
include-book
. When ld-skip-proofsp
is t
, ACL2 skips all proof
obligations but otherwise performs all other required analysis of
input events. When ld-skip-proofsp
is '
include-book
, ACL2 skips not
only proof obligations but all analysis except that required to
compute the effect of successfully executed events. To explain the
distinction, let us consider one particular event, say a defun
.
Very roughly speaking, a defun
event normally involves a check of
the syntactic well-formedness of the submitted definition, the
generation and proof of the termination conditions, and the
computation and storage of various rules such as a :
definition
rule
and some :
type-prescription
rules. By ``normally'' above we mean
when ld-skip-proofsp
is nil
. How does a defun
behave when
ld-skip-proofsp
is non-nil
?
If ld-skip-proofsp
is t
, then defun
performs the syntactic
well-formedness checks and computes and stores the various rules,
but it does not actually carry out the termination proofs. If
ld-skip-proofsp
is '
include-book
, defun
does not do the syntactic
well-formedness check nor does it carry out the termination proof.
Instead, it merely computes and stores the rules under the
assumption that the checks and proofs would all succeed. Observe
that a setting of '
include-book
is ``stronger'' than a setting of t
in the sense that '
include-book
causes defun
to assume even more
about the admissibility of the event than t
does.
As one might infer from the choice of name, the include-book
event
sets ld-skip-proofsp
to '
include-book
when processing the events in
a book being loaded. Thus, include-book
does the miminal work
necessary to carry out the effects of every event in the book. The
syntactic checks and proof obligations were, presumably,
successfully carried out when the book was certified.
A non-nil
value for ld-skip-proofsp
also affects the system's output
messages. Event summaries (the paragraphs that begin ``Summary''
and display the event forms, rules used, etc.) are not printed when
ld-skip-proofsp
is non-nil
. Warnings and observations are printed
when ld-skip-proofsp
is t
but are not printed when it is
'
include-book
.
Intuitively, ld-skip-proofsp
t
means skip just the proofs and
otherwise do all the work normally required for an event; while
ld-skip-proofsp
'
include-book
is ``stronger'' and means do as little
as possible to process events. In accordance with this intuition,
local
events are processed when ld-skip-proofsp
is t
but are skipped
when ld-skip-proofsp
is '
include-book
.
The ACL2 system itself uses only two settings, nil
and
'
include-book
, the latter being used only when executing the events
inside of a book being included. The ld-skip-proofsp
setting of t
is provided as a convenience to the user. For example, suppose one
has a file of events. By loading it with ld
with ld-skip-proofsp
set to t
, the events can all be checked for syntactic correctness
and assumed without proof. This is a convenient way to recover a
state lost by a system crash or to experiment with a modification of
an events file.
The foregoing discussion is actually based on a lie.
ld-skip-proofsp
is allowed two other values, 'initialize-acl2
and
'include-book-with-locals
. The first causes behavior similar to t
but skips local
events and avoids some error checks that would
otherwise prevent ACL2 from properly booting. The second is
identical to '
include-book
but also executes local
events. These
additional values are not intended for use by the user, but no
barriers to their use have been erected.
We close by reminding the user that ACL2 is potentially unsound if
ld-skip-proofsp
is ever set by the user. We provide access to it
simply to allow experimentation and rapid reconstruction of lost or
modified logical worlds.
ld
prints ``ACL2 Loading ...''
Major Section: MISCELLANEOUS
Ld-verbose
is an ld
special (see ld). The accessor is
(ld-verbose state)
and the updater is (set-ld-verbose val state)
.
Ld-verbose
must be t
, nil
or a string or consp
suitable for fmt
printing via the ~@
command. The initial value of ld-verbose
is a
fmt
message that prints the ACL2 version number, ld
level and
connected book directory.
Before processing the forms in standard-oi
, ld
may print a header.
The printing of this header is controlled by ld-verbose
. If
ld-verbose
is nil
, no header is printed. If it is t
, ld
prints the
message
ACL2 loading <file>where
<file>
is the input channel supplied to ld
. A similar
message is printed when ld
completes. If ld-verbose
is neither t
nor nil
then it is presumably a header and is printed with the ~@
fmt
directive before ld
begins to read and process forms. In this
case the ~@
fmt
directive is interpreted in an environment in which
#\v
is the ACL2 version string, #\l
is the level of the current
recursion in ld
and/or wormhole
, and #\c
is the connected book
directory (cbd)
.
Major Section: MISCELLANEOUS
Lemma instances are the objects one provides via :use
and :by
hints
(see hints) to bring to the theorem prover's attention some
previously proved or easily provable fact. A typical use of the
:use
hint is given below. The value specified is a list of five
lemma instances.
:use (reverse-reverse (:type-prescription app) (:instance assoc-of-app (x a) (y b) (z c)) (:functional-instance p-f (p consp) (f flatten)) (:instance (:theorem (equal x x)) (x (flatten a))))Observe that an event name can be a lemma instance. The
:use
hint
allows a single lemma instance to be provided in lieu of a list, as
in:
:use reverse-reverseor
:use (:instance assoc-of-app (x a) (y b) (z c))
A lemma instance denotes a formula which is either known to be a theorem or which must be proved to be a theorem before it can be used. To use a lemma instance in a particular subgoal, the theorem prover adds the formula as a hypothesis to the subgoal before the normal theorem proving heuristics are applied.
A lemma instance, or lmi
, is of one of the following five forms:
(1) name
, where name
names a previously proved theorem, axiom, or
definition and denotes the formula (theorem) of that name.
(2) rune
, where rune
is a rune (see rune) denoting the
:
corollary
justifying the rule named by the rune.
(3) (:theorem term)
, where term
is any term alleged to be a theorem.
Such a lemma instance denotes the formula term
. But before using
such a lemma instance the system will undertake to prove term
.
(4) (:instance lmi (v1 t1) ... (vn tn))
, where lmi
is recursively a
lemma instance, the vi
's are distinct variables and the ti
's are
terms. Such a lemma instance denotes the formula obtained by
instantiating the formula denoted by lmi
, replacing each vi
by ti
.
(5) (:functional-instance lmi (f1 g1) ... (fn gn))
, where lmi
is recursively a lemma instance and each fi
is an
``instantiable'' function symbol of arity ni
and gi
is a
function symbol or a pseudo-lambda expression of arity ni
. An
instantiable function symbol is any defined or constrained function
symbol except the primitives not
, member
, implies
, and
e0-ord-<
, and a few others, as listed by the constant
*non-instantiable-primitives*
. These are built-in in such a way
that we cannot recover the constraints on them. A pseudo-lambda
expression is an expression of the form (lambda (v1 ... vn) body)
where the vi
are distinct variable symbols and body
is any
term. No a priori relation is imposed between the vi
and the
variables of body
, i.e., body
may ignore some vi
's and may
contain ``free'' variables. However, we do not permit v
to occur
freely in body
if the functional substitution is to be applied to
any formula (lmi
or the constraints to be satisfied) that
contains v
as a variable. This is our draconian restriction to
avoid capture. If you happen to violate this restriction by
choosing a v
that does occur, say in one of the relevant
constraints, an informative error message will be printed. That
message will list for you the illegal choices for v
in the
context in which the functional substitution is offered. A
:functional-substitution
lemma instance denotes the formula
obtained by functionally instantiating the formula denoted by
lmi
, replacing fi
by gi
. However, before such a lemma
instance can be used, the system will undertake to prove that the
gi
's satisfy the constraints (see constraint) on the
fi
's. Any such constraint that was generated and proved by
ACL2 on behalf of a previously-proved event will be considered
proved.
Major Section: MISCELLANEOUS
Sometimes a ``local incompatibility'' is reported while attempting
to embed some events, as in an encapsulate
or include-book
. This is
generally due to the use of a locally defined name in a non-local
event or the failure to make a witnessing definition local.
Local incompatibilities may be detected while trying to execute the
strictly non-local events of an embedding. For example, encapsulate
operates by first executing all the events (local and non-local)
with ld-skip-proofsp
nil
, to confirm that they are all admissible.
Then it attempts merely to assume the non-local ones to create the
desired theory, by executing the events with ld-skip-proofsp
set to
'
include-book
. Similarly, include-book
assumes the non-local ones,
with the understanding that a previously successful certify-book
has
performed the admissiblity check.
How can a sequence of events admitted with ld-skip-proofsp
nil
fail
when ld-skip-proofsp
is '
include-book
? The key observation is that
in the latter case only the non-local events are processed. The
local ones are skipped and so the non-local ones must not depend
upon them.
Two typical mistakes are suggested by the detection of a local
incompatibility: (1) a locally defined function or macro was used in
a non-local
event (and, in the case of encapsulate
, was not included
among the signatures) and (2) the witnessing definition of a
function that was included among the signatures of an encapsulate
was not made local
.
An example of mistake (1) would be to include among your
encapsulated events both (local (defun fn ...))
and
(defthm lemma (implies (fn ...) ...))
. Observe that fn
is
defined locally but a formula involving fn
is defined
non-locally. In this case, either the defthm
should be made
local or the defun
should be made non-local.
An example of mistake (2) would be to include (fn (x) t)
among your
signatures and then to write (defun fn (x) ...)
in your events,
instead of (local (defun fn ...))
.
One subtle aspect of encapsulate
is that if you constrain any member
of a mutually recursive clique you must define the entire clique
locally and then you must constrain those members of it you want
axiomatized non-locally.
Errors due to local incompatibility should never occur in the
assumption of a fully certified book. Certification insures against
it. Therefore, if include-book
reports an incompatibility, we
assert that earlier in the processing of the include-book
a warning
was printed advising you that some book was uncertified. If this is
not the case -- if include-book
reports an incompatibility and there
has been no prior warning about lack of certification -- please
report it to us.
When a local incompatibility is detected, we roll-back to the world
in which we started the encapsulate
or include-book
. That is, we
discard the intermediate world created by trying to process the
events skipping proofs. This is clean, but we realize it is very
frustrating because the entire sequence of events must be processed
from scratch. Assuming that the embedded events were, once upon a
time, processed as top-level commands (after all, at some point you
managed to create this sequence of commands so that the local and
non-local ones together could survive a pass in which proofs were
done), it stands to reason that we could define a predicate that
would determine then, before you attempted to embed them, if local
incompatibilities exist. We hope to do that, eventually.
Major Section: MISCELLANEOUS
Examples: assoc caddr + "ACL2-USER" "arith" "project/task-1/arith.lisp" :here
A logical name is either a name introduced by some event, such as
defun
, defthm
, or include-book
, or else is the keyword :here
, which
refers to the most recent such event. See events. Every
logical name is either a symbol or a string. For the syntactic
rules on names, see name. The symbols name functions, macros,
constants, axioms, theorems, labels, and theories. The strings name
packages or books. We permit the keyword symbol :here
to be used as
a logical name denoting the most recently completed event.
The logical name introduced by an include-book is the full book name
string for the book (see full-book-name). Thus, under the
appropriate setting for the current book directory (see cbd)
the event (include-book "arith")
may introduce the logical name
"/usr/home/smith/project/task-1/arith.lisp" .Under a different
cbd
setting, it may introduce a different
logical name, perhaps
"/local/src/acl2/library/arith.lisp" .It is possible that identical
include-book
events forms in a
session introduce two different logical names because of the current
book directory.
A logical name that is a string is either a package name or a book
name. If it is not a package name, we support various conventions
to interpret it as a book name. If it does not end with the string
".lisp"
we extend it appropriately. Then, we search for any book
name that has the given logical name as a terminal substring.
Suppose (include-book "arith")
is the only include-book so far and
that "/usr/home/smith/project/task-1/arith.lisp"
is the source
file it processed. Then "arith"
, "arith.lisp"
and
"task-1/arith.lisp"
are all logical names identifying that
include-book
event (unless they are package names). Now suppose a
second (include-book "arith")
is executed and processes
"/local/src/acl2/library/arith.lisp"
. Then "arith"
is no longer
a logical name, because it is ambiguous. However, "task-1/arith"
is a logical name for the first include-book
and "library/arith"
is a logical name for the second. Indeed, the first can be named by
"1/arith"
and the second by "y/arith"
.
Logical names are used primarily in the theory manipulation
functions, e.g., universal-theory
and current-theory
with which you
may obtain some standard theories as of some point in the historical
past. The reference points are the introductions of logical names,
i.e., the past is determined by the events it contains. One might
ask, ``Why not discuss the past with the much more flexible language
of command descriptors?'' (See command-descriptor.) The reason
is that inside of such events as encapsulate
or macro commands that
expand to progn
s of events, command descriptors provide too coarse a
grain.
When logical names are used as referents in theory expressions used
in books, one must consider the possibility that the defining event
within the book in question becomes redundant by the definition of
the name prior to the assumption of the book.
See redundant-events.
Major Section: MISCELLANEOUS
See rule-classes for a discussion of the syntax of the
:loop-stopper
field of :
rewrite
rule-classes. Here we describe how
that field is used, and also how that field is created when the user
does not explicitly supply it.
For example, the built-in :
rewrite
rule commutativity-of-+
,
(implies (and (acl2-numberp x) (acl2-numberp y)) (equal (+ x y) (+ y x))),creates a rewrite rule with a loop-stopper of
((x y binary-+))
.
This means, very roughly, that the term corresponding to y
must be
``smaller'' than the term corresponding to x
in order for this rule
to apply. However, the presence of binary-+
in the list means that
certain functions that are ``invisible'' with respect to binary-+
(by default, unary--
is the only such function) are more or less
ignored when making this ``smaller'' test. We are much more precise
below.
Our explanation of loop-stopping is in four parts. First we discuss
ACL2's notion of ``term order.'' Next, we bring in the notion of
``invisibility'', and use it together with term order to define
orderings on terms that are used in the loop-stopping algorithm.
Third, we describe that algorithm. These topics all assume that we
have in hand the :loop-stopper
field of a given rewrite rule; the
fourth and final topic describes how that field is calculated when
it is not supplied by the user.
ACL2 must sometimes decide which of two terms is syntactically
simpler. It uses a total ordering on terms, called the ``term
order.'' Under this ordering constants such as '(a b c)
are simpler
than terms containing variables such as x
and (+ 1 x)
. Terms
containing variables are ordered according to how many occurrences
of variables there are. Thus x
and (+ 1 x)
are both simpler than
(cons x x)
and (+ x y)
. If variable counts do not decide the order,
then the number of function applications are tried. Thus (cons x x)
is simpler than (+ x (+ 1 y))
because the latter has one more
function application. Finally, if the number of function
applications do not decide the order, a lexicographic ordering on
Lisp objects is used. See term-order for details.
When the loop-stopping algorithm is controlling the use of
permutative :
rewrite
rules it allows term1
to be moved leftward over
term2
only if term1
is smaller, in a suitable sense. Note: The
sense used in loop-stopping is not the above explained term order
but a more complicated ordering described below. The use of a total
ordering stops rules like commutativity from looping indefinitely
because it allows (+ b a)
to be permuted to (+ a b)
but not vice
versa, assuming a
is smaller than b
in the ordering. Given a set of
permutative rules that allows arbitrary permutations of the tips of
a tree of function calls, this will normalize the tree so that the
smallest argument is leftmost and the arguments ascend in the order
toward the right. Thus, for example, if the same argument appears
twice in the tree, as x
does in the binary-+
tree denoted by the
term (+ a x b x)
, then when the allowed permutations are done, all
occurrences of the duplicated argument in the tree will be adjacent,
e.g., the tree above will be normalized to (+ a b x x)
.
Suppose the loop-stopping algorithm used term order, as noted above,
and consider the binary-+
tree denoted by (+ x y (- x))
. The
arguments here are in ascending term order already. Thus, no
permutative rules are applied. But because we are inside a
+-expression
it is very convenient if x
and (- x)
could be given
virtually the same position in the ordering so that y
is not
allowed to separate them. This would allow such rules as
(+ i (- i) j) = j
to be applied. In support of this, the
ordering used in the control of permutative rules allows certain
unary functions, e.g., the unary minus function above, to be
``invisible'' with respect to certain ``surrounding'' functions,
e.g., +
function above.
Briefly, a unary function symbol fn1
is invisible with respect to a
function symbol fn2
if fn2
belongs to the value of fn1
in
invisible-fns-alist
; also see set-invisible-fns-alist, which
explains its format and how it can be set by the user. Roughly
speaking, ``invisible'' function symbols are ignored for the
purposes of the term-order test.
Consider the example above, (+ x y (- x))
. The translated version
of this term is (binary-+ x (binary-+ y (unary-- x)))
. The initial
invisible-fns-alist
makes unary--
invisible with repect to binary-+
.
The commutativity rule for binary-+
will attempt to swap y
and
(unary-- x)
and the loop-stopping algorithm is called to approve or
disapprove. If term order is used, the swap will be disapproved.
But term order is not used. While the loop-stopping algorithm is
permuting arguments inside a binary-+
expression, unary--
is
invisible. Thus, insted of comparing y
with (unary-- x)
, the
loop-stopping algorithm compares y
with x
, approving the swap
because x
comes before y
.
Here is a more precise specification of the total order used for
loop-stopping with respect to a list, fns
, of functions that are to
be considered invisible. Let x
and y
be distinct terms; we specify
when ``x
is smaller than y
with respect to fns
.'' If x
is the
application of a unary function symbol that belongs to fns
, replace
x
by its argument. Repeat this process until the result is not the
application of such a function; let us call the result x-guts
.
Similarly obtain y-guts
from y
. Now if x-guts
is the same term as
y-guts
, then x
is smaller than y
in this order iff x
is smaller than
y
in the standard term order. On the other hand, if x-guts
is
different than y-guts
, then x
is smaller than y
in this order iff
x-guts
is smaller than y-guts
in the standard term order.
Now we may describe the loop-stopping algorithm. Consider a rewrite
rule with conclusion (equiv lhs rhs)
that applies to a term x
in a
given context; see rewrite. Suppose that this rewrite rule has
a loop-stopper field (technically, the :heuristic-info
field) of
((x1 y1 . fns-1) ... (xn yn . fns-n))
. (Note that this field can be
observed by using the command :
pr
with the name of the rule;
see pr.) We describe when rewriting is permitted. The
simplest case is when the loop-stopper list is nil
(i.e., n
is 0
);
in that case, rewriting is permitted. Otherwise, for each i
from 1
to n
let xi'
be the actual term corresponding to the variable xi
when lhs
is matched against the term to be rewritten, and similarly
correspond yi'
with y
. If xi'
and yi'
are the same term for all i
,
then rewriting is not permitted. Otherwise, let k
be the least i
such that xi'
and yi'
are distinct. Let fns
be the list of all
functions that are invisible with respect to every function in
fns-k
, if fns-k
is non-empty; otherwise, let fns
be nil
. Then
rewriting is permitted if and only if yi'
is smaller than xi'
with
respect to fns
, in the sense defined in the preceding paragraph.
It remains only to describe how the loop-stopper field is calculated
for a rewrite rule when this field is not supplied by the user. (On
the other hand, to see how the user may specify the :loop-stopper
,
see rule-classes.) Suppose the conclusion of the rule is of
the form (equiv lhs rhs)
. First of all, if rhs
is not an instance
of the left hand side by a substitution whose range is a list of
distinct variables, then the loop-stopper field is nil
. Otherwise,
consider all pairs (u . v)
from this substitution with the property
that the first occurrence of v
appears in front of the first
occurrence of u
in the print representation of rhs
. For each such u
and v
, form a list fns
of all functions fn
in lhs
with the property
that u
or v
(or both) appears as a top-level argument of a subterm
of lhs
with function symbol fn
. Then the loop-stopper for this
rewrite rule is a list of all lists (u v . fns)
.
Major Section: MISCELLANEOUS
To enter the ACL2 command loop from Common Lisp, call the Common
Lisp program lp
(which stands for ``loop,'' as in ``read-eval-print
loop'' or ``command loop.'') The ACL2 command loop is actually
coded in ACL2 as the function ld
(which stands for ``load''). The
command loop is just what you get by loading from the standard
object input channel, *standard-oi*
. Calling ld
directly from
Common Lisp is possible but fragile because hard lisp errors or
aborts throw you out of ld
and back to the top-level of Common Lisp.
Lp
calls ld
in such a way as to prevent this and is thus the
standard way to get into the ACL2 command loop. Also
see acl2-customization for information on the loading of an
initialization file.
All of the visible functionality of lp
is in fact provided by ld
,
which is written in ACL2 itself. Therefore, you should see ld
for detailed documentation of the ACL2 command loop. We sketch it
below, for novice users.
Every expression typed to the ACL2 top-level must be an ACL2 expression.
Any ACL2 expression containing no variables may be evaluated.
Because of the applicative nature of ACL2, we make a special
exception for the variable state
. If this variable occurs in the
form, it is taken to mean the ``current'' ACL2 state object. If the
form returns a new state object as one of its values, then that is
considered the new ``current'' state for the evaluation of the
subsequent form. See state.
If the form read is a single keyword, e.g., :
pe
or :
ubt
, then
special procedures are followed. See keyword-commands.
The command loop keeps track of the commands you have typed and allows you to review them, display them, and roll the logical state back to that created by any command. See history.
ACL2 makes the convention that if a top-level form returns three
values, the last of which is an ACL2 state, then the first is
treated as a flag that means ``an error occurred,'' the second is
the value to be printed if no error occurred, and the third is (of
course) the new state. When ``an error occurs'' no value is
printed. Thus, if you execute a top-level form that happens to
return three such values, only the second will be printed (and that
will only happen if the first is nil
!). See ld for details.
Major Section: MISCELLANEOUS
Examples: (x y z) (x y z &optional max (base '10 basep)) (x y &rest rst) (x y &key max base) (&whole sexpr x y)
The ``lambda-list'' of a macro definition may include simple formal
parameter names as well as appropriate uses of the following
lambda
-list keywords from CLTL (pp. 60 and 145):
&optional, &rest, &key, &whole, &body, and &allow-other-keys.ACL2 does not support
&aux
and &environment
. In addition, we make
the following restrictions:
You are encouraged to experiment with the macro facility. One way to do so is to define a macro that does nothing but return the quotation of its arguments, e.g.,(1) initialization forms in
&optional
and&key
specifiers must be quoted values;(2)
&allow-other-keys
may only be used once, as the last specifier; and(3) destructuring is not allowed.
(defmacro demo (x y &optional opt &key key1 key2) (list 'quote (list x y opt key1 key2)))You may then execute the macro on some sample forms, e.g.,
term value (demo 1 2) (1 2 NIL NIL NIL) (demo 1 2 3) (1 2 3 NIL NIL) (demo 1 2 :key1 3) error: non-even key/value arglist (because :key1 is used as opt) (demo 1 2 3 :key2 5) (1 2 3 NIL 5)Also see trans.
Major Section: MISCELLANEOUS
Examples Counter-ExamplesPRIMEP 91 (not a symbolp) F-AC-23 :CHK-LIST (in KEYWORD package) 1AX *PACKAGE* (in the Lisp Package) |Prime Number| 1E3 (not a symbolp)
Many different ACL2 entities have names, e.g., functions, macros,
variables, constants, packages, theorems, theories, etc.
Package names are strings. All other names are symbols and may not
be in the "KEYWORD"
package. Moreover, names of functions,
macros, constrained functions, and constants, other than those that
are predefined, must not be in the ``main Lisp package'' (which is
("LISP"
or "COMMON-LISP"
, according to whether we are
following CLTL1 or CLTL2). An analogous restriction on variables
is given below.
T
, nil
, and all names above except those that begin with ampersand
(&) are names of variables or constants. T
, nil
, and those names
beginning and ending with star (*) are constants. All other such
names are variables.
Note that names that start with ampersand, such as &rest
, may be
lambda list keywords and are reserved for such use whether or not
they are in the CLTL constant lambda-list-keywords
. (See pg 82
of CLTL2.) That is, these may not be used as variables. Unlike
constants, variables may be in the main Lisp package as long as they
are in the original list of imports from that package to ACL2, the
list *common-lisp-symbols-from-main-lisp-package*
, and do not
belong to a list of symbols that are potentially ``global.'' This
latter list is the value of *common-lisp-specials-and-constants*
.
Our restrictions pertaining to the main Lisp package take into
account that some symbols, e.g., lambda-list-keywords
and
boole-c2
, are ``special.'' Permitting them to be bound could
have harmful effects. In addition, the Common Lisp language does
not allow certain manipulations with many symbols of that package.
So, we stay away from them, except for allowing certain variables as
indicated above.
Major Section: MISCELLANEOUS
See bdd for information on this topic.
Major Section: MISCELLANEOUS
The value of this flag is normally nil
. If you want to prevent the
theorem prover from abandoning its initial work upon pushing the
second subgoal, set :otf-flg
to t
.
Suppose you submit a conjecture to the theorem prover and the system
splits it up into many subgoals. Any subgoal not proved by other
methods is eventually set aside for an attempted induction proof.
But upon setting aside the second such subgoal, the system chickens
out and decides that rather than prove n>1 subgoals inductively, it
will abandon its initial work and attempt induction on the
originally submitted conjecture. The :otf-flg
(Onward Thru the Fog)
allows you to override this chickening out. When :otf-flg
is t
, the
system will push all the initial subgoals and proceed to try to
prove each, independently, by induction.
Even when you don't expect induction to be used or to succeed,
setting the :otf-flg
is a good way to force the system to generate
and display all the initial subgoals.
The :otf-flg
may be supplied to defun
via the xargs
declare option. When you supply an :otf-flg
hint to defun
, the
flag is effective for the termination proofs and the guard proofs, if
any.
defpkg
s
Major Section: MISCELLANEOUS
Suppose (defpkg "pkg" imports)
is the most recently executed
successful definition of "pkg"
in this ACL2 session and that it
has since been undone, as by :
ubt
. Any future attempt in this
session to define "pkg"
as a package must specify an identical
imports list.
The restriction stems from the need to implement the reinstallation
of saved logical worlds as in error recovery and the :
oops
command.
Suppose that the new defpkg
attempts to import some symbol, a::sym
,
not imported by the previous definition of "pkg"
. Because it was
not imported in the original package, the symbol pkg::sym
, different
from a::sym
, may well have been created and may well be used in some
saved worlds. Those saved worlds are Common Lisp objects being held
for you ``behind the scenes.'' In order to import a::sym
into
"pkg"
now we would have to unintern pkg::sym
, rendering those
saved worlds ill-formed. It is because of saved worlds that we do
not actually clear out a package when it is undone.
At one point we thought it was sound to allow the new defpkg
to
import a subset of the old. But that is incorrect. Suppose the old
definition of "pkg"
imported a::sym
but the new one does not.
Suppose we allowed that and implemented it simply by setting the
imports of "pkg"
to the new subset. Then consider the conjecture
(eq a::sym pkg::sym)
. This ought not be a theorem because we did
not import a::sym
into "pkg"
. But in fact in AKCL it is a theorem
because pkg::sym
is read as a::sym
because of the old imports.