Prolog 中的剪切和失败语义

Cut and fail semantics in Prolog

下面的代码是做什么的?

not(P) :- P, !, fail.
not(P).

它与以下 2 个代码有何不同:

not(P) :- P, !, fail.
not(P) :- P, !.    

这是树:

第一个程序(反转P的成功值)

如果调用 P 成功:

  1. 输入谓词 not(P)
  2. 输入谓词 not(P) 的子句 1
  3. 调用(P) --> 成功
  4. 横切
  5. 调用失败 --> 失败
  6. 尝试回溯寻找替代解决方案
  7. 回溯途中有Cut;使用 Failure 退出整个谓词(如果 P 成功,则 Cut+Fail 强制谓词失败)

如果调用 P 失败:

  1. 输入谓词 not(P)
  2. 输入谓词 not(P) 的子句 1
  3. 调用(P) --> 失败
  4. 条款 1 导致 --> 失败
  5. 尝试替代条款 2
  6. 调用正确 --> 成功
  7. 无事可做;使用 Success
  8. 退出谓词

第二个程序(总是失败)

如果调用 P 成功:

行为与第一个程序完全相同,使用 Failure 退出整个谓词。

如果调用 P 失败:

  1. 输入谓词 not(P)
  2. 输入谓词 not(P) 的子句 1
  3. 调用(P) --> 失败
  4. 条款 1 导致 --> 失败
  5. 尝试替代条款 2
  6. 调用(P) --> 失败
  7. 无事可做;使用 Failure 退出谓词。实际上还有一个切口要遍历,但它什么也没做。

尝试程序 1

请注意 not/1 已经是内置的,但我想我们可以在本练习中覆盖它。

?- [user].
|: not(P) :- P, !, fail.
|: not(P).

Warning: user://1:9:
Warning:    Singleton variables: [P]
|: % user://1 compiled 0.02 sec, 2 clauses
true.

好的

?- not(true).
false.

?- not(false).
true.

看起来不错。

正在尝试程序 2

?- [user].
|: not(P) :- P, !, fail.
|: not(P) :- P, !.    
|: % user://1 compiled 0.02 sec, 2 clauses
true.

?- not(true).
false.

?- not(false).
false.

看起来不错。