next up previous contents
Next: Fail Goal Now Up: A Special Control Previous: Commit

Make Determinate

We now go onto the key problem of making our programs determinate. That is, if they succeed, then they succeed precisely once unless we really want them to generate alternative solutions. Many programmers find taming backtracking to be a major problem.

Consider the problem raised by this program:

 
sum(1,1).

sum(N,Ans):-

NewN is N-1,

sum(NewN,Ans1),

Ans is Ans1+N. [-5pt]

together with the goal
 
?- sum(2,X).

The meaning of sum/2 is that, for the first argument N (a positive integer), there is some integer, the second argument, which is the sum of the first N positive integers.

We know that, for the mode sum(+,-), there is only one such result. Therefore, if we try to redo a goal such as sum(2,Ans) it should fail. We could test that this is so with:

 
?- sum(2,Ans),write(Ans),nl,fail.

We would like the result:
 
3

no

Alas, here is the result using Edinburgh Prolog.
 
3

(a very very long wait)

We have a runaway recursion. Figure 9.2 shows the execution tree for the goal sum(2,Ans).

  
Figure 9.2: The First Solution to the Goal sum(2,Ans)

Now look at the goal:

 
?- sum(2,X),fail.

and the resulting fragment of the execution tree which is shown in figure 9.3.

  
Figure 9.3: Resatisfying the Goal sum(2,Ans)

Prolog goes into a non terminating computation. We want to make sure that, having found a solution, Prolog never looks for another solution via Redoing the goal. Figure 9.4 shows the consequence when the cut ( !/0) is used.

 
sum(1,1):-

.

sum(N,Ans):-

NewN is N-1,

sum(NewN,Ans1),

Ans is Ans1+N.

  
Figure 9.4: The Effect of the cut on the Goal sum(2,Ans)



next up previous contents
Next: Fail Goal Now Up: A Special Control Previous: Commit



Paul Brna
Mon May 24 20:14:48 BST 1999