Concurrency 序言延迟评估:后进先出还是先进先出唤醒?

Concurrency 序言延迟评估:后进先出还是先进先出唤醒?,concurrency,prolog,swi-prolog,sicstus-prolog,prolog-coroutining,Concurrency,Prolog,Swi Prolog,Sicstus Prolog,Prolog Coroutining,许多Prolog系统都有一个freeze/2谓词,一个谓词 那可能应该有名字geler/2,因为它是 甚至是在Prolog II之前发明的 假设我对同一个变量有一个条件,但有两个 不同的目标,即: ?- freeze(X, G1), freeze(X, G2), X=1. 首选的唤醒策略是什么,G1是否首先执行 还是先执行G2?如果G1和G2产生了新的 冻结,也会被唤醒: G1 :- freeze(Y, G3), Y=1. G2 :- freeze(Z, G4), Z=1. G3或G

许多Prolog系统都有一个
freeze/2
谓词,一个谓词 那可能应该有名字
geler/2
,因为它是 甚至是在Prolog II之前发明的

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

 ?- freeze(X, G1), freeze(X, G2), X=1.
首选的唤醒策略是什么,G1是否首先执行 还是先执行G2?如果G1和G2产生了新的 冻结,也会被唤醒:

 G1 :- freeze(Y, G3), Y=1.
 G2 :- freeze(Z, G4), Z=1. 
G3或G4是否总是在G1和G2之间执行,或者可能是这样 G3或G4是在G1和G2之后执行的,甚至是以后的任何时间


再见

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

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

类型2:预统一
在统一过程中,唤醒将发生在X被实例化之前。预统一对freeze/2没有任何意义,因为这样冻结的目标就看不到任何实例化

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

让我们看看此列表是否为FIFO:

SWI序言:

?- 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.
带有Minlog扩展名的Jekejeke序言:

?- 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
所以这个列表是先进先出的。所以很冷很快就醒了,
在上述两个Prolog系统中从左到右执行。从这一点,我们还可以推断,如果目标本身进一步冻结并立即醒来,会发生什么。

有趣的问题,但有点毛茸茸的。除了一些特定于实现的吹毛求疵之外,打破从左到右的评估模式的原因是什么?“它甚至是在Prolog II之前发明的”。“你在这里到底指的是什么?”false Warren在这里已经提到了联合例程:,1977年,Prolog II手册是1982年的。