Concurrency 序言延迟评估:后进先出还是先进先出唤醒?
许多Prolog系统都有一个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
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年的。