Prolog家族关系,意外失败

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

有人能告诉我为什么我的姑姑亲戚不工作吗?只要我试着调用它,它就会返回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
关系指定为
父母(孩子、父亲、母亲)
。我不明白为什么要定义两个查询

错误的是兄弟姐妹关系将在
兄弟(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).