Program Correctness

"The program and the correctness proof grow hand in hand."
-- Edsger Dijkstra, 1972, Turing award lecture

Program testing can at best show the presence of errors, but never their absence."
-- Edsger Dijkstra

The consequences of software errors can be great:

Many skills required to be a programmer or computer scientist - we've seen only a few of them so far
• ability to generalize
• create structured solutions to problems
• manage complexity and details
• trace code execution

Assertions - Detecting Errors in Programs Early

Rule of thumb about bugs - the earlier you find a bug, the faster you can fix it:
• If you find it as you are writing your psuedo-code or typing your program, the bug takes almost no time to fix.
• If you find it when compiling your program, the bug takes only a few seconds to fix.
• If you find it after you've finished the program and are testing it, you might not spend too much time fixing it.
• If the bug is found by users after you've shipped the software, you'll spend an arbitrarily large amount of time fixing the bug, and addressing the resulting fallout.

Assertions make it easier to find bugs earlier.

Logical Assertions

assertion
- a sentence that is true or false

In logic, we sometimes call sentences with a boolean value either a proposition or a statement.

Examples:
UT beat OU in 2009.
Halloween will be on a Friday in 2009.
It rained in Austin on October 30, 1999.
2 + 3 = 10
4 < 5

Examples:
Go to the store.
Can we go home now?
Is it cold outside?

Actually, in programs, assertions are often statements that are true or false at the time they are executed.  They may include a variable, and their truth value may only be determined at the program's run-time, when the variable has a specific value. In logic, we would call them predicates.

At run-time, these predicates become propositions (that is, they have a truth value), since their variables have been assigned specific values.

Examples:
x > 0
x!=3 && x > 0
It rained.

Given some context, we can determine the truth values of these assertions:
• x > 0 is true, when x = 7
• x!=3 && x > 0 is false, when x = 0
• It rained on the UT campus on October 19, 2009. (false)

It's an important skill to be able to make assertions about your program and determine when (in which contexts) those assertions are true.

Example:
Scanner scan = new Scanner(System.in);
System.out.print("Play again? yes or no: ");
String x = scan.next();
// is x equal to "yes" or "no" here?

Example:
Scanner scan = new Scanner(System.in);
System.out.print("Play again? yes or no: ");
String x = scan.next();
while(!x.equals("yes") && !x.equals("no")) {
System.out.println("That wasn't a yes or no. Try again.");
System.out.print("Play again? yes or no: ");
x = scan.next();
}
// is x equal to "yes" or "no" here?

Program Verification

"Computer programs may be regarded as formal mathematical objects whose properties are subject to mathematical proof."
- Robert Boyer and J. Strother Moore

program verification - proving the correctness of a program with respect to a formal specification of the software.

Several UTCS faculty members are active in this area of computer science: Moore, Boyer, Lam, Hunt, Emerson (winner of 2007 Turing award)

provable assertion - an assertion that can be proven true at a specified point in program execution

Example: For each point in this program, is the assertion "x > 3" true: sometimes, always, or never

if(x > 3) {
// point A
}
else if(x > 2) {
// point B
}
else {
// point C
}
// point D

Another Example with Assertions

Scanner scan = new Scanner(System.in);
System.out.print("Enter a non-negative integer: ");
int x = scan.nextInt();
// x >= 0... true sometimes, always, never?

while(x < 0)
{
// x >= 0... true sometimes, always, never?
System.out.print("Invalid input. Enter a non-negative integer: ");
x = scan.nextInt();
}

// x >= 0... true sometimes, always, or never?

• Inside an if/else structure, you may know the truth of an assertion based on the  condition(s) for the structure:
if(x > 100) {
// point A
}
else {
// point B
}

Assertion x > 100:
At point A?
At point B?

Assertion x < 200:
At point A?
At point B?

• A while or for loop condition may also indicate the truth of an assertion:
while(!x.equals("stop")) {
// point A
}

// point B

Assertion x equals "stop":
At point A?
At point B?

• Right after a variable is initialized, you know the truth value of assertions about that variable:
int number = 14;
// assertion number < 20 is ALWAYS true

• Typically assertions about the value of parameters have unknown truth values:
public static void mystery(int parm1, int parm2) {
// assertion: parm1 < 0   SOMETIMES true
// any assertion about the value of parm2: SOMETIMES true

• At the top of a loop body, the loop condition must be true:
while(a > 5) {
// is a > 5? ALWAYS true
}

• After a loop, the loop condition must be false:
while(a > 5) {
...
}
// is a > 5? NEVER true

Another Assertion Example

public static void mystery(int x, int y) {

int z = 0;

// Point A

x = x - y;
// Point B

while (x > y) {
// Point C
z++;
// Point D
}

// Point E

Which assertions are true at which points in the code? Answer: ALWAYS, SOMETIMES, or NEVER

 x < y z == 0 Point A Point B Point C Point D Point E

Assertion Exercise

public static int mystery(Scanner scan) {
int prev = 0;
int count = 0;
int next = scan.nextInt();
// Point A
while(next != 0) {
// Point B
if(next == prev) {
// Point C
count++;
}
prev = next;
next = scan.nextInt();
// Point D
}
// Point E

return count;

Which assertions are true and at which points in the code? Choose ALWAYS, NEVER, SOMETIMES
next == 0
prev == 0
next == prev

Assertions in Java

assert  <boolean expression>;

When the code is executed, the boolean expression is evaluated. If it is false, an exception is thrown. (Exceptions are Java's way of handling run-time errors).