certify-book
to write out a .acl2x
file
Major Section: SWITCHES-PARAMETERS-AND-MODES
Example Forms: (set-write-acl2x nil state) (set-write-acl2x t state) (set-write-acl2x '(nil) state) ; same as just above, but allow inclusion of ; uncertified books during certify-book (set-write-acl2x '(t) state) (set-write-acl2x '(include-book-with-locals) state)
General Form: (set-write-acl2x val state)where
val
evaluates to t
, nil
, or a one-element list whose
element is a legal value for the global 'ld-skip-proofsp
;
see ld-skip-proofsp. The value returned is an error triple, which in the
non-error case is (mv nil v state)
, where v
is the value of val
and state
is the result of updating the input state by assigning
state global 'write-acl2x
the value v
.The command (set-write-acl2x val state)
assigns the value of val
to
the state global variable 'write-acl2x
, affecting whether or not
certify-book
writes out a file with extension acl2x
, called a
``.acl2x
file'' and pronounced ``dot-acl2x file''. Such a file is read
or written by certify-book
when it is supplied with keyword argument
:acl2x t
. By default, such a call of certify-book
reads a .acl2x
file; but if the value of state global variable 'write-acl2x
is not
nil
, then certify-book
writes a .acl2x
file (in which case it is
illegal to specify a non-nil
value for certify-book
keyword
argument :pcert
). Consider for example
(certify-book "foo" 0 nil :acl2x t)
. By default, this command reads
file foo.acl2x
, which supplies replacements for some forms in
foo.lisp
, as described later below. But if the value of state global
'write-acl2x
is not nil
, then instead, this certify-book
command
writes such a file foo.acl2x
.
Before we discuss the function of .acl2x
files, we first explain more
about how a non-nil
value of state global 'write-acl2x
affects
the behavior of a command (certify-book ... :acl2x t ...)
. A significant
effect on the behavior is that after processing events in the given book,
ACL2 writes out a .acl2x
file and then returns, skipping the other
subsequent actions typically performed by certify-book
: a
local-incompatibility check, writing of a certificate file, and
possibly compilation. Another effect is that proofs may be skipped when
processing events assuming that the the certify-book
command does
not explicitly specify :skip-proofs-okp nil
, as we now explain. A
non-nil
value of 'write-acl2x
should either be t
or a one-element
list (x)
, where x
is a legal value for the state global
'ld-skip-proofsp
(see ld-skip-proofsp). In both cases, certify-book
will process events to write out a .acl2x
file as described above.
But in the latter (list) case, event processing will take place according to
the value of x
: in particular, proofs will be skipped when x
is not
nil
, and if moreover x
is the symbol include-book-with-locals
,
then only one pass will be made through each encapsulate
form. A third
effect of a non-nil
value of 'write-acl2x
, which is restricted to the
list case, is that include-book events encountered during event
processing are allowed to succeed on uncertified books, something that is
prohibited during most calls of certify-book
.
When certify-book
is used to write out a .acl2x
file, there is
typically a subsequent run of certify-book
that reads that file.
Consider how this can work with a book foo.lisp
. In the first call of
certify-book
, a file foo.acl2x
is written that contains all
make-event
expansions, but foo.cert
is not written. In the second
call of certify-book
, no make-event
expansion typically takes
place, because foo.acl2x
supplies the expansions. The command
(set-write-acl2x t state)
should be evaluated before the first
certification (though another legal non-nil
value may be used in place of
t
), setting the value of state
global 'write-acl2x
to t
, to
enable writing of foo.acl2x
; and the command
(set-write-acl2x nil state)
may be evaluated before the second
run (though this is not necessary in a fresh ACL2 session) in order to
complete the certification (writing out foo.cert
) using foo.acl2x
to
supply the make-event
expansions.
When Certify-book
is supplied with keyword argument :acl2x t
it
will read or write the book's .acl2x
file; when supplied with
:acl2x nil
, it will not read or write that .acl2x
file. The value of
:acl2x
is nil
by default. The interaction of certify-book
with
the corresponding .acl2x
file is as follows.
o If:acl2x
ist
, then: - Ifset-write-acl2x
has been (most recently) called with a value oft
for its first argument, then ACL2 writes the corresponding.acl2x
file. - Ifset-write-acl2x
has been (most recently) called with a value ofnil
for its first argument, or not called at all, then ACL2 insists on a corresponding.acl2x
file that is at least as recent as the corresponding.lisp
file, causing an error otherwise. o If:acl2x
isnil
, then: - Ifset-write-acl2x
has been (most recently) called with a valuet
for its first argument, or if argument:ttagsx
is supplied, then an error occurs. - If the.acl2x
file exists, then regardless of whether or howset-write-acl2x
has been called, ACL2 ignores the.acl2x
file but issues a warning about it.
Suppose you use the two-runs approach: first write a .acl2x
file, then
certify using (reading) that .acl2x
file. Then with scripts such as
makefiles, then you may wish to provide a single certify-book
command
to use for both runs. For that purpose, certify-book
supports the
keyword argument :ttagsx
. If this argument is supplied and
write-acl2x
is true, then this argument is treated as the :ttags
argument, overriding a :ttags
argument if present. That is, for the two
runs, :ttagsx
may be used to specify the trust tags used in the first
certification while :ttags
specifies the trust tags, if any (else
:ttags
may be omitted), used in the second certification. Note: If the
argument :ttagsx
is not supplied, then its value defaults to the
(explicit or default) value of the :ttags
argument.
The built-in ACL2 Makefile support automatically generates suitable
dependencies if you create a .acl2
file with a certify-book
call
matching the following regular expression, case-independent:
(certify-book[^;]*:acl2x tSee book-makefiles, and for an example
.acl2
file with a certify-book
call matching the above pattern, see community books file
books/make-event/double-cert-test-1.acl2
.Note that include-book
is generally not affected by
set-write-acl2x
, other than through the indirect effect on
certify-book
. More precisely: All expansions are stored in the
certificate file, so when include-book
is applied to a certified
book, the .acl2x
file is not consulted.
An example of how to put this all together may be found in community book
books/make-event/double-cert-test-1.lisp
. There, we see the following
form.
(make-event (progn (defttag :my-ttag) (progn! (let ((val (sys-call "pwd" nil))) (value (list 'defun 'foo () val))))))Imagine that in place of the binding computed using
sys-call
, which by
the way requires a trust tag, is some computation of your choice (such as
reading forms from a file) that is used to construct your own event,
in place of the defun
event constructed above. The Makefile
in
that directory contains the following added dependency, so that file
double-cert-test-1.acl2x
will be created:
double-cert-test-1.cert: double-cert-test-1.acl2xThere is also the file
double-cert-test-1.acl2
in that directory, which
contains a single form as follows.
(certify-book "double-cert-test-1" ? t :ttagsx :all :ttags nil)Thus, a call of
make
first creates file double-cert-test-1.acl2x
,
which uses the above :ttagsx
argument in order to support the use of
defttag
during make-event
expansion. Then, make
goes on to
cause a second certification in which no trust tags are involved. As a
result, the parent book double-cert-test.lisp
is ultimately certified
without requiring any trust tags.The discussion above is probably sufficient for most users of the two-run approach it describes. We conclude with further details for those who want more information. Those who wish to see a yet lower-level explanation of how all this works are invited to read the comment in the ACL2 source code entitled ``Essay on .acl2x Files (Double Certification).
Consider the .acl2x
file produced by the first run as described above.
It contains a single expression, which is an association list whose keys are
all positive integers, which occur in increasing order. When the .acl2x
file is present and at least as recent as the corresponding .lisp
file,
then for a subsequent certify-book
with argument :acl2x t
and the
(default) value of nil
for state global 'write-acl2x
, that
association list will be applied to the top-level events in the book, as
follows. Suppose the entry (n . ev)
belongs to the association list in
the .acl2x
file. Then n
is a positive integer, and the n
th
top-level event in the book -- where the 0
th event is the initial
in-package
form -- will be replaced by ev
. In practice, ev
is the make-event
expansion created during certification for the
nth
top-level event in the book; and this will always be the case if the
.acl2x
file is created by certify-book
after execution of the form
(set-write-acl2x t state)
. However, you are welcome to associate indices
manually with any events you wish into the alist stored in the
.acl2x
file.
Note: Also see the community book make-event/acl2x-help.lisp
for a
useful utility that can be used to skip proofs during the writing of
.acl2x
files.