The Source Linked Debugger

The Emacs-based source linked debugger for Quintus Prolog works very much like the QUI debugger (see dbg-sld), with a few significant differences. This document describes the differences.

In order to enable the Emacs-based debugger, execute the Emacs command <ESC> x enable-prolog-source-debugger; to disable it, type <ESC> x disable-prolog-source-debugger. If you would like always to use the source-linked debugger when debugging Quintus Prolog code under Emacs, put the following in your .emacs file:

     (add-hook 'comint-prolog-hook 'enable-prolog-source-debugger)

Alternatively, under Prolog you may load library(emacsdebug) and then execute the Prolog goal emacs_debugger(_,on) to enable source-linked debugging, emacs_debugger(_,off) to disable it, and emacs_debugger(State,State), to see whether it is enabled or not (State will be bound to on if enabled and off if disabled).

The first obvious difference when running the Emacs-based debugger compared to the QUI one is that it doesn't have any buttons or menu to control it. Therefore all commands are keyboard-based. Where possible, the commands are the same as those used in the standard debugger, so most of them should be easy to remember. The most important command in the Emacs-based debugger, as in the standard debugger is the help command, invoked by a single h or ? character. This command displays the following summary:

       c  creep         <RET> creep            <SPC> creep
       l  leap           +  spy goal/pred     b  break
       s  skip           -  nospy goal/pred   a  abort
       z  zip            [  frame up          ?  help
       n  nonstop        ]  frame down        h  help
       q  quasi-skip     |  frame back        =  debugging
       r  retry          f  fail              .  edit definition
       w  open extra window                   x  close extra window

The commands in the first column behave exactly as they do in the QUI debugger. The spy and nospy commands place a spypoint on the current predicate when at a head port, and on the current goal when at any other port. The frame up/down/back commands do exactly what the corresponding QUI debugger commands do, as do break and abort. The debugging command just invokes the standard debugging/0 built-in predicate, showing the current debugging and leashing modes, as well as listing the currently active spypoints.

The open/close extra window commands prompt for a single character to select the "extra" window to display, offering the choices b=bindings; s=standard; and a=ancestors. The bindings window is probably the most useful of the three.

Finally, the edit definition command opens puts the file being debugged in an editor buffer, putting point at the location of the current debugger port (where the arrow is). You may edit and save the file, and then recompile it. It is recommeded that you recompile the whole file rather than just the part you have changed, because the debugger keeps track of the times files are written and compiled, disabling source linking when the file on disk is newer than the code loaded into Prolog.

The graphical arrows of the QUI debugger are simulated by a two-character sequence in the Emacs-based debugger. The Call, Done and determinate Head ports are signified by ->. Exit and nondeterminate Head ports are signified by =>. Redo and Fail are shown as <-. The Exception port is indicated by <#. Finally, where the QUI debugger shows a "hollow" arrow to signify that the currently shown port is not actually the active port but an ancestor of it, the Emacs-based debugger shows ^>.

The Emacs-based debugger currently offers no way to change the leashing; you can do that using the usual Prolog leash/1 built-in predicate. Similarly, it offers no way to set a spyoint except when debugging a call to the predicate or goal to be spied. Again, the usual spy/1 and add_spypoint/1 built-in predicates can accomplish this. Finally, the Emacs-based debugger offers no direct way to set the print format. To change this you must use the window_format/3 command exported from the emacs_debug module:

     window_format(+Window, -Oldformat, +Newformat)

where Window is one of: source, bindings, ancestors, or standard, and Newformat is a list of valid options for the last argument to write_term/[2,3]. The default format for all windows is

     [quoted(true), portrayed(true), max_depth(5)]