【问题标题】:Prolog- Mappings (Associative Arrays)Prolog-映射(关联数组)
【发布时间】:2015-03-27 14:31:41
【问题描述】:

我正在学习序言,想知道是否有人指导我如何做这个问题,这是该领域中的第一个,知道如何做这个问题真的会帮助我进步。提前谢谢你。

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

【问题讨论】:

  • 破坏性地编辑问题绝对不行。阅读指南。

标签: list prolog


【解决方案1】:

这真的取决于你想如何表示你的“映射”。在 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) 是错误的;对于简单的情况,这是最便宜的解决方案。

【讨论】:

    【解决方案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.
    

    【讨论】:

    • 创建一个配对列表:K-V 而不是 (K, V)[k-a, k1-b...] 而不是 [(k, a), (k1, b)...]。对比 Prolog 中的“元组”更传统一些。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多