Sie sind auf Seite 1von 64

Computer Programming II

(TA C252, Lect 6)


Today’s Agenda

 Linear search
 Unordered List
 Ordered List
 Binary search
 Correctness issues

Friday, September 4, 2009 2


Linear search in ordered
sequence
10 15 18 21 25 33 41 53 55

Friday, September 4, 2009 3


Algorithm for Linear search

current=1;
while (current <=N) do
if (A[current] = = x) return current;
if(A[current]>x) return -1; // if sequence is ordered
current++;
endwhile;
return -1;

Friday, September 4, 2009 4


Divide and Conquer Example
2
Problem: Searching an Ordered list
 Given an ordered sequence of N elements,
find whether there exists an element
‘x’ in the sequence

Friday, September 4, 2009 5


Binary Search Algorithm

low = 1; high = N;
while (low < =high) do
mid = (low + high) /2;
if (A[mid] = = x) return mid;
else if (A[mid] < x) low = mid +1;
else high = mid – 1;
endwhile;
return -1;

Friday, September 4, 2009 6


Finding 55

10 15 18 21 25 33 41 53 55

low mid high

33 41 53 55

low mid high


53 55 55

low & mid high low, mid & high

Friday, September 4, 2009 7


Finding 22

10 15 18 21 25 33 41 53 55

low mid high

10 15 18 21

low mid high 21


21 25
18 21
low, mid and high
high & mid low
low & mid high

Friday, September 4, 2009 8


Correctness Issues

 Motivation
 Modules, Contracts, Invariants
 Tests and Test Cases

Friday, September 4, 2009 9


What is correctness?
 Design Correctness
 Solution (design) meets requirements
 Verified offline (often on paper)
 Proof arguments
 Implementation Correctness
 Implementation (program code) matches design
 Verified online (often by execution)
 Tests and Test Cases

Friday, September 4, 2009 10


What is Correctness?

 Output of Design step: Program Design


 High level solution to problem
 Consists of modules and module interconnections
 Modules are solutions to sub-problems
 Interconnections capture ways to combine sub-
solutions

Friday, September 4, 2009 11


Design Correctness

 Design Correctness involves


 Module correctness (for each module)
 Combination correctness
 Design Correctness is verified by correctness
arguments:
 Establish Module Correctness
 Verify contracts between modules.

Friday, September 4, 2009 12


Module Correctness

 Often reduces to algorithm correctness:


 Algorithm will terminate
 Algorithm will produce required result if and when
it terminates.
 Both arguments are fairly easy for “straight-
line” programs – i.e., no loops.

Friday, September 4, 2009 13


Module Correctness

 Problem: Given a, b, and c, solve quadratic


equation –
a*x2 + b*x + c = 0

Friday, September 4, 2009 14


Module Correctness

 Solution: Define function quad(a, b, c, sign) as


disc = b*b – 4*a*c;
if (sign) return (-b + sqrt(disc)) / (2 *a);
else return (-b – sqrt(disc)) / (2*a);

Friday, September 4, 2009 15


Module Correctness

 Termination:
 if sqrt terminates, this function terminates.
 Valid results:
 if sqrt is correct then this returns correct value.
 How do we handle the “if” conditions above?
 Contracts

Friday, September 4, 2009 16


Inter-Module Correctness
 Whoever writes sqrt function, specifies input-
output contract:
/* Pre-condition: m > 0
Post-condition: return n such that
|n * n – m| / m < .01
*/
float sqrt(float m)  argument must be +ve definite
{

Friday, September 4, 2009 17


Module Correctness for
sqrt(x)
R = m/2
Err = abs(R * R – m)/m

Err < .01? Yes return R


No

R= (R + m/R)/2
Err = abs(R*R – m)/m

Friday, September 4, 2009 18


float sqrt (float m) /*
{ Pre condition:
float R=m/2; m>0
float Err= (R*R – m)/m; Post condition:
while (Err >= 0.01) R = sqrt(m) (with a
{ relative error less than
1%)
R= (R + m/R)/2;
Err < 0.01
Err=(R*R – m)/m;
*/
}
return R;
}

Friday, September 4, 2009 19


Inter-Module Correctness

 Observation:
 Precondition m > 0
 This is required for sqrt to be correct (or may be
even to terminate).
 So, quad module must guarantee before invocation
of sqrt:
disc > 0

Friday, September 4, 2009 20


Inter-Module Correctness

 The previous contract may propagate up:


/* Pre-condition: b*b > 4*a*c
Post-condition: return x such that
| a*x*x + b*x + c | <= epsilon
*/
float quad(float a, float b, float c, int sign)
{

Friday, September 4, 2009 21


 Function interfacing errors minimized
due to the
Pre conditions and Post conditions.
 Why do need correctness ?
 Testing will be easy
 Helpful to the third party users
 Correct way a writing a function from now on:
/* Pre-condition : ……. */
/* Post-condition: …….*/
<Function >

Friday, September 4, 2009 22


Correctness of Algorithms
 After writing a program,
 test on sets of sample data.
 Choose sample data to test the correctness in
extreme cases.
 Testing on sample data can’t give perfect
confidence that the program is correct.
 Need a proof that the program is correct.
 Many methods of proofs for program
correctness are based on induction.

Friday, September 4, 2009 23


Pre-conditions and Post-conditions
 The predicate describing the initial state is called the
pre-condition of the algorithm.
 The predicate describing the final state is called the
post-condition of the algorithm.
 Example:
In an algorithm which computes
the product of prime numbers p1, p2, …, pn:
pre-condition: The input variables p1, p2, …, pn
are prime numbers.
post-condition: The output variable q equals
p1·p2· …·pn .
Friday, September 4, 2009 24
How the post conditions are
met?
- A revisit to single-step routines
 Take the post condition, push it up, one step at a time

 Infer the pre-condition


Example: 1 Example 2: Swap 2 Numbers

/*Precondition: x and y are integer


/* pre condition: x < 2 values
post condition x< 10 */ Post condition: x and y swapped
int compute (int x) Example x=6, y=8 */
{ void swap (int x, int y)
int y =3*x+1; {
x=y+3; x=x+y;
return x; y=x-y;
} x=x-y;
}

Friday, September 4, 2009 25


Correctness for Conditional statements
Example 1: Example 2: Largest of 3 numbers
//Post condition: y >0 // Precondition: a, b, and c are
integer values
//Pre condition: ???
//Post condition: result is the largest
int fun1(int x, int y) of a, b and c
{ int large3(int a, int b, int c)
if(x >0) {
y =y-1; int result;
else if((a>=b) && (a>=c))
y =y+1; result =a;
return y; else if ((b>=a) && (b>=c))
} result =b;
else
result =c;
return result;
}

Friday, September 4, 2009 26


Loop Invariants: Method to
prove correctness of loops
 Loop has the following appearance:
[pre-condition for loop]
while (Guard)
[Statements in body of loop. None
contain branching statements that
lead outside the loop.]
end while
[post-condition for loop]
Friday, September 4, 2009 27
Loop-Invariant
 Every loop has a pre-condition and post-condition
 There is some condition G
 True  the loop will continue and
 False  the loop terminates
 Some condition I remains constant in loop
 Correct before loop begins
 In each iteration of loop
 After loop terminates

Friday, September 4, 2009 28


Loop Invariance Example 1
/* Pre –condition : N >=0 */
/* Post –condition: fact =N! and i>0*/
int factorial (int N)
{
int fact =1; int i=1;
/* fact = i-1! and i>0 */
while (i<=N)
{
fact = fact * i;
i++;
/* fact = i-1! and i>0 */
}
/* fact = i-1! and i>0 */
return fact;
}
Loop Invariant: fact=i-1! and i>0

Friday, September 4, 2009 29


What is a loop invariant?
 Property that is maintained “invariant” by iterations
in a loop.
 Captures progressive computational role of the loop and
remaining true before and after the loop irrespective of how
many times the loop is executed
 How is it used:
 Verify before the loop
 Verify each iteration preserves it.
 Property on termination of loop must result in “what is
expected”

Friday, September 4, 2009 30


Using Loop Invariance
 Verify the following properties
n Basis property: The pre-condition implies that I is true before
the first iteration of the loop
• fact = i-1! and i>0
n Inductive property: If guard G and I are true before an
iteration, then I is true after the iteration.
• fact = i-1! and i>0 is preserved by the body of the loop
n Eventual falsity of Guard: After finite number of iterations of
the loop, the guard G becomes false. [Termination condition]
• i eventually becomes > N
n Correctness of the Post-Condition: Q: (NOT G) and I
implies the post-condition. {Q} ={I and ! G }
when termination occurs, i.e., i=N+1;
fact=((N+1)-1)! which is same as post-condition fact=N!

Friday, September 4, 2009 31


Loop Invariance Example
// Precondition: N>=0
1_Part
// Post condition: fact = N! and {
2
int factorial (int N)

i>=0 int fact =1; int i=N;


/* N! = fact * i! and i>=0 */
while (i>0)
{
fact = fact * i;
Loop Invariant: i––;
N!=fact * i! and i>=0 /* N! = fact * i! and i>=0 */
}
/* N! = fact * i! and i>=0 */
return fact;
}

Friday, September 4, 2009 32


Module Correctness for
sqrt(x)
R = x/2
Err = abs(R * R – x)/x

Err < .01? Yes return R


No

R= (R + x/R)/2
Err = abs(R*R – x)/x

Friday, September 4, 2009 33


Loop Invariance Example 2
/* float sqrt (float m)
Pre condition: {
m>0 float R=m/2;
Post condition: float Err= (R*R – m)/m;
R = sqrt(m) (with a relative while (Err >= 0.01)
error less than 1%) {
Err < 0.01 R= (R + m/R)/2;
*/ Err=(R*R – m)/m;
}
return R;
}

Friday, September 4, 2009 34


Module Correctness for
sqrt(x)
 Termination?
 Start with a range for R: x/2
 Every step reduces the size of the range: average
is closer to the middle than the ends
 Range should get smaller and smaller – must
terminate when R is close to the root.

Friday, September 4, 2009 35


Module Correctness for
sqrt(x)
 Loop Invariant:
R <= sqrt(x) <= x/R OR x/R <= sqrt(x) <= R
 Verify:
 Universally true?
 Side of a square vs. sides of a rectangle.
 At termination, (R*R – x)/x is small (approx.)

Friday, September 4, 2009 36


Loop Invariance – Example 3
 Consider the following Alg to find the index of largest integer in a list of integers
/* Pre condition: list(N) is assigned N positive integers
Post condition: list[indexMax] is a maximum element in list
*/
int maxIndex( int A[ ], int N)
{ int k, indexMax;
indexMax = 0; k=1;
while(k < N)
{
if (A[k] > A[indexMax])
indexMax = k;
k++;
}
return indexMax;
}
 Correctness:
∀ j, 0 <= j < N, A[j] <= A[indexMax] and 0 <= indexMax < N
 A useful invariant for the above loop:
∀j: 0 <= j < k, A[j] <= A[indexMax] and 0 <= indexMax < k

Friday, September 4, 2009 37


Loop Invariant – Example
 Basis property:
When k = 1: indexMax = 0, and j=0 only
A[j] = A[0]=A[indexMax] and indexMax=0<k.
 Inductive property:
Assume that the invariant is true for k = k0.
If A[k0] <= A[indexMax], then the invariant remains
true for the new k = k0+1, after executing k++
If A[k0] > A[indexMax], then after executing k++,
indexMax = k0 and A[j] <= A[indexMax], j <k0+1,
Since indexMax < k0+1, this verifies the invariant for k
= k0+1.
Friday, September 4, 2009 38
Loop Invariant – Example
 Eventual falsity of Guard: simple to prove in
this case
 Correctness of the Post-Condition: Falsity of
the guard and invariant implies the post
condition
(k = N) and (for all j, 0 <= j < k, A[j] <=
A[indexMax], and 0 <= indexMax < k)

Friday, September 4, 2009 39


Loop Invariance Example 4

 For the algorithm to find xy, (discussed


earlier)
 Write the module correctness (pre, post
conditions)
 Find an appropriate invariant
 Discuss the correctness argument

Friday, September 4, 2009 40


Correctness: Second Example

 Algorithm for xy
 Extract a power of 2 from y, say P.
 Compute xP and multiply this to a temp. result
 Repeat above steps until nothing to extract.

Friday, September 4, 2009 41


Correctness: Second Example
 Algorithm for xy
Ynext = y; P = 1; R=1;
while (Ynext > 0) do
if (Ynext mod 2 == 1)
then R = R * pow2(x, P);
P = 2 * P;
Ynext = Ynext / 2;
endwhile;

Friday, September 4, 2009 42


Module Correctness: xy
 Loop Invariant:
xy = R * x(P*Ynext)
 Before the loop:
xy = 1 * x(1*y)
 Inside the loop:
x(P*Ynext) = x(2*P*(Ynext/2)) if Ynext is even;
x(P*Ynext) = x(2*P*(Ynext/2))+P
= x(2*P*(Ynext./2)) * xP if Ynext is odd;

Friday, September 4, 2009 43


Module Correctness: xy

 Termination:
Ynext is reduced by (at the least) half for each
iteration.
So, for positive y, Ynext will eventually be 0 –
because of integer division.
 Pre-condition for Module xy:
y >= 0

Friday, September 4, 2009 44


Inter-Module Correctness

 Assumption:
 pow2(x,P) returns xP if P is a power of 2.
 Definition of pow2
/* Pre-condition: P = 2k for some k >= 0
Post-condition: return xP */
int pow2(int x, int P)

Friday, September 4, 2009 45


Loop Invariance Example 5
int bsearch(int a[ ], int N, int x)
Binary Search
/* Pre condition: N>0, A is in
{
non-decreasing order int lo=0; int hi=N-1; int mid;
Post condition:
Invariant: (x is not in A) OR (A[lo] <=x<=A[hi])
(1) x = A[m] and m is the
location of the element while (lo <= hi)
OR
{
(2) x in not in A
*/ mid = (lo + hi)/2;
if (A[mid] == x) return mid;
else if (A[mid]>x) hi=mid-1;
else lo = mid+1;
}
return -1 // Not found in the given list A
}
Friday, September 4, 2009 46
Why Testing?
 Verify fidelity of implementation.
 Does the implementation meet design
specifications?
 Verify robustness of design.
 Not everything is specified in design.
 Not everything about design is provably correct.
 Identify and understand exceptions.

Friday, September 4, 2009 47


Testing and Design

 Identification of test cases


 Should be done during or before Design Phase.
 High level test cases
 Based on problem specification.
 Low level test cases
 Based on solution (design)

Friday, September 4, 2009 48


Test Case Identification [1]

 E.g. Binary Search


Problem Specification:
Find the position of an element x
in an ordered list A
(of finite length, say N).

Friday, September 4, 2009 49


Binary Search Algorithm

low = 1; high = N;
while (low < =high) do
mid = (low + high) /2;
if (A[mid] = = x) return x;
else if (A[mid] < x) low = mid +1;
else high = mid – 1;
endwhile;
return Not_Found;

Friday, September 4, 2009 50


Test Case Identification [2]

 What is a test case?


 Any input: e.g., x = 3, A = {2, 3, 5, 7, 18}, N=5
 How many test cases are there ? (for a fixed
N)
 If each location of A can take k possible values, A
has kN possible values.
 So, there are at least kN+1 possible values

Friday, September 4, 2009 51


Test Case Identification [3]

 How many cases are enough?


 Ideally all cases must be covered.
 Similar cases may be grouped into classes.

e.g. x and A such that x < A{1}


 Which cases are to be tested?
 One sample case per class must be tested.

Friday, September 4, 2009 52


Test Case Identification [4]
 Will the algorithm handle one element array?
 e.g. x = 0 and A = {1}
 e.g. x = 1 and A = {1}
 e.g. x = 2 and A = {1}
 Will it handle the case where all array values are
equal?
 e.g. x = 5 and A = {5,5,5,5,5,5,5}
 What if the value is the first element of the array?
- e.g. x = 5 and A = {5, 7, 9, 12}

Friday, September 4, 2009 53


Test Case Identification [5]
 What if the value is the last element of the array?
- e.g. x = 12 and A = {5, 7, 9, 11, 12}
 What if the value is not found in the array?
- the value is within the range:
e.g. x = 8 and A = {5, 7, 9, 12}
- the value is below the range:
e.g. x = 4 and A = {5, 7, 9, 12}
- the value is above the range:
e.g. x = 13 and A = {5, 7, 9, 12}

Friday, September 4, 2009 54


Test Case Identification [6]

 All of the above questions are answerable at


design time.
 Testing ensures “fidelity” of implementation.
 Other questions?
 Is the design complete?
 Is the design proven?

Friday, September 4, 2009 55


Test Case Identification [7]

 Is the solution dependent on even or odd


locations?
 Needed because: (low + high)/2;
 Is the solution affected by large values of low
OR high?
 Suppose N=29 in LC-3. What happens when low >
28

Friday, September 4, 2009 56


Test Case Identification [8]

 E.g. quad
Problem Specification:
Given a, b, and c, solve quadratic equation:
a*x2 + b*x + c = 0

Friday, September 4, 2009 57


Test Case Identification [9]

 Solution:
// Pre-condition: b*b > 4*a*c
function quad(float a, float b, float c, boolean
sign) returns float
disc = b*b – 4*a*c;
if (sign) return (-b + sqrt(disc)) / (2 *a);
else return (-b – sqrt(disc)) / (2*a);

Friday, September 4, 2009 58


Test Case Identification [10]

 Does the algorithm handle positive values for


a,b, and c?
 Does the algorithm handle negative values
for a,b, and c?
 What if a or b or c is zero?
 What if all of them are zeroes?
 Are calls to sqrt correct?

Friday, September 4, 2009 59


Test Case Identification [11]

 Open issues in design:


 Will a high value of b cause an overflow?
 Will high values of a and c cause an overflow?
 Will there be underflow?
 b* b – 4 * a *c
 (-b + sqrt(disc)) / (2*a)

Friday, September 4, 2009 60


sqrt function
/* float sqrt (float m)
Pre condition: {
m>0 float R=m/2;
Post condition: float Err= (R*R – m)/m;
R = sqrt(m) (with a relative while (Err >= 0.01)
error less than 1%) {
Err < 0.01 R= (R + m/R)/2;
*/ Err=(R*R – m)/m;
}
return R;
}

Friday, September 4, 2009 61


Test Case Identification [12]

 function sqrt(float x) returns float


 Will sqrt be able to handle all positive values?
 Will there be any underflows?

Friday, September 4, 2009 62


Test Case Identification [13]

 Exceptions
 What happens when contracts are violated?
e.g. sqrt(-1)
e.g. quad(2, 1, 2, true)
- Is graceful termination guaranteed?

Friday, September 4, 2009 63


Test Case Identification [14]

 Exercise:
 Identify test cases for function pow2(x,y) that
computes xy when y is a power of 2.
 Identify test cases for function pow(x,y) that
computes xy.
 Identify exception (crash) scenarios!

Friday, September 4, 2009 64

Das könnte Ihnen auch gefallen