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)
Reasoning about Assertions
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?
Reasoning about Assertions
- 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).