What is a correct program?
What is an incorrect program?
Recall the idea of the state of a program:
A state is an assignment of a value to each variable in the program.
e.g. If the variables are x,y,z,ip
is a state.
A program specifies transitions
between states:
specifies
among an infinite number of other transitions
An assertion is a logical specification about states.
Typical assertions are attached to points between statements.
Attaching an assertion does not make the assertion true.
Assertions which are always true are called invariants.
We are interested in assertions which are true relative to starting states of interest.
Starting states of interest are specified by assertions, which we call
input assertions
or possibly
assumptions.
Thus we are interested in assertions which are invariant relative
to assumptions.
We claim the intermediate and ouptut assertions shown are
invariant relative to the input assertion n > 5.
Because the state set is generally infinite, such claims have to be verified
by induction of some form.
Two main principles:
transition induction :
induction on # of transitions made to get to state
structural induction :
induction on data domain
Consider verifying the intermediate assertion in
Basis: Assertion is true the first time we get to this point.
Proof of basis We see that n>5 and x==0 the first time. So x + n > 5n > 0.
Induction Step: Assume assertion is true now, show it will be true next time.
Use a prime
to designate the value of a variable
next time.
The induction step is
To prove this, we need to know how the primed variables
relate
to the unprimed ones.
We see
To prove a statement of form
one typically
assumes H,
tries to derive C.
How to get 6&7 from 1-5?
Deriving 6:
x' + n' > 5
From 3 & 4, 6 is equivalent to
(x + 1) + (n - 1) > 5
Which is equivalent to
x + n > 5
Which is exactly assumption 1.
QED
Deriving 7:
n' > 0
From 4, this is equivalent to
which follows from 5 (n > 5, assuming n integer ).
Now consider showing that the output assertion
follows from the intermediate assertion
The verification condition is
(we don't need primes, since no changes.)
The combination
implies
n == 0
Combining this with x + n > 5
we get
x > 5
QED
An invariant assertion placed before the test in a loop
is called a loop invariant.
Loop invariants are the key stepping stone between input and output assertions.
In a textual while loop, where does the loop invariant get
placed?
----initialization----
while( ----condition---- )
{
----body----
}
Another approach to
showing invariants (not always applicable).
Note that going around the loop leaves the quantity
x + n
unchanged.
Make the initial assertion:
Use as the invariant in the loop:
First Time
true since
x == 0
n == n0
n0 > 5
Induction step
x + n does not change
n0 does not change
n > 0 to go around loop
so n > 0 after decrementing 1
Exit
mean that n == 0
since x + n == n0
x == n0 on exit, and n0 > 5.
Typically, proposed loop invariants need to be "fine-tuned" during
development:
e.g. from the input assertion.
to complete the induction.
Identify the most informative loop invariant in the following:
Suggestion: Try hand-simulation
First cut at invariant
s == j2
Induction:
Basis : First time s == 0, j == 0
s == j2 is true
Induction Step :
s == j2 s' == j'2
where
s' == s + k
j' == j + 1
Can't be shown, because there is no restriction on k.
Second Try
s == j2k == 2j + 1
Basis: (you do it)
Induction Step: To show
[ s == j2k == 2j + 1s' == s + kj' == j + 1k' == k + 2 ]
[ s' == j'2k' = 2j' + 1 ]
Substituting into the Conclusion, it is
sufficient
to show that
s + k == (j+1)2k + 2 = 2(j+1) + 1
follows from
s == j2k == 2j + 1
Working forward from the latter:
QED
Ideally, the loop invariant asserts the "essence" of what is going on
in the loop.
More importantly, the loop usually is trying to establish some output assertion. Knowing that assertion helps tune the loop invariant.
Often, we can work backward from the output assertion to get the invariant.
A likely output assertion for the present example is
s == n2
i.e. the purpose of the program was to compute n2 without using multiplication.
Is the loop invariant adequate to show this?
If not, strengthen it so that adequacy is achieved.
Use of Invariant Assertions leads to the following form of
correctness
If the input assertion is true when the program starts,
then the output assertion will be true when & if the program ends.
This is called Partial Correctness because it does not establish that the program will terminate.
Total Correctness
wrt an input assertion
means
partial correctness
+
termination whenever we start in a state with that assertion.
Establishing Termination requires a second argument.
Here is one technique that can be used:
An energy function is a function
e: States{0,1,2,3,...}
such that on any two successive visits to the loop point s*s'
e(s) > e(s')
i.e. the energy has decreased.
If an energy function can be found, then the loop is guaranteed to
terminate.
Reason:
e(s) > e(s') > e(s'') > ...
cannot continue forever, since e has a minimum value of 0.
Identify an Energy Function for
Proving that a Program satisfies a
Specification
can be viewed as a kind of
checks & balances
activity.
The specification checks the program, the program checks the specification.
Specifications will, in general, require axioms about the data abstractions used.
Developing such abstractions is similar in many ways to
functional & logic programming.
The latter can be viewed as hybrids between programs and specifications.