首先是术语问题:freeze/2、when/2 和 dif/2 在任何情况下都不能称为守卫。守卫出现在CHR等扩展名中,或GHC(日文链接)或其他Concurrent logic programming languages等相关语言中;您甚至(在某些限制下)可能会考虑以下形式的子句
头:-Guard, !,...
as 包含保护和剪切的子句在这种情况下称为提交。但没有一个适用于上述原语。 Guards 的灵感来自 Dijkstra 1975 年的Guarded Command Language。
freeze(X, Goal)(最初称为geler)与when(nonvar(X), Goal) 相同,它们在声明上都等同于Goal。与守卫的功能没有直接关系。但是,当与 if-then-else 一起使用时,您可能会实现这样的保护。但那是完全不同的。
freeze/2 和类似的构造在一段时间内被认为是改进 Prolog 执行机制的一般方法。然而,事实证明它们使用起来非常脆弱。通常,他们过于保守,从而不必要地延迟了目标。也就是说,几乎每个有趣的查询都会产生一个“挣扎”的答案,如下面的查询。此外,终止程序和非终止程序之间的界限现在要复杂得多。对于终止的纯单调 Prolog 程序,在程序中添加一些终止目标将保留整个程序的终止。但是,freeze/2 不再是这种情况。然后从概念的角度来看,freeze/2 并没有得到系统顶层的很好支持:只有少数系统以全面的方式(例如 SICStus)显示了延迟目标,这对于理解成功/答案和解决方案之间的区别至关重要。对于延迟的目标,Prolog 现在可能会产生一个没有解决方案的答案:
?- 冻结(X,X = 1),冻结(X,X = 2)。
冻结(X,X=1),
冻结(X,X=2)。
freeze/2 的另一个困难是终止条件更难确定。因此,虽然 freeze 应该解决所有终止问题,但它经常会产生新问题。
还有更多与freeze/2 相关的技术困难,特别是 w.r.t 表格和其他防止循环的技术。清楚地考虑一个目标freeze(X, Y = 1),Y 现在是1,即使它还没有绑定,它仍然等待X 先绑定。现在,一个实现可能会考虑为目标g(Y) 提交表格。 g(Y) 现在要么没有解决方案,要么只有一个解决方案 Y = 1。这个结果现在将作为g/1 的only 解决方案存储,因为freeze-goal 对目标不直接可见。
正是由于这些原因,freeze/2 被认为是约束逻辑编程的 goto。
另一个问题是 dif/2 今天被认为是一个约束。与freeze/2 和其他协同程序原语相比,约束能够更好地管理一致性并保持更好的终止属性。这主要是因为约束引入了定义明确的语言,具体属性可以得到证明,并且已经开发了特定的算法并且不允许一般目标。然而,即使对他们来说,也有可能获得不是解决方案的答案。更多关于answer and success in CLP。