prolog中的守卫条款?

时间:2012-12-07 09:08:49

标签: prolog prolog-dif guard-clause prolog-coroutining

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

SWI-Prolog的coroutining谓词(freezewhendif等)具有guards的功能。它们如何适合首选的Prolog编程风格?

我对逻辑编程非常陌生(使用Prolog和完全),并且有点混淆的事实是它不是纯粹的声明,并且即使在非常简单的情况下也需要程序性考虑(参见本question about using \== or dif)。我错过了一些重要的事情吗?

3 个答案:

答案 0 :(得分:5)

首先是术语问题:在任何情况下,freeze/2when/2dif/2都不会被称为警卫。警卫显示为CHR等扩展名,或相关语言GHC(日语链接)或其他Concurrent logic programming languages;你甚至(在某些限制下)可能会考虑表格的条款

  

:-警卫, !, ...

因为包含一个后卫和剪切的子句在这种情况下称为提交。但是没有一个适用于上述原语。卫兵的灵感来自1975年Dijkstra的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现在可能会产生一个没有解决方案的答案:

?- freeze(X, X = 1), freeze(X, X = 2).
freeze(X, X=1),
freeze(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解决方案,因为目标无法直接显示freeze目标。

出于这样的原因,freeze/2被认为是约束逻辑编程的结果。

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

答案 1 :(得分:4)

冻结/ 2,当/ 2就像逻辑编程的“转到”。它们不是纯粹的,可交换的等等。

另一方面,

dif / 2是完全纯粹的,声明性的,单调的,可交换的等.dif / 2是一个声明性谓词,如果它的论点不同,它就成立。至于“首选的Prolog编程风格”:陈述什么是持有的。如果你想表达两个一般术语不同的约束,那么dif / 2就是说明这一点。

当您不在Prolog的纯声明性子集中编程时,通常最需要程序注意事项,但使用不可交换的不纯谓词等。在现代Prolog系统中,几乎没有理由留下纯粹的声明性子集。

答案 2 :(得分:0)

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

  

非正式地,过程调用通过匹配   争吵(消极统一)和满足后卫目标。   当目标可以在一个过程中提交多个子句时,它   不确定地承诺其中一个(其他候选人   被扔掉)。出现在头部和后卫的结构   如果相应的参数,子句会导致执行暂停   目标的实例化程度不够。暂停的调用   当与被挂起的变量相关联时,可以在以后恢复   调用变得足够实例化。

并发逻辑编程语言的发展
埃文·迪克-1995
https://core.ac.uk/download/pdf/82787481.pdf

因此,我猜想在使用某些when / 2魔法时,提交的选择代码可以 改写成普通的Prolog。该方法将是 如下。对于具有相同谓词的一组提交选择规则:

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

这可以重写为以下内容,其中Hi'和Gi' 需要实施被动统一。例如使用 ISO更正subsumes_term / 2。

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

以上翻译不适用于CHR,因为CHR无效 丢掉候选人。