SWI Prolog中的变量名称

时间:2012-02-20 09:17:24

标签: prolog

我一直在使用chr库和jpl接口。我有一个普遍的询问。我将来自SWI Prolog的约束发送到我的CHR程序中的java类的实例。例如,如果输入约束是leq(A,B),则变量的名称消失,并且出现的变量名称以_G开头。即使我尝试在不使用界面的情况下打印leq(A,B),也会发生这种情况。似乎每当处理变量时,名称将被替换为新名称。我的问题是,是否有办法做回映射。例如,是否有办法知道_G123对应于A等等。 非常感谢你。

1 个答案:

答案 0 :(得分:8)

(这个问题与CHR无关,也不是SWI特有的。)

Prolog系统完全丢弃编写Prolog程序时使用的变量名。原因是此信息不能用于准确打印变量。该变量可能有几个独立的实例。因此,需要为变量名添加一些唯一标识符。此外,在运行时维护该信息会产生大量开销。

要查看此内容,请考虑谓词mylist/1

?- [user].
|: mylist([]).
|: mylist([_E|Es]) :- mylist(Es).
|: % user://2 compiled 0.00 sec, 4 clauses
true.

在这里,我们对列表的每个元素使用了变量_E。 toplevel现在使用唯一标识符打印所有这些元素:

?- mylist(Fs).
Fs = [] ;
Fs = [_G295] ;
Fs = [_G295, _G298] .
Fs = [_G295, _G298, _G301] .

第二个答案可能会打印为Fs = [_E]。但第三个呢?它不能打印为Fs = [_E,_E],因为元素是不同的变量。所以像Fs = [_E_295,_E_298]这样的东西是我们能得到的最好的东西。但是,这意味着会有很多额外的簿记。

但还有另一个原因,为什么将源代码变量名称与运行时变量相关联会导致极端复杂:在不同的地方,该变量可能具有不同的名称。这是一个人为的例子来说明这一点:

p1([_A,_B]).

p2([_B,_A]).

查询:

?- p1(L), p2(L).
L = [_G337, _G340].

这两个元素应该具有哪些名称?第一个元素的名称可能为_A_B,甚至可能更好:_A_or_B。或者,甚至是_Ap1_and_Bp2。这对谁有利?

请注意,顶级查询中提到的变量名称将被保留:

?- Fs = [_,F|_], mylist(Fs).
Fs = [_G231, F] ;
Fs = [_G231, F, _G375] ;
Fs = [_G231, F, _G375, _G378] 

所以有办法获取这些信息。关于如何在阅读术语时获取SWI和YAP中的变量名称,请参阅this question