\documentstyle[11pt,reduce]{article}
\title{\bf Debugging in \REDUCE{}}

\date{}
\author{
H. Melenk \\[0.05in]
Konrad--Zuse--Zentrum \\
f\"ur Informationstechnik Berlin \\
Heilbronner Strasse 10 \\
D--10711 Berlin Wilmersdorf \\
Federal Republic of Germany \\[0.05in]
Email:  melenk@sc.zib--berlin.de}

\begin{document}
\maketitle

\section{Introduction}

The module {\bf rdebug} supports the use of the trace
and break debugging
facilities of Portable Standard LISP (PSL) for REDUCE
programming. These include
\begin{itemize}
\item Entry-Exit tracing of functions,
\item Assignment tracing,
\item Setting of break points,
\item Conditional trace and break.
\item Trace of rules when they fire.
\end{itemize}
In contrast to the bare LISP level tracing the values
are printed in algebraic style whenever possible. The
output has been specially tailored for the needs of
algebraic mode programming. Most features can be applied
without modifying the target program, and they can be
turned on and off dynamically at run time.

To make the facilities available, load the
module by a command
\begin{verbatim}
    load rdebug.
\end{verbatim}
Restriction: the investigated program should not be compiled, when the
{\bf trst} functions are to be applied.

\section{Trace: TR, UNTR}

The command {\bf tr} puts one or several procedures to
under trace. Every time such a function is executed, a message
is printed during the procedure entry and another one is generated
at the return time. The entry message records the 
actual procedure arguments equated to the dummy parameter
names, and at the exit time the procedure value is printed.
Recursive calls are marked by an indentation and a level number.

\begin{verbatim}
   tr <proc1>,<proc2>,...,<procn>;
\end{verbatim}
Here $<proc1>,<proc2>, \ldots ,<procn>$ are names of procedures
to be added to the set of traced procedures. Tracing is
stopped for one or several functions by the
command {\bf untr}:
\begin{verbatim}
   untr <proc1>,<proc2>,...,<procn>;
\end{verbatim}

\section{Assignment Trace: TRST, UNTRST}

One often needs information about the inner behavior of
a procedure, especially if it is a longer piece of code.
For a procedure declared in a {\bf trst} command 
\begin{verbatim}
   trst <proc1>,<proc2>,...,<procn>;
\end{verbatim}
all executed explicit assignments and passed labels inside these
procedures are printed
during procedure execution. For removing the extended
trace use a statement {\bf untrst} or {\bf untr}:
\begin{verbatim}
   untrst <proc1>,<proc2>,...,<procn>;
\end{verbatim}

Note: When your program contains a {\bf for} loop, 
{\small REDUCE} translates this to a sequential piece of
LISP instructions. When using {\bf trst}, the printout
is driven by the unfolded code. When the code contains a
{\bf for each in} command, the name of the control variable is
internally used to keep the remainder of the list during the loop
control, and you will see the corresponding assignments
in the printout rather than the individual values in the
loop steps. E.g.
\begin{verbatim}
   procedure fold(u); for each x in u sum x;
   trst fold;
   fold {z,z*y,y};
\end{verbatim}
produces the following output:
\begin{verbatim}
   fold being entered
      u:   {z,y*z,y}$
   x := (z,y*z,y)$
   g0003 := 0$
   g0003 := z$
   x := (y*z,y)$
   g0003 := y*z + z$
   x := (y)$
   g0003 := y*z + y + z$
   x := ()$
   fold = y*z + y + z$
\end{verbatim}
In this example the printed assignments for $x$ show the
various stages of the loop control. The variable $g0003$ is
an internally generated slot for the sum.

\section{Conditional tracing: TRWHEN}

The trace output can be tunrned on or off automatically by
a boolean expression which is linked to a traced procedure
by the command {\bf trwhen}:
\begin{verbatim}
   trwhen <name>,<boolean-expr>;
\end{verbatim}
The boolean expression must follow
standard {\small REDUCE} syntax. It may contain references
to global values and to
the actual parameters of the procedure. As long as the
procedure is not compiled, the original names of the dummy arguments
are used. For a compiled procedure the  original names 
are not available; instead the names $a1$, $a2$, $\ldots$
must be used. Example: the following procedure produces trace
output only if the main variable of its argument is $x$:
\begin{verbatim}
    procedure hugo(u); otto(u);
    tr hugo;
    trwhen hugo,mainvar(u)=x;
\end{verbatim}
Note: for a symbolic procedure, the {\bf trwhen} command
must be given in symbolic mode or with prefix $symbolic$.

\section{Breakpoints: BR, UNBR}

A {\bf break loop} is an interrupt of the program execution
where control is given temporarily to the terminal for
entering commands in a standard command -- evaluate -- print loop. 
When a break occurs, you can inspect the current
 environment or even alter it, and the
interrupted computation may be terminated or continued
\footnote{Not all cases allow a continuation.}. A break can be
caused
\begin{itemize}
\item by an internal error,
\item by an explicit call of the function $break$,
\item at entry and exit time of a procedure.
\end{itemize}

\subsection{Break switch}
When the switch {\bf break} is set on, every
evaluation error causes a break loop. Most of these
breaks are non-continuable; however, you have the 
opportunity to read the actual values of local variables
in the environment which caused the error.

\subsection{Break call}
A call
\begin{verbatim}
    lisp break();
\end{verbatim}
initiates an ``programmed" break loop. In contrast to
explicitly introduced write statements, a break loop
allows you to read actual values dynamically, e.g. if
you don't know the critical variables in advance.

\subsection{Breakpoint declaration}
When the command {\bf br} is given for a set of
procedures, the program execution is interrupted every
time such a procedure is entered and for a second time
when it is left.
\begin{verbatim}
   br <proc1>,<proc2>,...,<procn>;
\end{verbatim}
The break property can be removed by calling the command
{\bf unbreak}
\begin{verbatim}
   unbr <proc1>,<proc2>,...,<procn>;
\end{verbatim}

\subsection{Break loop control}
In a break situation the evaluation  is stopped temporarily
and the control returns to the terminal with a special prompt:
\begin{verbatim}
  break[1]1:
\end{verbatim}
The number in square brackets counts the break level - it is
increased when a break occurs inside a break; the normal
{\small REDUCE} statement counter follows. Each break loop supports its
own statement numbers and input and output buffers.
After terminating of a break loop the
previous statement counters and buffers are restored.

In a break loop all {\small REDUCE} commands can be
entered. Additionally, there is a set of single character commands
which allow you to control the break environment. All these
begin with an underscore character:

\begin{tabular}{r  l}
   \_a;    &  terminate break  and return to the top  REDUCE level\\
   \_c;    &  continue execution of interrupted procedure\\
   \_i;    &  print a backtrace (list of procedures in the call hierarchy)\\
   \_l \verb+<var>+;& read the content of the local variable  \verb+<var>+\\
   \_m;    &  print the last (LISP-) error message\\
   \_q;    &  terminate the break loop and return to the next higher level\\
\end{tabular}

Global variables can be accessed as usual in the {\small REDUCE} language.
They can also be set to different values in the break loop.
The inspect values assigned to dummy arguments and scalar variables of
procedures in the actual call hierarchy, you need a special command $\_l$.
These values cannot be altered in the break loop.
Example:
\begin{verbatim}
  procedure p1(x); 
    begin scalar y1; y1:=x^2; return p2(y1); end;
  procedure p2(q); q^2;
  br p2;
  x:=22;
  p1(alpha);
\end{verbatim}
In the corresponding break loop caused by calling $p2$ 
indirectly via $p1$, you can access the global $x$, the
local $x$ and $y1$ of $p1$ and the $q$ of $p2$:
\begin{verbatim}

p2 being entered

   q:   alpha**2$
Break before entering `p2'

break[1]1: x;

22

break[1]2: _l x;

alpha

break[1]3: _l y1;

     2
alpha

break[1]4: _l q;

     2
alpha


break[1]6: _c;
Break after call `p2', value `(expt (expt alpha 2) 2)'

break[1]1: _c;

     4
alpha
\end{verbatim}

\section{Conditional break: BRWHEN}

A break depending on a condition can be assigned to a procedure
using the command {\bf brwhen}
\begin{verbatim}
   brwhen <name>,<boolean-expr>; 
\end{verbatim}
The conventions correspond to those of {\bf trwhen}.

\section{Trace for rules and rule sets: TRRL, UNTRRL}

The command {\bf trrl} allows you to trace individual rules
or rule sets when they fire.
\begin{verbatim}
   trrl <rs1>,<rs2>,...,<rsn>;
\end{verbatim}
where each of the $<rs_i>$ is
\begin{itemize}
\item a rule or a rule set,
\item a name of a rule or rule set (that is a non--indexed variable which
      is bound to a rule or rule list),
\item an operator name, representing the rules assigned to this
      operator.
\end{itemize}
The specified rules are (re--) activated in {\small REDUCE} in
a style that each of them prints a report every time if fires.
The report is composed of the name or the rule or the 
name of the rule set plus the number of the rule in the set,
the form matching the left hand side (``input´´) and the 
resulting right hand side (``output´´). 
For an explicilty given rule, {\bf trrl} assigns a generated name.

With {\bf untrrl} you can remove the tracing from rules
\begin{verbatim}
   untrrl <rs1>,<rs2>,...,<rsn>;
\end{verbatim}
The rules are reactivated in their original form. Alternatively
you can use the command {\bf clearrules} to remove the
rules totally from the system. Please do not modify the
rules between {\bf trrl} and {\bf untrrl} -- the result
may be unpredictable.   

\section{Output control: TROUT, TRLIMIT}

The trace output can be redirected to a separate file
by using the command {\bf trout}, followed
by a file name in string quotes. A second call of {\bf trout}
closes the actual output file and assigns a new one. 
The file name NIL (without string quotes) causes the trace output 
to be redirected to the standard output device.

Remark: under Windows a file name starting with ``win:" causes
a new window to be opened which receives the complete 
output of the debugging services.

The integer valued share variable {\bf trlimit} defines
an upper limit for the number of items printed in formula
collections, e.g. when tracing a {\bf for each} loop. The
initial value is 5. A different value can be assigned to
increase or lower the output size.

If you want to select LISP style printing during trace, set
\begin{verbatim}
    lisp(trprinter!* := 'printx);
\end{verbatim}
after loading {\bf rdebug}.
 
\end{document}
