Writing Correct Programs
CORRECT PROGRAMS DON'T just happen. It takes planning and attention to detail to avoid
errors in programs. There are some techniques that programmers can use to increase the
likelihood that their programs are correct.
8.2.1 Provably Correct Programs
In some cases, it is possible to
that a program is correct. That is, it is possible to
demonstrate mathematically that the sequence of computations represented by the program will
always produce the correct result. Rigorous proof is difficult enough that in practice it can only
be applied to fairly small programs. Furthermore, it depends on the fact that the "correct result"
has been specified correctly and completely. As I've already pointed out, a program that correctly
meets its specification is not useful if its specification was wrong. Nevertheless, even in
everyday programming, we can apply some of the ideas and techniques that are used in proving
that programs are correct.
The fundamental ideas are
. A state consists of all the information relevant to
the execution of a program at a given moment during its execution. The state includes, for
example, the values of all the variables in the program, the output that has been produced, any
input that is waiting to be read, and a record of the position in the program where the computer is
working. A process is the sequence of states that the computer goes through as it executes the
program. From this point of view, the meaning of a statement in a program can be expressed in
terms of the effect that the execution of that statement has on the computer's state. As a simple
example, the meaning of the assignment statement "
x = 7;
" is that after this statement is
executed, the value of the variable
will be 7. We can be absolutely sure of this fact, so it is
something upon which we can build part of a mathematical proof.
In fact, it is often possible to look at a program and deduce that some fact must be true at a given
point during the execution of a program. For example, consider the
TextIO.put("Enter a positive integer: ");
N = TextIO.getlnInt();
} while (N <= 0);
After this loop ends, we can be absolutely sure that the value of the variable
is greater than
zero. The loop cannot end until this condition is satisfied. This fact is part of the meaning of the
loop. More generally, if a
loop uses the test "
after the loop ends, we can be sure that the
is false. We can then use this fact to
draw further deductions about what happens as the execution of the program continues. (With a
loop, by the way, we also have to worry about the question of whether the loop will ever end.
This is something that has to be verified separately.)