Prolog家庭关系,意外失败

时间:2013-10-14 21:17:06

标签: prolog program-slicing

有谁能告诉我为什么我的姨妈关系不起作用?每当我尝试调用它时它只返回false。

我在它下面写的叔叔关系似乎完美无缺。我无法弄清楚有什么区别。我试过(不是(母亲(X,Y))。最后也是,但这并没有改变任何东西。

/* 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)).

3 个答案:

答案 0 :(得分:3)

简短的回答是uncle正在运作(某种程度上)而aunt没有,因为您对malefemale的定义不足:它没有除非他们有孩子,否则认识到男性或女性。在你的事实中,没有女性(通过名字判断)谁会有孩子,并有一个有孩子的兄弟姐妹。出于同样的原因,scott不应该出现在叔叔列表中。

解决这个问题很简单:你可以

  1. 删除推断性别的规则并改为说明性别,或
  2. parents个事实替换为son / daughter个事实+ parents规则,并根据某人是某人的女儿的事实推断出性别。

答案 1 :(得分:3)

您问为什么aunt(A,P)没有任何解决方案。换句话说

  

没有阿姨。

这是使用程序切片本地化问题的系统方法。由于与aunt/2相关的程序是一个纯粹的单调程序,我们可以非常系统地将问题本地化。

你的问题是这样的:你的目标aunt(A,P)太专业了。我们现在试着概括它。但只要目标仍然失败。通过这种方式,我们将获得仍然失败的最大泛化。因此,问题必须在剩下的部分。

首先,让我在您的程序中介绍以下定义:

:- op(950,fx, *).

*_.

这允许使用前缀*“注释掉”目标。通过这种方式,我们将概括您的计划。让我们用阿姨的定义来试试这个。也就是说,在目标前插入*,重新加载示例并查看它是否仍然失败。以下是它的最大推广:

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

即使这种概括也失败了!换句话说,sister/2总是失败。

  

没有姐妹。

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

甚至上面都失败了!

  

没有父亲的女性。

您可以坚持这一点,或者继续,通过他们的定义替换目标。

sister(X, Y) :- mother(X,_), parents(X, Z, _), * father(Z, Y).
再来一次:

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

因此,只有母亲可能是姐妹,这肯定是有点过分的限制。

答案 2 :(得分:1)

您正在引入大量冗余,至少是奇怪的检查机制。

fathermother关系意味着您将parents/3关系指定为parents(child,father,morther)。我不明白你为什么要定义两个查询。

出了什么问题,兄弟姐妹关系会在brother(X,X)成功。可以用X \= X来避免这种情况,这基本上就是你在阿姨语句中解决的问题。

此外,您还需要提供其他信息。 malefemale关系仅在此人(X)有子女时解决。但是,如果你自己没有孩子,可能会成为阿姨或叔叔。

这应该有效:

/* 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).