Re: Can you violate invariant within an operation



Responding to Johansson...

Is it right that you are allowed to violate invariant when executing an operation but before you
exit the operation the invariant must be valid again.

It depends on where the observer is standing. B-) The answer is Yes and No.


method (y):
   x = operation1(y)
   x = operation2(x)
   x = operation3(x)
   return x

If the invariant is that X < 65535 then one can violate the invariant within operation2 and operation3 so long as 'x' is always < 65535 at any point where it exists in 'method'. That's because operationN is viewed as a logically indivisible activity at the level of abstraction of 'method'. Logical indivisibility implies a somewhat magical instantaneous conversion or input 'x' to output 'x' so there isn't an opportunity for violating the constraint.

However, there is nothing to preclude operationN from violating the invariant within its scope when one reduces the level of abstraction to what happens in a procedure. For example, suppose operation2 applies some stochastic process to the input sample and returns the mean of the input value and the modified value(s). In that case some of the modified values of 'x' might exceed 65535 but that will be transparent to 'method' so long as the mean remains < 65535.

[Of course there is an issue of what 'x' is in this example. One could argue that 'x' within operationN is not the same one as in 'method' (i.e., 'x' only appears as an input parametric value that doesn't change within operationN, which produces an entirely different output). But let's not go there because it leads to the logical conundrum of whether the 'x' returned is the same one that 'method' provided as input. (I used the daisy chaining specifically to underscore this issue.)]

OTOH, the 'method' invariant will be reflected in conditions on the processing /within/ the operationN procedures when one reduces the level of abstraction to that level. For example, suppose operation2 squares the input value. Then a postcondition of output x < 65535 will apply. That, in turn, implies a precondition for operation2 that the input x < 65535**0.5. In addition, there may be additional constraints that apply within the operationN procedure. For example, there might be intermediate multiplications that could cause overflow on a 16-bit machine. IOW, 'method' and other context specify requirements on operationN even though the implementation is logically indivisible from the viewpoint of 'method' and those requirements would be reflected in contract conditions.

As the discussion demonstrates, when operations are not atomic one can get into rather pedantic discussions about things like what 'x' is when dealing with invariant transitivity. In such cases it is easier to treat the operation contract as a completely different contract with its own unique suite of conditions as I did above. Those conditions may or may not require transitivity of the invariant to the operation, depending upon context.


************* There is nothing wrong with me that could not be cured by a capful of Drano.

H. S. Lahman
hsl@xxxxxxxxxxxxxxxxx
Pathfinder Solutions  -- Put MDA to Work
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
(888)OOA-PATH



.