For a deterministic binary operation on an abstract data type, let be its specified operation on abstract values and the implementation on concrete states. For every permitted valid input pair , require both
The first condition preserves the representation invariant. The second makes a commutative diagram: either execute and then apply the abstraction function, or apply the abstraction function to both inputs and then execute the abstract operation ; both paths reach the same value. These conditions state functional correctness of a completed operation; termination is an additional obligation for algorithm correctness.[ref]
For addition in the unreduced rational representation, choose
For example, represents , precisely the sum of and . The short correctness argument uses nonzero denominators: and imply , preserving the representation invariant, and
Figure 1.
Correct rational addition makes both paths agree; an invariant-preserving incorrect operation gives a different value
. Details.
Now consider an incorrect implementation that uses addition on the numerators and multiplication on the denominators:
It preserves the representation invariant for every valid input pair because its denominator is still . Yet represents , not the specified sum . Even perfect checks of the representation invariant before and after this call would miss the error: the result is a legal representation of the wrong rational number.
The incorrect operation also exposes an accidental dependence on representation. Replace by the equivalent state while keeping . The correct operation gives , still representing ; the incorrect operation gives , representing instead of its previous . A correct addition must yield the same abstract result for equivalent inputs, although its concrete outputs may differ. This is why checks against the formal specification should compare abstract values, including unreduced representations and representations with a negative denominator, rather than demand identical stored pairs.
The calculation assumes exact integers. An implementation with bounded storage must additionally specify how it handles products and sums outside its supported range; the mathematical argument alone does not establish its functional correctness. The bounded queue with encapsulation illustrates the corresponding need to account for returned status values and failed operations, alongside the abstract state transition.

There are no discussions about this article yet.

Articles by others on the same topic (NaN)

There are currently no matching articles.