Major Section: SWITCHES-PARAMETERS-AND-MODES
This utility is intended for system hackers, not standard ACL2 users.
ACL2 prints summaries at the conclusions of processing events (unless
summaries are inhibited; see set-inhibit-output-lst and also
see set-inhibited-summary-types). You may arrange for processing to take
place just after the summary, by defining a function with argument list
(ctx body state)
that returns one value, namely state
. We describe
ctx
and body
at the end below, but you may simply prefer to ignore
these arguments.) Your function should normally be a guard-verified
:
logic
mode function with no guard other than that provided by the
input requirement on state
, that is, (state-p state)
; but later
below we discuss how to avoid this requirement. You then
attach (see defattach) your function to the function
finalize-event-user
. The following example illustrates how this all
works.
(defun finalize-event-user-test (ctx body state) (declare (xargs :stobjs state) (ignore ctx body)) (cond ((and (boundp-global 'abbrev-evisc-tuple state) (open-output-channel-p *standard-co* :character state)) (pprogn (if (eq (f-get-global 'abbrev-evisc-tuple state) :DEFAULT) (princ$ "Abbrev-evisc-tuple has its default value.~%" *standard-co* state) (princ$ "Abbrev-evisc-tuple has been modified.~%" *standard-co* state)))) (t state))) (defattach finalize-event-user finalize-event-user-test)
After admission of the two events above, an event summary will conclude with extra printout, for example:
Note: Abbrev-evisc-tuple has its default value.
If the attachment function (above, finalize-event-user-test
) does not
meet all the requirements stated above, then you can use the :skip-checks
argument of defattach
to get around the requirement, as illustrated by
the following example.
(defun finalize-event-user-test2 (state) (declare (xargs :stobjs state :mode :program) (ignore ctx body)) (observation 'my-test "~|Value of term-evisc-tuple: ~x0~|" (f-get-global 'term-evisc-tuple state))) (defttag t) ; needed for :skip-checks t (defattach (finalize-event-user finalize-event-user-test2) :skip-checks t)So for example:
ACL2 !>(set-term-evisc-tuple (evisc-tuple 2 7 nil nil) state) (:TERM) ACL2 !>(defconst *foo6* '(a b c)) Summary Form: ( DEFCONST *FOO6* ...) Rules: NIL Time: 0.00 seconds (prove: 0.00, print: 0.00, other: 0.00) ACL2 Observation in MY-TEST: Value of term-evisc-tuple: (NIL 2 7 NIL) *FOO6* ACL2 !>
Note that (as of this writing) the macro observation
expands to a call
of a :
program
-mode function. Thus, the trick shown above involving
:skip-checks
allows the use of :program
-mode functions; for example,
you can print with fmt
.
See community book books/misc/defattach-bang.lisp
for a variant of
defattach
that uses ec-call
to avoid issues of guard
verification.
Also see initialize-event-user, which discusses the handling of state
globals by that utility as well as by finalize-event-user
.
Finally, as promised above, we briefly describe the arguments ctx
and
body
. These are the arguments passed to the call of macro
with-ctx-summarized
under which finalize-event-user
(or
initialize-event-user
) was called. Thus, they are unevaluated
expressions. For example, system function defthm-fn1
has a body of the
following form.
(with-ctx-summarized (if (output-in-infixp state) event-form (cons 'defthm name)) (let ((wrld (w state)) (ens (ens state)) .....Thus, when
initialize-event-user
and finalize-event-user
are called
on behalf of defthm
, ctx
is the s-expression
(if (output-in-infixp state) event-form (cons 'defthm name))while
body
is the following s-expression (with most code elided).
(let ((wrld (w state)) (ens (ens state)) .....
You might find it helpful to use trace$
to get a sense of ctx
and
body
, for example, (trace$ finalize-event-user)
.