前几天我在prolog中解决了一个难题,并意识到如果我使用其他编程语言,我会使用哈希表/字典,但据我所知,这在prolog中是不可能的。
所以我的第一个问题是,是否有任何prolog支持类似字典的数据结构以及哈希表的性能特征?
其次,我想到,由于大多数prolog使用哈希表来存储谓词,我可以编写一个包装器谓词来断言和收回事实,创建一个字典接口来利用谓词的底层哈希表。但是我会获得散列表的性能特征,还是会增加会降低性能的开销?
答案 0 :(得分:9)
某些Prolog环境有关联列表,可用于创建和编辑字典:
修改强>
您可以通过在外语中实现谓词来获得更好的性能,例如:
答案 1 :(得分:7)
我刚刚发现:
SWI-Prolog版本7引入了 dicts 作为带有的抽象对象 用于访问成员的具体现代语法和功能表示法 以及用户定义的访问功能。
语法如下:
Tag{Key1:Value1, Key2:Value2, ...}
有关详细信息,请参阅Dicts: structures with named arguments。
请注意:
point{x:1,y:2}.x
dict
的复合词。第一个参数是标签。其余参数创建一组已排序的键值对" 当前(2019)实施的操作的时间复杂性在"5.4.5: Implementation Notes about dicts"下的SWI Prolog手册中给出:
Dicts目前使用仿函数表示为复合词
dict
。第一个参数是标签。剩下的参数创建 一组已排序的键值对。这种表现形式紧凑 保证良好的地方。查找是订单 log(N),同时添加 值,删除值以及与其他dicts合并的顺序为 N 。 主要的缺点是在大的dicts中改变值是 在记忆和时间方面都很昂贵。未来版本可能在单独的结构中共享密钥或使用二进制文件 树木允许更便宜的更新。其中一个问题是 代表必须保持规范或统一必须 扩展以补偿替代表示。
答案 2 :(得分:4)
我不是Prolog人(只是一个外部观察者),但我发现了这个:
http://www.sics.se/sicstus/docs/4.0.7/html/sicstus/lib_002davl.html
当我搜索“prolog有限地图平衡树”时。它说它是关联列表的替代实现。
(为什么我想到这个:在Haskell中,一种纯粹的函数式语言,而不是关联列表或哈希表,通常使用树来表示(持久性)字典或有限映射。查找也是O(log(N)有关实现具有平衡树的地图的一些参考,请参见Data.Map。)
答案 3 :(得分:3)
答案 4 :(得分:2)
以下评论大致从“更具体”到“更一般”的顺序解决了您的问题。
首先,解决你的具体评论:
我会使用哈希表/字典,但据我所知,这在Prolog中是不可能的。
所有严肃的Prolog实现都允许您使用例如setarg/3
破坏性地修改Prolog术语。使用arg/3
和setarg/3
可以让O(1)访问术语的每个参数,这足以完全像在其他语言中一样实现哈希表,假设您的系统没有对其进行任意限制。术语。
自己这样做并不是一个好主意,因为您必须考虑所有条款的意外复制和条款共享。相反,依靠图书馆来做到这一点。
哪些图书馆?我是其他人写的第二篇:使用基于树的库,例如library(assoc)
,library(avl)
等,而不是哈希库。这些库在普通情况下不如哈希效率高,但是:
正如其他人所写,破坏性修改与逻辑编程不兼容,树库具有巨大优势,可以用 ISO Prolog 和纯粹方式实现渐近最佳效率。
最后,SWI-Prolog的字典扩展不符合ISO ,甚至语法,因此无法移植到符合要求的Prolog系统!有关如何以符合ISO标准的方式添加中缀点,请参阅Ulrich Neumerkel的comments。