问题
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)).
回答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).
回答2:
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
- drop the rules that infer gender and state the gender instead, or
- replace the
parents
facts withson
/daughter
facts +parents
rule, and infer the gender from the fact that someone is a daughter of someone.
回答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.
来源:https://stackoverflow.com/questions/19369465/prolog-family-relation-unexpected-failure