当我最近略过一些prolog相关问题时,我偶然发现this answer by @mat提问How to represent directed cyclic graph in Prolog with direct access to neighbour verticies。
到目前为止,我在Prolog中对归因变量的个人经验非常有限。但@mat给出的用例激发了我的兴趣。所以我尝试用它来回答另一个问题ordering lists with constraint logic programming。
首先,好消息:我第一次使用属性变量就像我想要的一样。
然后,不那么好的消息:当我通过回答发布时,我意识到在Prolog中有几个API和属性变量的实现。
我觉得我在这里过头了......特别是我想知道以下内容:
很多问号,这里......请分享你的经验/立场? 提前谢谢!
以上是上述answer的代码段:
init_att_var(X,Z) :-
put_attr(Z,value,X).
get_att_value(Var,Value) :-
get_attr(Var,value,Value).
到目前为止,我“只”使用put_attr/3
and get_attr/3
,但是 - 根据关于属性变量的SICStus Prolog文档--- SICStus提供put_attr/2
and get_attr/2
。
所以即使这个非常浅的用例 也需要一些仿真层(以这种方式或其他方式)。
答案 0 :(得分:11)
我想集中讨论在使用属性变量的不同接口时注意到的一个重要的一般要点:在为属性变量设计接口时,实现者还应该记住以下内容:
[X,Y] = [0,1]
?例如在SICStus Prolog中可以这样做,因为在verify_attributes/3
被调用之前,这样的绑定是撤消。在hProlog(attr_unify_hook/2
提供的界面中,在>>统一之后称为并且所有绑定已经到位)很难考虑Y
的(之前)属性在推断X
中attr_unify_hook/2
的统一时,因为Y
此时不再是变量!对于只能基于地面值做出决策的求解器来说,这可能就足够了,但对于需要通常存储在属性中的额外数据的求解器来说,这是一个严重的限制,以确定统一是否应该成功,哪些不再容易获得。一个明显的例子:布尔统一与决策图。
截至2016年,由于verify-attributes branch的大量实施工作,SWI-Prolog的Douglas Miles也支持verify_attributes/3
。该分支已准备好进行测试,并且只要它正确有效地工作就打算合并到主服务器中。为了与hProlog兼容,该分支还支持attr_unify_hook/2
:它通过在编译时将这些定义重写为更通用的verify_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
给你的剩余目标始终是列表。这有助于用户避免代码中的默认,并鼓励更具声明性的接口,因为纯粹的约束目标列表不能包含控制结构。
有趣的是,这两个界面都不允许您解释语法以外的其他联系。就个人而言,我认为在某些情况下,您可能希望以不同于语法的方式解释统一,但是,也可能存在很好的反对意见。
归因变量的其他接口谓词通常可以与不同系统的简单包装谓词轻松互换。
答案 1 :(得分:7)
Jekejeke Minlog具有无状态或瘦属性变量。不完全是,属性变量可以有零个,一个或多个钩子,允许闭包,因此可以带有一点状态。
但通常一个实现管理状态else。为了这 目的Jekejeke Minlog允许从变量创建引用类型, 这样它们就可以用作表格的索引。
如果这与尾随和/或结合,则释放出全部潜力 正向链接。作为一个例子,我们已经实现了CLP(FD)。还有一个小解算器教程。
我们案例中的原始ingredients是:
1)无状态属性变量
2)尾随和变量键
3)延续队列
属性变量挂钩可能具有绑定效果,直到扩展连续队列,但只执行一次。来自延续队列的目标可以是非确定性的。
在实现应用程序之前还有一些额外的层,这些层主要是基元的聚合以暂时进行更改。
a)有限域约束求解器
b)Herbrand约束
c)目标暂停
再见
答案 2 :(得分:6)
您可以在ECLiPSe中找到最古老,最精细的属性变量实现之一,它构成了实现约束求解器的更广泛基础架构的一部分。
这种设计的主要特点是:
This paper (section 4)和ECLiPSe文档有更多详细信息。
答案 3 :(得分:5)
关于属性变量库的另一个视角是每个模块可以定义多少个属性。对于SWI-Prolog / YAP并引用SWI文档:
每个属性都与模块和钩子相关联 (
attr_unify_hook/2
)在此模块中执行。
对于诸如CLP(FD)之类的库的实现者来说,这是一个严重的限制,因为它强制使用附加模块的唯一目的是具有多个属性,而不是能够定义实现其库的模块中所需的那么多属性。 SICStus Prolog接口上不存在此限制,该接口提供了一个指令attribute/1
,允许为每个模块声明任意数量的属性。