Prolog家族关系,意外失败
有人能告诉我为什么我的姑姑亲戚不工作吗?只要我试着调用它,它就会返回false 我在它下面写的叔父关系似乎很好地发挥了作用。我想不出有什么区别。我试过(不是(妈妈(X,Y))。最后也试过了,但这并没有改变任何事情Prolog家族关系,意外失败,prolog,program-slicing,Prolog,Program Slicing,有人能告诉我为什么我的姑姑亲戚不工作吗?只要我试着调用它,它就会返回false 我在它下面写的叔父关系似乎很好地发挥了作用。我想不出有什么区别。我试过(不是(妈妈(X,Y))。最后也试过了,但这并没有改变任何事情 /* FACTS */ parents(david, george, noreen). parents(jennifer, george, noreen). parents(georgejr, george, noreen). parents(scott, george, noreen
/* 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
关系指定为父母(孩子、父亲、母亲)
。我不明白为什么要定义两个查询
错误的是兄弟姐妹关系将在兄弟(X,X)
上成功。可以通过X\=X
避免这种情况,这基本上就是您在阿姨子句中解决的问题
此外,您还需要提供其他信息。男性
和女性
的关系只有在此人(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).
简单的回答是,叔叔(某种程度上)在工作,
婶婶(某种程度上)没有,因为你对男性和女性的定义是有缺陷的:除非他们有孩子,否则它不能识别男性或女性。在你的一组事实中,没有女性(从名字判断)谁会有孩子,谁的兄弟姐妹也会有孩子。同样的原因,scott
不应该出现在叔叔的名单上
解决这个问题很简单:你可以
删除推断性别的规则,改为说明性别,或
将父母
事实替换为儿子
/女儿
事实+父母
规则,并根据某人是某人女儿的事实推断性别
你在问为什么姨妈(A,p)
没有任何解决办法。换句话说
没有阿姨
这是一种使用程序切片来定位问题的系统方法。由于与aurn/2
相关的程序是纯单调程序,因此我们可以以非常系统的方式定位问题
你的问题是:你有一个目标阿姨(a,p)
,它太专业化了。我们现在将尝试对它进行推广。但只要目标仍然失败。通过这种方式,我们将获得仍然失败的最大推广。因此,问题一定在剩余部分的某个地方
首先,让我在您的程序中介绍以下定义:
:- op(950,fx, *).
*_.
这允许使用前缀*
对目标进行“注释”。通过这种方式,我们将对您的程序进行泛化。让我们使用阿姨的定义尝试一下。也就是说,在目标前面插入*
,重新加载示例,看看它是否仍然失败。以下是它的最大泛化:
aunt(X,Y) :- sister(X,Z), * parents(Y, Z, _).
aunt(X,Y) :- sister(X,Z), * parents(Y, _, Z).
甚至以上都失败了
没有女性有父亲
您可以坚持这一点,或者继续,用目标的定义替换目标
sister(X, Y) :- mother(X,_), parents(X, Z, _), * father(Z, Y).
姐妹(X,Y):-母亲(X,uu),父母(X,Z,u),*父亲(Z,Y)。
还有一点:
sister(X, Y) :- parents(_,_,X), parents(X, Z, _), * father(Z, Y).
姐妹(X,Y):-父母(X,Z,X),父母(X,Z,Y),*父亲(Z,Y)。
因此,只有母亲可能是姐妹,这当然是一个有点太多的限制。我从我的讲师那里获得了上述所有代码,包括姑姑/叔叔关系。你能确切地告诉我我需要更改什么吗?我对prolog非常陌生,非常迷茫。请稍等,我正在运行一些测试(无意冒犯).我现在也在编辑答案(我想提供一些基本信息)。谢谢你花时间。这应该是正确的,我已经测试过了,尽管我不会把我的生命押在它上面:D.Hmm,我理解你的解决方案。正如我已经提到的,我的讲师给了我所有的代码,并告诉我写一个阿姨、叔叔和表亲规则。有没有办法按照规则/事实来做这件事?或者我有def从一开始就有代码?@DannyWalsh要知道某人是其他人的姑姑,你需要知道他是父母中一方的女性兄弟姐妹,或者是父母中一方的男性兄弟姐妹的配偶。从你展示的场景来看,判断某人性别的唯一方法是等待他们生孩子,然后看他们是谁我是父母关系的一方。我不知道如何在不引入新事实的情况下解决这个问题。下面是第一种方法的演示()。
sister(X, Y) :- parents(_,_,X), parents(X, Z, _), * father(Z, Y).