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