我开始学习prolog,并希望让整个切割更加清晰。 我已经读到“绿色切割不会改变程序的声明性含义,而红切不会”。但是,程序的含义并不是真正纯粹的声明(仅仅是因为prolog实际上是为所有选项回溯)。
以下是一个例子:
p(1).
p(2) :- !.
p(3).
据说这是绿色切割。但如果我这样做:
p(X), X =:= 3.
我会在没有剪辑的情况下获得“真实”,并且在剪切时获得“假”。 所以,我错过了什么?
提前致谢。
答案 0 :(得分:17)
剪切非常简单,可以解释操作,或者如果您愿意,程序。但是,由于大多数关于逻辑编程和Prolog主题的文献都倾向于Prolog程序的声明含义(有充分理由),因此难以解释切割。一种纠正这种情况的尝试是通过"着色"削减取决于他们的影响。
这是我试图让一切变得更加清晰。
切割的操作含义,
从SWI-Prolog's reference manual:"放弃自进入剪切出现的谓词后创建的所有选择点。换句话说,提交剪切出现的子句,并丢弃当前子句中剪切左侧目标创建的选择点。"
来自"The Art of Prolog" by Sterling and Shapiro:" 目标成功,并将Prolog提交给所有选择,因为父目标与该条款的首部统一,切割发生在 [强调不是我的]。虽然这个定义是完整和准确的,但其后果和含义并不总是直观清晰或明显。"
从"The Craft of Prolog" by O'Keefe:&#34; [cut]将选择点的堆栈修剪回到词典中包含词法包含切词的谓词时的位置。另一种说法就是切割成功并将Prolog提交给自父母目标被称为之后做出的所有选择<再次,强调不是我的...&#34;
我建议您至少从上面引用的两本书中阅读有关剪辑及其用途的章节。它肯定会帮助您了解实际情况。
一个常见的讨论是找到解决方案与答案与证据之间的区别。我们(用户,程序员)通常需要答案。评估Prolog谓词的结果是解决方案。但是,Prolog实际上正在寻找的是证明。
举个例子。您有数据库p(1). p(2). p(3).
。你现在想问Prolog,&#34;是否有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.来自上面),&#34;当搜索证据到达p/1
的第二个子句时,将其参数与2统一的那个,修剪选择点的堆栈调用p/1
时的位置。&#34;调用p/1
时,没有选择点。因此,当X =:= 3
失败时,搜索证明已完成,联合无法证明,没有解决方案,也没有答案。
(尝试查询?- p(X), X =:= 2.
。当您没有剪切时,它是否与同一查询相同?)
现在转到 colors .....在联合p(X), X =:= 3.
的上下文中,这个剪辑修剪了一个解决方案和一个证据。你没有得到你期望的答案。此剪辑为红色。
如果我们能告诉Prolog我们的意思是切割为绿色或红色(或绿色或格子或红色或蓝色),那将是很好的,但Prolog不允许我们这样做。 &#34;颜色&#34;是程序的预期意义(程序员的意图)和裁员的操作(程序)效果的结果。
但实际上,请尝试获取一本书并阅读有关削减的部分。甚至两本书。