Preconditions
Postconditions
Loop Invariants
Loop Variant
Often when writing contracts you end up rewriting your code. This is ok.
Ideally you should write your contracts and the code at separate times. Otherwise, any condition you forget in one will be forgotten in the other. Contracts aren't magic. They can be incomplete and/or suffer from errors in logic and syntax as well.
Languages Using Contracting:
(Not required reading.)
Contracting is more than comments:
Assert statements (or defensive programming) is the most basic way to implement contracting:
assert [boolean expression];
A full description of Java's assert is here. A shorter example follows:
// Add an array of numbers, where each number must be between 1 and 100
int AddArrayOfNumbers(int[] inArray) {
int arraySum = 0, oldVariantI = 0;
// Preconditions
assert inArray <> null; // The order of assertions matter
assert inArray.length > 0;
for (int i = 0; i < inArray.length; i++)
{ assert inArray[i] > 0 && inArray[i] < 101; }
// Algorithm
oldVariantI = inArray.length; // Initialize the variant
for (int i = 0; i < inArray.length; i++) {
// Variant decreases
asssert (oldVariantI - 1) < OldVariantI;
// Invariant: inArray.length
arraySum = arraySum + inArray[i];
oldVariantI = oldVariantI - 1;
}
// Postconditions
assert arraySum >= inArray.length;
assert arraySum <= (inArray.length * 100);
// Finally, return the value
return arraySum;
}
In the above code, observe that: