SE 504 Development and proof of a linear search algorithm (alternative to Cohen's from pp. 131-134) Given the following specification, devise a program that meets it, and prove the program's correctness. |[ con N : int; { N>0 } con b : array [0..N) of bool; { (Vj | 0<=j0 } con b : array [0..N) of bool; { (Vj | 0<=j ? od {postcondition R: b.k & (&j | 0<=j=N results in abortion (due to an "array subscript out-of-bounds error"). Hence, we should include 0<=k0 } con b : array [0..N) of bool; { (Vj | 0<=j k := k+1 od {postcondition R: b.k & (&j | 0<=j0.) For convenience, we refer to the three conjuncts of P as P0, P1, and P2. (i) {Q} S_init {P} (equivalently, [Q ==> wp.S_init.P]) As no precondition Q is explicitly given in the program (aside from the global invariants already mentioned), we take it to be TRUE. wp.S_init.P = < defn of S_init > wp.(k := 0).P = < wp assignment law > P[k:=0] = < defn of P, textual sub. > (&j | 0<=j<0 : ~b.j) & 0<=0 & 0 (&j | 0<=j<0 : ~b.j) = < 0<=j<0 = false > (&j | false : ~b.j) = < (9.2); (3.75); (9.8) > true (ii) {P & ~b.k} k := k+1 { P } (equivalently, [P & ~b.k ==> wp.(k:=k+1).P]) We (attempt to) prove wp.(k:=k+1).P using P and ~b.k as assumptions. wp.(k:=k+1).P = < wp assignment law > P[k:=k+1] = < defn of P, textual sub. > (&j | 0<=j (&j | 0<=j 0<=k+1 & k+1 k+1 k k k ~(k ~(P & ~b.k) = < ~(a=b; DeMorgan (3.47a), (3.12) > k >= N-1 ==> ~P v b.k = < defn of >= : a>=b = a>b v a=b > (k>N-1 v k=N-1) ==> ~P v b.k = < (3.78) > (k > N-1 ==> ~P v b.k) & (k = N-1 ==> ~P v b.k) Thus, it suffices to prove each of the two conjuncts of the above. We prove the first by assuming its antecedant (k>N-1) and showing its consequent: ~P v b.k = < defn of P > ~((&j | 0<=j ~(&j | 0<=j = a>=b) > (Vj | 0<=j=N v b.k = < assumption k>N-1 is equivalant to 3rd disjunct above > (Vj | 0<=j true Now we prove the 2nd conjunct (again, by assuming the antecedant (k=N-1) and showing the consequent): ~P v b.k = < repeating the first three steps from proof of 1st conjunct > (Vj | 0<=j=N v b.k = < split off term (8.23) > (Vj | 0<=j=N = < assumption k=N-1 and (3.84a) > (Vj | 0<=j=N = < algebra > (Vj | 0<=j=N = < 1st disjunct above is global invariant > true v ... = < (3.29) > true This completes the proof of item (ii) in the loop checklist!! (iii) [P & ~B ==> R] We need not even go through the proof, because the invariant and loop guard were chosen to satisfy this! The loop invariant P is P0 & P1 & P2, the loop guard is ~B, and the postcondition is R: P0 & B. Hence, we have P & ~B = < P is P0 & P1 & P2 > P0 & P1 & P2 & ~B ==> < (3.76b) > P0 & ~B = < R is P0 & ~B > R Postponing checkpoint (iv), we now do (v): (v) {P & ~~b.k & N-k=T} k:=k+1 { N-k (N-k < T)[k:=k+1] = < textual sub. > N - (k+1) < T = < assumption N-k=T > N - (k+1) < N-k = < algebra > 0 < 1 = < number theory !! > true Finally, let us prove loop checkpoint (iv): (iv) [P & ~b.k ==> N-k > 0]. N-k > 0 = < algebra > N > k = < assumption P2: k true Just for fun, let's show that, even if neither P1 nor P2 were included as conjuncts of P, we could still carry out a proof of (iv). That is, we will show [P0 & ~b.k ==> N-k > 0]. To do this, we show its contrapositive, [N <= k ==> ~P0 v b.k] by assuming the antecedant and proving the consequent. ~P0 v b.k = < defn of P0 > ~(&j | 0<=j (Vj | 0<=j (Vj | 0<=j (Vj | 0<=j (Vj | 0<=j true v (Vj | N<=j true