归因变量:库接口/实现/可移植性

rep*_*eat 43 prolog

当我撇了一些最近相关的问题,我偶然发现这个答案通过@mat质疑如何在Prolog中表示定向循环图,可直接通往邻居verticies.

到目前为止,我在Prolog中对属性变量的个人经验非常有限.但@mat给出的用例激发了我的兴趣.所以我尝试用它来回答另一个问题,用约束逻辑编程排序列表.

首先,好消息:我第一次使用归因变量就像我想要的那样.

然后,不是那么好的消息:当我通过回答发布时,我意识到在Prolog中有几个API和属性变量的实现.

我觉得我在这里过头了......特别是我想知道以下内容:

  • 什么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).
Run Code Online (Sandbox Code Playgroud)

到目前为止,我"只"使用put_attr/3get_attr/3,但是 - 根据SICStus Prolog文档中的属性变量--- SICStus提供put_attr/2get_attr/2.

因此,即使是非常浅的用例也 需要一些仿真层(一种方式或另一种方式).

mat*_*mat 12

我想集中讨论在使用属性变量的不同接口时注意到的一个重要的一般要点:在为属性变量设计接口时,实现者还应该记住以下内容:

  • 在推理同步统一时是否可以考虑属性,如[X,Y] = [0,1]

这在例如SICStus Prolog中是可能的,因为在调用之前这样的绑定被撤消verify_attributes/3.在hProlog提供的界面中(在统一之后attr_unify_hook/2调用并且所有绑定已经到位),很难考虑推理关于in 的统一的(先前)属性,因为此时不再是变量!对于只能基于地面值做出决策的求解器来说,这可能就足够了,但对于需要通常存储在属性中的额外数据的求解器来说,这是一个严重的限制,以确定统一是否应该成功,哪些不再容易获得.一个明显的例子:布尔统一与决策图.YXattr_unify_hook/2Y

截至2016年,由于Douglas Miles的大量实施工作,SWI-Prolog 的验证属性分支也得到了支持.该分支已准备好进行测试,并且只要它正确有效地工作就打算合并到主服务器中.为了与hProlog兼容,该分支还支持:它通过在编译时将这些定义重写为更通用来实现.verify_attributes/3attr_unify_hook/2verify_attributes/3

在性能方面,显然可能存在缺点verify_attributes/3,因为同时将多个变量置于同一时间可能会让您更快地看到(attr_unify_hook/2统一)统一不能成功.但是,我很乐意和任何时候交换这个通常可以忽略不计的优势,以提高可靠性,易用性和增加功能,更通用的界面为您提供,并且无论如何已经是SICStus Prolog中的标准行为.它的普遍性也是一个更快的Prolog系统.

SICStus Prolog还具有一个称为的重要谓词project_attributes/2:顶层使用它来预测查询变量的约束.SWI-Prolog在最近的版本中也支持这一点.

SWI界面还有一个巨大的优势:剩余的目标,attribute_goals//1因此copy_term/3给你总是一个列表.这有助于用户避免代码中的默认,并鼓励更具声明性的接口,因为纯约束目标列表不能包含控制结构.

有趣的是,这两个界面都不允许您解释语法以外的统一.就个人而言,我认为在某些情况下,您可能希望以不同于语法的方式解释统一,但是,也可能存在很好的反对意见.

对于不同的系统,属性变量的其他接口谓词通常很容易与简单的包装器谓词互换.

  • 具有讽刺意味的是,SICStus界面中提到的功能在Udine的ICLP 2008中被称为**fat**. (2认同)
  • 您能否确认YAP与SWI具有相同的缺点? (2认同)
  • 最近SWI的变化是否正在实现这一目标? - 请更新你的答案,以防万一. (2认同)

Tra*_*ers 7

Jekejeke Minlog具有无状态或精简属性变量.嗯,不完全是,属性变量可以有零个,一个或多个钩子,允许闭包,因此可以带有一点状态.

但通常一个实现管理状态else.为此,Jekejeke Minlog允许从变量创建引用类型,以便它们可以用作表的索引.

如果这与尾随和/或前向链接相结合,则释放出全部潜力.作为一个例子,我们已经实现了CLP(FD).还有一个小解算器教程.

我们案例中的原始成分是:

1)无状态属性变量
2)尾随和变量键
3)继续队列

属性变量挂钩可能具有绑定效果,直到扩展连续队列,但只执行一次.来自延续队列的目标可以是非确定性的.

在实现应用程序之前还有一些额外的层,主要是基元的聚合以暂时进行更改.

到目前为止,主要的应用程序是开源这里这里:

a)有限域约束求解器
b)Herbrand约束
c)目标暂停

再见

  • 编辑:自1.1.2发行版以来,Jekejeke Prolog还有一个继续队列,允许实现诸如freeze/2之类的谓词.所以在帖子中有一个新的项目3)和一个新的示例应用程序c). (2认同)

jsc*_*mpf 6

您可以在ECLiPSe中找到最古老,最精细的属性变量实现之一,它可以构成实现约束求解器的更广泛基础架构的一部分.

这种设计的主要特点是:

  • 必须声明属性,作为回报,编译器支持高效访问
  • 属性变量的语法,以便可以读取和写入它们
  • 一组更完整的属性操作处理程序,因此不仅要考虑统一属性,还要考虑其他通用操作,如术语复制和包含测试
  • 变量属性和暂停目标的概念之间的明确分离
  • 用于十几个ECLiPSe的库中

本文(第4节)和ECLiPSe文档有更多细节.


Pau*_*ura 5

关于属性变量库的另一个视角是每个模块可以定义多少属性.对于SWI-Prolog/YAP并引用SWI文档:

每个属性都与一个模块相关联,并且hook(attr_unify_hook/2)在此模块中执行.

这对于诸如CLP(FD)之类的库的实现者来说是严重的限制,因为它强制使用附加模块仅用于具有多个属性,而不是能够定义实现其库的模块中所需的那么多属性.SICStus Prolog接口上不存在此限制,该接口提供attribute/1允许每个模块声明任意数量属性的指令.

  • 不完全是一个严重的限制.将许多小属性实现为单个每模块属性的参数非常简单. (3认同)
  • @jschimpf是的,但这种解决方法远非理想.你从属性名称转到整数.您需要访问巨型属性值,复合术语,然后使用其位置而不是属性名称访问其中一个参数,而不是直接访问属性值.删除属性可能意味着重新混洗其他属性.这些更改将需要传播到该超级属性的任何处理程序. (2认同)