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
。削减消除了其余的解决方案。