Prolog 序言:停止条件?

Prolog 序言:停止条件?,prolog,prolog-toplevel,Prolog,Prolog Toplevel,下面是一个非常简单的序言知识库: spouse(bill,cheryl). married(X,Y) :- spouse(X,Y). married(X,Y) :- spouse(Y,X). 我运行了以下查询。请注意,有时答案是正确的名称(仅限),但有时答案是正确的名称和“假” 有人能解释这种看似不一致的行为吗?提前感谢。来自Prolog的错误响应意味着Prolog有一个选择点可以返回,试图找到进一步的答案,但没有找到更多。谓词和事实的设置顺序可能会影响它是否认为有更多的选择可供探索 在给定情

下面是一个非常简单的序言知识库:

spouse(bill,cheryl).
married(X,Y) :- spouse(X,Y).
married(X,Y) :- spouse(Y,X).
我运行了以下查询。请注意,有时答案是正确的名称(仅限),但有时答案是正确的名称和“假”


有人能解释这种看似不一致的行为吗?提前感谢。

来自Prolog的
错误
响应意味着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

交换
已婚/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
(与上面第二个子句是唯一解决方案的情况相同)

有一种诱惑,就是试图通过使用cuts来“清理”
错误的
响应。尽管这可能会产生预期的短期结果,但这是有风险的,因为您正在从谓词中删除选择点,并且在添加数据和逻辑时可能会删除您真正想要的解决方案

因此,在修改后的情况下:

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.

?-

比尔和谢丽尔是唯一的已婚夫妇吗?不它遗漏了内特和艾玛。切割消除了其余的解决方案。

Prolog的
错误
响应意味着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

交换
已婚/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
(与上面第二个子句是唯一解决方案的情况相同)

有一种诱惑,就是试图通过使用cuts来“清理”
错误的
响应。尽管这可能会产生预期的短期结果,但这是有风险的,因为您正在从谓词中删除选择点,并且在添加数据和逻辑时可能会删除您真正想要的解决方案

因此,在修改后的情况下:

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.

?-

比尔和谢丽尔是唯一的已婚夫妇吗?不它遗漏了内特和艾玛。切割消除了其余的解决方案。

Prolog的
错误
响应意味着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

交换
已婚/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
(与上面第二个子句是唯一解决方案的情况相同)

有一种诱惑,就是试图通过使用cuts来“清理”
错误的
响应。虽然这可以得到所需的sho