0
votes

I have a few facts:

parent(bob, anne). % bob is a. parent of anne.
sibling(anne, mary).

I'm trying to get parents from sibling facts, so if I query parent(X, mary) bob should be an output. So far my rules are:

siblingOf(X,Y) :- sibling(X,Y).
siblingOf(X,Y) :- sibling(Y,X).

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

It goes on an infinite loop. I suspect it is because the recursive call has no end condition. What can I do to make it work?

1
Your main problem is that parent/2 is both a fact about bob and anne and also a rule that recursively calls parent/2. parent(bob, X) can thus re-enter parent/2 with the same variables. Rename the rule to something else, like parentOf/2 the way you did with siblingOf/2 instead of sibling/2 and you may have better luck.Daniel Lyons
I tried renaming the rule, but it returns false when parent(X, mary)Juan Dela Cruz
You're now asking me to help you debug code I can't see. But I think your problem is that you should try parentOf(X, mary), if you followed my advice above.Daniel Lyons
The code on my question is the only code. I did exactly what you said, as mentioned in my reply. I renamed the rule to parentOf. I will try tinkering more with it, keeping your advice in mind.Juan Dela Cruz

1 Answers

1
votes

You already used the same trick: make a predicate with a different name, and thus make sure that you do not call the predicate recursively here:

parentOf(P, C) :-
    parent(P, C).
parentOf(P, C) :-
    siblingOf(C, S),
    parent(P, S).

We thus say that X can be a parent of Y based on two conditions:

  1. we defined a parent/2 fact, so explicitly mentioned the parent relation; or
  2. P is a parent/2 of a sliblingOf/2 our child C.

Then we obtain:

?- parentOf(X, Y).
X = bob,
Y = anne ; 
X = bob, 
Y = mary.
?- parentOf(X, mary).
X = bob.