读一剪!在序言中

Bra*_*roy 6 prolog prolog-cut swi-prolog-for-sharing

我正在阅读Learn Prolog Now!的关于切割的章节,同时是 Bratko 的人工智能 Prolog 编程,第 5 章:控制回溯。起初,cut 似乎是模仿其他编程语言中已知的 if-else 子句的直接方式,例如

# Find the largest number
max(X,Y,Y):- X =< Y,!. 
max(X,Y,X).
Run Code Online (Sandbox Code Playgroud)

但是,正如下面所指出的,即使在我们期望的情况下,在所有变量都被实例化的情况下,此代码将失败false,例如

?- max(2,3,2).
true.
Run Code Online (Sandbox Code Playgroud)

原因很明显:第一个规则失败,第二个不再有任何条件与之相关,所以它会成功。我明白这一点,但随后提出了一个解决方案(这是一个swish):

max(X,Y,Z):- X =< Y,!, Y = Z. 
max(X,Y,X).
Run Code Online (Sandbox Code Playgroud)

我很困惑我应该如何阅读这个。我认为的!意思是:“如果在此之前的所有内容!都是真的,请停止终止,包括具有相同谓词的任何其他规则”。但是,这不可能是正确的,因为这意味着 的实例化Y = Z仅在失败的情况下发生,这对于该规则是无用的。

那么应该如何以“人”的方式阅读剪辑?而且,作为扩展,我应该如何阅读上述建议的解决方案max/3

小智 6

另请参阅此答案此问题

我应该如何阅读上述 max/3 的建议解决方案?

max(X,Y,Z):- X =< Y, !, Y = Z. 
max(X,Y,X).
Run Code Online (Sandbox Code Playgroud)

您可以按如下方式阅读:

当 时X =< Y,忘记谓词的第二个子句,并统一YZ

切割会丢弃选择点。选择点是证明树中的标记,它告诉 Prolog 在找到解决方案后在哪里继续搜索更多解决方案。所以切割会切掉证明树的一部分。上面的第一个链接(再次在这里)详细讨论了削减,但该答案的很大一部分只是引用了其他人对其他地方削减的看法。

我想带回家的信息是,一旦你在 Prolog 程序中加入了一个剪辑,你就会强迫自己以操作方式而不是声明方式阅读它。为了了解证明树的哪些部分将被切掉,您(程序员)必须经历各种动作,考虑子句的顺序,考虑哪些子目标可以创建选择点,考虑丢失哪些解决方案。您需要构建证明树(而不是让 Prolog 来做)。

很多你可以用它来避免创建的选择点,你知道你并不需要的技术。然而,这是一个有点大的话题。您应该阅读可用材料并提出具体问题。