SWI Prolog中的变量名称

use*_*625 6 prolog

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

fal*_*lse 8

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

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

要看到这一点,请考虑一个谓词mylist/1.

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

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

?- mylist(Fs).
Fs = [] ;
Fs = [_G295] ;
Fs = [_G295, _G298] .
Fs = [_G295, _G298, _G301] .
Run Code Online (Sandbox Code Playgroud)

第二个答案可能会被打印出来Fs = [_E].但第三个呢?它不能打印,Fs = [_E,_E]因为元素是不同的变量.所以Fs = [_E_295,_E_298]我们可以获得最好的东西.但是,这意味着需要额外的预订.

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

p1([_A,_B]).

p2([_B,_A]).
Run Code Online (Sandbox Code Playgroud)

和查询:

?- p1(L), p2(L).
L = [_G337, _G340].
Run Code Online (Sandbox Code Playgroud)

你想要这两个元素应该有哪些名字?第一个元素可能有名称,_A或者_B甚至可能更好:_A_or_B.或者,甚至_Ap1_and_Bp2.这对谁有利?

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

?- Fs = [_,F|_], mylist(Fs).
Fs = [_G231, F] ;
Fs = [_G231, F, _G375] ;
Fs = [_G231, F, _G375, _G378] 
Run Code Online (Sandbox Code Playgroud)

所以有一种方法可以获得这些信息.关于如何在阅读术语时获取SWI和YAP中的变量名称,请参阅此问题.