它们存在吗?如何实现?
SWI-Prolog的coroutining谓词(freeze
,when
,dif
等)具有guards的功能。它们如何适合首选的Prolog编程风格?
我对逻辑编程(与Prolog一起使用)非常陌生,并且对它不是纯粹的声明性事实感到困惑,即使在非常简单的情况下,也需要过程上的考虑(请参阅question about using \==
or dif
)。我缺少重要的东西吗?
最佳答案
首先是一个术语问题:在任何情况下,freeze/2
,when/2
或dif/2
都不被称为 guard 。防护以扩展名CHR或相关语言出现GHC(日语链接)或其他Concurrent logic programming languages出现;您甚至(在某些限制下)可能会考虑以下形式的子句
在这种情况下,包含 guard 队和削减的as子句称为提交。但是,没有一个适用于上述基元。卫兵颇受迪克斯特拉(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)
,即使尚未绑定(bind)Y
,现在也就是1
,它仍然等待X
首先绑定(bind)。现在,实现可能会考虑为目标g(Y)
制表。 g(Y)
现在将没有解决方案,或者只有一个解决方案Y = 1
。现在,此结果将存储为g/1
的唯一解决方案,因为freeze
-goal对目标不是直接可见的。
出于这种原因,freeze/2
被视为约束逻辑编程的起点。
另一个问题是dif/2
,今天已将其视为约束。与freeze/2
和其他相关原语相比,约束可以更好地管理一致性并保持更好的终止属性。这主要是由于以下事实:约束条件引入了定义良好的语言,同时可以证明具体的属性,并且已经开发了特定的算法并且不允许总体目标。但是,即使对于他们,也有可能获得不是解决方案的答案。有关answer and success in CLP的更多信息。