Учитывая замену S и список Xs, как применить S к Xs

#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, и вы помогли мне реструктурировать мою программу в соответствии с вашим ответом. Спасибо.