2
votes

Add the predicate related(X,Y) such that x is related to y if x and y have any ancestor in common but are not the same person

For my homework i need to add the predicate to the .PL i have to prove if 2 people are related. i have worked it out so it will say if they are related if they are brother and sister but i just cant figure out the code for cousins and so on. any help would be much appreciated.

% File FAMILY.PL% Part of a family tree expressed in Prolog
% In father/2, mother/2, and parent/2,
% first arg. is parent and second arg. is child.
father(michael,cathy).
father(michael,sharon).
father(charles_gordon,michael).
father(charles_gordon,julie).
father(charles,charles_gordon).
father(jim,melody).
father(jim,crystal).
father(elmo,jim).
father(greg,stephanie).
father(greg,danielle).
mother(melody,cathy).
mother(melody,sharon).
mother(hazel,michael).
mother(hazel,julie).
mother(eleanor,melody).
mother(eleanor,crystal).
mother(crystal,stephanie).
mother(crystal,danielle).
parent(X,Y) :- father(X,Y).
parent(X,Y) :- mother(X,Y).
sibling(X,Y) :- mother(M,X), mother(M,Y), \+ X == Y.
ancestor(X,Y) :- parent(X,Z), ancestor(Z,Y).
related(X,Y) :- sibling(X,Y), \+ X == Y.

I was trying to add something like this but no luck. related(X,Y) :- ancestor(Z,X),ancestor(Z,Y).

so i added

related(X,Y) :- parent(Z,X),parent(P,Y),parent(Q,Z),parent(Q,P), \+ X == Y.

and that is working in all my tests. anything wrong with that? or a better way to write it?

3

3 Answers

1
votes

Among other problems, your ancestor rule cannot complete, being a recursive rule and missing the base case. Try

ancestor(X,Y) :- parent(X,Y). % base case
ancestor(X,Y) :- parent(X,Z), ancestor(Z,Y). % recursive case

Note: I'm unsure about the linguistic sense of sibling/2, but should be independent of gender, I think

sibling(X,Y) :- parent(P,X), parent(P,Y), X \= Y.

And related/2 could be

related(X,Y) :- ancestor(A,X), ancestor(A,Y), X \= Y.
0
votes

Complementary to ancestor = The next generation …

nextgen(X,Y) :- parent(Y,X).
nextgen(X,Y) :- parent(Y,Z), nextgen(Z,X).
0
votes

In order to propose something more refined than ancestor/2 which is talked about tons of times, you can also add depth with something like ancestor/3 :

ancestor(X,Y,0) :-
% Base : X ancestor of Y and N=0 if
 parent(X,Y).     % X parent of Y

ancestor(X,Y,N) :-
% Recursive : X ancestor of Y if
 N>0,
 parent(X,Z),     % X parent of Z and
 M is N-1,
 ancestor(Z,Y,M). % Z also ancestor of Y