#variables #prolog #dcg #unification
#переменные #пролог #dcg #объединение
Вопрос:
Предположим, у меня есть замена S и список Xs, где каждая переменная, встречающаяся в Xs, также встречается в S. Как бы я нашел список S (Xs), т. е. список, полученный путем применения подстановки S к списку Xs.
Более конкретно, у меня есть набор предикатов и правил DCG, которые выглядят примерно так
pat(P) --> seg(_), P, seg(_).
seg(X,Y,Z) :- append(X,Z,Y).
Если я попытаюсь сопоставить шаблон P с переменными со списком, я получу замену S:
?- pat([a,X,b,Y],[d,a,c,b,e,d],[]).
X = c,
Y = e
Я хочу применить замену S = {X = c, Y = e} к списку Xs с переменными X и Y и получить список с выполненными заменами, но я не уверен, какой наилучший способ подойти к проблеме.
Если бы я решал эту проблему в Haskell, я бы построил конечное отображение из переменных в значения, а затем выполнил замену. Эквивалентным подходом было бы создать список в правиле DCG пар переменных и значений, затем использовать карту для поиска нужного списка. Однако это неподходящий подход.
Ответ №1:
Поскольку замена не является материализованной (не является объектом Prolog), вы можете привязать список к переменной и позволить унификации выполнять свою работу:
?- Xs = [a,X,b,Y], pat(Xs,[d,a,c,b,e,d],[]).
Xs = [a, c, b, e],
X = c,
Y = e .
Редактировать: Если вы хотите сохранить исходный список после замены, используйте copy_term
:
?- Xs = [a,X,b,Y], copy_term(Xs,Ys), pat(Xs,[d,a,c,b,e,d],[]).
Xs = [a, c, b, e],
X = c,
Y = e,
Ys = [a, _G118, b, _G124] .
Комментарии:
1. Я предполагал, что Xs будет другим списком, чем аргумент правила DCG, но этот ответ был полезен. Я думал не так, как хотел, чтобы я думал prolog, и вы помогли мне реструктурировать мою программу в соответствии с вашим ответом. Спасибо.