For the sake of simplicity we assume that do not need to represent couples without children. Therefore we can choose these three fundamental relations to build our tree: 'male', 'female' and 'parent'.
Here's an example from the Bible:
amram jochebed ___________|________ / | \ moses aaron miriam zipporah elisheba / \ | gershom eliezer nadab male(amram). male(aaron). male(moses). male(gershom). male(eliezer). male(nadab). female(jochebed). female(miriam). female(zipporah). female(elisheba). parent(amram,moses). parent(jochebed,moses). parent(amram,aaron). parent(jochebed,aaron). parent(amram,miriam). parent(jochebed,miriam). parent(moses,gershom). parent(zipporah,gershom). parent(moses,eliezer). parent(zipporah,eliezer). parent(aaron,nadab). parent(elisheba,nadab).
All the other family relationships can be defined in terms of these three fundamental predicates. The following definitions are all optmized for the first argument being a constant and the second being a variable:
% profile -,+ father(X,Y) :- parent(X,Y), male(X). mother(X,Y) :- parent(X,Y), female(X). % The inverse of parent child(X,Y) :- parent(Y,X). son(X,Y) :- parent(Y,X), male(X). % just the same %son(X,Y) :- child(X,Y), male(X). daughter(X,Y) :- parent(Y,X), female(X). % Siblings have the same parents. sibling(X,Y) :- father(Z,Y), mother(W,Y), parent(Z,X), parent(W,X), X \== Y. % unoptmized version: %sibling(X,Y) :- father(Z,Y), mother(W,Y), father(Z,X), mother(W,X), X \== Y. % A brother is a male sibling. brother(X,Y) :- sibling(X,Y), male(X). % A sister is a female sibling. sister(X,Y) :- sibling(X,Y), female(X). % Here we assume that one only marries once. husband(X,Y) :- mother(Y,Z), father(X,Z), !. wife(X,Y) :- father(Y,Z), mother(X,Z), !. grandparent(X,Y) :- parent(Z,Y), parent(X,Z). grandmother(X,Y) :- parent(Z,Y), mother(X,Z). % just the same %grandmother(X,Y) :- grandparent(X,Y), female(X). grandfather(X,Y) :- parent(Z,Y), father(X,Z). cousin(X,Y) :- parent(Z,Y), sibling(W,Z), parent(W,X). % An aunt is a parent's sister. aunt(X,Y) :- parent(Z,Y), sister(X,Z). % An uncle is a parent's brother. uncle(X,Y) :- parent(Z,Y), brother(X,Z).
Note that if we define siblings as:
sibling(X,Y) :- parent(Z,X), parent(Z,Y), X \== Y.
we have a problem. We get each sibling twice:
?- sibling(X,moses). X = aaron ; X = aaron ; X = miriam ; X = miriam ; false.
Can you see why? If not, a little bit of debug output will help you:
sibling(X,Y) :- parent(Z,X), parent(Z,Y), X \== Y, write(Z).
Example queries:
?- father(X,miriam). X = amram ; false. ?- sibling(X,moses). X = aaron ; X = miriam ; false. ?- wife(X,moses). X = zipporah. ?- grandparent(X,gershom). X = amram ; X = jochebed ; false. ?- grandmother(X,eliezer). X = jochebed ; false. ?- cousin(X,nadab). X = gershom ; X = eliezer ; false. ?- aunt(X,eliezer). X = miriam ; false.
No comments:
Post a Comment