Post-Eiffel 中的特征违反条件

Post-Condition Violation with Feature in Eiffel

这是 class 的一部分。这个 class 叫做 BAG[G -> {HASHABLE, COMPARABLE}] 它继承自 ADT_BAG,后者具有延迟功能,例如计数、扩展、删除、remove_all、add_all... 更多,以及要重新实现的域。

domain returns ARRAY[G] 这是 G

的排序数组列表

我总是得到 Post-condition violation "value_semantics",这与对象比较有关,但我检查了一下,没有用于对象比较的代码,这很奇怪。

我多次尝试重新编写域功能的代码,但总是以 post 条件违规或失败告终。

当我检查调试器时,从域返回的数组 "a" 总是计数为 0 但这没有意义,因为我将键从 table 移动到 "a" 但计数还是0.

也许我将密钥错误地传输到阵列?

代码:

count: INTEGER
        -- cardinality of the domain
    do
        result := domain.count -- has to be domain.count because loop invariant: consistent: count = domain.count
    end


domain: ARRAY[G]
        -- sorted domain of bag
    local
        tmp: G
        a: ARRAY[G]

    do
        create a.make_empty

        across 1 |..| (a.count) as i  -- MOVING keys from table to array
          loop
                across table as t
                  loop
                       if not a.has (t.key) then
                            a.enter (t.key, i.item)
                            i.forth
                       end
                  end

           end

        across 1 |..| (a.count-1) as i  -- SORTING
          loop
                if a[i.item] > a[i.item+1] then
                    tmp := a[i.item]
                    a[i.item] := a[i.item+1]
                    a[i.item+1] := tmp
                end

           end

    Result := a

    ensure then
        value_semantics: Result.object_comparison -- VIOLATION THROWN HERE
        correct_items: across 1 |..| Result.count as j all
            has(Result[j.item]) end
        sorted: across 1 |..| (Result.count-1) as j all
            Result[j.item] <= Result[j.item+1] end
    end

测试代码:

     t3: BOOLEAN
    local
        sorted_domain: ARRAY[STRING]
    do
        comment("t3:test sorted domain")
        sorted_domain := <<"bolts", "hammers", "nuts">>
        sorted_domain.compare_objects
        Result := bag2.domain ~ sorted_domain -- fails here
        check Result end
    end

第一个循环 across 1 |..| (a.count) as i 不会进行单次迭代,因为 a 一开始是空的(没有元素)。实际上,它是刚刚用 create a.make_empty.

创建的

此外,由于 table 中的键是唯一的,因此检查是否已将键添加到结果数组中是无用的:测试 not a.has (t.key) 将始终成功。

因此第一个循环应该遍历 table 的键并将它们添加到结果数组中。在这种情况下,特征 {ARRAY}.force 可能很有趣。但是,添加新元素不应在数组中产生任何 "holes" 。实现此目的的一种方法是在数组的当前上限之后立即添加一个新元素。

排序循环也不正确。这里的情况和前面的情况相反:排序不能在一个循环中完成,至少需要嵌套两次循环。模板好像用的是插入排序,算法可以参考elsewhere.

编辑: 原始答案指的是 {ARRAY}.extend 而不是 {ARRAY}.force。不幸的是 {ARRAY}.extend 并不普遍可用,但 a.extend (x)a.force (x, a.upper + 1) 具有相同的效果。