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