0

This is part of the class. This class is called BAG[G -> {HASHABLE, COMPARABLE}] it inherits from ADT_BAG which has deferred features such as count, extend, remove, remove_all, add_all... more, and domain to be re-implemented.

domain returns ARRAY[G] which is a sorted array list of G

i always get Post-condition violation "value_semantics" which is something to do with object comparison but I checked and there is no code for object comparison which is very weird.

I tried to remake the code for domain feature several times and it ALWAYS ends up with a post-condition violation or a fail.

When I check the debugger the array "a" that is returned from domain always has count 0 but this does not make sense because i move keys from table to "a" but count is still 0.

Maybe I am transferring the keys wrong to the array?

code:

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

test code:

     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
geforce
  • 61
  • 6

1 Answers1

1

The first loop across 1 |..| (a.count) as i is not going to make a single iteration because a is empty (has no elements) at the beginning. Indeed, it has been just created with create a.make_empty.

Also, because keys in the table are unique it is useless to check whether a key has been added to the resulting array: the test not a.has (t.key) will always succeed.

Therefore the first loop should go over keys of a table and add them into the resulting array. The feature {ARRAY}.force may be of interest in this case. The addition of the new elements should not make any "holes" in the array though. One way to achieve this is to add a new element right after the current upper bound of the array.

The sorting loop is also incorrect. Here the situation is reversed compared to the previous one: sorting cannot be done in a single loop, at least two nested loops are required. The template seems to be using Insertion sort, its algorithm can be found elsewhere.

EDIT: the original answer referred to {ARRAY}.extend instead of {ARRAY}.force. Unfortunately {ARRAY}.extend is not generally available, but a.extend (x) would have the same effect as a.force (x, a.upper + 1).

Alexander Kogtenkov
  • 5,770
  • 1
  • 27
  • 35