这是一个非常简单的Prolog知识库:
spouse(bill,cheryl).
married(X,Y) :- spouse(X,Y).
married(X,Y) :- spouse(Y,X).
我运行了以下查询。请注意,有时答案是正确的名称(仅限),但有时候答案是正确的名称和“false”。
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.
有人可以解释这种看似不一致的行为吗?提前谢谢。
答案 0 :(得分:3)
来自Prolog的false
回复意味着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
个案例中,两个married/2
子句中的第一个满足查询married/2
。一旦满意,Prolog意识到它有另一个选择(第二个married/2
子句),并提示您寻找更多。按;
,然后Prolog探索第二个(也是最后一个)子句,找不到更多解决方案,然后返回false
。
交换married/2
条款的顺序,看看会发生什么:
spouse(bill,cheryl).
married(X,Y) :- spouse(Y,X).
married(X,Y) :- spouse(X,Y).
?- married(bill,X).
X = cheryl.
?- married(cheryl,X).
X = bill ;
false.
?- married(X,bill).
X = cheryl ;
false.
?- married(X,cheryl).
X = bill.
正如预期的那样,结果是相反的,因为我们已经改变了第一个条款满足的查询。
false
响应可能看起来与开始Prolog程序员不一致,并且“感觉”像错误或警告,但它实际上是一个完全正常的Prolog响应。 Prolog在尝试寻找解决方案时的行为非常一致,当不再存在选择时,它将返回false
。如果Prolog在找到最终解决方案之前已经用尽所有其他选择,它会显示解决方案并且不会返回false
(如上面第二个子句是唯一解决方案的情况)。
有一种诱惑,试图通过使用剪切来“清理”false
响应。虽然这可能会产生预期的短期结果,但由于您从谓词中删除选择点并且添加数据和逻辑可能会消除您真正想要的解决方案,因此存在风险。
因此,在修改过的案例中:
spouse(bill,cheryl).
spouse(emma,nate).
married(X,Y) :- spouse(X,Y), !. % If we found the spouse, we're done, no more!
married(X,Y) :- spouse(Y,X).
?- married(bill,X).
X = cheryl.
?- married(cheryl,X).
X = bill.
?- married(X,bill).
X = cheryl.
?- married(X, cheryl).
X = bill.
耶,生活是美好的!但是,等等,如果我们这样做:
?- married(X,Y).
X = bill,
Y = cheryl.
?-
bill
和cheryl
是唯一的已婚夫妇吗?不......它遗漏了nate
和emma
。削减了其余的解决方案。