Consider an original FIFO queue example storing immutable labels, with fixed positive integer capacity . Its abstract state is a finite sequence , with . The API has enqueue(x), dequeue(), peek() and size(). Successful enqueue returns ok; a full queue returns full and is unchanged. Successful dequeue returns the first label and removes it; an empty queue returns empty and is unchanged. peek returns the first label or empty without modification, and size returns . The status results are distinct from stored labels.
For a compact array representation , fix and require the representation invariant
The abstraction function is . Only these first entries matter; unused slots have no abstract meaning. On successful enqueue(x), write and then set . On successful dequeue(), save , shift the remaining entries left, and decrement . Testing the full or empty case before updating gives the specified unchanged failure state.
Figure 1.
Permitted queue calls preserve valid states; an unrestricted count write bypasses the API
. Details.
With and , enqueue(C) produces ; enqueue(D) returns full without change. A raw write violates the representation invariant. More subtly, changing the count from two to one satisfies its bounds but discards without a permitted operation. Validity of the storage state and legality of the API transition are different obligations. A setter for every storage field would surrender the useful boundary even if its name looked like an ordinary operation.

Articles by others on the same topic (NaN)

There are currently no matching articles.