В дополнение к @ ответ MOG, давайте рассмотрим более общий случай:
Что, если грамматика настолько сложна, что переназначения DCG-правила не помогут? Как мы можем все еще перечислять все предложения? Если грамматика сформулирована таким образом, что она оканчивается на фиксированную длину, мы получаем все предложения с
?- length(Xs, N), phrase(s, Xs).
Целью length
только будет перечислять все списки справедливым образом. То есть, начиная с самой короткой []
всех списки перечисляются:
?- length(Xs, N).
Xs = [],
N = 0 ;
Xs = [_G307],
N = 1 ;
Xs = [_G307, _G310],
N = 2 ;
Xs = [_G307, _G310, _G313],
N = 3 ;
Xs = [_G307, _G310, _G313, _G316],
N = 4 ; ...
И теперь, длина фиксируется, цель phrase(s, Xs)
найти все ответы на эту фиксированную длину. В качестве примера посмотрим на ответ Матса на this grammar.
Так что это общий метод проверки предложений грамматики. Однако - есть такая цена, чтобы заплатить за эту общность!Для грамматик с конечным числом предложений, из метода не прекращается:
:- use_module(
library(double_quotes)
).
s --> "a"|"b".
?- phrase(s, Xs).
Xs = "a" ;
Xs = "b".
Эта грамматика работает из коробки, но вместе с length/2
мы получаем в настоящее время:
?- length(Xs, N),phrase(s, Xs).
Xs = "a",
N = 1 ;
Xs = "b",
N = 1 ;
**loops**
Этот метод часто называют iterative deepening, хотя этот термин более точно налагает привязку к глубине вывода. Но мы навязываем привязку к фактическому «выходу». Таким образом, итеративное углубление также способно обрабатывать левую рекурсию, тогда как length/2
работает только для грамматик, которые заканчиваются для фиксированной входной длины.
Что делает эту технику особенно интересной в Prolog, так это то, что она идеально сочетается с хронологическим механизмом обратного отслеживания Prolog.
Спасибо, что это работает, но можно ли детерминировать (без возврата), когда он проверяет слово, и он все еще может генерировать все слова – whd
, вы можете использовать 'once/1' при необходимости:' once (фраза (s, [ 'a', 'b'])). 'или переходите к фразе ((s, {!}), ['a', 'b'])." или к какой-то вещи. Но научиться терпеть «неудачу» - это интересный способ решить проблему: p – m09
Как использовать fail в dcg? как его fail/0 не работает/2? – whd