Reputation: 209
multiply(A,0,0).
multiply(A,B,C) :- D is B-1, multiply(A,D,E), C is E+A.
After using this rule once and Prolog returns an answer, if I want it to continue searching (prompts A = 5 ? and I hit ;), Prolog crashes. I don't understand why? Would anyone be able to explain. Thank you.
Upvotes: 3
Views: 778
Reputation: 1316
Here is how you can make an endless loop easily:
?- [user].
|: loop(0).
|: loop(X) :- X0 is X - 1, loop(X0).
|: ^D% user://1 compiled 0.01 sec, 2 clauses
true.
?- loop(3).
true ;
After you redo (when you press ;
) you backtrack into the second clause with a 0.
Then X0
becomes -1, you go into the recursive loop(X0)
, and from here on the first clause will never again match.
Try for example querying:
?- loop(-1).
Your version of the infinite loop is not tail-recursive, which means that it will use up the stack eventually. Here is a minimal example:
?- [user].
|: out_of_stack(0, 0).
|: out_of_stack(X, Y) :- X0 is X - 1, out_of_stack(X0, Y0), Y is Y0 + 1.
|: ^D% user://1 compiled 0.01 sec, 2 clauses
true.
?- out_of_stack(3, R).
R = 3 ;
ERROR: Stack limit (1.0Gb) exceeded
ERROR: Stack sizes: local: 1.0Gb, global: 19Kb, trail: 1Kb
ERROR: Stack depth: 11,183,864, last-call: 0%, Choice points: 3
ERROR: Possible non-terminating recursion:
ERROR: [11,183,864] user:out_of_stack(-11183853, _5046)
ERROR: [11,183,863] user:out_of_stack(-11183852, _5066)
So this is what is happening and why Prolog crashes.
To get rid of the problem, do as other have suggested. The other solution is to use 0
, s(0)
, s(s(0))
, ... to represent natural numbers.
Upvotes: 1
Reputation: 1124
The problem is,
multiply(A,B,C) :- D is B-1, multiply(A,D,E), C is E+A.
This code does not have the constraint B > 0
that would prevent the stack overflow from occurring.
You can modify the code as,
multiply(A,B,C) :- B > 0, D is B-1, multiply(A,D,E), C is E+A.
Also, this line multiply(A,0,0).
gives a singleton warning, so you can possibly change it into multiply(_,0,0)
Note : I wrote the constraint B > 0
thinking that you call the predicate as multiply(5,1,A)
.
Upvotes: 5