【问题标题】:Variable Names in SWI PrologSWI Prolog 中的变量名
【发布时间】:2012-03-10 15:29:45
【问题描述】:

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

【问题讨论】:

    标签: reflection prolog


    【解决方案1】:

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

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

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

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

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

    ?- 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

    【讨论】:

    • 非常感谢您的回复。我知道变量名被替换了。问题是如果有办法知道变量 _G123 例如映射到 A。同样的方法是你指出的问题,但不必使用 read_term,因为我不能这样做,因为我正在使用 CHR,所以输入是约束。谢谢
    • 不幸的是,F 在跟踪期间未显示。 SWI Prolog 和 GNU Prolog 都不是。并且 GNU Prolog 在答案中使用 _ 并在 A、B、C 中使用......因此与 trace 的对应关系在答案中丢失了。 Jekejeke Prolog 在跟踪期间做得很好。
    • @user1220625:简短回答:没有简单的方法可以说明这一点。请记住,您想要的听起来很简单,但实现和使用都可能非常复杂。我会在我的回答中添加一个更有说服力的例子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    相关资源
    最近更新 更多