在YAP-prolog中将术语转换为保留变量名的原子
是否有办法配置YAP(和/或SWI prolog),以便在调用在YAP-prolog中将术语转换为保留变量名的原子,prolog,Prolog,是否有办法配置YAP(和/或SWI prolog),以便在调用term\u to_atom/2时保留变量名 例如,当我执行此操作时: term_to_atom(member(X, [1,2]), A). 我得到的答案是: A = 'member(_131405,[1,2])' 其中,X已由其内部表示形式替换 然而,我想得到的答案是: A = 'member(X,[1,2])' 谢谢你的帮助 涉及两个问题。如何将变量名X放入系统中,以及如何将带有此类变量的术语放入atom中 您键入的X由顶层
term\u to_atom/2
时保留变量名
例如,当我执行此操作时:
term_to_atom(member(X, [1,2]), A).
我得到的答案是:
A = 'member(_131405,[1,2])'
其中,X
已由其内部表示形式替换
然而,我想得到的答案是:
A = 'member(X,[1,2])'
谢谢你的帮助 涉及两个问题。如何将变量名
X
放入系统中,以及如何将带有此类变量的术语放入atom中
您键入的X
由顶层读取,顶层将其转换为没有关联名称的常规变量。让我们在YAP中看到这一点:
?- read(Term).
|: X+3*Y+X.
Term = _A+3*_B+_A
|:
是YAP的输入提示。我们已经输入了X+3*Y+X。
但是,变量术语包含\u A
和\u B
(由顶层选择的名称)代替X
和Y
。因此,信息一旦被read/1读取,就会丢失,无法恢复
您必须以不同的方式访问这些信息,使用更通用的内置readingread\u term/2,3
和选项variable\u names/1
?- read_term(T,[variable_names(Eqs)]).
|: X+3*Y+X.
Eqs = ['X'=_A,'Y'=_B],
T = _A+3*_B+_A
因此,读取选项variable\u names/1
为您提供了恢复变量名称的信息。对于read\u term/2
读取的每个命名变量,都有一个结构Name=variable
,其中Name是表示变量名称的原子。上面,'X'
是大写字母X的名称
匿名变量,即名称为\uuu
的变量,不会出现在变量名称列表中。它们可以像这样快速提取:
?- read_term(T,[variable_names(Eqs)]),
term_variables(Eqs, Named),
term_variables(Named+T, Vars),
append(Named, Anons, Vars).
阅读到此为止
现在开始写作。我们不能直接编写术语,但必须随附列表eq
。让我们调用新谓词term\u to_atom(term,Eqs,atom)
。在YAP和SWI中,都有一个将Goal
的输出写入不同目的地,如atom(A)
。因此,您现在可以使用write_term/2随心所欲地编写术语。例如:
?- with_output_to(atom(A),write_term('a b'+X,[quoted(true)])).
A = '\'a b\'+_131284'.
变量_131284看起来非常难看。要获取与其名称相关联的变量以便打印,我们可以实现term_To_atom/3
,如下所示:
term_to_atom(T, Eqs, A) :-
with_output_to(atom(A), write_term(T,[variable_names(Eqs),quoted(true)]) ).
并像这样使用它:
?- 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
在ISO、Minerva、Jekejeke、GNU、B、SWI、YAP和SICStus中
在将术语写入列表的发起者SICStus中,有人写道:
:- 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).
以下是6.3.4之前YAP的ISO不兼容解决方案。不再需要了。至于与单独写入选项的区别:term_to_atom/3
,如下定义会干扰约束,并且无法正确呈现“$VAR”/1
?- read_term(T,[variable_names(Eqs)]).
|: X+3*Y+X.
Eqs = ['X'=_A,'Y'=_B],
T = _A+3*_B+_A
但目前我们只能近似于理想的选择
变量名称/1
。要使用我们自己的变量名打印术语,
变量必须在YAP中用'$VAR'(代码)
替换,其中
code
是字符代码的列表。这并不完全符合实际情况
相同,但非常接近。这将进入一个文件:
:- 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) ).
对于SWI,您必须用N=Ch
替换atom_代码(N,Chs)
。
然后先安装。它预先安装在YAP中
谢谢你的回答。我有点困惑,你能给我举个例子吗?。我从你的回答中了解到,我应该使用的不是术语\u to \u atom/2,但我仍然不知道如何使用\u output \u to/2(对不起,我远不是Prolog专家:)我在ISO中找不到“$VAR”(字符串)。@CookieMonster:你的评论不再相关@差不多了。由于支持写入选项,$VAR不再与此问题相关。