在Erlang

时间:2015-06-23 17:16:41

标签: functional-programming erlang set

给定集合的数据结构,测试两个集合的相等似乎是一个理想的任务,实际上许多实现允许这样做(例如python中的内置集合)。

Erlang中有不同的集合实现:setsordsetsgb_sets。他们的文档没有说明是否可以使用术语比较来测试相等性(" =="),它们也不提供用于测试相等性的显式函数。

一些天真的案例似乎允许使用" =="进行同等性测试,但我有一个更大的应用程序,我可以生成setsgb_sets是相等的(使用下面的函数测试),但不要与" =="进行比较。对于ordsets,他们总是比较平等。遗憾的是,我还没有找到一种方法来生成一个最小的例子,其中相等的集合与" =="

相等。

为了可靠地测试相等性,我使用以下函数,基于此theorem on set equality

%% @doc Compare two sets for equality.
-spec sets_equal(sets:set(), sets:set()) -> boolean().
sets_equal(Set1, Set2) ->
    sets:is_subset(Set1, Set2) andalso sets:is_subset(Set2, Set1).

我的问题:

  1. 他们的理由是,为什么Erlang设置实现不提供显式的相等测试?
  2. 如何解释用" =="测试集合相等性时的差异与不同的集合实现?
  3. 如何生成sets的最小示例,其中" =="给出上述代码时,不比较相等,但这些集合相等?
  4. 关于问题2的一些想法:

    sets州的文档,"未定义集合的表示。"作为ordsets状态的文档,其中" ordset是集合的表示"。 gb_sets上的文档没有提供任何类似的指示。 来自source code of the sets implementation的以下评论似乎重申了文档中的陈述:

      

    请注意,由于键的顺序未定义,我们可以自由地重新排序存储桶中的键。

    我的解释是,与" =="在Erlang中,对集合的表示起作用,即如果它们的表示相同,则两个集合仅相等。这可以解释不同集合实现的不同行为,但也强化了问题,为什么没有明确的相等比较。

1 个答案:

答案 0 :(得分:5)

ordsets被实现为排序列表,并且实现相当开放并且可见。他们将比较相等(==),但==表示1.0等于1.他们不会比较严格相等(=:=)。

sets被实现为哈希表的一种形式,其内部表示不适用于任何形式的直接比较;当哈希冲突发生时,添加的最后一个元素被添加到给定哈希条目的列表中。此前置操作对添加元素的顺序很敏感。

gb_sets被实现为一般的平衡树,树的结构确实取决于元素的插入顺序以及何时进行重新平衡。直接比较它们是不安全的。

要将两组相同类型的数据进行比较,一种简单的方法是调用Mod:is_subset(A,B) andalso Mod:is_subset(B,A) - 当两组相等时,它们只能是彼此的子集。