序言中的保护子句



它们存在吗?它们是如何实施的?

SWI-Prolog的协同谓词(freezewhendif等)具有保护功能。它们如何适应首选的Prolog编程风格?

我对逻辑编程(使用Prolog和)非常陌生,而且有点困惑,因为它不是纯粹的声明性的,即使在非常简单的情况下也需要过程性的考虑(请参阅关于使用==dif的问题)。我是不是错过了什么重要的东西?

首先是一个术语问题:freeze/2when/2dif/2在任何情况下都不被称为卫士。卫士出现在CHR等扩展中,或出现在GHC(日语链接)等相关语言或其他并发逻辑编程语言中;你甚至(在某些限制下)可能会考虑格式的条款

:-护卫, !,。。。

作为包含保护和剪切的子句,在这种情况下称为提交。但并没有一个适用于上述原语。卫队的灵感来源于1975年Dijkstra的《卫队指挥语言》。

freeze(X, Goal)(最初称为geler)与when(nonvar(X), Goal)相同,并且它们在声明上都等价于Goal。与防护装置的功能没有直接关系。然而,当与if-then-else一起使用时,您可能会实现这样的保护。但这完全不同。

CCD_ 15和类似的构造在一段时间内被认为是改进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)建立表格。CCD_ 26现在将没有解决方案或者只有一个解决方案CCD_。该结果现在将存储为g/1的仅解决方案,因为freeze-目标对目标不直接可见。

正是由于这些原因,freeze/2被认为是约束逻辑编程的goto。

另一个问题是dif/2,它今天被认为是一个约束。与freeze/2和其他协程原语相比,约束能够更好地管理一致性,并保持更好的终止属性。这主要是因为约束引入了一种定义良好的语言,因为可以证明具体的属性,并且已经开发了特定的算法,而不允许实现一般目标。然而,即使对他们来说,也有可能获得并非解决方案的答案。更多关于CLP的答案和成功。

冻结/2和when/2就像逻辑编程的"goto"。它们不是纯的、可交换的等等。

另一方面,dif/2是完全纯的、声明性的、单调的、可交换的等等。至于"首选的Prolog编程风格":说明什么是适用的。如果你想表达两个通用项不同的约束,dif/2正是这个状态。

当您不在Prolog的纯声明性子集中编程,而是使用不可交换的不纯谓词等时,通常最需要过程性考虑。在现代Prolog系统中,几乎没有理由离开纯声明性子集。

Evan Tick的一篇论文解释了CC:

在非正式情况下,过程调用通过匹配头部争论(被动统一)和满足后卫目标。当一个目标可以在一个过程中承诺多个子句时,它非决定性地承诺给其中一个(其他候选人被扔掉)。出现在如果对应的自变量,子句将导致执行暂停目标的未充分实例化。挂起的调用当与挂起的关联的变量调用变得充分实例化。

并发逻辑编程语言的发展
EvanTick-1995
https://core.ac.uk/download/pdf/82787481.pdf

所以我想通过一些when/2魔术,一个承诺的选择代码可以被重写为普通的Prolog。方法如下如下。对于同一谓词的一组承诺选择规则:

H1 :- G1 | B1.
...
H2 :- Gn | Bn.

这可以重写为以下内容,其中Hi和Gi需要实施被动统一。例如,使用ISO勘误表包含文本/2。

H1' :- G1', !, B1.
..
H1' :- Gn', !, Bn.
H :- term_variables(H, L), when_nonvar(L, H).

以上翻译不适用于CHR,因为CHR不适用抛弃候选人。

最新更新