Here is an example of a Java method that is supposed to get some integers from the user until it sees a Control-D:
public static int sumInts ( )
{
// Reads ints from System.in, one per line, until a line with Control-D.
// Returns sum of integers read.
int soFar = 0;
String thisLine;
// Java stuff necessary to read from System.in
BufferedReader br = new BufferedReader (new InputStreamReader (System.in));
System.out.println
("Enter integers, one per line, then Control-D:");
while ( (thisLine = br.readLine()) != null) {
soFar += Integer.parseInt (thisLine);}
return soFar;}
What does it mean for this code to be ``correct''? We would like to be sure that if the user does the right thing (inputs the integers as requested), the method will return the correct value. In general we can say what we want from the code by giving preconditions and postconditions. A precondition is a statement that should be true before the code is executed --- here it is ``the user inputs zero or more integers, one per line, followed by a blank line''. A postcondition is something that should be true after the code is executed if the preconditions were met. Here our postcondition is ``the returned value is the sum of the given integers''. We define the code to be partially correct if the postconditions must always be true after execution whenever the preconditions were true before. (So partial correctness says nothing about how to handle erroneous input, for example, unless the preconditions and postconditions say how to do so.)
How could we be sure that this code is correct? Coding mistakes are easy to make, and even if the compiler finds no syntax errors there could be subtle errors of logic. We could test the code on sample inputs, but some errors might cause bad behavior only on rare inputs that we didn't think to test (and in most cases we could never test all the relevant inputs).
What we need is a formal argument --- a proof! We want to show how the
statement of partial correctness follows logically from things that
we can assume to be true. The things we can assume are the basic properties
of the language and the library procedures. For example, if the user does
input an integer, the properties of readLine
and
Integer.parseInt
can tell us how that integer will go from the input
device into the value of some variable in our program.
while
loop each time. Explain why
if your invariant holds when the while
loop exits, the desired postcondition has
been met.
public static natural div (natural x, natural y)
{// Returns x/y unless y is zero
int q = 0;
while (x >= y) {
x -= y; q++;}
return q;}
Last modified 15 September 2004