这取决于如何在引擎盖下实现 freeze/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 Prolog:
?- 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 系统中从左到右执行。从这一点也可以推断如果目标进一步冻结并立即自行唤醒会发生什么。