SE 504 Formal Methods and Models
Sample proof of a program computing 1 + 2 + ... + n

Problem: Prove the correctness of the following program:

  |[ con N : int; 
     var j, sum : int; 
     {precondition P: N ≥ 0}
     j, sum := 0,0;
     {invariant I : 0 ≤ j ≤ N  ∧  sum = (+i | 0<i≤j : i)}
     {bound function t: N-j}
     do j ≠ N  --->  j := j+1 ; sum := sum+j;
     od;
     {postcondition Q : sum = (+i | 0<i≤N : i) }
  ]|

For the purpose of making hints more precise, it is helpful to name each conjunct of I. We have

   I1 : 0≤j       I2 : j≤N      I3 : sum = (+i | 0<i≤j : i)

(Note that the first conjunct of I is really an abbreviation for I1 ∧ I2.) The given program is a loop preceded by some initialization. Thus, to prove its correctness, it suffices to prove each of the five points on the loop checklist, which we do now.

(i) {P} Sinit {I}  (i.e., [P ==> wp.Sinit.I])

     wp.Sinit.I

   =    < defn of Sinit >

     wp.(j,sum := 0,0).I

   =    < wp assignment rule >

     I(j,sum := 0,0)

   =    < defn. of I, textual substitution >

     0≤0  ∧  0≤N  ∧  0 = (+i | 0<i≤0 : i)

   =    < range 0<i≤0 is empty; by Empty Range (8.13) and fact
          that zero is the identity of addition, result is 0 >

     0≤0  ∧  0≤N  ∧  0 = 0

   =    < (0≤0) = true, (0 = 0) = true; Identity of ∧ (3.39), twice >

     0≤N

   =    < definition of P >

     P 

Thus, we have demonstrated that [P = wp.Sinit.I], from which it certainly follows that [P ==> wp.Sinit.I].

NOTE: The above is written at a greater level of detail than is really necessary to obtain such a simple result. In practice, we would normally just observe that execution of Sinit (in a state satisfying P) "obviously" establishes a state that satisfies I. However, when things are not so obvious, we should rely upon our formal notation to guide us in proving, rigorously, what is needed. Typically, proving checkpoint (ii) is somewhat more difficult than proving (i) and thus the level of detail given above (as well as below) is more appropriate in that context.


(ii) {I ∧ B} S {I} (i.e., [I ∧ B ==> wp.S.I])

Of course, here we have B : j ≠ N.

We assume both I and B and prove wp.S.I.

     wp.S.I

  =     < defn of S >

     wp.(j:=j+1; sum:=sum+j).I

  =     < wp catenation (sequential composition) rule >

     wp.(j:=j+1).(wp.(sum:=sum+j).I)

  =     < wp assignment rule >

     wp.(j:=j+1).(I(sum:=sum+j))

  =     < wp assignment rule >

     (I(sum:=sum+j))(j:=j+1)

  =     < defn of I, textual substitution >

     (0≤j ∧ j≤N ∧ sum+j = (+i | 0<i≤j : i))(j:=j+1)

  =     < textual substitution >

     0≤j+1  ∧  j+1≤N  ∧  sum+(j+1) = (+i | 0<i≤j+1 : i)

  =     < I1 implies 0≤j+1; I2 ∧ B implies j+1≤N; (3.39) twice >

     sum+(j+1) = (+i | 0<i≤j+1 : i)

  =     < (8.23) One-point rule (Assumption I1 guarantees range is non-empty) >

     sum+(j+1) = (+i | 0<i≤j : i) + i(i:=j+1)

  =     < Assumption I3 and textual substitution >

     sum+(j+1) = sum + (j+1)

  =     < = is reflexive >

     true

Thus, we have demonstrated that [I ∧ B ==> wp.S.I], as required!


(iii) [I ∧ ¬B ==> Q]

    I ∧ ¬B

  =    < defn of B >

    I ∧ ¬(j ≠ N)

  =    < defn of I; ¬(j≠N) = (j=N)>

    0≤j  ∧  j≤N  ∧  sum = (+i | 0<i≤j : i)  ∧  j=N

  =    < Substitution (3.84a), with e,f := j,N and E := sum = (+i | 0<i≤j : i) >

    0≤j  ∧  j≤N  ∧  sum = (+i | 0<i≤N : i)  ∧  j=N

 ==>   < (3.76b) >

    sum = (+i | 0<i≤N : i) 

  =    < defn of Q >

    Q 


(iv) [I ∧ B ==> t > 0]

Recalling that the bound function t is given by the expression N - j, we assume I ∧ B and show that N-j > 0.

    N - j > 0

  =    < algebra >

    N > j

 =     < assumptions B: j ≠ N  and  I2: j <= N together guarantee j < N  >

    true


(v) {I ∧ B ∧ t=T} S {t < T}.

Because we have chosen t : N-j, this is just {I ∧ B ∧ N-j=T} S {N-j < T}, which is equivalent to [I ∧ B ∧ N-j = T ==> wp.S.(N-j < T)]

  
    wp.S.(N-j < T)

  =   < defn of S >

    wp.(j:=j+1; sum:=sum+j).(N-j < T)

  =   < wp catenation (sequential composition) law >

    wp.(j:=j+1).(wp.(sum:=sum+j).(N-j < T))

  =   < wp assignment rule >

    wp.(j:=j+1).((N-j < T)(sum:=sum+j))

  =   < textual substitution  (no occurrences of sum in N-j<T) >

    wp.(j:=j+1).(N-j < T)

  =   < wp assignment rule >

    (N-j < T)(j:=j+1)

  =   < textual substitution >

    N-(j+1) < T

  =   < assumption N-j = T >

    N-(j+1) < N-j

  =   < algebra >

    -1 < 0

  =   < arithmetic >

    true

Again, the above is written at an excessive level of detail. In practice, we would simply observe that S causes the value of j to increase by one (while leaving the value of N unchanged), from which it follows that the value of N-j (i.e., the value of t) decreases by one on each iteration of the loop.

In practice (and depending upon the intended readership), in proofs such as the ones above we would combine some of the more trivial sequences of steps together into a single step.