4

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)).
false
  • 10,264
  • 13
  • 101
  • 209
Danny
  • 343
  • 2
  • 5
  • 17

3 Answers3

3

The short answer is that an uncle is working (sort of) and the aunt does not because your definition of male and female is deficient: it does not recognize people a male or a female unless they have kids. In your set of facts there is no female (judging by name) who would have kids and have a sibling who has kids. It is for the same reason that scott should not be showing up among the list of uncles.

Fixing this is simple: you could either

  1. drop the rules that infer gender and state the gender instead, or
  2. replace the parents facts with son/daughter facts + parents rule, and infer the gender from the fact that someone is a daughter of someone.
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Hmm, I understand your solution. As I already mentioned I was given all of the code by my lecturer and told to write an aunt, uncle & cousin rule. Is there any way of doing this with the rules / facts as they are? Or was I supplied with defective code from the start? – Danny Oct 14 '13 at 21:39
  • @DannyWalsh In order to know that someone is someone else's aunt you need to know that it's a female sibling of one of the parents, or a spouse of a male sibling of one of the parents. Judging from the set that you presented, the only way to tell someone's gender is to wait for them to have a child, and is to see on which side of the `parents` relationship they end up. I do not see how to fix this without introducing new facts. Here is a demo of the first approach ([link](http://ideone.com/zkkjIk)). – Sergey Kalinichenko Oct 14 '13 at 21:46
3

You are asking why aunt(A,P) does not have any solution. In other words

There are no aunts.

Here is a systematic way to localize the problem using program slicing. Since the program relevant for aunt/2 is a pure monotonic program, we can localize the problem in a very systematic manner.

Your problem is this: you have a goal aunt(A,P) that is too specialized. We will now try to generalize it. But only as long as the goal still fails. In this manner we will obtain a maximal generalization that still fails. Therefore, the problem must be somewhere in the remaining part.

To begin with, let me introduce the following definition in your program:

:- op(950,fx, *).

*_.

This permits to "comment out" a goal with prefix *. In this manner we will generalize your program. Let us try this out with the definition of aunt. That is, insert * in front of a goal, reload the example and see if it still fails. The following is its maximal generalization:

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

Even that generalization fails! So, in other words, also sister/2 is always failing.

There are no sisters.

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

And even above fails!

There are no females with a father.

You might stick to this, or continue, by replacing the goals by their definitions.

sister(X, Y) :- mother(X,_), parents(X, Z, _), * father(Z, Y).

one more:

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

So only mothers may be sisters which certainly is a bit too much of a restriction.

false
  • 10,264
  • 13
  • 101
  • 209
1

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).
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555