Prolog 属性变量:库接口/实现/可移植性
最近我在浏览一些相关的问题时,偶然发现了一个问题 到目前为止,我个人在Prolog中使用属性变量的经验非常有限。但是@mat给出的用例激发了我的兴趣。所以我试着用它来回答另一个问题 首先,好消息是:我第一次使用属性变量的结果就像我希望的那样 然后,还有一个不太好的消息:当我通过answer发布时,我意识到在Prolog中有几个用于属性变量的API和实现 我觉得我有点不知所措。。。我特别想知道以下几点:Prolog 属性变量:库接口/实现/可移植性,prolog,Prolog,最近我在浏览一些相关的问题时,偶然发现了一个问题 到目前为止,我个人在Prolog中使用属性变量的经验非常有限。但是@mat给出的用例激发了我的兴趣。所以我试着用它来回答另一个问题 首先,好消息是:我第一次使用属性变量的结果就像我希望的那样 然后,还有一个不太好的消息:当我通过answer发布时,我意识到在Prolog中有几个用于属性变量的API和实现 我觉得我有点不知所措。。。我特别想知道以下几点: 广泛使用的API是什么?到目前为止,我发现了两个:SICStus和SWI 不同的属性变量实现
- 广泛使用的API是什么?到目前为止,我发现了两个:SICStus和SWI
- 不同的属性变量实现提供了哪些功能?同样的?还是一个包含另一个
- 语义上有区别吗
- 实际执行情况如何?有些人比其他人更有效率吗
- 使用属性化变量是否是可移植性问题
编辑2015-04-22 下面是上面提到的代码片段:
init_att_var(X,Z) :-
put_attr(Z,value,X).
get_att_value(Var,Value) :-
get_attr(Var,value,Value).
到目前为止,我“仅”使用,但是——根据SICStus关于属性变量的Prolog文档——SICStus提供
因此,即使这个非常肤浅的用例也需要一些仿真层(一种方式或另一种方式)。我想重点关注一个我在使用属性变量的不同接口时注意到的重要的一般点:当为属性变量设计接口时,实现者还应该记住以下几点:
- 在对同时统一进行推理时,是否可以考虑属性,如
[X,Y]=[0,1]
verify_attributes/3
之前,这些绑定是撤消的。在hProlog提供的接口中(attr\u unified\u hook/2
,在统一后被称为,并且所有绑定都已就位),在推理attr\u unified\u hook/2
中的X
的统一时,很难考虑Y
的(先前)属性,因为此时,Y
不再是变量!这对于可以仅基于基本值做出决策的解算器来说可能已经足够了,但对于需要额外数据(通常存储在属性中)以查看统一是否应该成功的解算器来说,这是一个严重的限制,这些数据不再容易获得。一个明显的例子:决策图的布尔统一
截至2016年,SWI Prolog的版本还支持验证_属性/3
,这要归功于。分支已准备好进行测试,并打算在其正确有效地工作后立即合并到主分支中。为了与hProlog兼容,该分支还支持attr\u unified\u hook/2
:它在编译时将这些定义重写为更通用的verify\u attributes/3
就性能而言,verify_attributes/3
显然有缺点,因为同时使用多个变量可以让您更快地看到(在attr_unified_hook/2
中)统一无法成功。但是,我很乐意随时将这一通常可以忽略不计的优势与更通用的界面所提供的更高的可靠性、易用性和功能性交换,在任何情况下,这已经是SICStus Prolog中的标准行为,它是最通用的,也是最快的Prolog系统之一
SICStus Prolog还具有一个重要的谓词,称为project\u attributes/2
:顶级到项目约束使用它来查询变量。SWI Prolog在最新版本中也支持这一点
SWI界面还有一个巨大的优势:属性\u goals//1
和复制\u term/3
给你的剩余目标总是一个列表。这有助于用户避免代码中的默认设置,并鼓励使用更具声明性的接口,因为纯约束目标列表不能包含控制结构
有趣的是,这两个接口都不允许您从语法上解释统一。就我个人而言,我认为在某些情况下,你可能希望以不同于语法的方式来解释统一,然而,也可能有很好的理由反对这一点
属性化变量的其他接口谓词大多很容易与不同系统的简单包装器谓词互换。关于属性化变量库的另一个观点是每个模块可以定义多少属性。对于SWI Prolog/YAP和引用SWI文件: 每个属性都与一个模块和挂钩相关联 (
attr\u unify\u hook/2
)在此模块中执行
对于CLP(FD)等库的实现者来说,这是一个严重的限制,因为它强制使用附加模块的唯一目的是拥有多个属性,而不是能够在实现其库的模块中定义所需的尽可能多的属性。SICStus Prolog接口不存在此限制,它提供了一个指令
attribute/1
,允许每个模块声明任意数量的属性。您可以在,它是实现约束求解器的更广泛基础设施的一部分
这种设计的主要特点是:
- 属性必须声明,作为回报,编译器支持高效访问
- 属性化变量的语法,因此