1

I am trying to get my cousin relationship to work accurately. For example when I do the query: cousins(X,ron). It returns: X = nancy;X = nancy;X = jeff;X = jeff;X = david;X = thomas. I believe these are the correct cousins but I don't want to return a name more than once. How can I fix this? And this is the one relationship that is difficult for me to decipher if these are actually cousins or not.

parent(A,B) :- mother(A,B); father(A,B).
grandparent(C,E) :- parent(C,D),parent(D,E).
grandmother(C,E) :- mother(C,D),parent(D,E).
grandfather(C,E) :- father(C,D),parent(D,E).
siblings(B,G) :- parent(P,B), parent(P,G), B\=G.
cousins(X,Y) :- parent(A,X), parent(B,Y), siblings(A,B), X\=Y.

mother(mary,sue).
mother(mary,bill).
mother(sue,nancy).
mother(sue,jeff).
mother(jane,ron).
mother(nancy,alice2).
mother(gail,jane).
mother(gail,elaine).
mother(laura,alice).
mother(elaine,david).
mother(sarah,frank).
mother(elaine,thomas).

father(john,sue).
father(john,bill).
father(bob,nancy).
father(bob,jeff).
father(bill,ron).
father(charlie,alice2).
father(david,charlie).
father(carl,jane).
father(peter,laura).
father(frank,thomas).
father(frank,david).
father(thomas,alice).
father(henry,frank).

(ancestor(A,D):-parent(A,D)).
(ancestor(A,D):-(parent(P,D),ancestor(A,P))).
Royale_w_cheese
  • 297
  • 2
  • 9
  • instead of `\=` try `@<` – CapelliC Nov 12 '18 at 17:04
  • no that did not work...it made the siblings relationship invalid – Royale_w_cheese Nov 12 '18 at 17:11
  • 1
    i'll try that in SWI prolog. Sometimes SWISH does weird things – Royale_w_cheese Nov 12 '18 at 17:19
  • so it did not work In SWI prolog either. and my original code is returning every cousin name twice in SWI prolog. – Royale_w_cheese Nov 12 '18 at 17:26
  • You should check `siblings/2` behavior first since `cousins/2` depends upon it. `siblings/2` looks like it will succeed twice for anyone who shares two parents. You need to adjust your `siblings/2` logic. Actually, it will succeed 4 times because of the symmetry. Try the query `siblings(X, Y)`. – lurker Nov 12 '18 at 22:40
  • yeah siblings(X, bill). returns sue twice because they have the same father and mother – Royale_w_cheese Nov 12 '18 at 23:11
  • but that's not what i want obviously. if i query siblings(X, elaine). it only returns Jane because they only have the same mother – Royale_w_cheese Nov 12 '18 at 23:13
  • 1
    When you have a rule like, `parent(A,B) :- mother(A,B); father(A,B).`, you're going to get possibly two logically distinct solutions to a query like `parent(P, john)` if they have two parents. If you want your rules to be as general as possible (not lose solutions) and not use a cut (`!`) or `once/1`, there's not much you can do about it as there's no further logical reduction to be done or tighter conditions to check. Logically speaking, there are two solutions. In those cases, you can let your predicate find all the solutions then use something like `setof/3` to get a unique collection. – lurker Nov 13 '18 at 13:12

0 Answers0