当我撇了一些序言最近相关的问题,我偶然发现这个答案通过@mat质疑如何在Prolog中表示定向循环图,可直接通往邻居verticies.
到目前为止,我在Prolog中对属性变量的个人经验非常有限.但@mat给出的用例激发了我的兴趣.所以我尝试用它来回答另一个问题,用约束逻辑编程排序列表.
首先,好消息:我第一次使用归因变量就像我想要的那样.
然后,不是那么好的消息:当我通过回答发布时,我意识到在Prolog中有几个API和属性变量的实现.
我觉得我在这里过头了......特别是我想知道以下内容:
很多问号,这里......请分享你的经验/立场?先感谢您!
这是上面提到的答案的代码片段:
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/3和get_attr/3,但是 - 根据SICStus Prolog文档中的属性变量--- SICStus提供put_attr/2和get_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给你总是一个列表.这有助于用户避免代码中的默认,并鼓励更具声明性的接口,因为纯约束目标列表不能包含控制结构.
有趣的是,这两个界面都不允许您解释语法以外的统一.就个人而言,我认为在某些情况下,您可能希望以不同于语法的方式解释统一,但是,也可能存在很好的反对意见.
对于不同的系统,属性变量的其他接口谓词通常很容易与简单的包装器谓词互换.
Jekejeke Minlog具有无状态或精简属性变量.嗯,不完全是,属性变量可以有零个,一个或多个钩子,允许闭包,因此可以带有一点状态.
但通常一个实现管理状态else.为此,Jekejeke Minlog允许从变量创建引用类型,以便它们可以用作表的索引.
如果这与尾随和/或前向链接相结合,则释放出全部潜力.作为一个例子,我们已经实现了CLP(FD).还有一个小解算器教程.
我们案例中的原始成分是:
1)无状态属性变量
2)尾随和变量键
3)继续队列
属性变量挂钩可能具有绑定效果,直到扩展连续队列,但只执行一次.来自延续队列的目标可以是非确定性的.
在实现应用程序之前还有一些额外的层,主要是基元的聚合以暂时进行更改.
a)有限域约束求解器
b)Herbrand约束
c)目标暂停
再见
关于属性变量库的另一个视角是每个模块可以定义多少属性.对于SWI-Prolog/YAP并引用SWI文档:
每个属性都与一个模块相关联,并且hook(
attr_unify_hook/2)在此模块中执行.
这对于诸如CLP(FD)之类的库的实现者来说是严重的限制,因为它强制使用附加模块仅用于具有多个属性,而不是能够定义实现其库的模块中所需的那么多属性.SICStus Prolog接口上不存在此限制,该接口提供attribute/1允许每个模块声明任意数量属性的指令.