NICE-ESG-Libs Digest Thu, 17 Aug 95 Volume 1 : Issue 284
Today's Topics:
ARRAY 'make'
NICE Eiffel Standards Group -- Library Committee Mailing List
To post to list:
NICE-ESG-Libs@atlanta.twr.com
To send mail to the Chairman of the committee:
NICE-ESG-Libs-chair@atlanta.twr.com
Administrative matters (sign up, unsubscribe, mail problems, etc):
NICE-ESG-Libs-request@atlanta.twr.com
Date: Thu, 17 Aug 1995 10:31:15 GMT
From: Roger Browne <rogerb@eiffel.demon.co.uk>
Subject: ARRAY 'make'
To: NICE-ESG-Libs@atlanta.twr.com
Thanks Jim for your useful comments about ARRAY's 'make'.
Jim McKim wrote:
> Let me put forth three specific possibilities...
>
> 1) The current version.
>
>
> make (min_index, max_index: INTEGER)
> -- Allocate array; set index interval to
> -- minindex .. maxindex; set all values to default.
> -- (Make array empty if minindex > maxindex.)
> ensure
> no_items: min_index > max_index implies (lower = 0 and upper = -1)
> lower_initialized : min_index <= max_index implies lower = min_index
> upper_initialized: min_index <= max_index implies upper = max_index
> items_initialized: -- for_all i, lower..upper (item(i) /= Void implies item(i) = item(i).default)
I guess what Jim means by "current version" is the current semantics with the
addition of his proposed postconditions. For convenient reference, here is the
ELS95 version, together with the class invariant:
make(minindex, maxindex: INTEGER)
-- Allocate array; set index interval to
-- 'minindex .. maxindex'; set all values to default.
-- (Make array empty if 'minindex > maxindex.')
ensure
no_count: (minindex > maxindex) implies (count = 0);
count_constraint: (minindex <= maxindex) implies
(count = maxindex - minindex + 1)
invariant
consistent_size: count = upper - lower + 1;
non_negative_count: count >= 0
This raises some points:
1. The first postcondition is not as strong is it should be. The LHS is true
if and only if the RHS is true, so we could write:
no_count: (minindex > maxindex) = (count = 0);
2. The postcondition does not specify what happens to 'upper' and 'lower' when
we create an empty array (i.e. minindex > maxindex). Jim's version
deliberately overrides 'minindex' and 'maxindex' and sets 'lower' to 0
and 'upper' to -1.
This seems counterintuitive. Consider the code fragment:
a: ARRAY[X]
...
!!a.make(5, 4)
a.force(x, 5)
It would be very strange if the array range after execution of this
code was 0..5 rather than 5..5
I had assumed that the intention of ELS95 was that 'lower' would always
be set to 'minindex' and 'upper' to 'maxindex', even in the case of an
empty array. But if we allow (as ELS95 does) arbitrary values of 'minindex'
and 'maxindex', then the following ELS95 invariant is in error:
consistent_size: count = upper - lower + 1;
So, clearly ARRAY's 'make' needs to be fixed. This leads us to consider
Jim's third case:
> 3. A version that allows empty arrays, but with a bit more control than
> (1), inspired by Roger's comments
>
> make (min_index, max_index: INTEGER)
> -- Allocate array; set index interval to
> -- min_index .. max_index; set all values to default.
> require
> valid_indices: min_index <= max_index + 1
> ensure
> lower_initialized : lower = min_index
> upper_initialized: upper = max_index
> items_initialized: -- for_all i, lower..upper (item(i) /= Void implies
> item(i) = item(i).default)
I favour this suggestion, and would suggest one stylistic change to the
final, commented, postcondition.
change:
item(i) /= Void implies item(i) = item(i).default
to:
item(i) = Void or else item(i) = item(i).default
Because I mentally replace 'A implies B' with 'not A or else B', I find the
revised wording clearer because it eliminates a double negative.
> My current favorite is (3) as Roger has convinced me, but of course that's
> for the committee to decide. If (3) is adopted then two invariant
> clauses from my earlier proposal, postive_count and valid_bounds, would
> have to change.
>
> nonnegative_count: count >= 0
> valid_bounds: upper + 1 >= lower
We can strengthen this by saying more about 'count'. I favour retaining the
existing ELS95 invariant (which would now be correct with the new version of
'make'), as follows:
consistent_size: count = upper - lower + 1;
non_negative_count: count >= 0
Taken together, these imply Jim's 'valid_bounds' invariant, but they say
more about 'count'.
Jim's third proposal, plus these minor changes, yields an ARRAY 'make' with
the following natural semantics:
- 'lower' is always set to 'minindex'
- 'upper' is always set to 'maxindex'
Furthermore, zero-size arrays are permitted, and (unlike the ELS95 version
which requires an 'if-then-else'), they do not impose any special case on the
implementation of 'count'.
Regards,
Roger
--
-- Roger Browne, 6 Bambers Walk, Wesham, PR4 3DG, UK | Ph 01772-687525
-- Everything Eiffel: compilers/libraries/publications | +44-1772-687525

|
|