Пролог отложил оценку: LIFO или FIFO пробуждение?

Многие системы Пролог имеют freeze/2 предикат, предикат, который, возможно, должен иметь имя geler/2 поскольку он был изобретен еще до Пролога-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, или даже когда-нибудь позже?

до свидания

1 ответ

Немного зависит от того, как freeze/2 реализован под капотом. Два основных типа интерфейсов переменных атрибутов, которые могут вступать в игру, - это тип 1 и тип 2 в отношении пробуждения. А именно:

Тип 1: пост-унификация
Пробуждение произойдет после того, как будет создан экземпляр X и достигнута текущая цель, прежде чем будет вызвана следующая цель. С этим типом замороженная цель будет видеть любые экземпляры, но выполнение не будет немедленным и не всегда.

Тип 2: Предварительная унификация
Пробуждение произойдет до того, как X будет создан во время объединения. Предварительное объединение не имеет никакого смысла для freeze/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 с расширением Minlog:

?- 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. Из этого можно также сделать вывод о том, что произойдет, если цели приведут к дальнейшему замораживанию и сразу же проснутся.

Другие вопросы по тегам