Расширение DCG: игнорируется ли стойкость?

Предположим, у меня есть следующее правило DCG:

 factor(X) --> "(", expr(X), ")".

Обычно это переводится на:

 factor(X, A, B) :-
    [40|C] = A, expr(X, C, D), [41|B] = D.

Может ли система Пролога переводить это следующим образом, то есть
объединять унификации в голове и цели?

 factor(X, [40|A], B) :-
    expr(X, A, [41|B]). 

Если расширение DCG не будет устойчивым,
не будет разрешено помещать [41 | B] в третий аргумент вызова expr.

Но, полагаю, стойкость есть, значит, все должно быть в порядке?

Пока

PS: Неформальное определение стойкости см .:
Ричард О'Киф, 2009:
«Как изобретатель термина« стойкий »в программировании на Prolog,
мне следует быть в его пользу. Стойкость в основном
означает, что вы не можете заставить предикат пойти по неверному пути
путем неправильного заполнения выходных аргументов. "
http://blog.gmane.org/gmane.comp.ai.prolog.swi/month=20090301

P.S.S .: Другой перевод DCG см., Например, в новейшем предложении стандарта DCG. Приложение содержит переводчик DCG
исходный код:
ISO / IEC DTR 13211–3: 2006
Правила грамматики с определенными предложениями
Клаус Даесслер
20 ноября 2012 г.
N238 DIN Draft 2012-11-20


person Mostowski Collapse    schedule 27.10.2012    source источник


Ответы (1)


Ваш перевод действителен. На стойкость не влияет. Однако это все равно может быть не очень желательно. Но это зависит от конкретной реализации, которую вы используете. Учитывать:

opcl --> "".
opcl --> "(", opcl, ")".

Если флаг Prolog double_quotes установлен в chars, второе предложение теперь может быть расширено до

opcl1(['('|S0],S) :-
   opcl1(S0,S1),
   S1 = [')'|S].

or

opcl2(['('|S0],S) :-
   opcl2(S0,[')'|S]).

Теперь рассмотрим цель phrase(opcl,"(((())))".

На обычных машинах, таких как WAM (например, YAP, SICStus), ZIP (SWI), TOAM Jr. (B):

opcl1

opcl1 просто проверит правильность списка, используя стек вызовов для процедурного контроля. В случае успеха никакая cons-ячейка не будет создана, и стек вызовов снова станет пустым. На самом деле, вышеперечисленные реализации не могут определить, что цель определена, поэтому они оставят одну точку выбора открытой. Вы можете увидеть это на верхнем уровне:

?- phrase(opcl,"(((())))").
true ;
false.

Эту точку выбора можно аккуратно и безопасно удалить с помощью _ 8_.

opcl2

opcl2 создаст четыре экземпляра [')' | _] в куче, которые должны быть освобождены сборщиком мусора. Но они сохраняют стек вызовов. То есть будут только хвостовые рекурсивные вызовы, которые очень эффективно обрабатываются в WAM, минимально менее эффективно в TOAM Jr. и относительно дороги в SWI.

Все становится еще дороже, когда мы рассматриваем выполнение с проверкой на наличие событий. В Qu-Prolog он всегда включен, а в SWI, XSB и CX вы можете включить его с помощью такого флага:

?- phrase(opcl,Xs,Xs).
true ;
Xs = ['(',')'|Xs] ;
Xs = ['(','(',')',')'|Xs] ...

?- set_prolog_flag(occurs_check,true).
true.

?- phrase(opcl,Xs,Xs).
true ;
**LOOPS**

SWI не нужно выполнять единственную проверку на наличие opcl1. Но это происходит для каждого ) в opcl2.

Таким образом, для этих машин ваш перевод не подходит. Но это может быть интересно для другой машины, где нет отдельного стека вызовов и которая не основана на продолжениях.

звонок // 1

Ваш перевод изменит точное соединение в call//1. Однако цель в call//1 всегда должна быть написана таким образом, чтобы она была непоколебимой! Иначе разницу можно было увидеть уже при звонке phrase(call(Cont),Xs0,Xs)! Для соответствующего Cont это будет то же самое, что phrase(call(Cont),Xs0,XsC), XsC=Xs


Что касается вашей цитаты о стойкости: это очень неформальное определение понятия. В конце концов, что значит «неправильно»?

Лучшее определение стойкости для phrase/3, о котором я знаю, это:

phrase(NT, Xs0,Xs) и phrase(NT, Xs0, XsC), XsC = Xs с XsC новой новой переменной всегда одинаковы.

person false    schedule 27.10.2012
comment
... всегда одинаковы. Это объясняет постоянное изменение состояния? Или ограничивается «чистым» Прологом? - person CapelliC; 28.10.2012
comment
@chac: все, вплоть до потребления ресурсов и аналогичных свойств, зависящих от реализации (например, номеров переменных, порядка переменных). Так что сюда входят побочные эффекты, ошибки и прекращение действия. Стойкость - свойство, которое применимо к любой программе Prolog. - person false; 28.10.2012
comment
Кстати: Это неплохо: Линдгрен Т. (1994): Стиль продолжения-прохождения для Пролога, Международный симпозиум по логическому программированию, 603-617, 1994 citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.49.3062 - person Mostowski Collapse; 02.01.2013
comment
@CookieMonster: Если я правильно помню, это CPS для OR-control. То есть при возврате восстановления памяти нет. - person false; 02.01.2013