today’s agenda correctness issues. why correctness? programming is engineering program is a...
TRANSCRIPT
Why Correctness?
Programming is engineering Program is a product Program quality to be determined during
production process Program Correctness is one essential aspect of
quality
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
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
Module Correctness
Often reduces to algorithm correctness: Algorithm should terminate Algorithm should produce required result when it
terminates. Both arguments are fairly easy for “straight-
line” programs – i.e., no loops.
Module Correctness
e.g.,
Define function to compute square (x) as
return x * x It is easy to verify the requirements:
It terminates: a single step It computes the square of a given number: x2=x*x
Module Correctness
Similar argument can be applied for more than one step as well.
Problem: Given a, b, and c, solve quadratic equation – a*x2 + b*x + c = 0
Solution
X1 = (-b + √b2 – 4ac ) / 2a
X2 = (-b - √b2 – 4ac ) / 2a
Module Correctness
Solution:
Define function quad(a, b, c, sign)
disc = b*b – 4*a*c;if (sign) return (-b + sqrt(disc)) / (2 *a);else return (-b – sqrt(disc)) / (2*a);
Module Correctness
Termination: if sqrt terminates, quad() function terminates.
Valid results: if sqrt is correct then quad() returns correct value.
How to verify this? Contracts
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
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
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)
Why do we need correctness ?
Testing will be easy
-Helpful to the third party users When you write a function you should
write:
/* Pre-condition : ……. */
/* Post-condition: …….*/
<Function >
Module Correctness for sqrt(x)R = x/2
Err = abs(R * R – x)
Err < .01?Yes
return R
R= (R + x/R)/2Err = abs(R*R – x)
No
Illustration: sqrt(9)
Iteration Rnext Errnext =R2 –x
0 =x/2=9/2=4.5 4.52 -9 <0.01? N
1 (4.5+9/4.5)/2=3.25 3.252 -9 <0.01N[10.5625 -9 = 1.5625]
2 (3.25+9/3.25)/2
=3.0096
3.00962 -9<0.01N
[0.057692]
3
(3.0096 +9/ 3.0096)/2
=3.00 Rnext ~ sqrt(9)
3.002 -9 <0.01 Y Exits from while
Functions for quadratic eqn
int main(){
float a,b,c,x1,x2;scanf("%f %f %f",&a,&b,&c);x1 = quad(a,b,c,1);x2 = quad(a,b,c,-1);printf("x1 = %f x2 = %f\n",x1,x2);return(0);
}
float quad(float a,float b,float c,int sign){
float disc,res ;disc= b*b - 4*a*c;if(disc > 0){if(sign) res = (-b + sqrt(disc))/(2*a);else res = (-b - sqrt(disc))/(2*a); return (res);}return(-1.0);
}
float sqrt(float x) {
float r,err;r = x/2.0;err = abs(r*r - x);while((err > 0.01)||(err == 0.01)){
r = (r + x/r)/2;err = abs(r*r - x);
}printf("sqrt of disc is %f\n",r);return (r);}
}
What is a loop invariant?
Property that is maintained “invariant” by iterations in a loop.
How is it used?Verify before the loop Verify each iteration preserves it.Property on termination of loop must result
in “what is expected”
Loop Invariants: Method to prove correctness of loops
Loop has the following appearance:[pre-condition for loop]while (Guard)
[Statements in body of loop. Branching statements that lead outside the loop.]
end while[post-condition for loop]
Loop Invariance (Example 1 )Program to do sum of the elements in an array.
Sum() { int s = 0; i = 0; // pre condn : s=0 && i=0While(i < n){
// s is the sum of first i array elements
// s = a[0] + … + a[i-1]s = s + a[i];i = i + 1;
}//post condn s = a[0] + ….+ a[i-1]
Return s; //post cond : s = a[0] + ………+ a[n-1]