views:

496

answers:

2

The following story is from N. Wirths (1976) Algorithsm + 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 have 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 it self 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?

+2  A: 

My prolog course has been a long long time ago but what about removing

parent(X,Y):-
   child(Y,X).

and just replacing any usage of parent(A,B) with child(B,A)? You can still add facts about parents because the inverse rule is still available - you could also remove that one but in that case you cannot use any facts about parents anymore and you'll have to write all your facts as child(a,b) as well.

It's the same isn't it?

Simon Groenewolt
A: 

Note that my knowledge of Prolog is old (and never that deep)...

I think you need to make parent (or child) primary (not dependent on other relationships).

child(X,Y):-
    parent(Y,X).

parent(X,Y):-
    child(Y,X).

is what is probably causing the loops.

Kathy Van Stone