153 lines
5.1 KiB
HTML
153 lines
5.1 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
|
|
<!Originally converted to HTML using LaTeX2HTML 95 (Thu Jan 19 1995) by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds >
|
|
<HEAD>
|
|
<TITLE> Ensuring Proper Termination</TITLE>
|
|
</HEAD>
|
|
<BODY>
|
|
<meta name="description" value=" Ensuring Proper Termination">
|
|
<meta name="keywords" value="lp">
|
|
<meta name="resource-type" value="document">
|
|
<meta name="distribution" value="global">
|
|
<P>
|
|
<BR> <HR>
|
|
<A HREF="node47.html"><IMG ALIGN=BOTTOM ALT="next" SRC="next_motif.gif"></A>
|
|
<A HREF="node41.html"><IMG ALIGN=BOTTOM ALT="up" SRC="up_motif.gif"></A>
|
|
<A HREF="node45.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="previous_motif.gif"></A> <BR>
|
|
<A HREF="lp.html"><B>Contents</B></A>
|
|
<B> Next:</B>
|
|
<A HREF="node47.html"> Abstraction</A>
|
|
<B>Up:</B>
|
|
<A HREF="node41.html"> Programming Techniques</A>
|
|
<B> Previous:</B>
|
|
<A HREF="node45.html"> Recursion on Numbers</A>
|
|
<BR> <HR> <P>
|
|
<H1> Ensuring Proper Termination</H1>
|
|
<P>
|
|
Often it happens that the Lisp programmer unknowingly
|
|
implements an infinite loop. This could happen in two different ways:
|
|
an infinite ``do'' loop, or an improper recursion. In the first case,
|
|
it may be that the programmer is using the general ``do'' construct and
|
|
has specified a test for termination that will never occur. This
|
|
problem can be avoided by using the more specific constructs ``dotimes'' or
|
|
``dolist'' (chapter 3). These constructs have a built-in test for
|
|
termination; ``dotimes'' iterates a specified number of times, and
|
|
``dolist'' iterates once for each element in a given list. Improper
|
|
recursion, however, is often more difficult to discover.
|
|
<BLOCKQUOTE>
|
|
<PRE><TT> <H4><b>Example 8:
|
|
<P>
|
|
The following definition wrongly implements the function to determine
|
|
<P>
|
|
the length of a list:
|
|
<P>
|
|
<tt> (defun length (lst)</tt>
|
|
<P>
|
|
<tt> (cond ((null lst) 0)</tt>
|
|
<P>
|
|
<tt> (t (+ 1 (length lst)))))</tt>
|
|
<P>
|
|
</b></h4></TT></PRE>
|
|
</BLOCKQUOTE>
|
|
The following notation illustrates why the above function does
|
|
not terminate:
|
|
<BLOCKQUOTE>
|
|
<PRE>(length '(a b c))
|
|
= (+ 1 (length '(a b c)))
|
|
= (+ 1 (+ 1 (length '(a b c))))
|
|
= (+ 1 (+ 1 (+ 1 (length '(a b c)))))
|
|
= (+ 1 (+ 1 (+ 1 (+ 1 (length '(a b c))))))
|
|
= (+ 1 (+ 1 (+ 1 (+ 1 (+ 1 (length '(a b c)))))))
|
|
= ...
|
|
= ...
|
|
</PRE>
|
|
</BLOCKQUOTE>
|
|
The list is passed-in unmodified in the recursive call. Such simple
|
|
mistakes are very common, and their frequency increases with longer and
|
|
more complicated programs. Compare this definition of ``length'' with
|
|
the one given in section 4.2.
|
|
<BLOCKQUOTE>
|
|
<PRE><TT> <H4><b>RULE OF THUMB 7:
|
|
<P>
|
|
To ensure proper termination do two things:
|
|
<P>
|
|
(1) make sure that you are changing at least one argument
|
|
<P>
|
|
in your recursive call;
|
|
<P>
|
|
(2) make sure that your test for termination looks at the
|
|
<P>
|
|
arguments that change in the recursive call.
|
|
<P>
|
|
</b></h4></TT></PRE>
|
|
</BLOCKQUOTE>
|
|
|
|
<BLOCKQUOTE>
|
|
<PRE><TT> <H4><b>Example 9:
|
|
|
|
<P>
|
|
A function, ``exp,'' takes two positive, non-zero integers, x and y, and
|
|
<P>
|
|
raises x to the y power. Will the following recursive definition for
|
|
<P>
|
|
``exp'' terminate properly?
|
|
<P>
|
|
<tt> (defun exp (x y)</tt>
|
|
<P>
|
|
<tt> (cond ((= y 0) 1)</tt>
|
|
<P>
|
|
<tt> (t (* x (exp x (- y 1))))))</tt>
|
|
<P>
|
|
</b></h4></TT></PRE>
|
|
</BLOCKQUOTE>
|
|
Yes, the above definition is correct and will terminate properly
|
|
according to Rule of Thumb 7. We fulfill both requirements of the
|
|
rule:
|
|
<DL COMPACT><DT>(1)
|
|
<DD> We are changing at least one argument in the
|
|
recursive call, namely y, which is decremented
|
|
by one.
|
|
<DT>(2)
|
|
<DD> In our test for termination, <code>(= y 0)</code>, we are
|
|
using an argument that we change in the
|
|
recursive call, namely y.
|
|
<P>
|
|
</DL>
|
|
|
|
<div style="border: 1px solid red; background: #ffffdd; margin: 10px; text-align: center"><b>NOTE:</b> The example above again illustrates that you are allowed to redefine functions that are built into Lisp. Programmer beware!!</div>
|
|
|
|
|
|
<BLOCKQUOTE>
|
|
<PRE><TT> <H4><b>RULE OF THUMB 8:
|
|
<P>
|
|
<b>Two simple cases may occur when changing an argument in a
|
|
<P>
|
|
<b>recursive call:
|
|
<P>
|
|
<b>(1) if you are using ``rest'' to change an argument which is
|
|
<P>
|
|
<b>a list, use ``null'' in the test for termination;
|
|
<P>
|
|
<b>(2) if you are decreasing an argument which is a number,
|
|
<P>
|
|
<b>compare it with 0 in the test for termination.
|
|
<P>
|
|
</TT></PRE>
|
|
</BLOCKQUOTE></H4></b></H4></b></b></b></b></b></b></H4></b></H4></b></b></b></b></b></b></b><BR> <HR>
|
|
<A HREF="node47.html"><IMG ALIGN=BOTTOM ALT="next" SRC="next_motif.gif"></A>
|
|
<A HREF="node41.html"><IMG ALIGN=BOTTOM ALT="up" SRC="up_motif.gif"></A>
|
|
<A HREF="node45.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="previous_motif.gif"></A> <BR>
|
|
<A HREF="lp.html"><B>Contents</B></A>
|
|
<B> Next:</B>
|
|
<A HREF="node47.html"> Abstraction</A>
|
|
<B>Up:</B>
|
|
<A HREF="node41.html"> Programming Techniques</A>
|
|
<B> Previous:</B>
|
|
<A HREF="node45.html"> Recursion on Numbers</A>
|
|
<BR> <HR> <P>
|
|
<BR> <HR>
|
|
<P>
|
|
<ADDRESS>
|
|
<I>© Colin Allen & Maneesh Dhagat <BR>
|
|
March 2007 </I>
|
|
</ADDRESS>
|
|
</BODY>
|