More
on Correctness
Prime Factorization
Problem: Write a program that computes
all the prime factors of a given number
Solution (Idea):
• Factors are less than or equal to the given number
• Starting from the smallest prime (2), check whether all
prime numbers less than the given number is a factor
• For every factor, compute its multiplicity also
Program prime_factor
implicit none
integer:: i, m, n
read *, n
i = 2; m = n ! n is the number to be factorized
outer : do
if ( i*i > m) exit
inner : do
if ( modulo(m,i) /= 0)
exit
m = m/i
print *, i
end do inner
i = i+1
end do outer
if ( m > 1) print *, m
end program prime_factor
Correctness of the solution
• Study the program
• It may print the same number more than once. Why?
• No check for primality is made!
• Is the program correct?
• How do you check this?
• Test the program. How?
• Run the program for some inputs
Program Testing
•
This
is the standard approach used to ensure the correctness
•
various
issues to be addressed
–
What
inputs should be given?
•
Give
inputs that test `corner cases', `boundary conditions', `representative
inputs', eg.
–
1, 2 (corner cases),
–
7,
53, 81, 224 (representative cases)
•
Choose inputs that exercise all the `paths'
in the program
–
What
outputs are expected?
•
Independent
computation of outputs necessary
–
How
many inputs should be given?
•
As
much to gain confidence
Program Verification
• Program Testing is good for detecting
bugs in the final implementations
• It is a bit ad hoc and not recommended
for ensuring correctness of algorithms or high level programs
• It can not ensure correctness - `it can
reveal presence of bugs never their absence’
• A more rigorous approach is Formal
Verification (FV)
• FV proves the correctness
mathematically
• In general difficult and followed very
little in practice
Correctness of the solution
• FV requires a very precise definition of correctness
• What is the definition of correctness?
When input constraints are satisfied the program
terminates producing output with the desired
properties
• In this example:
– Input constraint: The number (n>0)
– Output property:
• Any number printed is a prime factor
(safety)
• All prime factors are printed
(liveness)
• Correctness demands that these two properties should hold
for any number
Loop Invariance
• For proving these properties, identify loop invariants:
– a loop invariant is a property relating
the values of variables such that if it is true before an iteration starts then
it is true at end of iteration
• property preserved under iterations
• loop invariant, if it holds before the start of the loop
then it will hold at the end
• How? Proof by
induction on the number of iterations
Prime Factorization
• a loop invariant for outer loop
– none of j , 1 < j < i, is a
factor of m
– product of all numbers printed and m is
n
• This is true at start of iteration
• To prove that it is indeed an
invariant,
– let m = l and i = k at the start of an
iteration.
– Then l not divisible by any j, 1 < j
< k
Proof
At the end of this iteration,
– value of i = k+1. k is not a factor of the new value of m,
since in the iteration m is divided by k as many times as possible
– None
of j, 1 < j < k continue to be a factor of new value of m (why?)
– every
time k is printed, m is divided by k and hence product of m and all numbers
printed is n
– Hence
the loop invariant holds at end of iteration
Proof of Safety Property
To prove that any number printed is a
prime factor
Proof:
Case1: k is printed in the inner loop
Then k divides m but no number < k divides m. So k is prime. Loop invariant implies that m is a factor
and hence k is a factor
Case2: m is printed
At
end of loop, value of m is either 1 or a prime
Loop
invariant ensures that at end of loop, product of printed numbers and m is n
since
m is printed, it is prime.
Proof of Liveness Property
To prove that all prime factors are
printed
– Any prime factor p of n has the
property:
either
p*p <= n or p has multiplicity 1
– The loops checks all numbers i s.t i*i
<= n, whether it is factor
– Both the loops terminate (why?)
– The prime factor p s.t. p*p > n, if
it exists is m when the outer loop terminates
Formal Verification
• More rigorous, proves the correctness
• Does not run the program for particular inputs
• More time consuming but should be done for increased
confidence
• Many applications required more confidence
• Safety-critical applications
– Aircraft control, nuclear plant
control, Missile avionics, patient monitoring systems, etc
•
CFDVS at IIT Bombay
• Lesson for you: Write loop invariants
Prove that the loop terminates