• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
      • Break-rewrite
      • Proof-builder
      • Accumulated-persistence
      • Cgen
      • Forward-chaining-reports
      • Proof-tree
      • Print-gv
      • Dmr
      • With-brr-data
      • Splitter
      • Guard-debug
      • Set-debugger-enable
        • Redo-flat
        • Time-tracker
        • Set-check-invariant-risk
        • Removable-runes
        • Efficiency
        • Explain-near-miss
        • Tail-biting
        • Failed-forcing
        • Sneaky
        • Invariant-risk
        • Failure
        • Measure-debug
        • Dead-events
        • Compare-objects
        • Prettygoals
        • Remove-hyps
        • Type-prescription-debugging
        • Pstack
        • Trace
        • Set-register-invariant-risk
        • Walkabout
        • Disassemble$
        • Nil-goal
        • Cw-gstack
        • Set-guard-msg
        • Find-lemmas
        • Watch
        • Quick-and-dirty-subsumption-replacement-step
        • Profile-all
        • Profile-ACL2
        • Set-print-gv-defaults
        • Minimal-runes
        • Spacewalk
        • Try-gl-concls
        • Near-misses
      • Std
      • Proof-automation
      • Macro-libraries
      • ACL2
        • Theories
        • Rule-classes
        • Proof-builder
        • Recursion-and-induction
        • Hons-and-memoization
        • Events
        • Parallelism
        • History
        • Programming
        • Operational-semantics
        • Real
        • Start-here
        • Debugging
          • Break-rewrite
          • Proof-builder
          • Accumulated-persistence
          • Cgen
          • Forward-chaining-reports
          • Proof-tree
          • Print-gv
          • Dmr
          • With-brr-data
          • Splitter
          • Guard-debug
          • Set-debugger-enable
            • Redo-flat
            • Time-tracker
            • Set-check-invariant-risk
            • Removable-runes
            • Efficiency
            • Explain-near-miss
            • Tail-biting
            • Failed-forcing
            • Sneaky
            • Invariant-risk
            • Failure
            • Measure-debug
            • Dead-events
            • Compare-objects
            • Prettygoals
            • Remove-hyps
            • Type-prescription-debugging
            • Pstack
            • Trace
            • Set-register-invariant-risk
            • Walkabout
            • Disassemble$
            • Nil-goal
            • Cw-gstack
            • Set-guard-msg
            • Find-lemmas
            • Watch
            • Quick-and-dirty-subsumption-replacement-step
            • Profile-all
            • Profile-ACL2
            • Set-print-gv-defaults
            • Minimal-runes
            • Spacewalk
            • Try-gl-concls
            • Near-misses
          • Miscellaneous
          • Output-controls
          • Macros
          • Interfacing-tools
        • Interfacing-tools
        • Hardware-verification
        • Software-verification
        • Math
        • Testing-utilities
      • Debugging

      Set-debugger-enable

      Control whether Lisp errors and breaks invoke the Lisp debugger

      Forms (see below for explanations and GCL exceptions):
      
      (set-debugger-enable t)         ; enable breaks into the raw Lisp debugger
      (set-debugger-enable :break)    ; same as above
      :set-debugger-enable t          ; same as above
      (set-debugger-enable :break-bt) ; as above, but print a backtrace first
      (set-debugger-enable :bt-break) ; as above, but print a backtrace first
      (set-debugger-enable :bt)       ; print a backtrace but do not enter debugger
      (set-debugger-enable :never)    ; disable all breaks into the debugger
      (set-debugger-enable nil)       ; disable debugger except when calling break$

      Introduction. Suppose we define foo in :program mode to take the car of its argument. This can cause a raw Lisp error. ACL2 will then return control to its top-level loop unless you enable the Lisp debugger, as shown below (except: the error message can take quite a different form in non-ANSI GCL).

      ACL2 !>(defun foo (x) (declare (xargs :mode :program)) (car x))
      
      Summary
      Form:  ( DEFUN FOO ...)
      Rules: NIL
      Warnings:  None
      Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)
       FOO
      ACL2 !>(foo 3)
      ***********************************************
      ************ ABORTING from raw Lisp ***********
      ********** (see :DOC raw-lisp-error) **********
      Error:  Attempt to take the car of 3 which is not listp.
      ***********************************************
      
      If you didn't cause an explicit interrupt (Control-C),
      then it may help to see :DOC raw-lisp-error.
      
      To enable breaks into the debugger (also see :DOC acl2-customization):
      (SET-DEBUGGER-ENABLE T)
      ACL2 !>(SET-DEBUGGER-ENABLE T)
      <state>
      ACL2 !>(foo 3)
      Error: Attempt to take the car of 3 which is not listp.
        [condition type: TYPE-ERROR]
      
      Restart actions (select using :continue):
       0: Abort entirely from this (lisp) process.
      [Current process: Initial Lisp Listener]
      [1] ACL2(1): [RAW LISP]

      Details. ACL2 usage is intended to take place inside the ACL2 read-eval-print loop (see lp). Indeed, in most Lisp implementations ACL2 comes up inside that loop, as evidenced by the prompt:

      ACL2 !>

      However, one can occasionally hit a raw Lisp error. Here is the above example again, this time for a GCL implementation, which unfortunately gives a slightly less aesthetic report.

      ACL2 !>(foo 3)
      
      Error: 3 is not of type LIST.
      Fast links are on: do (si::use-fast-links nil) for debugging
      Error signalled by CAR.
      Backtrace: funcall > system:top-level > lisp:lambda-closure > lp > acl2_*1*_acl2::foo > foo > car > system:universal-error-handler > system::break-level-for-acl2 > let* > UNLESS
      ACL2 !>

      Here, the user has defined foo in :program mode, with an implicit guard of t. The ACL2 evaluator therefore called the Lisp evaluator, which expected nil or a consp argument to car.

      By default, ACL2 will return to its top-level loop (at the same level of ld) when there is a raw Lisp error, as though a call of er with flag HARD has been evaluated. If instead you want to enter the raw Lisp debugger in such cases, evaluate the following form.

      (set-debugger-enable t)

      You can subsequently return to the default behavior with:

      (set-debugger-enable nil)

      Either way, you can enter the Lisp debugger from within the ACL2 loop by evaluating (break$). If you want break$ disabled, then evaluate the following, which disables entry to the Lisp debugger not only for Lisp errors but also when executing (break$).

      (set-debugger-enable :never)

      The discussion above also applies to interrupts (from Control-C) in some, but not all, host Common Lisps — perhaps all except for non-ANSI GCL, where interrupts will likely always put you into the debugger.

      It remains to discuss options :break, :bt, :break-bt, and :bt-break. Option :break is synonymous with option t, while option :bt prints a backtrace. Options :break-bt and :bt-break are equivalent, and each has the combined effect of :bt and :break: a backtrace is printed and then the debugger is entered.

      Note that set-debugger-enable applies not only to raw Lisp errors, but also to ACL2 errors: those affected by break-on-error. However, for ACL2 errors, entering the debugger is controlled only by break-on-error, not by set-debugger-enable. For ACL2 errors encountered after evaluating (break-on-error t), the set-debugger-enable values of :bt, :break-bt, and :bt-break will result in the same effect: in many host Lisps, this effect will be to cause a backtrace to be printed.

      Remark for Common Lisp hackers (except for the case that the host Lisp is non-ANSI GCL). You can customize the form of the backtrace printed by entering raw Lisp (with :q) and then redefining function print-call-history, whose definition immediately precedes that of break-on-error in ACL2 source file ld.lisp. Of course, all bets are off when defining any function in raw Lisp, but as a practical matter you are probably fine as long as your books are ultimately certified with an unmodified copy of ACL2. If you come up with improvements to print-call-history, please pass them along to the ACL2 implementors.