2015-10-17 87 views
0

我有这些家庭的事实:基于知识的系统

male(jerry). 
male(stuart). 
male(warren). 
male(peter). 
female(kather). 
female(maryalice). 
female(ann). 
brother(jerry,stuart). 
brother(jerry,kather). 
brother(peter, warren). 
sister(ann, maryalice). 
sister(kather,jerry). 
parent_of(warren,jerry). 
parent_of(maryalice,jerry). 

而且使用基本谓词malefemaleparent_of我想定义fathermothersondaughtersiblingspouseparent_of

这是我做了什么:

father(P,C) :- male(P), parent_of(P,C). 
mother(P,C) :- female(P), parent_of(P,C). 
son(C,P) :- male(C), parent_of(P,C). 
daughter(C,P) :- female(C), parent_of(P,C). 
sibling(C,OC) :- parent_of(P,C), parent_of(P,OC). 
spouse(H,W) :- parent_of(H,C), parent_of(W,C). 
parent_of(P,C) :- 
    ((sister(C,OC) ; sister(OC,C)) 
    ; (brother(C,OC) ; brother(OC,C))). 

通过查询parent_of(P,C)它应该返回warrenjerry,stuart and kather父母和maryalicejerry, stuart and kather是父母。但这是我得到的:

?- parent_of(X,Y). 
X = warren, 
Y = jerry ; 
X = maryalice, 
Y = jerry ; 
Y = ann ; 
Y = kather ; 
Y = maryalice ; 
Y = jerry ; 
Y = jerry ; 
Y = jerry ; 
Y = peter ; 
Y = stuart ; 
Y = kather ; 
Y = warren. 

它没有任何意义!任何帮助深表感谢!

亲切的问候, 理查德

回答

0

你混淆事实和谓词这基本上是可能的,但不推荐的方法(至少在这种情况下)。

你写你自己要定义malefemaleparent_of的基本事实,但在你的第一个源代码,上面还定义sisterbrother。你可以很容易地通过一个规则来定义,例如“当S是女性并且具有父母C并且X具有相同的父母C并且不等于S”时,S是X的姐妹。 有没有必要通过sisterbrother重新定义parent_of

现在,让我们看看你的查询结果:

前两个结果是你所定义的事实(Warren和杰里,marryalice和杰里)。

下一个结果由您的谓词产生。由于您没有指定有关变量P的任何内容,因此它保持未绑定状态并且不会显示在结果中(因此只显示Y = ...)。

而在谓词变量C满足您指定的四个条件之一(C是某人的妹妹(ANN,kather),有人是C(maryalice,杰里)一个妹妹,C是某人的兄弟(两次杰里,彼得)或某人是C(司徒,kather,沃伦)

摘要兄弟:可以通过规则替换的brothersister的定义和丢弃parent_of谓词

+0

谢谢你回复@danielp和@CapelliC。 (S,X): - 女性(S),parent_of(C,S),parent_of(C,X),S \ = X.'和'brother(S,X): - 男性(S),父母(C,S),父母(C,X),S 1 = X.“,并删除了”parent_of“规则。我试图用兄弟姐妹的事实来查询'parent_of(X,Y)',但没有它们,但它仍然只返回我定义的事实(warren和jerry,maryalice和jerry)。 –

+0

除了您定义的那些之外,您还会得到什么额外结果? – danielp

+0

由于'杰里'有兄弟姐妹'stuart'和'kather'我除了看到'warren'是'stuart'和'kather'的父母。另外'maryalice'是'stuart'和'kather'的父亲。 –

0

我完全同意丹尼尔普的答案,但我希望吸引你对另一个问题的关注,那可能没有被注意到:为什么X只出现在前两个结果上?这是因为你的最后一个谓词是有效的

parent_of(P,C) :- sister(C,OC). 
parent_of(P,C) :- sister(OC,C). 
parent_of(P,C) :- brother(C,OC). 
parent_of(P,C) :- brother(OC,C). 

并且P永远不会受这些规则的约束。所以,你是对的

它没有任何意义!

+0

谢谢你的回复。我对Prolog很陌生,你是什么意思,“P永远不会受这些规则的约束?”它仅与规则左侧的P有什么关系?预先感谢您 –

+0

是的,P是所谓的*单身*。因此,相当无用,并且由于它没有得到一个值,所以Prolog顶层(用户界面,所谓的REPL,ReadEvalPrintLoop)没有显示它。 – CapelliC

+0

谢谢,我想我现在明白了。请看下面我的评论:你知道为什么parent_of-query只返回我定义的两个parent_of-facts,而不是更多? –