Prolog延迟评估:LIFO还是FIFO唤醒?

时间:2016-01-31 22:29:34

标签: prolog swi-prolog sicstus-prolog prolog-coroutining

许多Prolog系统都有一个schema_2.table_1谓词,一个谓词 因为它应该有名称freeze/2 甚至在Prolog-II之前发明。

假设我对同一个变量有条件,但有两个 不同的目标,即:

geler/2

首选的唤醒策略是什么,首先执行G1 还是G2首先执行?如果G1和G2产生新的东西怎么办? 冻结,也被唤醒了:

 ?- freeze(X, G1), freeze(X, G2), X=1.

G3或G4是否总是在G1和G2之间执行,或者可能是 G3或G4是在G1和G2之后执行,还是在以后的任何时间执行?

再见

1 个答案:

答案 0 :(得分:1)

这取决于如何在引擎盖下实现freeze / 2。可以发挥作用的两种主要类型的属性变量接口是关于唤醒的类型1和类型2。即:

类型1:统一后
在调用下一个目标之前,在实例化X并且当前目标成功之后将发生唤醒。使用这种类型,冻结的目标将看到任何实例化,但执行不是立即的而不是总是。

类型2:预先统一
唤醒将在统一期间X被实例化之前发生。 pre-unify对于冻结/ 2没有任何意义,因为那时冻结的目标不会看到任何实例化。

在上面的示例中,成功的目标是X = 1,下一个目标是查询结束的伪目标。从变量的属性值读取的唤醒目标将被推送到列表中,以便它们可用于下一个目标。

让我们看看这个列表是否是FIFO:

SWI-Prolog的:

?- freeze(X, write('ha ')), freeze(X, write('tschi ')), X=1, nl.
ha tschi 
X = 1.

?- freeze(X, write('ha ')), freeze(X, write('tschi ')), (X=1; X=2), nl.
ha tschi 
X = 1 ;
ha tschi 
X = 2.

Jekejeke Prolog with Minlog Extension:

?- use_module(library(term/suspend)).
% 5 consults and 0 unloads in 90 ms.
Yes

?- freeze(X, write('ha ')), freeze(X, write('tschi ')), X=1, nl.
ha tschi 
X = 1

?- freeze(X, write('ha ')), freeze(X, write('tschi ')), (X=1; X=2), nl.
ha tschi 
X = 1 ;
ha tschi 
X = 2

所以列表是FIFO。冷冻,立即醒来, 在上述两个Prolog系统中执行从左到右的执行。从这一点开始,我们也可以推断出如果目标进一步冻结并立即自行唤醒将会发生什么。