我遇到了一些问题,并且不知道在哪里可以找到解决方案。你可能听说过飞鸟的问题:
bird(eagle).
bird(penguin).
can_fly(penguin):-!,fail.
can_fly(X):-bird(X).
我尝试修改并将这些知识用于某些爱情故事"。想象一下这个
maried(a, b).
maried(c, d).
lovers(a, d).
likes(X, Y):-maried(X, Y).
现在我想说"如果X与Y结婚,但X是Z的情人,那么X不喜欢Y,但是喜欢Z"。 我试过这个:
likes(X, Y) :- lovers(X, Y).
likes(X, Y) :- maried(X, Y), lovers(X, _),!,fail.
likes(X, Y) :- maried(X, Y).
除非我想评估一个目标
,否则它有效likes(A, B).
如果数据库中有更多事实并且Prolog找到第一个骗子,它将停止回溯,我找不到任何其他解决方案。也许之后会很明显,但现在我脑子里什么也没有了......
提前致谢(也许对不起我的英语:))
答案 0 :(得分:5)
你的第一个例子已经不太有用了。你可以问:
但你甚至不能问,#34;哪些鸟可以飞?":
?- can_fly(Bird).
false.
如果您希望能够提出更一般的问题,例如,"哪些鸟可以飞?"或者#34;哪些鸟不能飞?",你需要明确列出飞行或非飞行的鸟类。由于大多数鸟类都可以飞行,所以让我们明确列出非飞行鸟类:
bird(eagle).
bird(penguin).
bird(ostrich).
bird(dodo).
bird(sparrow).
bird(pigeon).
flightless_bird(penguin).
flightless_bird(ostrich).
flightless_bird(dodo).
bird_of_pray(eagle).
extinct(dodo).
extinct(wooly_mammoth).
can_fly(Bird) :-
bird(Bird),
\+ flightless_bird(Bird).
extinct_bird(Bird) :-
bird(Bird),
extinct(Bird).
请注意使用ISO谓词进行否定\+/1
。如果无法证明目标,那就确实如此。它比您正在使用的失效切割组合更清晰。
如何组织您的知识是一个完全不同的问题。我给出的例子不完整,不一定是最好的方法。作为一般规则,您应该尝试将数据保持为规范化形式,事实和事实条款扮演表和表行的角色。
希望这个答案指向正确的方向。
答案 1 :(得分:4)
切断失败的东西是一个误导你的反模式。在原文中说这样的话要好得多:
bird(eagle).
bird(penguin).
flightless(penguin).
can_fly(X) :- bird(X), \+ flightless(X).
请参阅@ boris的答案,以便对此问题进行出色而详尽的讨论。
所以,你有这个数据库。我打算把名字放进去,以便我能更好地理解它。
married(bill, hillary).
married(barack, michelle).
lovers(bill, michelle).
现在你要说的是已婚人士彼此喜欢,除非他们在作弊。好吧,最好在Prolog中定义这些术语,以便我们可以推理它们。创建我们需要用来定义域的语言。这看起来像这样:
cheating(Cheater, SpitedSpouse, Lover) :-
married(Cheater, SpitedSpouse),
lovers(Cheater, Lover),
SpitedSpouse \= Lover.
现在定义likes/2
更容易了!
likes(Husband, Wife) :- married(Husband, Wife), \+ cheating(Husband, Wife, _).
likes(Husband, Lover) :- cheating(Husband, _, Lover).
我们甚至可以恰当地定义不喜欢:
dislikes(SpitedSpouse, Lover) :- cheating(_, SpitedSpouse, Lover).
dislikes(Cheater, Spouse) :- cheating(Cheater, Spouse, _).
看看我们学到了什么:你真正拥有的是两个人之间的婚姻关系,或三个人之间的欺骗关系,以及你的其他谓词只是对这两种基本关系的预测。这很漂亮,是吗? :) cheating/3
基本上是经典的“三角恋”。这表明我们可以将程序发展为更有效的方式:当然,处理爱情四边形!等等。
注意一些有趣的事情?此代码无法“捕获”michelle
- 她不像bill
那样有罪吗?这强调了一个更大的问题:谓词的性别/方向限制。我认为让这些具体的名词看到逻辑关系会有所帮助,但这是一个应该解决的危险捷径。处理逻辑的一种简单方法是创建一个这样的谓词:
spouse(X, Y) :- married(X, Y)
spouse(X, Y) :- married(Y, X).
当然,你必须做更多的检查,以确保没有重复相同的人,但这并不难,然后将你的变量更改为性别不太明确。