I bet it looks less confusing if you use better variable names:
grand_parent(Grandchild, Grandparent) :-
parent(Parent, Grandchild),
parent(Grandparent, Parent).
You see when you ask the query grand_parent(carl, X)
, Prolog is going to find the definition of grand_parent/2
and substitute carl
for Grandchild
. To prove this, it has to prove parent(Parent, carl)
. Well, this succeeds once, unifying Parent
with bob
. The comma works like "and", so now Prolog has to prove parent(Grandparent, bob)
. It succeeds, unifying Grandparent
with albert
. Prolog always searches the database in the order you supply it with facts, that's why we got Albert before we get Alice.
When you hit ;
it's like you're having a conversation with Prolog and you're saying "or?" as if to prompt it for another solution. So Prolog backs up to the last choice point and starts scanning forward. The last choice point was in parent(Grandparent, bob)
so it scans forward until it finds parent(alice, bob)
which succeeds, unifying Grandparent
with alice
. You ask it for another solution and it will exhaust all the possibilities with parent(Grandparent, bob)
so it will back up to parent(Parent, carl)
, which doesn't find any more solutions. At that point Prolog says false
because it's out of ideas.
Hope this helps!