有没有办法配置YAP(和/或SWI prolog),以便在term_to_atom/2
的任何调用中保留变量名??
例如,当我执行此命令时:
term_to_atom(member(X, [1,2]), A).
我得到了这个答案:
A = 'member(_131405,[1,2])'
其中X
已由其内部表示替换。
但是,我想得到这个答案:
A = 'member(X,[1,2])'
感谢您的帮助!
答案 0 :(得分:11)
涉及两个问题。如何将变量名称X
添加到系统中,以及如何将具有此类变量的术语放入原子中。
您键入的X
由顶级读取,它将其转换为没有关联名称的常规变量。让我们在YAP中看到:
?- read(Term).
|: X+3*Y+X.
Term = _A+3*_B+_A
|:
是YAP的输入提示。我们已输入 X+3*Y+X.
但是,变量Term
包含_A
和_B
(由顶级选择的名称)代替{{ 1}}和X
。因此,信息丢失,一旦读取/ 1读取,就无法恢复。
您必须使用更通用的内置内容来阅读Y
和read_term/2,3
选项,以获得不同的信息。
variable_names/1
因此,读取选项 ?- read_term(T,[variable_names(Eqs)]).
|: X+3*Y+X.
Eqs = ['X'=_A,'Y'=_B],
T = _A+3*_B+_A
为您提供了恢复变量名称的信息。对于variable_names/1
读取的每个命名变量,都有一个结构read_term/2
,其中Name是表示变量名的原子。在上面,Name = Variable
是名称大写X.
匿名变量,即名称为'X'
的变量,不会出现在变量名称列表中。它们可以像这样快速提取:
_
阅读非常多。
现在写作。我们不能直接写这个术语,但必须与列表 ?- read_term(T,[variable_names(Eqs)]),
term_variables(Eqs, Named),
term_variables(Named+T, Vars),
append(Named, Anons, Vars).
一起使用。让我们调用新的谓词Eqs
。在YAP和SWI中,with_output_to(Output, Goal)
将term_to_atom(Term, Eqs, Atom)
的输出写入Goal
等不同目的地。因此,您现在可以使用write_term / 2来编写术语。一个例子:
atom(A)
变量_131284看起来很难看。要获取与其名称相关联的变量以进行打印,我们可以按如下方式实现?- with_output_to(atom(A),write_term('a b'+X,[quoted(true)])).
A = '\'a b\'+_131284'.
:
term_to_atom/3
并像这样使用它:
term_to_atom(T, Eqs, A) :-
with_output_to(atom(A), write_term(T,[variable_names(Eqs),quoted(true)]) ).
ISO,Minerva,Jekejeke,GNU,B,SWI,YAP和SICStus中的 variable_names/1
exists as a write option。
在SICStus中,将术语写入列表的创始人,写道:
?- read_term(T,[variable_names(Eqs)]), term_to_atom(T, Eqs, Atom).
|: X+3*Y+X.
Atom = 'X+3*Y+X',
Eqs = ['X'=_A,'Y'=_B],
T = _A+3*_B+_A
以下是针对6.3.4之前的YAP的ISO不兼容的解决方法。它不再是必要的。至于与单独写入选项的差异::- use_module(library(codesio)).
term_to_atom(T, Eqs, Atom) :-
write_term_to_codes(T, Codes, [variable_names(Eqs),quoted(true)]),
atom_codes(Atom, Codes).
如下定义会干扰约束并且无法正确呈现term_to_atom/3
。
但目前我们只能接近理想的选择
'$VAR'/1
。要使用我们自己的变量名称打印术语, 变量必须在YAP中由variable_names/1
替换'$VAR'(Codes)
是字符代码列表。这不完全是 同样,但它非常接近。这将进入一个文件:Codes
对于SWI,您必须将
:- use_module(library(apply)). :- use_module(library(lambda)). write_eqs_term(T, Eqs) :- \+ \+ ( maplist(\Eq^( Eq = (N='$VAR'(Chs)), atom_codes(N,Chs)), Eqs), write_term(T,[numbervars(true),quoted(true)]) ). term_to_atom(T, Eqs, A) :- with_output_to(atom(A), write_eqs_term(T, Eqs) ).
替换为atom_codes(N,Chs)
。 并首先安装library(lambda)
。它已预先安装在YAP中。