\documentstyle[cprog]{simslide}
\uppercorners{Data Structures in C++}{\thepage}
\lowercorners{Proving Correctness}{Chapter 5}
\begin{document}

\slide{}

{\Huge \bf
\begin{center}
$\;$ \\ $\;$ \\
Data Structures \\
in C++ \\ $\;$ \\
Chapter 5 \\ $\;$ \\
Tim Budd \\ $\;$ \\
Oregon State University \\
Corvallis, Oregon \\
USA \\
\end{center}
}

\slide{Outline -- Chapter 5}

{\bf Confidence Building Measures}

\begin{itemize}
\item
Program Proving
\item
Invariants
\item
Program Testing
\end{itemize}

\slide{The Role of Program Proving}

Program proofs are techniques used, not for the computer, but for the sake
of the programmer and other members of a development teams.

Often given as part of a code walk-through.

Just one form of confidence building measure.

\slide{Invariants}

An {\em invariant} is simply a statement about what is true when execution
reaches a certain point in a program.  We can draft an argument concerning
the correct functioning of a program around a sequence of invariants.

\slide{Example Program with Invariants}
{\large\begin{cprog}
int triangle (int a, int b, int c)
	// characterize the triangle with sides a, b, and c
{
	if (a == b) {
		if (b == c) {
			// inv: a equals b, b equals c,
			// so a equals c and all are equal
			return 1;
			}
		else {
			// inv: a equals b, but b does not equal c
			// so only two sides are equal
			return 2;
			}
		}
	else {
		if (b == c) {
			// inv: a not equal to b, but b equals c,
			// so two sides are equal
			return 2;
			}
		else {
			// inv: so no sides are equal
			return 3;
			}
		}
}
\end{cprog}}

\slide{Another Example Program}
\begin{cprog}
double minimum (double values [ ], unsigned n)
{
	// make sure there is at least one element
	assert(n > 1);
	double minValue = values [0];
		// inv 1: minValue is the minimum 
		// value found in range 0 .. 0
	for (unsigned int i = 1; i < n; i++) {
		// inv 2: minValue is the minimum 
		// value found in range 0 .. i-1
		if (values[i] < minValue)
			minValue = values[i];
		// inv 3: minValue is the minimum 
		// value found in range 0 .. i
		}
	// inv 4: minValue is the minimum value
	// found in the range 0 .. n-1
	return minValue;
}
\end{cprog}

\slide{A proof using Invariants}

To make a proof using invariants, must give a bunch of little arguments,
one for each possible path from one invariant to the next.

Each argument is a conditional -- {\em if} the first invariant is true,
{\em then} the second must also be true.

Start by showing the first invariant must always be true.

\begin{cprog}

double minimum (double values [ ], int n)
{
	// make sure there is at least one element
	assert(n > 1);
	double minValue = values [0];
		// inv 1: minValue is the minimum
		// value in the range 0 .. 0
\end{cprog}

\slide{Invariant 1 to Invariant 2}

\begin{cprog}

	...
	double minValue = values [0];
		// inv 1: minValue is the minimum 
		// in the range 0 .. 0
	for (unsigned int i = 1; i < n; i++) {
		// inv 2: minValue is the minimum 
		// in the range 0 .. i-1
	...

\end{cprog}

\slide{Invariant 3 to Invariant 3}

\begin{cprog}

	...
		// inv 2: minValue is the minimum 
		// in the range 0 .. i-1
		if (values[i] < minValue)
			minValue = values[i];
		// inv 3: minValue is the minimum 
		// in the range 0 .. i
	...

\end{cprog}

\slide{Invariant 3 back to Invariant 2}

\begin{cprog}

	for (unsigned int i = 1; i < n; i++) {
		// inv 2: minValue is the minimum
		// in the range 0 .. i-1
		if (values[i] < minValue)
			minValue = values[i];
		// inv 3: minValue is the minimum 
		// in the range 0 .. i
		}
\end{cprog}

\slide{Invariant 3 to Invariant 4}

\begin{cprog}

	for (unsigned int i = 1; i < n; i++) {
			...
		// inv 3: minValue is the minimum 
		// in the range 0 .. i
		}
	// inv 4: minValue is the minimum value
	// in the range 0 .. n-1
\end{cprog}

\slide{Do not forget, Invariant 1 to Invariant 4}

\begin{cprog}

	...
		// inv 1: minValue is the minimum
		// in the range 0 .. 0

	for (unsigned int i = 1; i < n; i++) {
		...
		}

		// inv 4: minValue is the minimum 
		// in the range 0 .. n-1

\end{cprog}

\slide{Invariants and Mathematical Induction}

The use of invariants is put on a solid mathematical foundation by relating
to mathematical induction.

The induction is the {\em number of times} the loop executes.

Argue that if we have executed $n$ times, and the invariant is still true,
and if we execute an addition $n+1$ time, that the invariant will still
be true.  So no matter how many times we loop, the invariants must still
be true.

\slide{Asserting Outcome is Correct}

An invariant must assert the outcome is correct.  May involve ideas not
expressly presented in the code.

\begin{cprog}

int isPrime (unsigned int n)
{
	for (unsigned int i = 2; i * i < n; i++) {
			// inv 1: n no factors in 2 to i-1
		if (0 == n % i) {
				// inv 2: i divides n, not prime
			return 0;
			}
			// inv 3: n no factors in 2 to i
		}
		// inv 4: n has no factors in 2 to
		// ceiling(sqrt(n)), therefore must
		// be prime
	return 1;
}
\end{cprog}

\slide{Making Progress Towards an Objective}
{\Large
\begin{cprog}
unsigned int binarySearch (double v [ ], unsigned int n, double value)
	// search for value in ordered array of data
	// return index of value, or index of
	// next smaller value if not in collection
{
	unsigned int low = 0;
	unsigned int high = n;

	while (low < high) {
		// inv: data[0 .. low-1] less than value
		// data[high .. max] greater than or equal 
		// to value
		unsigned mid = (low + high) / 2;
		if (data[mid] < value)
			low = mid + 1;
		else
			high = mid;
		}
	// inv: data[0..low-1] less than value 
	// and value less than or equal to data[low+1]
	return low;
}
\end{cprog}}

\slide{Simulate binary search}

Simulate binary search on the values
\begin{center}
	2 4 5 7 9 12 14 37 96
\end{center}

\slide{Loops May have their Own Agenda}
{\Large\begin{cprog}
void bubbleSort (double & v[], unsigned int n)
{
	for (unsigned int i = n - 1; i > 0; i--) {
		// inv: elements i+1 to n-1 are correct
		for (unsigned int j = 0; j < i; j++) {
			// inv: v[j] is largest in (0..j)
			if (v[j+1] < v[j]) { // if out of order
				double temp = v[j]; // then swap
				v[j] = v[j + 1];
				v[j + 1] = temp;
				}
			// inv: v[j+1] is largest in (0..j+1)
			}
		// inv: v[i] holds largest in (0..i)
		// inv: therefore, elements i to n-1 are ordered
		}
	// inv: elements indexed 0 to n-1 are ordered
}
\end{cprog}}

\slide{Invariants and Unnamed Quantities}

\begin{cprog}
unsigned int gcd (unsigned int n, unsigned int m)
	// compute the greatest common divisor
	// of two positive integer values
{
	assert (n > 0 && m > 0);

	while (m != n) {
		if (n > m)
			n = n - m;
			// inv: gcd of n and m
			// has not been altered
		else
			m = m - n;
			// inv: gcd of n and m
			// has not been altered
		}
		// n equal to m,
		// so n is divisor of both
	return n;
}
\end{cprog}

\slide{Invariants and Function Calls}

When functions are involved, the argument is again conditional -- 
{\em if} the called routine is correct, then we can argument that the
current routine is correct.

\begin{cprog}

void printPrimes (unsigned int n)
	// print numbers between 2 and n
	// indicating which are prime
{
	for (unsigned int i = 2; i <= n; i++) {
		if (isPrime (i))
			cout << i << " is prime\n";
		else
			cout << i << " is not prime\n";
		}
}
\end{cprog}

\slide{Recursive Algorithms}

The analysis of recursive algorithms breaks into cases:
\begin{itemize}
\item
Base case argument -- same as any other function
\item
Recursive case argument -- conditional, {\em if} the recursive call
works as advertised, then argue that the rest of the program must work
correctly.
\end{itemize}

{\Large\begin{cprog}
void printUnsigned (unsigned int val)
{
	if (val < 10)
		printChar (digitChar(val));
	else {
			// print high order part
		printUnsigned (val / 10);
			// print last character
		printChar (digitChar(val % 10));
		}
}
\end{cprog}}

\slide{Another Recursive Algorithm}

\begin{cprog}

double power (double base, unsigned int n)
	// return the value base
	// raised to the integer n value
{
	if (n == 0)
		return 1.0;
	else if (even(n))
			// base ^ n is same as
			// (base ^ 2) ^ (n / 2) for even n 
		return power (base * base, n / 2);
	else
			// for odd n base ^ n is same as
			// base * (base ^ 2) ^ (n / 2) 
		return power (base * base, n / 2) * base;
}
\end{cprog}

\slide{Program Testing}

An alternative (and complementary) way of increasing confidence in
correctness.  Can be performed on many levels

\begin{itemize}
\item
Individual function (or method)
\item
Class
\item
Complete application
\end{itemize}

\slide{Drivers and Stubs}

Testing bits of code in isolation frequently requires writing temporary
harness code.

\begin{itemize}
\item
Drivers to load test cases, run program, print or verify results,
\item
Stubs to simulate called routines
\end{itemize}

\slide{Goals for Testing}

\begin{itemize}
\item
Make sure every statement in the function is exercised by at least one
test value.
\item
If there is a minimal legal input value, such as an empty array or
a smallest integer value, use this as one of your test cases.
\item
If the function (or program) has both legal and illegal inputs, a set
of test cases should include both clearly legal values and clearly 
illegal values,
as well as values that are ``barely'' legal and ``barely'' not legal.
\item
If the program involves loops that can exercise a variable number of
iterations, try to develop a test case in which the
loop executes zero times.
\end{itemize}


\end{document}

