Consider a flag that may be up or down, as on an old fashioned mail box, with
methods to put the flag up, put it down, and reverse it. There is just one
attribute (namely up?) showing whether the flag is up or down; see the Java
applet (due to Grant Malcolm) and BOBJ specification below.

We want to show that if we reverse the flag twice, then the flag returns to
its original state, i.e., we want to show that for all flags F,

rev rev F = F .

Unfortunately, this equation is not satisfied by all models (i.e.,
implementations) of FLAG! For example, consider the
model whose states are natural numbers, and whose operations are defined as
follows:

where EVENAT denotes the natural numbers with an
even operation. Here, the equation is not satisfied
because

rev rev F = F + 2 .

For another example, consider the model whose states are "histories"
that is, sequences of all methods (i.e., messages) received so far. Then the
state after a double reversal of F is the sequence
rev rev F, which does not equal the sequence F. Such an implementation (or one a little simpler) would
be needed if some other attributes were required, such as the number of
methods received, or the last method received.

Actually, there is only one implementation (up to isomorphism) where
the equation is actually true of all reachable states! There are infinitely
many other implementations where the equation is literally false, but
always appears to be true. This means that the equation is
observationally or behaviorally satisfied by M, which we write as

M (F : Flag) rev rev F = F

even though

M (F : Flag) rev rev F = F

(ordinary satisfaction) does not hold. Thus, we need a technique that allows
us to prove behavioral satisfaction, not just ordinary satisfaction.
This is why we use coinduction. This situation is actually very common:
software engineers often write clever code that doesn't really satisfy its
specification, but does always "appear to" to satisfy it.

Flags are about the simplest non-trivial example of coinduction we could
find, but if you are not already familiar with hidden algebra and coinduction, you will have some work to do before you can
follow our proof. In that case, you should do some background reading, and
start with some proofs using more familiar techniques, such as induction; the
tatami project
homepage would be a good place to start, especially its links to the
hidden algebra tutorial.