2015-04-22 2 views
4

Я пишу парсер для SPARQL (язык семантического веб-запроса), используя DCG. Я хочу заменить имена переменных SPARQL на переменные Prolog. Как я могу это сделать?Как последовательно заменить атомы переменными в Prolog?

Я могу сгенерировать новые переменные, используя length([NewVar], 1), но я не могу отслеживать существующие назначения, просто используя список пар с переменными имен. В операции member/2 в списке будет возвращена новая переменная, а не та, которая хранится в списке.

Есть ли простой способ для именования переменных в Prolog, например, '$VAR(Name)'?

+2

'член/2' * будет * выход один сохраненный в списке (в противном случае мы бы вряд ли назвать это«член»). Пример: '? - Vs = [a -_, b-_], memberchk (a-V1, Vs), memberchk (a-V2, Vs), V1 == V2.', преуспевая, как ожидалось. Обратите внимание, что я просто использую '_' для создания новой переменной« на лету ». Разумеется, вам нужно прорисовать список пар имен переменных через все предикаты, которым необходимо получить к нему доступ. Рассмотрите возможность нарезания резьбы через неявно через DCG для лучшей читаемости. Кроме того, рассмотрите использование сбалансированного дерева, как в 'library (assoc)', чтобы сохранить соответствие между именами SPARQL (= атомов) и переменными Prolog. – mat

+1

Чтобы ответить на ваш последний вопрос, см. ['Variable_names/1'] (http://stackoverflow.com/questions/7947910/converting-terms-to-atoms-preserving-variable-names-in-yap-prolog/7948525#7948525). '' $ VAR '/ 1' - это 1970-е. – false

ответ

1

участник/2 сделают то, что вы хотите. Вот пример:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.25) 
Copyright (c) 1990-2016 University of Amsterdam, VU Amsterdam 

L=[a-X,b-Y,c-Z], member(b-V,L). 
L = [a-X, b-V, c-Z], 
Y = V 

Но вы можете получить проблемы, если вы чередовать записи/1 с членом/2, поскольку переменная может изменить свою идентичность, то есть символ записи в следующих случаях:

  • из-за сборки мусора, если переменная записывается как _G <memloc>
  • из-за наложения спектров, в приведенном выше примере memloc из V может быть показано
    вместо memloc из Y

Такая же проблема с (@ <)/2. Один выхода заключается в использовании атрибутов переменных, которых по крайней мере кладет конец ступенчатости, поскольку переменные атрибуты обычно объединены в прошлом,

так что в приведенном выше пример, если Y представляет собой переменный атрибут и V представляет собой обычных переменный вы никогда не увидите memloc of V после вызывающий член/2.

Bye

1

Я написал реализацию предиката, который последовательно заменяет каждый атом с переменной в списке.

atoms_to_vars(List,Output) :- 
    atoms_to_vars(List,_,Output). 
atoms_to_vars([],_,[]). 
atoms_to_vars([A1|List],Dict,[A2|Output]) :- 
    (atom(A1),member(A1:A2,Dict); 
    is_list(A1),atoms_to_vars(A1,Dict,A2); 
    A1=A2), 
    atoms_to_vars(List,Dict,Output). 

Это пример его выхода в SWI-Пролог:

?- atoms_to_vars(['a',1,['b','a']],Output). 
Output = [_8828, 1, [_8858, _8828]] 
Смежные вопросы