Можно ли сохранить имена переменных при написании и чтении термина программно? - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь написать предикат SWI-Prolog, который применяет numbervars/3 к анонимным переменным термина, но сохраняет предоставленные пользователем имена его неанонимных переменных.В конце концов я планирую добавить какой-нибудь хук к term_expansion (или что-то в этом роде).

Пример желаемого результата:

    ?- TestList=[X,Y,Z,_,_].
       > TestList=[X,Y,Z,A,B].

Этот ответ квопрос Преобразование терминов в атомы с сохранением имен переменных в прологе YAP показывает, как использовать read_term для получения в качестве атомов имен переменных, используемых в термине.Этот список (в форме [X = 'X', Y = 'Y', ...]) не содержит анонимных переменных, в отличие от списка переменных, полученного с помощью term_variables, что делает изоляцию анонимных переменных довольно простой.

Однако полезность этой замечательной функции несколько ограничена, если ее можно применять только к терминам, считываемым непосредственно из терминала.Я заметил, что все примеры в ответе включают непосредственный пользовательский ввод термина. Можно ли получить (в виде атомов) имена переменных для терминов, которые не получены путем прямого ввода данных пользователем? То есть есть какой-то способ «написать» термин (сохранениеимена переменных) в какой-то невидимый поток, а затем «прочитать» его, как если бы он был введен с терминала?

В качестве альтернативы ... Возможно, это скорее образ мышления LaTeX, но есть ли какой-то способ«обернуть» переменные внутри одинарных кавычек (тем самым, используя их атомизацию) до того, как Prolog развернет / попытается объединить их как переменные, в результате чего они будут рассматриваться как атомы, начинающиеся с заглавных букв, а не как переменные?

Ответы [ 2 ]

0 голосов
/ 26 января 2019

Вы можете использовать стандартную опцию ISO: переменные_имя / 1 для чтения и записи. Вот пример кода, который заменяет анонимные переменные в отображении имени переменной:

% replace_anon(+Map, +Map, -Map)
replace_anon([_=V|M], S, ['_'=V|N]) :- member(_=W, S), W==V, !, 
   replace_anon(M, S, N).
replace_anon([A=V|M], S, [A=V|N]) :- 
   replace_anon(M, S, N).
replace_anon([], _, []). 

variable_names / 1 является основным стандартом ISO. Это всегда был вариант чтения. Затем это стало вариантом записи, а также. Смотрите также: https://www.complang.tuwien.ac.at/ulrich/iso-prolog/WDCor3

Вот пример запуска:

Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.25)

?- read_term(X,[variable_names(M),singletons(S)]), 
   replace_anon(M,S,N), 
   write_term(X,[variable_names(N)]).
|: p(X,Y,X).
p(X,_,X)

Использовать старые numbervars / 3 не рекомендуется, поскольку они несовместимы с переменными атрибутов. Вы не можете использовать его, например, в присутствии CLP (FD).

0 голосов
/ 25 января 2019

Можно ли получить (в виде атомов) имена переменных для терминов, которые не получены посредством прямого пользовательского ввода?

если вы хотите получить имена переменных из исходных файлов, вам следуетпрочитайте их оттуда.

Самый простой способ сделать это, используя расширение термина.

Решение:

read_term_from_atom(+Atom, -Term, +Options)

Используйте read_term/3 для чтенияследующий срок от Atom.

Atom является атомом или строковым объектом.

Для Atom не обязательно указывать точку с полной остановкой.

Используйте Atom в качестве входных данных для read_term/2, используя опцию variable_names и возвращайте термин чтения в Term и привязки переменных в variable_names(Bindings).

Bindings - это список Name = Var пар, что обеспечивает доступ к фактическим именам переменных.См. Также read_term/2.

Если Atom не имеет допустимого синтаксиса, возникает исключение syntax_error.

write_term( Term ) :-
  numbervars(Term, 0, End),
  write_canonical(Term), nl.
...