add(0,Y,Y).
add(succ(X),Y,succ(Z)) :-
add(X,Y,Z).
I don't understand how this one works. If I run the query:
add(succ(succ(succ(0))), succ(succ(0)), R)
How does it remove succ from the first argument?
If I run it:
X=succ(succ(succ(0)))
Y=succ(succ(0))
R=?
This satisfied the body. We input them into the head:
add(succ(X),Y,succ(Z)) %% becomes
add(succ(succ(succ(0))),succ(succ(0)),succ(R))
I.e. it looks to me as if it just adds succ, not removes them from the first argument? I saw that there's another post about this exact question but it does not make sense to me.
When you call the goal
add(succ(succ(succ(0))), succ(succ(0)), R)
and Prolog tries to execute the clause with the headadd(succ(X),Y,succ(Z))
, unification happens. Unification is one of the central concepts of Prolog, and it's important to understand it well. Unification is also the operation that is performed by the=
operator. What happens when the head of the clause is executed is exactly the same as happens when you execute the following equivalent query:It is important to understand that unification is not just "unpacking" or "building up" terms, but both at the same time.
It can "extract" information from terms:
Here we found that
a
is the argument of thef
functor inX
.It can "construct" terms:
Here we "inserted" the term
g(h)
into the "hole"Y
inX
.It can also do both at the same time to more than one term:
Here unification "unpacked" both
f
terms, then "filled in" a hole in each of them.Now, armed with this knowledge, what does the unification in your example do?
In particular, when
succ(succ(succ(0)))
is unified withsucc(X)
, this will bindX
tosucc(succ(0))
.X
is not bound to the entire termsucc(succ(succ(0)))
but only to an "inner" part. This is what removes one level ofsucc
from the argument.