С такой грамматикой:
as --> [].
as --> [a], as.
b(b(a)) --> as.
c(X) --> b(X).
phrase(b(X), [a, a])
и phrase(c(X), [a, a])
работают без проблем. Оба возвращают X = b(a).
.
Но можно ли унифицировать что-то подобное?
phrase(c(X), [b(a)]).
OR:
phrase(c(X), [b(b(a))]).
Мне не повезло, хотя кажется, что это должно быть возможно. Я думаю, это означает, что у меня есть некоторое недопонимание о DCG. Я знаю, что они работают со списками различий и добиваются успеха, когда могут применить ряд правил для использования всех элементов списка. Есть ли что-то особенное в атомах или токенах с точки зрения phrase/2
?
Вот как выглядит трассировка:
[trace] [4] ?- phrase(c(X), [b(a)]).
Call: (5,411) c(_57162, [b(a)], []) ? creep
Call: (5,412) b(_57162, [b(a)], []) ? creep
Call: (5,413) [b(a)]as[] ? creep
Fail: (5,413) [b(a)]as[] ? creep
Fail: (5,412) b(_57162, [b(a)], []) ? creep
Fail: (5,411) c(_57162, [b(a)], []) ? creep
false.
Провал на [b(a)]as[]
мне интересен. Что там тестируют? И... что означает этот синтаксис?
Я знаю, что некоторым людям легче ответить на вопрос, когда они немного больше понимают, чего я на самом деле пытаюсь достичь, поэтому:
Иногда в моем приложении я хотел бы перефразировать неэлегантные предложения. Например, иногда я сталкиваюсь с чем-то вроде ["bake", "that" "many", "pie", "plus", "one"]
. Я бы хотел, чтобы DCG обработала это так, как будто вместо этого она столкнулась с ["bake", "x", "pie"]
. Так что я мог бы использовать phrase(foo(X), ["x", "pie"])
, и если это удастся, я мог бы обернуть его в другое правило выше в грамматике. (Почему бы просто не вызвать правило более высокого уровня для начала? Некоторые из правил более высокого уровня очень медленны в моей грамматике, поэтому я пытаюсь быстро выйти из строя, сначала протестировав правило грамматики более низкого уровня.)
Спасибо заранее за любые советы!