Using Logic for

Building Correct Software


What is a correct program?

 

 

 

 

 

What is an incorrect program?

 

 

 

 


Assertions

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.

 


Example

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


Summary of What is to be Shown


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:


Exercise

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.