Prolog-映射(关联数组)

时间:2015-03-27 14:31:41

标签: list prolog

我正在研究prolog,并想知道是否有人给我指导如何去做这个问题,这是该领域的许多人中的第一个,知道如何做这个问题将真正帮助我取得进步。提前谢谢你。

使用Prolog定义谓词mapof(K,M,V),这样,当用K实例化到一个键调用,并且M实例化到一个映射时,mapof会将变量V实例化为值(或其中一个值) )与映射M中的K相关联。如果K在映射M中不作为关键字出现,则谓词应该失败。

2 个答案:

答案 0 :(得分:4)

这取决于你想要如何表示你的#34;映射"。在Prolog中,事实表是最明显的方法。对于两个映射mn

m(a, 1).
m(b, 2).
m(c, 3). % and so on

n(a, foo).
n(b, bar).
n(c, baz). % and so on

然后,你的mapof将是:

mapof(K, m, V) :- m(K, V).
mapof(K, n, V) :- n(K, V).

或者也许:

mapof(K, M, V) :- call(M, K, V).

列表可以用来表示映射,如@Yasel所示,但Prolog中的列表[a, b, c]是一个嵌套的术语,如.(a, .(b, .(c, [])))。您通常不会将关联数组表示为单链表,对吧?

在SWI-Prolog中,有一个库比使用简单列表更好地表示作为Prolog术语的可追踪关联数组:library(assoc)。有了它,你可以这样做:

mapof(K, M, V) :- gen_assoc(K, M, V).

此库将关联数组表示为AVL树。您可以在SWI-Prolog代码源中找到另外两个关联数组实现:一个使用RB-trees,另一个使用non-backtrackable RB-trees

如果你的关联数组中包含大约100个键值对,那么这里提到的所有三个库都可能比一个简单的键值对[k1-v1, k2-v2...]更有效。这并不意味着使用对列表并执行member(Key-Value, List_of_pairs)是错误的;对于简单的案例来说,这是最便宜的解决方案。

答案 1 :(得分:2)

使用内置谓词member/2,您可以像这样构建谓词mapof/3

mapof(K, M, V):- member((K,V), M).

咨询:

?- mapof(k1, [(k, a),(k1,b),(k2,c),(k1,d)], V).
V = b ;
V = d.