TRACE!

trace the indicated functions after creating an active trust tag
Major Section:  TRACE

Example:
(trace! (fact :native t :entry *foo*))

General Form:
(trace! spec1 ... specn)
where the fni are suitable arguments to trace$.

Trace! is a version of trace$ that avoids the need for an already-active trust tag (or ``ttag''; see defttag), as explained below. See trace$ for when a trust tag can be necessary.

See untrace$ for how to undo the effect of trace!.

The evaluation of a trace! form causes temporary creation of an active trust tag, :trace!, followed by the corresponding trace$ form. The trust tag will disappear when the call to trace! completes. Even though trace! will remove its temporary ttag, it will still print a ``TTAG NOTE'', which indicates that the session is suspect. See defttag and see ttags-seen for further remarks on this issue.

Because of the active trust tag, it is possible to do things with trace! that are useful but without logical justification. Below is an example of how to use trace! to cause a function call to change state, even though the function does not take state as a parameter.

ACL2 !>(defun fact (n)
         (declare (xargs :guard (natp n) :verify-guards nil))
         (if (zp n)
             1
           (* n (fact (1- n)))))

The admission of FACT is trivial, using the relation O< (which is known
to be well-founded on the domain recognized by O-P) and the measure
(ACL2-COUNT N).  We observe that the type of FACT is described by the
theorem (AND (INTEGERP (FACT N)) (< 0 (FACT N))).  We used the :compound-
recognizer rule ZP-COMPOUND-RECOGNIZER and primitive type reasoning.

Summary
Form:  ( DEFUN FACT ...)
Rules: ((:COMPOUND-RECOGNIZER ZP-COMPOUND-RECOGNIZER)
        (:FAKE-RUNE-FOR-TYPE-SET NIL))
Warnings:  None
Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)
 FACT
ACL2 !>(defun update-foo (n value state)
         (declare (xargs :stobjs state :verify-guards nil))
         (assign foo (cons (cons n value) (@ foo))))

Since UPDATE-FOO is non-recursive, its admission is trivial.  We observe
that the type of UPDATE-FOO is described by the theorem
(AND (CONSP (UPDATE-FOO N VALUE STATE))
     (TRUE-LISTP (UPDATE-FOO N VALUE STATE))).
We used primitive type reasoning.

(UPDATE-FOO * * STATE) => (MV * * STATE).

Summary
Form:  ( DEFUN UPDATE-FOO ...)
Rules: ((:FAKE-RUNE-FOR-TYPE-SET NIL))
Warnings:  None
Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)
 UPDATE-FOO
ACL2 !>(trace! (fact :exit (update-foo n value state)))

TTAG NOTE: Adding ttag :TRACE! from the top level loop.
 ((FACT :EXIT (UPDATE-FOO N VALUE STATE)))
ACL2 !>(assign foo nil)
 NIL
ACL2 !>(fact 7)
1> (ACL2_*1*_ACL2::FACT 7)
  2> (ACL2_*1*_ACL2::FACT 6)
    3> (ACL2_*1*_ACL2::FACT 5)
      4> (ACL2_*1*_ACL2::FACT 4)
        5> (ACL2_*1*_ACL2::FACT 3)
          6> (ACL2_*1*_ACL2::FACT 2)
            7> (ACL2_*1*_ACL2::FACT 1)
              8> (ACL2_*1*_ACL2::FACT 0)
              <8 NIL
            <7 NIL
          <6 NIL
        <5 NIL
      <4 NIL
    <3 NIL
  <2 NIL
<1 NIL
5040
ACL2 !>(@ foo)
((7 . 5040)
 (6 . 720)
 (5 . 120)
 (4 . 24)
 (3 . 6)
 (2 . 2)
 (1 . 1)
 (0 . 1))
ACL2 !>(verify-guards fact)

Computing the guard conjecture for FACT....

The guard conjecture for FACT is trivial to prove, given the :compound-
recognizer rules NATP-COMPOUND-RECOGNIZER and ZP-COMPOUND-RECOGNIZER,
primitive type reasoning and the :type-prescription rule FACT.  FACT
is compliant with Common Lisp.

Summary
Form:  ( VERIFY-GUARDS FACT)
Rules: ((:COMPOUND-RECOGNIZER NATP-COMPOUND-RECOGNIZER)
        (:COMPOUND-RECOGNIZER ZP-COMPOUND-RECOGNIZER)
        (:FAKE-RUNE-FOR-TYPE-SET NIL)
        (:TYPE-PRESCRIPTION FACT))
Warnings:  None
Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)
 FACT
ACL2 !>(assign foo nil)
 NIL
ACL2 !>(fact 7)
1> (ACL2_*1*_ACL2::FACT 7)
  2> (FACT 7)
    3> (FACT 6)
      4> (FACT 5)
        5> (FACT 4)
          6> (FACT 3)
            7> (FACT 2)
              8> (FACT 1)
                9> (FACT 0)
                <9 NIL
              <8 NIL
            <7 NIL
          <6 NIL
        <5 NIL
      <4 NIL
    <3 NIL
  <2 NIL
<1 NIL
5040
ACL2 !>(@ foo)
((7 . 5040)
 (7 . 5040)
 (6 . 720)
 (5 . 120)
 (4 . 24)
 (3 . 6)
 (2 . 2)
 (1 . 1)
 (0 . 1))
ACL2 !>(trace! (fact :exit (progn (update-foo n value state)
                                  (cons traced-fn values))))

TTAG NOTE: Adding ttag :TRACE! from the top level loop.
 ((FACT :EXIT (PROGN (UPDATE-FOO N VALUE STATE)
                     (CONS TRACED-FN VALUES))))
ACL2 !>(assign foo nil)
 NIL
ACL2 !>(fact 7)
1> (ACL2_*1*_ACL2::FACT 7)
  2> (FACT 7)
    3> (FACT 6)
      4> (FACT 5)
        5> (FACT 4)
          6> (FACT 3)
            7> (FACT 2)
              8> (FACT 1)
                9> (FACT 0)
                <9 (FACT 1)
              <8 (FACT 1)
            <7 (FACT 2)
          <6 (FACT 6)
        <5 (FACT 24)
      <4 (FACT 120)
    <3 (FACT 720)
  <2 (FACT 5040)
<1 (ACL2_*1*_ACL2::FACT 5040)
5040
ACL2 !>(@ foo)
((7 . 5040)
 (7 . 5040)
 (6 . 720)
 (5 . 120)
 (4 . 24)
 (3 . 6)
 (2 . 2)
 (1 . 1)
 (0 . 1))
ACL2 !>

Finally, we remark that the use trace! can cause errors in situations where tracing is automatically suspended and re-introduced. This is likely to be a rare occurrence, but consider the following example.

(trace! (lexorder :native t :multiplicity 1))
(certify-book "foo" 0 t)
If the certify-book causes compilation, you may see an error such as the following.

ACL2 Error in (CERTIFY-BOOK "foo" ...):  The keyword :NATIVE cannot
be used in a trace spec unless there is an active trust tag.  The trace
spec (LEXORDER :NATIVE T :MULTIPLICITY 1) is thus illegal.  Consider
using trace! instead.  The complete list of keywords that require a
trust tag for use in a trace spec is: (:NATIVE :DEF :MULTIPLICITY).

This error is harmless. The function will appear, when calling (trace$), to remain traced, but in fact there will be no tracing behavior, so you may want to call untrace$ on the function symbol in question.