Reputation: 7730
Here is my knowledge base:
numeral(0).
numeral(succ(X)) :- numeral(X).
Here is my query:
numeral(X).
Here is what SWI Prolog returns in trace mode:
[trace] ?- numeral(X).
Call: (8) numeral(_3806) ? creep
Exit: (8) numeral(0) ? creep
X = 0 ;
Redo: (8) numeral(_3806) ? creep
Call: (9) numeral(_4006) ? creep
Exit: (9) numeral(0) ? creep
Exit: (8) numeral(succ(0)) ? creep
X = succ(0) ;
Redo: (9) numeral(_4006) ? creep
Call: (10) numeral(_4010) ? creep
Exit: (10) numeral(0) ? creep
Exit: (9) numeral(succ(0)) ? creep
Exit: (8) numeral(succ(succ(0))) ? creep
X = succ(succ(0))
I understand how it finds X=0
answer, I do not fully grasp how it obtains: X = succ(succ(0))
. I understand that this is correct answer, but I am not sure how Prologs searched for it.
Here is my thinking:
When it prints Call: (9) numeral(_4006) ? creep
it tries this rule: numeral(succ(X)) :- numeral(X).
And in particular it probably substitutes _4006 = succ(X)
then it checks that it only holds when numeral(X)
holds, which Prolog checks against numeral(0)
, so result is _4006 = succ(0)
.
Now if we ask for anther solution it again comes back to numeral(_4006)
, but what does it guess when is calls numeral(_4010)
. What is branching process here?
Is there way to get more details?
P.S. This is taken from the following link
Upvotes: 0
Views: 115
Reputation: 476574
Prolog searches trough bactracking. There are two ways Prolog can aim to satisfy an numeral(X)
call:
numeral(0)
in which case it unifies X
with 0
; andnumeral(succ(Y)) :- numeral(Y)
in which case it unifies X
with succ(Y)
and makes a recursive call.I here used Y
since this also creates confusion: the variables in a clause are locally scoped in the sense that an X
in a clause, is not the same variable as an X
in a call.
Now in case Prolog backtracks and aims to satisfy the predicate with the clause, then this means that X = succ(Y)
with Y
a variable, but it needs to make an extra call with numeral(Y)
as specified in the body.
Again there are two choices:
numeral(0)
in which case it unifies Y
with 0
; andnumeral(succ(Z)) :- numeral(Z)
in which case it unifies Y
with succ(Z)
and makes a recursive call.In case we go for the first one, Y
is set to 0
, and thus X = succ(Y)
hence X = succ(0)
. In the latter case X = succ(Y)
, and Y = succ(Z)
, and we again make a recursive call.
Now in case we again use the first line for numeral(0)
, this thus means that Z
is unified with 0
, hence Z = 0
, hence Y = succ(0)
, hence X = succ(succ(0))
.
Upvotes: 1