\chapter{Debugging}
\label{errorsystem}
\label{debugging}

It will become apparent to you many times during a program's evolution that
the program is not entirely right.  Instead of blaming the program for these
faults, strange creatures called bugs are blamed.  In this way, the programmer
remains free of guilt.  Errors and incorrect results are sure signs that bugs
lurk inside a program, for the bugs cause the aberrant behavior.

Debugging usually depends on empirical testing, thus it can serve to reinforce
the programmer's belief in the correctness of his program, and it can aid in
correction of a program which is not behaving as expected, but it cannot {\em
prove} that the program is correct.  If the program succeeds during debugging,
there may be some yet-to-be-uncovered bug lurking within, waiting to show
itself in some later run.  The best protection against program bugs is a
program that is well thought out and clearly set down in code.

Scheme provides several features to aid in debugging programs.  Among these
are the ability to {\tt trace} the execution of a procedure, the ability to
examine the current environment, and the ability to set {\em breakpoints}.
From a breakpoint, you can examine the recent process history of your program.

Bugs are sometimes detected by the occurrence of an error while the program is
running.  When Scheme encounters an error, execution is abruptly halted, you
are notified, and you are given the choice of either aborting from the error,
or entering an {\em error read-eval-print-loop}.  (See
section~\ref{rep-loops}).  Here is a typical error response:
\begin{scheme}
(+ 1 'a)

Illegal datum in second argument position A
Within procedure \#{}[PRIMITIVE PROCEDURE \&{}+]
There is no environment available;
using the current read-eval-print environment.
\end{scheme}

The error message---a concise description of the error---is the first thing
printed.  In this case, the error was a bad argument: the symbol {\tt a} to
the {\tt +} procedure.

The error message is sometimes followed by information about the environment
in which the error occurred.  This is useful because the debugger includes
some advanced features that allow you to probe or modify the environment.
(See sections \ref{wheresection} and \ref{debugsection}.)  Sometimes, as in
the example above, the system will tell you that no environment was found at
all, which means that you are in the environment of the previous REP loop.

If you choose not to abort, the mode line information (indicating
Scheme's status) will change from
\begin{scheme}
I 1 \verb|[|REP Loop\verb|]|
\end{scheme}
to
\begin{scheme}
I 2 \verb|[|Error\verb|]|
\end{scheme}
\noindent
to indicate that you are in an error REP loop.  The number 2 signals that this
REP loop is subordinate to a level 1 (top level) REP loop.  See sections
\ref{rep-loops} and \ref{errorrep} for information on REP loops.

If you do choose to abort, you will return to the previous REP loop and you
can try another expression.  Beginning programmers have a tendency to
automatically abort as soon as an error is encountered.\footnote{This is
similar to the behavior of children writing or drawing, who will ordinary
crumple up the paper and start over again as soon as they make a mistake.
Presumably, the error triggers some kind of ``abort'' reaction whose goal is
to return the cognitive process to a simple known state as rapidly as
possible.  One of the useful things we can learn from programming is the
possibility of {\em debugging} to correct our mistakes.} This is unfortunate,
because it destroys information about the error that can be used to aid in
debugging.  When you encounter an error, take some time to {\em think} about
the error, rather than immediately aborting as a ``knee-jerk'' reaction.

Scheme provides system features that make use of the error environment in
order to help you to try and locate where the error occurred.  That is, you
can see what expressions were being executed at the time of the error.  The
environment and history examiners, \ide{where} and \ide{debug}, respectively,
are used for this.  Of course, much can be determined about the state of the
system at the time of the error by simply examining the values of variables in
the error environment.

The program may run without error, but the result produced may
be preposterous---another indication of bugs.  For instance,
\begin{scheme}
(prime? 7)     \ev  \schfalse
\end{scheme}
\noindent
In this situation, Scheme offers no clue as to the location of the
bug---you're on your own.  You might produce a theory about the cause of the
deviant behavior and then test it using the {\tt trace} facility.  You can
also edit the program to insert checks and traces.

Debugging, like programming, is an acquired skill and an art.  The tools
available to you are described in the sections below.  Use them creatively.
The laboratory assistants are there to help you.  Feel free to ask them for
help.

\section{Read-Eval-Print Levels}
\label{rep-loops}

The Scheme interpreter works by running a \defining{read-eval-print} loop (or
REP loop).  This means that expressions are read, evaluated, and the result of
the evaluation is printed on the console.  A REP loop can be nested inside
another REP loop.  This is what happens at a breakpoint or an error.  The mode
line indicator is changed to {\tt Break} or {\tt Error} to signify that
another nested REP loop has been entered.  The Emacs commands \ctlc{G},
\ctlc{U}, and \ctlc{X} all affect the REP level you are at.
The {\tt Level} is the degree of nesting of REP loops, where level 1 is the
topmost REP loop.  Below are listed some control characters used to interrupt
programs on various levels, also listed are other useful control characters.

\begin{description}
\item [\ctlc{B}] Enters a Breakpoint.  The new level will be one higher
than it was before the breakpoint.

\item [\ctlc{G}] Halts execution at all levels. Returns to the top level
(level 1) REP loop.

\item [\ctlc{U}] Halts execution locally.  Returns to the previous REP
loop, unless already at the top level loop.  That is, the new level is one
less than it used to be, unless you were already at level 1.

\item [\ctlc{X}] Halts execution locally.  Returns to the current REP
loop.  The level number remains unchanged.
\end{description}

Once again, the different mode line indicators are: {\tt REP}, ordinary
read-eval-print loop; {\tt Break}, a breakpoint REP loop; and {\tt Error} an
error REP loop.

\section{Breakpoint and Error REP Loops}
\label{errorrep}

As mentioned above, you can choose to enter an error REP loop whenever an
error is signalled.  This error may have been signalled internally by Scheme,
or it may have been signalled by an \ide{error} statement that you inserted in
the program yourself.  Loops of a slightly different flavor can be entered via
the \ide{bkpt} special form or by typing a \ctlc{B} at the keyboard.

The Scheme breakpoint facility allows you to pause execution of a program in
midstream, whereupon you can examine and modify the values of local variables,
among other things.  When you pause execution and enter a breakpoint, Scheme
runs a REP loop just as it normally does---you type expressions and the
interpreter evaluates them and prints their value.  The difference is that the
environment in which these expressions are evaluated is not the global
environment, but rather the environment from which the breakpoint was entered.

Breakpoints can be entered in the following ways:

\begin{itemize}
\item Typing \ctlc{B} at the keyboard.  This will always leave you in the
environment of the previous (lower level number) REP loop.

\item Executing a procedure that had a breakpoint installed via one of the
commands \ide{break}, \ide{break-entry}, \ide{break-exit}, or
\ide{break-both}.  This will leave you in the environment created to
evaluate the body of the ``broken'' procedure.

\item Executing the procedure \ide{bkpt}.  This will leave you in the
environment in which the {\tt bkpt} is evaluated.

\item Encountering an error.  You are left in the environment in which the
expression causing the error was evaluated.  Because the Scheme interpreter is
optimized so that it saves only environments that are needed for subsequent
evaluations, errors may occur when there is no environment at all. In this
case a warning is printed and you are left in the environment of the previous
(lower level number) REP loop.
\end{itemize}

To continue from a breakpoint, evaluate the expression \ide{(proceed)}.  The
interpreter will continue as though the breakpoint had not occurred.  If the
REP loop was entered because of a {\tt bkpt} or {\tt error} special form,
evaluating {\tt (proceed \var{expression})} will evaluate the expression and
return that value for the value of the special form.

If the REP loop was entered because of a {\tt break-entry} or {\tt
break-exit}, {\tt (proceed \var{expression})} will evaluate {\em expression}
and return that value in place of the value which would be calculated by the
``broken'' procedure.  This is convenient if you realize that a procedure is
calculating the wrong answer. You may want to quickly try out the rest of your
program as though this procedure really worked.  You can {\tt break-entry} the
questionable procedure, and then use {\tt (proceed \var{expression})} to
simulate the way the procedure should work.

Instead of continuing the program by using {\tt proceed}, you can type
\ctlc{G} which aborts execution and returns to the top-level REP loop.  This
is frequently done after ``snooping around'' to discover the problem: type
\ctlc{G} and try again.  Similarly, \ctlc{U} halts execution and returns to
the preceding (lower level number) REP loop. \ctlc{X} resumes the current REP
loop.  This is useful, for example, when you ask Scheme to pretty-print a long
procedure and want to stop it in the middle of the printing and get back to
the current REP loop prompt.

For REP loops caused by errors in Scheme primitives, evaluating {\tt
(proceed)} will simply call the primitive again.  This is rarely what you want
to do. You should investigate the problem, fix the program, and try it all
over again.

\section{Trace and Break}
\label{trace}
\label{break}

Scheme provides procedures that allow you to trace the execution of a program
and set breakpoints in the program.  A procedure can be traced on entry or on
exit.  In addition, a breakpoint can be set when the procedure is entered or
exited.  When the entry of a program is traced, the arguments passed to it are
shown at each entry.  When the exit of a program is traced the arguments
passed and the result returned are shown at each exit.  Here is an example.
The indicators preceding the user's input show the level and REP loop
information that appears in the mode line at each point.
\begin{scheme}
 [1 REP] (define (fact n)
           (cond ((zero? n) 1)
                 (else (* n (fact (-1+ n))))))
FACT 
     
 [1 REP] (trace-entry fact)
     
 [1 REP] (trace-exit fact)

 [1 REP] (fact 3)
 Entering <\#{}<COMPOUND-PROCEDURE FACT> 3>
 Entering <\#{}<COMPOUND-PROCEDURE FACT> 2>
 Entering <\#{}<COMPOUND-PROCEDURE FACT> 1>
 Entering <\#{}<COMPOUND-PROCEDURE FACT> 0>
 1 <== <\#{}<COMPOUND-PROCEDURE FACT> 0>
 1 <== <\#{}<COMPOUND-PROCEDURE FACT> 1>
 2 <== <\#{}<COMPOUND-PROCEDURE FACT> 2>
 6 <== <\#{}<COMPOUND-PROCEDURE FACT> 3>
 6

 [1 REP] (untrace fact)

 [1 REP] (fact 3)
 6

 [1 REP] (break-exit fact)

 [1 REP] (fact 2)
 1 <== <\#{}<COMPOUND-PROCEDURE FACT> 0>
 Breakpoint on exit

 [2 Break] (*args*)
 (0) 

 [2 Break] (*result*)
 1 

 [2 Break] (proceed -1) 
 -1 <== <\#{}<COMPOUND-PROCEDURE FACT> 1>
 Breakpoint! Level: 2

 [2 Break] (proceed) 
 -2 <== <\#{}<COMPOUND-PROCEDURE FACT> 2>
 Breakpoint on exit

 [2 Break] (proceed) 
 -2 
\end{scheme}

During the breakpoint inserted by \ide{break-exit}, the procedures
\ide{*proc*}, \ide{*args*}, and \ide{*result*} can be called to see the
``broken'' procedure, the values of the arguments, and the computed result
(available only during an exit break), respectively.  Type {\tt (proceed)} to
proceed from the breakpoint and return the value shown by {\tt (*result*)}, or
type {\tt (proceed \var{expression})} to return the value of \var{expression}.
In the above example, we made {\tt (fact 0)} return $-1$ instead of 1.

\section{The Environment Examiner: Where}
\label{wheresection}

The {\tt where} procedure provides a method of examining and modifying
environments.  {\tt Where} is a procedure of 0 or 1 arguments that enters a
read-execute command loop when called.  Unlike a REP loop, this loop reads one
letter and treats it as a command to be performed.  Scheme will prompt for the
one-character command at the bottom of the screen in the Emacs echo area.  To
give a command, just type the character---you needn't press {\sc return}.

If called with no arguments, {\tt where} examines the current REP loop
environment.  The optional argument can be an environment or an object with an
environment associated with it, such as a procedure.  Below is an example of
{\tt where} being called at a breakpoint in a Scheme procedure.  This
illustrates some of the things which can be done with {\tt where}.

While the {\tt where} procedure is a very useful debugging aid, using it
effectively requires a good understanding of Scheme's environment structures.
For this reason you may find it less confusing to use only the {\tt C} command
initially.

Here is a brief description of each {\tt where} command.
\begin{description}
\item [{\tt ?}] Prints a summary of the {\tt where} command
characters.

\item[{\tt A}] (for all) Displays the bindings in all of the frames
in the current environment chain.

\item [{\tt C}] (for current) Displays the bindings in the current frame.

\item [{\tt E}] (for eval) Enters a REP loop in the current environment.

\item [{\tt N}] (for name) Shows the name of procedure that created
current environment frame.

\item [{\tt P}] (for parent) Moves up to the parent of the current
environment frame, then does a C command.

\item [{\tt Q}] (for quit) Exits {\tt where}.

\item [{\tt S}] (for son) Move to the son of the current environment
frame. This undoes a P command.

\item [{\tt V}] (for value) Evaluates one expression in the current frame
and  pretty-prints the result.

\item [{\tt W}] (for {\tt where}) Evaluate an expression in the current
frame and call {\tt where} on the result.
\end{description}

Here is an example of using {\tt where}.  The indicators at the left of the
user input show the information that would appear in the buffer mode line, and
in the prompts in the echo area:
\begin{scheme}
 [1 REP] (define (one x y z) 
           (define (two x y z)
             (define (three x y z)
               (bkpt "In procedure three environment"
                     (list x y z)))
             (three 1 2 3))
           (two 4 5 6))
     
 ONE 
     
 [1 REP] (one 'a 'b 'c)
 In procedure three environment (1 2 3)
 Breakpoint

 [2 Break] (where)
 Environment Inspector
 [3 Where] c
 Frame created by the procedure THREE.
 Depth (relative to starting frame): 0
 Has bindings:
     
 X = 1
 Y = 2
 Z = 3
\end{scheme}


The C command prints the variable bindings in the currently selected
environment frame.  Since the breakpoint occurred inside the execution of the
procedure {\tt three}, the current environment is the one resulting from the
application of C to the arguments 1 2 3.

The P command moves to the frame in which {\tt three} was defined.  In this
case the parent is the frame created by the application of the procedure {\tt
two} to the arguments 4 5 6.
\begin{scheme}     
 [3 Where] p
 Frame created by the procedure TWO.
 Depth (relative to starting frame): 1
 Has bindings:

 X = 4
 Y = 5
 Z = 6
 THREE = \#{}<COMPOUND-PROCEDURE THREE>

     
 [3 Where] p
 Frame created by the procedure ONE.
 Depth (relative to starting frame): 2
 Has bindings:
     
 X = A
 Y = B
 Z = C
 TWO = \#{}<COMPOUND-PROCEDURE TWO>
     
     
 [3 Where] p
 Frame created by a MAKE-PACKAGE special form.
 Depth (relative to starting frame): 3
 Has bindings:

 USER-INITIAL-ENVIRONMENT = \#{}<ENVIRONMENT 13679124>
 ONE = \#{}<COMPOUND-PROCEDURE ONE>
\end{scheme}     
Here we have reached the user initial environment in which the top most
procedure {\tt one} was defined.  That's enough $\ldots$
\begin{scheme}
 [3 Where] q
\end{scheme}
\noindent
and we are back in the REP loop where we started.  We can continue the program
by typing {\tt (proceed)}.

Notice that we could stop at any environment and create a REP loop in it by
using the E command.  This allows you, for example, to define missing
variables when you encounter an {\tt unbound variable} error.  Similarly, you
can use the {\tt V} (one expression) command to evaluate a single expression
in any of the frames in the environment chain.

\section{The Scheme Debugger: Debug}
\label{debugsection}

A breakpoint will allow you only to examine local variables and to evaluate
expressions at the breakpoint.  Often, however, tracking down a bug will
require a more extensive investigation of the circumstances surrounding the
error.  The Scheme debugger system provides additional capabilities to aid in
debugging.

The history examiner, entered using the {\tt debug} command, enables you to
examine the history of execution of an expression.  The environment of any
procedure application may then be examined and the interrupted process may be
continued from any of the displayed nodes of evaluation.

Calling the {\tt debug} procedure from within a Scheme breakpoint enters a
read-execute loop, which accepts single-character commands which enable you to
move backwards and forwards in the history of the expressions which have been
evaluated.  You can also examine procedures and variables at the different
evaluation levels.  The prompt is {\tt Debug}.  Just as with {\tt where},
Scheme prompts for the commands in the mode line at the bottom of the screen.

In order to make good use of the debugger, you must understand the concept of
a \defining{reduction} and a \defining{subproblem}.  The interpreter evaluates
an expression by {\em reducing} it to a simpler expression.  In general,
Scheme's evaluation rules designate that evaluation proceeds from one
expression to the next by either starting to work on a {\em subexpression} of
the given expression, or by {\em reducing} the entire expression to a new
(simpler, or reduced) form.  Thus, a history of the successive forms processed
during the evaluation of an expression will show a sequence of subproblems,
where each subproblem may involve a sequence of reductions.  The best way to
get a feeling for how reductions and subproblems work is to write some test
expressions and play with them using the {\tt debug} procedure.


Here is a summary of the {\tt debug} commands.
\begin{description}
\item [{\tt ?}] Prints a summary of the {\tt debug} commands.

\item [{\tt B}] (for back) Moves back to the ``previous expression,'' that was
being processed.  What this means is as follows: One goes backwards along the
sequence of reductions that produced the current expression until reaching the
subproblem that led to this chain of reductions.  Then one moves ``upward'' in
the tree of subproblems, until reaching the expression that was typed at the
REP loop which initiated the whole process.

\item [{\tt C}] (for current) Shows all the variable bindings in the
environment in which the current subproblem was being evaluated.
  
\item [{\tt D}] (for down) Moves down to a lower subproblem level.  This
is the subproblem which was evaluated after (in time) the current one.

\item [{\tt E}] (for eval) Enters a REP loop in the environment in which
the current subproblem was being evaluated.

\item [{\tt F}] (for forward) Moves to the ``next'' expression after the current
one.  The order is (the opposite of) the one described for the B command.

\item [{\tt G}] (for go) Goes to a particular subproblem and reduction
level.  {\tt Debug} asks you for the numbers.  Each expression has two numbers
to indicate a subproblem and a reduction of that subproblem.  Simplified (more
reduced) expressions have lower reduction numbers.  Lower level (smaller
subproblem) expressions have lower subproblem numbers.  Thus the current error
expression is numbered $(0,0)$.

\item [{\tt H}] (for history) Prints a summary of the entire history.
This is like typing B repeatedly.

\item [{\tt I}] (for information) Redisplays the error message.

\item [{\tt L}] (for list current expression) Pretty-prints the
current expression.

\item [{\tt P}] (for procedure) Pretty-prints current procedure.

\item [{\tt Q}] (for quit) Exits {\tt debug} returning to the environment in
which the error occurred, and at the expression which caused the error.

\item [{\tt R}] (for reductions) Prints all the reductions of the current
subproblem level.

\item [{\tt S}] (for subproblem) Prints the current subproblem and reduction
showing where in the evaluation history the user is.

\item [{\tt U}] (for up) Moves up to the previous subproblem level.
This is a subproblem which includes as one of its parts the current
subproblem.  It has a higher subproblem number.

\item [{\tt V}] (for value) Asks for an expression and evaluates it in
the environment in which the current subproblem was being evaluated.

\item [{\tt W}] (for where) Enters {\tt where} on the current environment

\item [{\tt Z}] (for zap) Asks for an expression and evaluates it in
the current environment.  The value of the expression is used in place of the
value the current subproblem would have returned, and execution is resumed
from this point in the original evaluation.
\end{description}

For a first look at the debugger we will use several of the common commands
just to see how they work.  Here is a demonstration.
\begin{scheme}
 [1 REP] (define (fact n)
           (if (zero? n)
               l
               (* n (fact (-1+ n)))))
 FACT 
     
 [1 REP] (fact 3)
 Unbound Variable L
 Error!
     
 [2 Error] (debug)
 Subproblem Level: 0  Reduction Number: 0
 Expression:
 L 
 within the procedure FACT.
 applied to (0)

 [3 Debug]
\end{scheme}

The application of the procedure {\tt fact} caused an error.  We then called
the debugger, which printed the expression whose evaluation caused the error
to occur.  The ``Subproblem Level'' and the ``Reduction Number'' are ways of
numbering expressions in the history.  The procedure whose body is currently
being evaluated, as well as the arguments passed to it are displayed.  The
debugger accepts one letter commands which can be listed by typing {\tt ?}.

The factorial problem above has a simple typo; the letter {\tt L} is used
instead of the number 1 in the {\tt if} form, resulting in an {\tt unbound
variable} error.  The debugger indicates that the error occurred when {\tt
fact} was called with 0 as its argument.

Although the bug in this case is easy to spot, we can look through the
evaluation history, to see how the evaluation proceeds.  The command {\tt H}
lists a summary of the history.

\begin{scheme}

 [3 Debug] h
 Sub Prb. Procedure Name    Expression

 0                  FACT    L
 0                  FACT    (IF (ZERO? N) L (* N (FACT (-1+ N))))
 0                  FACT    (FACT (-1+ N))
 1                  FACT    (* N (FACT (-1+ N)))
 2                  FACT    (* N (FACT (-1+ N)))
 3                  FACT    (* N (FACT (-1+ N)))
 4                          (PRINT (SCODE-EVAL SCODE USER-CURRENT-ENVI ... 
 5                          (SEQUENCE (SETUP-HISTORY! MAX-SUBPROBLEMS  ...
 6                  LOOP    (LOOP (CATCH (LAMBDA (AGAIN) (FLUID-LET (( ...
 7           DRIVER-LOOP    (DRIVER-LOOP (CATCH (LAMBDA (QUIT) (SET! T ...
 8  STARTUP-TOP-LEVEL-DR... (SEQUENCE (CATCH (LAMBDA (CONT) (SET! TOP- ...

 [3 Debug]
Quit! Level: 1
\end{scheme}
Lines 4 through 8 printed by the examiner are pieces of the Scheme REP loop
implementation itself, and should be ignored.

The most common error that can be corrected easily from the debugger is an
{\tt unbound variable} error.  In this case, there are two possibilities.  If
you forgot to define the variable you can use the {\tt B} command to search
back through the history until you find the place where the variable should
have been defined.  Then, use the {\tt E} command to enter a REP loop, and
define the variable.

\section{An Extended Debugging Session}

This section illustrates use of the Scheme \ide{debug} procedure in an
extended session.  The first example is the buggy {\tt fact} procedure that
was used as an example in section~\ref{debugsection} above.  The sequence
begins with the interaction already described in section~\ref{debugsection}.

\begin{scheme}
     
 [1 REP] (define (fact n)
           (if (zero? n)
               l
               (* n (fact (-1+ n)))))
     FACT 
     
 [1 REP] (fact 3)
     Unbound Variable L
     Error!
     
 [2 Error] (debug)
     Subproblem Level: 0  Reduction Number: 0
     Expression:
     L 
     within the procedure FACT.
     applied to (0)

 [3 Debug] s
     Subproblem Level: 0  Reduction Number: 0
     Expression:
     L 
     within Procedure FACT
     applied to (0)

\end{scheme}
The command {\tt S} displays the current subproblem.  The command {\tt B}
moves backwards in time.
\begin{scheme}
 [3 Debug] b
     Subproblem Level: 0  Reduction Number: 1
     Expression:
     (IF (ZERO? N) L (* N (FACT (-1+ N)))) 
     within Procedure FACT
     applied to (0)
     
 [3 Debug] b
     Subproblem Level: 0  Reduction Number: 2
     Expression:
     (FACT (-1+ N)) 
     within Procedure FACT
     applied to (1)
     
 [3 Debug] b
     Subproblem Level: 1  Reduction Number: 0
     Expression:
     (* N (FACT (-1+ N))) 
     within Procedure FACT
     applied to (1)
     
\end{scheme}
The {\tt F} command moves forward through reductions one at a time, in the
opposite direction to {\tt B}.
\begin{scheme}
 [3 Debug] f
     Subproblem Level: 0  Reduction Number: 2
     Expression:
     (FACT (-1+ N)) 
     within Procedure FACT
     applied to (1)
     
 [3 Debug] f
     Subproblem Level: 0  Reduction Number: 1
     Expression:
     (IF (ZERO? N) L (* N (FACT (-1+ N)))) 
     within Procedure FACT
     applied to (0)
     
 [3 Debug] f
     Subproblem Level: 0  Reduction Number: 0
     Expression:
     L 
     within Procedure FACT
     applied to (0)
     
\end{scheme}
We are now back at the subproblem level containing the offending expression.
The variable {\tt L} is unbound.  The {\tt Z} (for ZAP) command asks for an
expression to evaluate and returns this value as the value of the current
subproblem to the previous subproblem, that is, the containing subproblem.
Here we wanted {\tt L} to be 1.
\begin{scheme}
 [3 Debug] z
     Enter an expression to EVALUATE and CONTINUE with: 1 
     That evaluates to:
     
     1 
     Confirm: [Y or N] -> y
     6 
     
\end{scheme}
And here is the correct result.  Let's look at another example:
\begin{scheme}

 [1 REP] (define (square-root x)
           (define (square-root-iter ans)
             (if (close? ans)
                 ans
                 (square-root-iter (average (/ x ans) ans))))
           (define (close? ans)(< (abs (- (* ans asn) x)) .0001))
           (square-root-iter 1))

 SQUARE-ROOT 

 [1 REP] (square-root 4)
 Unbound Variable ASN
 Error! Level: 2

 [2 Error] (debug)
 Subproblem Level: 0  Reduction Number: 0
 Expression:
 ASN 
 within Procedure CLOSE?
 applied to (1)

 [3 Debug] b
 Subproblem Level: 1  Reduction Number: 0
 Expression:
 (* ANS ASN) 
 within Procedure CLOSE?
 applied to (1)
 
 [3 Debug] b
 Subproblem Level: 2  Reduction Number: 0
 Expression:
 (- (* ANS ASN) X) 
 within Procedure CLOSE?
 applied to (1)

 [3 Debug] b
 Subproblem Level: 3  Reduction Number: 0
 Expression:
 (ABS (- (* ANS ASN) X)) 
 within Procedure CLOSE?
 applied to (1)

 [3 Debug] b
 Subproblem Level: 4  Reduction Number: 0
 Expression:
 (< (ABS (- (* ANS ASN) X)) .0001) 
 within Procedure CLOSE?
 applied to (1)
\end{scheme}
Above is a square root program that is divided into sub-procedures.  In the
program there is a bug.  The debugger was called to reveal that the unbound
variable {\tt ASN} is in the expression {\tt (* ans asn)} in the procedure
{\tt CLOSE?}.

Here is another example:

\begin{scheme}
 [1 REP] (define (sum term low high)
           (define (sum-iter sum index) 
             (if (> index high)
                 sum
                 (sum-iter (+ sum (term index)) (1+ index))))
           (sum-iter 0 low))
 SUM 

 [1 REP] (define (term-proc i)(if (evin? i) 1 0))
 TERM-PROC 

 [1 REP] (pp term-proc)
 (DEFINE (TERM-PROC I) (IF (EVIN? I) 1 0))

 [1 REP] (sum term-proc 1 5)
 Unbound Variable EVIN?
 Error!

 [2 Error] (debug)
 Subproblem Level: 0  Reduction Number: 0
 Expression:
 EVIN? 
 within Procedure TERM-PROC
 applied to (1)

 [3 Debug] b
 Subproblem Level: 1  Reduction Number: 0
 Expression:
 (EVIN? I) 
 within Procedure TERM-PROC
 applied to (1)

 [3 Debug] b
 Subproblem Level: 2  Reduction Number: 0
 Expression:
 (IF (EVIN? I) 1 0) 
 within Procedure TERM-PROC
 applied to (1)

 [3 Debug] b 
 Subproblem Level: 3  Reduction Number: 0
 Expression:
 (+ SUM (TERM INDEX)) 
 within Procedure SUM-ITER
 applied to (0 1)

 [3 Debug] h
 Sub Prb. Procedure Name    Expression

 0             TERM-PROC    EVIN?
 1             TERM-PROC    (EVIN? I)
 2             TERM-PROC    (IF (EVIN? I) 1 0)
 3              SUM-ITER    (+ SUM (TERM INDEX))
 4              SUM-ITER    (SUM-ITER (+ SUM (TERM INDEX)) (1+ INDEX))
\end{scheme}

The bug here is that the procedure {\tt EVEN?} was spelled {\tt EVIN?}, in the
definition of the procedure {\tt TERM-PROC}.  By looking at the history we can
see that the procedure {\tt SUM} was called somewhere at subproblem 4.  The
command {\tt G} used below goes to a specified subproblem and reduction.
Below we see the call to {\tt SUM} in subproblem 4, reduction 4.

\begin{scheme}
 [3 Debug] g
 Subproblem number: 4 
 Reduction Number (0 through 4 inclusive): 4 

 Subproblem Level: 4  Reduction Number: 4
 Expression:
 (SUM TERM-PROC 1 5) 
 within a MAKE-PACKAGE special form
 applied to (\#{}<ENVIRONMENT 13033164>)

 [3 Debug] c
 Frame created by a MAKE-PACKAGE special form.
 Has bindings:

 USER-INITIAL-ENVIRONMENT = \#{}<ENVIRONMENT 13833016>
 SUM = \#{}<COMPOUND-PROCEDURE SUM>
 TERM-PROC = \#{}<COMPOUND-PROCEDURE TERM-PROC>
\end{scheme}
The environment in which subproblem 4 was being evaluated is the {\tt
user-initial-environment}. The {\tt C} command displayes the variable bindings
in the evaluation environment of the current subproblem.  Which in this case
is the {\tt user-initial-environment}.  This is where {\tt evin?} should be
defined.  The {\tt V} command evaluates an expression in the current
environment.

\begin{scheme}
 [3 Debug] v
 [3 Eval] (define evin? even?)
 EVIN? 

 [3 Debug] c
 Frame created by a MAKE-PACKAGE special form
 Has bindings:

 USER-INITIAL-ENVIRONMENT = \#{}<ENVIRONMENT 13833016>
 SUM = \#{}<COMPOUND-PROCEDURE SUM>
 TERM-PROC = \#{}<COMPOUND-PROCEDURE TERM-PROC>
 EVIN? = \#{}'<COMPOUND-PROCEDURE EVEN?>

 [3 Debug] q

 [2 Error] (proceed) 
 2 
\end{scheme}

Above we defined the variable {\tt evin?} to have as its value the procedure
{\tt even?}. We then left the debugger.  By typing {\tt (proceed)} at the
error prompt we cause the program to continue with the evaluation of the
expression that caused the error, and the procedure completes returning the
correct answer.
