1.2 Outline of the Thesis
2.1.2 Proof Methods for Program Verification
There are two methods for verifying a program, both of which can be applied to any sequential program which does not modify itself. The method of inductive assertions verifies the partial cor- rectness of programs (Floyd, 1967): a program (or command) is said to establish postcondition
Q
from preconditionP
if whenever the program beginning in a state satisfyingP
terminates, it does2.1 Program Verification 14
so in a state which satisfies
Q
. The method of intermittent assertions verifies the total correctness of a program (Manna, 1974; Burstall, 1974): the program is said to establish postconditionQ
from preconditionP
if execution of a program in a state satisfyingP
eventually terminates and does so in a state satisfyingQ
. The method of intermittent assertions is equivalent to the method of inductive assertions together with a proof that the program terminates (Cousot & Cousot, 1987).In both proof methods, the program to be verified is broken down into sequences of com- mands each of which is shown to satisfy an intermediate specification. These intermediate spec- ifications are then used to establish the program specification. The proof methods describe how the sequences of commands and their intermediate specifications must be chosen. The proof methods also describe how the intermediate specifications are established from the sequences of commands; the approach used suggests a method for simplifying program verification.
Proving Correctness
The method of inductive assertions and the method of intermittent assertions are both applied in the same way. Assume program
p
is to establish postconditionQ
from preconditionP
. Also assume that the program terminates in a state in which a final command is selected. As the first step, a set of cut-points are chosen such that the first command of the program is a cut- point, the final command is a cut-point and at least one command in every loop is a cut-point. Each cut-point cuti is associated with an assertionA
i. If cuti is the first command thenA
i is the precondition of the programP
. If it is the final command, thenA
i is the postcondition of the programQ
. All other assertions are intermediate assertions, chosen so that if the program establishes the intermediate assertions then the program specification will be established as a logical consequence. The cut-points at the loops are needed to allow the properties of loops in the program to be established by induction on the program variables (Floyd, 1967).Associating the cut-points with the intermediate assertions breaks down the proof that the program
p
establishesQ
from preconditionP
to the smaller proofs of each of the statements:From precondition
P
, programp
establishes assertionA
i. From assertionA
i, programp
establishes assertionA
j.. .
From assertion
A
k, programp
establishes the postconditionQ
The assertions
A
i form intermediate specifications to be satisfied by the sequences of commands between each cut-point in the program. For each cut-point cuti, the sequence of commandscuti
;c
1;::: ;c
n is formed up to, but not including, the next cut-point: commandc
n is followed by a cut-point cutj. The cut-points do not need to be distinct, if cuti is cutj then the commands are part of a loop in the program. The intermediate assertions,A
i andA
j, associated with the cut-points are the pre- and postcondition forming the specification to be satisfied by the sequence. Each sequence of commands, cuti;c
1;::: ;c
n is shown to satisfy its specification by associ-2.1 Program Verification 15
ating a second set of assertions,
B
1;::: ;B
n, with each command in the sequence. Each pair of assertionsB
i;B
i+1is a pre- and postcondition for commandc
i. The precondition for cuti is the assertionA
i and the postcondition forc
n is the assertionA
j. As before, assertionsB
1;::: ;B
n are chosen so that if each command satisfies its specification then the sequence of commands also satisfies its specification. The sequence is then verified by a proof of each of the formulas:A
i )wp(cuti;B
1 )B
1 )wp(c
1;B
2 ) .. .B
n)wp(c
n;A
j)If the sequence of commands is part of a loop (which may have been broken down into more than one sequence) then the proof will be by induction on the value of one or more variables. To show that the loop satisfies a specification, each sequence of commands in the loop must be shown to establish a property under each of the assumptions required for the induction scheme. The properties of each command in the sequence may therefore be the subject of more than one proof attempt.
Applying the Proof Methods
To verify a program using either the method of inductive assertions or the method of intermittent assertions requires a semantics for the programming language. This is needed to determine the effect of executing commands in the program as well as the method used to form sequences of commands in a program. For example, if a command
c
must be shown to satisfy the specificationB
i )wp(c;B
i+1
), then the effect of executing
c
in a state satisfyingB
i must be to produce a state satisfyingB
i. This can only be established from a specification of the command’s semantics.A large part of the work needed to verify a program is due to the method used to reason about the sequences of commands between program cut-points. Breaking down the sequences into individual commands means that the work needed to verify the program is proportional to the number of program commands. However, neither the proof method of Floyd (1967) nor that of Burstall (1974) requires that every command in the program be considered. It is only necessary to show that the program establishes the assertions at the program cut-points. If only these assertions are considered then the work needed is proportional to the number of cut-points. The number of cut-points will usually be less, and at worst no more, than the total number of program commands. It follows that transforming a program so that only the assertions at the program cut-points need to be considered can reduce the work needed to verify the program.
The languageLhas two purposes: the first, to provide a method for describing arbitrary ob- ject code programs in a form which allows the use of the proof methods of Floyd (1967) and Burstall (1974). The second, to support the transformation of a program so that only the asser- tions at the program cut-points need to be considered during verification. For this, the language L will allow a sequence of commands to be described as a single command of L. This can be used to describe a sequence of commands between program cut-points as a single command