1
votes

If you have these facts:

parent(albert, bob).
parent(albert, betsy).
parent(albert, bill).

parent(alice, bob).
parent(alice, betsy).
parent(alice, bill).

parent(bob, carl).
parent(bob, charlie).

And then this code:

grand_parent(X, Y) :-
parent(Z, X),
parent(Y, Z).

And if you type:

grand_parent(carl, A)

Then it returns:

A = albert ? ;
A = alice ? ;
no

How does this work?
It's a bit confusing. Especially the "Z" part.

1
What's the problem? - Willem Van Onsem
Sorry something messed up. I've retyped it now. Thanks. - F1R3

1 Answers

4
votes

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!