Prolog家族树

11

我已经做了,但它没有显示答案。当我询问兄弟姐妹、叔叔阿姨时,出现了这个问题。

这是我写的,有什么问题吗?

/*uncle(X, Y) :– male(X), sibling(X, Z), parent(Z, Y).*/
/*uncle(X, Y) :– male(X), spouse(X, W), sibling(W, Z), parent(Z, Y).*/

uncle(X,Y) :-
  parent(Z,Y), brother(X,Z). 

aunt(X,Y) :-
  parent(Z,Y), sister(X,Z). 

sibling(X, Y) :-
      parent(Z, X),
      parent(Z, Y),
      X \= Y.

sister(X, Y) :-
      sibling(X, Y),
      female(X).

brother(X, Y) :-
      sibling(X, Y),
      male(X).

parent(Z,Y) :- father(Z,Y).
parent(Z,Y) :- mother(Z,Y).

grandparent(C,D) :- parent(C,E), parent(E,D).

aunt(X, Y) :– female(X), sibling(X, Z), parent(Z, Y).
aunt(X, Y) :– female(X), spouse(X, W), sibling(W, Z), parent(Z, Y).

male(john).
male(bob).
male(bill).
male(ron).
male(jeff).

female(mary).
female(sue).
female(nancy).

mother(mary, sue).
mother(mary, bill).
mother(sue, nancy).
mother(sue, jeff).
mother(jane, ron).

father(john, sue).
father(john, bill).
father(bob, nancy).
father(bob, jeff).
father(bill, ron).

sibling(bob,bill).
sibling(sue,bill).
sibling(nancy,jeff).
sibling(nancy,ron).
sibling(jell,ron).

还有一件事,我该如何优化关于兄弟的规则,使得X不是自己的兄弟。

6个回答

7

如果你正在尝试复制这个图表,那么看起来你的一些公理是错误或缺失的。

缺失:

female(jane).

father(john, bob).

错误的:

father(john, sue).

这可能会导致同级规则发生冲突。但是我对Prolog了解甚少。

3
您的兄弟规则已经验证了brother(bob, bob)会失败,因为它调用了sibling(X, Y),该规则检查确保X \= Y
此外,看起来一切在我的机器上都正常,但我不得不更改这些行中的破折号:
aunt(X, Y) :– female(X), sibling(X, Z), parent(Z, Y).
aunt(X, Y) :– female(X), spouse(X, W), sibling(W, Z), parent(Z, Y).

to:

aunt(X, Y) :- female(X), sibling(X, Z), parent(Z, Y).
aunt(X, Y) :- female(X), spouse(X, W), sibling(W, Z), parent(Z, Y).

是的,它们看起来相同,但是顶部版本中的破折号略微更长… 当我“咨询”文件时似乎会出现问题。

我之所以注意到这一点,是因为我为Notepad ++创建了一个Prolog配色方案,如果有人感兴趣,我可以在线发布它。


较长的破折号可能是由一些智能文字处理器创建的 em 或 en 破折号。 - 1800 INFORMATION
我猜这段代码是从其他地方复制粘贴过来的,不是作者自己写的 :) - John Rasch

1
你的aunt/2谓词没有放在一起,因此Prolog认为grandparent/2是aunt/2。请像下面这样把它们放在一起或使用


:- discontiguous(aunt/2).

您使用了spouse/2,但没有定义它。此外,Prolog假定应该有一个sibling/2谓词,并使用father/2。这是因为您在KB底部定义了兄弟姐妹的列表。再次将它们像下面一样放在一起。
如其他答案所述,您可以使用not(X = Y)。
parent(Z,Y) :- father(Z,Y) ; mother(Z,Y).

sibling(bob,bill).
sibling(sue,bill).
sibling(nancy,jeff).
sibling(nancy,ron).
sibling(jell,ron).

sibling(X,Y) :-
    parent(A,X),
    parent(A,Y),
    not(X = Y).


sister(X, Y) :-
      sibling(X, Y),
      female(X),
      not(X = Y).

brother(X, Y) :-
      sibling(X, Y),
      male(X),
      not(X = Y).

grandparent(C,D) :- parent(C,E), parent(E,D).

aunt(X,Y) :-
  parent(Z,Y), sister(X,Z). 
aunt(X, Y) :- female(X), sibling(X, Z), parent(Z, Y).
% aunt(X, Y) :- female(X), spouse(X, W), sibling(W, Z), parent(Z, Y). 

uncle(X,Y) :-
  parent(Z,Y), brother(X,Z). 


male(john).
male(bob).
male(bill).
male(ron).
male(jeff).

female(mary).
female(sue).
female(nancy).
female(jane).

mother(mary, sue).
mother(mary, bill).
mother(sue, nancy).
mother(sue, jeff).
mother(jane, ron).

father(john, sue).
father(john, bill).
father(bob, nancy).
father(bob, jeff).
father(bill, ron).

1

优化规则:X的兄弟不能是自己。

你应该这样做:

brother(X, Y) :-
      sibling(X, Y),
      male(X),
      not X=Y.

1
您有一个强大的事实数据库和一个非常重要的谓词,称为parent(X,Y)。在逻辑上考虑方法。
谁是兄弟姐妹: a)男性/女性,因此必须在谓词中包含male(X)female(X) b)X和Y相同,但要小心使用motherfather函数,否则结果将显示两次。 PS:确保X/=Y. =)
例如: brother(X,Y):- X/=Y, male(X), father(Father,X), father(Father,Y). 谁是叔叔/阿姨(有点棘手,但不是很难): a)是男性/女性。 b)姑姑/叔叔是兄弟姐妹的母亲或父亲的姐妹/兄弟。
例如: aunt(X,Y):- female(X), parent(Parent,Y),sister(X,Parent).

PS:阿姨也可以被视为兄弟姐妹的妈妈或爸爸的妻子(叔叔的妻子)。但在这种情况下,您需要介绍一个新事实,表示一个 married_couple

aunt(X,Y):- female(X),
parent(Parent,Y),
(sister(X,Parent); (brother(Parent,Uncle),married_couple(Uncle,X)))。

希望这样能行;)


0

首先:

将您的事实放在代码开头

而对于兄弟:

equal(X,Y) :-
   X=Y.

different(X,Y):-
   not(equal(X,Y)).

brother(X, Y) :-
  sibling(X, Y),
  male(X),
  different(X,Y).

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接