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)
具有相同的效果。
这是 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)
具有相同的效果。