Major Section: TRACE
The acronym ``wet'' stands for ``with-error-trace''. Wet
provides a
convenient way to obtain a backtrace when evaluation causes a guard violation
or other error.
The basic idea is that (wet form)
evaluates form
and, if there is an
error, shows a backtrace of calls that led to that error. Note however that
by default only calls of user-defined (not built-in) functions ``supporting''
form
in the following sense will show up in the backtrace: those that
occur in the macroexpansion of form
or (recursively) support any of those
functions. So for example, since (make-event form)
macroexpands to
(make-event-fn (quote form) ...)
, calls of functions occurring in
form
will likely not show up in the backtrace by default. The option
:fns all
overrides this default, with potential loss of speed; more on
this below.
The following example explains the use of wet
. First, submit the
following three definitions:
(defun foo (x) (declare (xargs :guard (consp x))) (car x)) (defun bar (x) (foo (cdr x))) (defun g (x) (bar (cdr x)))Now imagine you have obtained the following guard violation:
ACL2 !>(g '(3 4)) ACL2 Error in TOP-LEVEL: The guard for the function call (FOO X), which is (CONSP X), is violated by the arguments in the call (FOO NIL). To debug see :DOC print-gv, see :DOC trace, and see :DOC wet. See :DOC set-guard-checking for information about suppressing this check with (set-guard-checking :none), as recommended for new users. ACL2 !>With
wet
, you can get a backtrace of user-defined functions. The
package prefixes shown below, ACL2_*1*_
, indicate that the
executable (logical) counterparts of the corresponding raw Lisp functions are
being called; see guard. Don't forget to start with
(include-book "misc/wet" :dir :system)
.
ACL2 !>(wet (g '(3 4))) ; Fast loading /projects/acl2/devel/books/misc/wet.fasl TTAG NOTE: Adding ttag :TRACE! from the top level loop. ACL2 Error in WET: The guard for the function call (FOO X), which is (CONSP X), is violated by the arguments in the call (FOO NIL). To debug see :DOC print-gv, see :DOC trace, and see :DOC wet. See :DOC set-guard-checking for information about suppressing this check with (set-guard-checking :none), as recommended for new users. Backtrace stack: ---------------- 1. (ACL2_*1*_ACL2::FOO NIL) 2. (ACL2_*1*_ACL2::BAR (4)) 3. (ACL2_*1*_ACL2::G (3 4)) ACL2 !>By default, large structures are hidden during the printing of the backtrace stack. But you can supply a value for keyword argument
:evisc-tuple
to
modify the printing: nil
to avoid hiding, else a suitable evisc-tuple, as
shown below (see evisc-tuple).
ACL2 !>(wet (g '(3 4)) :evisc-tuple (evisc-tuple 1 1 nil nil)) ; Fast loading /projects/acl2/devel/books/misc/wet.fasl TTAG NOTE: Adding ttag :TRACE! from the top level loop. ACL2 Error in WET: The guard for the function call (FOO X), which is (CONSP X), is violated by the arguments in the call (FOO NIL). To debug see :DOC print-gv, see :DOC trace, and see :DOC wet. See :DOC set-guard-checking for information about suppressing this check with (set-guard-checking :none), as recommended for new users. Backtrace stack: ---------------- 1. (ACL2_*1*_ACL2::FOO ...) 2. (ACL2_*1*_ACL2::BAR ...) 3. (ACL2_*1*_ACL2::G ...) ACL2 !>For a backtrace as a data object, evaluate the form
(@ wet-stack)
. But
note that this object may not be a legal ACL2 value, for example because of
the ``*1*
'' symbols shown above.
General Form: (wet form ; an arbitrary form :book bk-form ; optional, not evaluated ;;; the rest are optional and evaluated: :evisc-tuple e ; an evisc-tuple :fns fns ; :all, or a list of functions to show in a backtrace :compile c ; :same, t, or nil; default :same (nil if :fns supplied)
Form
is evaluated. If there is an error, a backtrace stack is printed to
the standard output (*standard-co*
), containing (by default) the
user-defined function calls made before the error. Such printing is
controlled by the :evisc-tuple
if supplied; otherwise, hiding of large
structures will occur. (Technical detail: by default the global
abbrev-evisc-tuple is used, if bound; see set-evisc-tuple.
The :fns
option. As mentioned above, by default the wet
backtrace
shows user-defined functions that syntactically ``support'' the form being
evaluated. This default can be overridden by supplying an explicit list,
fns
, of functions, using option :fns fns
; these will then be the
functions whose calls are eligible for inclusion in the backtrace. The
special value :fns :all
will allow all user-defined function calls in the
backtrace. This value can be useful when using oracle-apply
, for
example, since the function being applied isn't typically included as
a syntactic supporter of the form being evaluated.
The :compile
option. Wet
uses the trace$
utility to modify the
definitions of affected functions so that they can record information for the
backtrace. As described above, these affected functions are those that
syntactically ``support'' the form unless specified by the :fns
option.
As is the case for trace$
-- see trace$ -- the new definitions of
these affected functions may or may not be compiled. For trace$
and for
wet
, the default is to compile the new definition if and only if the
original definition was compiled, except: For wet
, if option
:fns :all
is provided, then the default is not to compile the affected
definitions. And for trace$
and wet
, the :compile
option
overrides the default, to specify what will be compiled: value :same
to
compile each affected function if and only if its original definition was
compiled, value t
to compile all affected functions, and value nil
to
skip compilation.
The :book
option. Wet
actually works by temporarily including a
community book,
(include-book "misc/wet" :dir :system)and then passing its arguments to macro
wet!
, defined in that book.
The keyword argument :book
allows you to specify a different book that
defines a macro wet!
to which to pass its arguments. If the value of
:book
is a string, then the book named by that string is temporarily
included using include-book
: (include-book "bk")
. Otherwise
:book
should be a list of arguments, to be provided (unevaluated) to
include-book
, for example ("my-wet" :dir :my-utils)
. Thus you
can experiment by copying community book books/misc/wet.lisp
to your
own directory and making modifications to the copy. If you make changes, we
invite you to share them with the ACL2 community (see books). Note that you
can also supply :book nil
, in which case the definition of wet!
in
your current session will be used without including a book.Also see trace$ for a general tracing utility. As mentioned above, wet
is implemented using trace$
. Wet
actually first applies
untrace$
; upon completion, wet
then applies trace$
to
re-trace any functions that it had untraced, using their original trace
specs.