prologprogram-slicing

Prolog Family Relation, unexpected failure


Could anyone tell me why my aunt relation isn't working? It just returns false whenever I try to call it.

The Uncle relation I wrote under it seems to work perfectly. I can't figure out what the difference is. I tried (not(mother(X,Y)). at the end also but that doesn't change anything.

/* FACTS */
parents(david, george, noreen).
parents(jennifer, george, noreen).
parents(georgejr, george, noreen).
parents(scott, george, noreen).
parents(joanne, george, noreen).
parents(jessica, david, edel).
parents(clara, david, edel).
parents(michael, david, edel).
parents(laura, georgejr, susan).
parents(anna, scott, siobhan).


/* Relationships */
father(X, Y) :- parents(Y, X, _).
male(X) :- father(X, _).

mother(X, Y) :- parents(Y, _, X).
female(X) :- mother(X, _).

grandfather(X, Y) :- father(X, Z), father(Z, Y).
grandfather(X, Y) :- father(X, Z), mother(Z, Y).

grandmother(X, Y) :- mother(X, Z), mother(Z, Y).
grandmother(X, Y) :- mother(X, Z), father(Z, Y).

brother(X, Y) :- male(X), father(Z, X), father(Z, Y).

sister(X, Y) :- female(X), father(Z, X), father(Z, Y).

aunt(X,Y) :- sister(X,Z), parents(Y, Z, _).
aunt(X,Y) :- sister(X,Z), parents(Y, _, Z).

uncle(X, Y) :- brother(X, Z), parents(Y, Z, _), not(father(X,Y)).
uncle(X, Y) :- brother(X, Z), parents(Y, _, Z), not(father(X,Y)).

Solution

  • You are introducing a lot of redundancy and at least strange checking mechanisms.

    The father and mother relationship imply that you specify the parents/3 relationship as parents(child,father,morther). I don't see why you define two queries.

    What goes wrong is that the brother and sister relationship will succeed on brother(X,X). One can avoid this with X \= X, this is basically what you resolve in the aunt clause.

    Furthermore you will need to provide additional information. The male and female relationship are only resolved when the person (X) has children. It is however possible to be an aunt or uncle when you have no children on your own.

    This should work:

    /* FACTS */
    
    parents(david, george, noreen).
    parents(jennifer, george, noreen).
    parents(georgejr, george, noreen).
    parents(scott, george, noreen).
    parents(joanne, george, noreen).
    parents(jessica, david, edel).
    parents(clara, david, edel).
    parents(michael, david, edel).
    parents(laura, georgejr, susan).
    parents(anna, scott, siobhan).
    
    
    /* Relationships */
    
    parent(X,Y) :- parents(Y,X,_).
    parent(X,Y) :- parents(Y,_,X).
    
    father(X, Y) :- parents(Y, X, _).
    
    male(michael).
    male(X) :- father(X, _).
    
    mother(X, Y) :- parents(Y, _, X).
    
    female(joanne).
    female(jessica).
    female(jennifer).
    female(clara).
    female(laura).
    female(anna).
    female(X) :- mother(X, _).
    
    grandfather(X, Y) :- father(X, Z), father(Z, Y).
    grandfather(X, Y) :- father(X, Z), mother(Z, Y).
    
    grandmother(X, Y) :- mother(X, Z), mother(Z, Y).
    grandmother(X, Y) :- mother(X, Z), father(Z, Y).
    
    brother(X, Y) :- male(X), father(Z, X), father(Z, Y), X \= Y.
    
    sister(X, Y) :- female(X), father(Z, X), father(Z, Y), X \= Y.
    
    aunt(X,Y) :- sister(X,Z), parent(Z,Y).
    
    uncle(X, Y) :- brother(X, Z), parent(Z,Y).