18

我开始学习 prolog,并想让整个剪辑更清晰。我读过“绿色剪切不会改变程序的声明性含义,而红色剪切会”。但是,该程序的含义并不是真正纯粹的声明性(仅从 prolog 实际上回溯所有选项这一事实)。

这是一个例子:

p(1).
p(2) :- !.
p(3).

据说这是绿切。但是如果我运行这个:

p(X), X =:= 3.

我会得到“真”而没有切割,而“假”有切割。那么,我想念什么?

提前致谢。

4

1 回答 1

24

从操作上或如果您愿意,从程序上解释剪辑非常简单。然而,由于大多数关于逻辑编程和 Prolog 主题的文献都偏向于 Prolog 程序的声明性含义(有充分的理由),因此难以解释这种削减。纠正这种情况的一种尝试是根据效果对剪辑进行“着色”。

这是我试图让一切变得不那么清晰的尝试。

切割的操作意义,

  1. 来自SWI-Prolog 的参考手册:“丢弃自输入出现切分的谓词以来创建的所有选择点。换句话说,承诺出现切分的子句并丢弃由目标左侧创建的选择点当前条款中的删减。”

  2. 来自Sterling 和 Shapiro 的“Prolog 的艺术”:“目标成功并将 Prolog 提交给所有选择,因为父目标与子句的头部统一,切割发生在[强调不是我的]。虽然这个定义是完整而精确,但其后果和影响并不总是直观清晰或明显。”

  3. 来自O'Keefe 的“The Craft of Prolog”:“[切割] 将选择点的堆栈修剪回调用包含切割的词法的谓词时的位置。另一种说法是切割成功并且将 Prolog 提交给自调用父目标以来所做的所有选择[再次强调不是我的]”

我建议您至少从上面引用的两本书中阅读有关剪辑及其用途的部分。它肯定会帮助您了解实际发生的情况。

一个常见的讨论是寻找解决方案与答案与证明之间的区别。我们(用户、程序员)通常需要答案。评估 Prolog 谓词的结果是解决方案。然而,Prolog 真正寻找的是证明

以你为例。你有数据库p(1). p(2). p(3).。你现在想问 Prolog,“有没有p(X)这样的X =:= 3

?- p(X), X =:= 3.
X = 3.

你得到一个单一的解决方案X = 3。你也得到了你的问题的答案:是的,有这样一个p(X),X 是 3,显然没有更多的答案。

(尝试查询?- p(X), X =:= 2.。它的行为是否与原始查询相同?

通过跟踪查询可以(以某种方式)看到您的证明树:

?- trace(p/1), trace(=:=).
%         p/1: [call,redo,exit,fail]
%         (=:=)/2: [call,redo,exit,fail]
true.

[debug]  ?- p(X), X =:= 3.
 T Call: (7) p(_G1004)
 T Exit: (7) p(1)
 T Call: (7) 1=:=3
 T Fail: (7) 1=:=3
 T Redo: (7) p(_G1004)
 T Exit: (7) p(2)
 T Call: (7) 2=:=3
 T Fail: (7) 2=:=3
 T Redo: (7) p(_G1004)
 T Exit: (7) p(3)
 T Call: (7) 3=:=3
 T Exit: (7) 3=:=3
X = 3.

基本上,每个子句p/1都是依次尝试的。前两个没有产生证明,因为连词的第二个子目标失败了。每次从最后一个选择点( 的下一个子句p/1)开始搜索证明。最后一个可以被证明,你会得到一个解决方案和你的查询的答案。

现在,您在p/1:的第二个子句的正文中进行了删减p(1). p(2) :- !. p(3).。您告诉 Prolog(根据上面的定义 3.),“当对证明的搜索到达 的第二个子句时p/1,将其参数与 2 统一起来的那个子句,将选择点的堆栈修剪到它p/1被调用时的位置。 " 当p/1被调用时,没有选择点。因此,当X =:= 3失败时,证明的搜索完成,无法证明合取,没有解决方案,你也得不到答案。

(尝试查询?- p(X), X =:= 2.。当您没有剪辑时,它是否与同一个查询相同?)

现在到颜色...... p(X), X =:= 3.你没有得到你期望的答案。这个切口是红色的。

如果我们可以告诉 Prolog 我们的意思是绿色或红色(或绿色或绿色或红色或蓝色)的切割,那就太好了,但 Prolog 不允许我们这样做。“颜色”是程序的预期含义(程序员的意图)和剪辑的操作(程序)效果的结果。

但实际上,试着买一本书并阅读关于削减的部分。甚至两本书。

于 2014-10-21T09:34:01.353 回答