Prolog Family Relation, unexpected failure

爱⌒轻易说出口 提交于 2019-12-10 17:37:50

问题


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

  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.



回答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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!