【发布时间】:2014-01-27 20:16:57
【问题描述】:
这是一个非常简单的 Prolog 知识库:
spouse(bill,cheryl).
married(X,Y) :- spouse(X,Y).
married(X,Y) :- spouse(Y,X).
我运行了以下查询。请注意,有时答案是正确的名称(仅),但有时答案是正确的名称和“假”。
1 ?- married(bill,X).
X = cheryl ;
false.
2 ?- married(cheryl,X).
X = bill.
3 ?- married(X,bill).
X = cheryl.
4 ?- married(X,cheryl).
X = bill ;
false.
有人可以解释这种看似不一致的行为吗?提前致谢。
【问题讨论】:
-
false表示 Prolog 有一个选择点可以返回以尝试找到更多答案,但它没有找到更多答案,所以它返回了false。你的谓词和事实的设置顺序会影响它是否认为它有更多的选择可供探索。交换married子句的顺序,看看会发生什么。 :) 在您的情况下,false在您的第一个子句成功时发生,然后 Prolog 返回尝试第二个子句。 -
你是对的。没有递归。当我说配偶(X,Y):-配偶(Y,X)时,递归是在早期尝试解决这个问题。但这只是导致循环,所以我改为这个(更简单?)示例。我尝试交换结婚条款,但结果相同。
-
我修好了……有点。我加了一个剪辑。上面显示的查询现在可以正常工作(没有“假”)。但是...添加另一个配偶谓词,查询仅在第一对之后停止。配偶(比尔,谢丽尔)。配偶(艾玛,纳特)。已婚(X,Y):-配偶(Y,X),!。已婚(X,Y):- 配偶(X,Y)。查询...缺少 emma,nate: 6 ?- 已婚(X,Y)。 X = 谢丽尔,Y = 比尔。 7 ?-
-
根据我的经验,你几乎总是在代码的中间层出现一个额外的
false。性能问题通常在代码的其他地方,并且由于普通用户受到保护,不受 REPL 的“美学”影响,因此尝试找到并删除它往往不值得。对于像我们这样的初学者来说,剪掉它通常比它的价值更麻烦。