The following story is from N. Wirth's (1976) Algorithms + Datastructures = Programs.
I married a widow (let's call her W) who had a grown-up daughter (call her D). My father (F), who visited us quite often, fell in love with my step-daughter and married her. Hence, my father became my son-in-law and my step-daughter became my mother. Some months later, my wife gave birth to a son (S1), who become the brother-in-law of my father, as well as my uncle. This wife of my father, that is, my step-daughter, also had a son (S2).
I'm attempting to model these relations in prolog so eventually I'll be able to type:
| ?- grandfather(i,i).
And I'll be given a "Yes", or a "No" on whether or not I'm my own grandpa.
Here is the code I have written so far (grandpa.pl):
aunt(X,Y):-
sibling(X,Z),
parent(Z,Y),
female(X).
brother(X,Y):-
sibling(X,Y),
male(X).
brother_in_law(X,Y):-
child(X,Z),
married(Z,W),
parent(W,Y),
not(sibling(X,Y)),
male(X).
brother_in_law(s1,f).
child(X,Y):-
parent(Y,X).
daughter(X,Y):-
parent(Y,X),
child(X,Y),
female(X).
daughter(d,w).
father(X,Y):-
parent(X,Y),
male(X).
father(f,i).
father_in_law(X,Y):-
child(X,Z),
married(Y,Z),
not(child(X,Y)),
male(X).
grandparent(X,Y):-
parent(X,Z),
parent(Z,Y).
grandmother(X,Y):-
grandparent(X,Y),
female(X).
grandfather(X,Y):-
grandparent(X,Y),
male(X).
grandchild(X,Y):-
child(X,Z),
child(Z,Y).
married(X,Y):-
wife(X,Y),
female(X).
married(X,Y):-
husband(X,Y),
male(X).
married(i,w).
married(f,d).
mother(X,Y):-
parent(X,Y),
female(X).
parent(X,Y):-
child(Y,X).
sibling(X,Y):-
parent(Z,X),
parent(Z,Y).
sister(X,Y):-
sibling(X,Y),
female(X).
son(X,Y):-
parent(Y,X),
male(X).
son(s1,w).
son(s2,d).
son_in_law(X,Y):-
child(X,Z),
not(child(X,Y)),
married(Z,Y),
male(X).
son_in_law(f,i).
step_daughter(X,Y):-
child(X,Z),
married(Z,Y),
not(child(X,Y)),
female(X).
step_daughter(d,i).
step_parent(X,Y):-
married(X,Z),
parent(Z,Y),
not(parent(X,Y)).
step_father(X,Y):-
step_parent(X,Y),
male(X).
step_mother(X,Y):-
step_parent(X,Y),
female(X).
step_mother(d,i).
uncle(X,Y):-
sibling(X,Z),
parent(Z,Y),
male(X).
uncle(s1,i).
Right now I'm having a lot of trouble with circular definitions so that I get into infinite loops when running the query: grandfather(i,i).
For example, I have:
(1 ms) yes {trace} | ?- grandfather(i,i). 1 1 Call: grandfather(i,i) ?
2 2 Call: grandparent(i,i) ?
3 3 Call: parent(i,_103) ?
4 4 Call: child(_127,i) ?
5 5 Call: parent(i,_151) ?
6 6 Call: child(_175,i) ?
7 7 Call: parent(i,_199) ?
8 8 Call: child(_223,i) ?
9 9 Call: parent(i,_247) ?
10 10 Call: child(_271,i) ?
11 11 Call: parent(i,_295) ?
12 12 Call: child(_319,i) ?
13 13 Call: parent(i,_343) ?
14 14 Call: child(_367,i) ?
15 15 Call: parent(i,_391) ?
...
This is because child defines itself as has having a parent, and parent defines itself has having a child (as you'll see in the above predicates I posted).
Can anyone help me re-define my predicates for these relationships so that I can determine if I'm my own grandpa?