将术语转换为原子,在YAP prolog中保留变量名称

时间:2011-10-30 21:22:13

标签: prolog

有没有办法配置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])'

感谢您的帮助!

1 个答案:

答案 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读取,就无法恢复。

您必须使用更通用的内置内容来阅读Yread_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中。