repeat/0
repeat
Succeeds immediately when called and whenever reentered by backtracking.
Generally used to simulate the looping constructs found in traditional procedural languages. The general form of a repeat loop is as follows:
repeat, action1, action2, ..., actionn, test, !, ... rest of clause body ...
The effect of this is to execute action1 through actionn in sequence.
The test is then executed. If it succeeds, the loop is (effectively)
terminated by the cut (!
) (which cuts away
any alternatives in the clause,
including the one created by repeat/0
). A failure of the test will
cause backtracking that will be caught by repeat/0
, which will
succeed again and re-execute the actions.
The easiest way to understand the effect of repeat/0
is to think of
failures as "bouncing" back off them causing re-execution of the later
goals.
Repeat loops are not often needed; usually recursive procedure calls will
lead to code that is easier to understand as well as more efficient.
There are certain circumstances, however, in which repeat/0
will lead to
greater efficiency. An important property of Quintus Prolog
is that all run-time data is stored in stacks so that any
storage that has been allocated during a proof of a goal is recovered
immediately on
backtracking through that goal. Thus, in the above example, any space
allocated by any of the actions is very efficiently reclaimed.
When an iterative construct is implemented using recursion, storage
reclamation will only be done by the garbage collector.
In the most common use of repeat loops, each of the calls succeeds
determinately.
It can be confusing if calls sometimes fail, so that
backtracking starts before the test is reached, or if calls are
nondeterminate, so that backtracking does not always go right back to
repeat/0
.
Note that the repeat loop can only be useful if one or more of the actions involves a side-effect -- either a change to the data base (such as an assertion) or an I/O operation. Otherwise you would do the same thing each time around the loop (which would never terminate).
repeat/0
could have been written in Prolog as follows:
repeat. repeat :- repeat.