为什么在这个Prolog递归中删除cut运算符并不重要



无论我在下面的代码中是否使用切割运算符,我都会收到相同的答案Y=2。

%% Operation 1
f([H|T], Y) :- 
f(H, A),
f(T, B),
Y is A + B,
!.
%% Operation 2
f(c, 1) :- 
!.
%% Operation 3
f(_, 0).

当我运行查询f([c, [c], d], Y).和跟踪时,我看到采取了相同的步骤。我试图从操作2中删除切割运算符(!(,但没有发现任何差异。删除后,我还从操作1中删除了切割运算符,也没有看到任何区别。为什么在这里使用切割运算符无关紧要?(运行代码链接(

您的查询f([c, [c], d], Y).首先与规则1相结合,然后与Y = 2相结合。但该规则的最后一个目标是对这个派生路径进行切割(即防止回溯(,只剩下那个解决方案。你可以通过删除规则1中的切口来找到缺失的答案。

这种现象的一个最小例子如下:

g(1) :-
!.
g(2).

一般查询现在只有一个答案,尽管有两个:

?- g(X).
X = 1.
?- g(1).
true.
?- g(2).
true.

换句话说,cut破坏了Prolog的逻辑基础,因为泛化规则(p(t(→ ∃x P(x(,即谓词对实例成立意味着它对谓词也成立,其中术语被变量替换(不再成立。

最新更新