SE 504 Correctness Proof of a program computing 0+1+2+...+N Consider the following specification: |[ con N : int; {N>=0} var sum : int; {precondition H: true} calculate_sum {postcondition Q: sum = (+j | 0<=j<=N : j) } ]| Gauss, widely thought to be one of the greatest mathematicians in history, is reported to have derived the formula (+j | 0<=j<=N : j) = N(N+1)/2 during an elementary school exercise. This leads to the one-line solution sum := (N * (N+1)) / 2 But let's suppose that we are unaware of Gauss's formula and thus must resort to repetition to solve the problem. One obvious solution is |[ con N : int; {N>=0} var sum : int; var i : int; {precondition H: true} i, sum := 1,0; do i != N+1 ---> sum := sum + i; i := i+1; od {postcondition Q: sum = (+j | 0<=j<=N : j) } ]| Here, we simply initialize sum to zero and a "loop control variable", i, to 1. The purpose of i is to iterate through the values 1, 2, ..., N so that we can add these values to sum. If we were to take a snapshot of the state of this program in execution each time the loop guard was about to be evaluated, we would get i sum --- --- After 0 iterations 1 0 After 1 iteration 2 0+1 After 2 iterations 3 0+1+2 After 3 iterations 4 0+1+2+3 ... ... ... ... ... ... After N iterations N+1 0+1+2+3+...+N This suggests that sum = 0+1+2+...+(i-1) (i.e., sum = (+j | 0<=j=0} var sum : int; var i : int; {precondition H: true} i, sum := 1,0; {loop invariant P: P1 & P2, where P1: sum = (+j | 0<=j sum := sum + i; i := i+1; od {postcondition Q: sum = (+j | 0<=j<=N : j) } ]| This program is the catenation (or sequential composition, if you prefer) of an assignment and a loop. That is, it gives rise to a Hoare Triple of the form {H} A; L {Q} where A is an assignment command and L is a repetition (i.e., loop) command. As the intermediate predicate, we choose the loop invariant P. By the Hoare Triple Catenation Law, then, we prove {H} A; L {Q} by showing each of {H} A {P} and {P} L {Q}. Note that the condition N >= 0 may be assumed throughout. Proof of {H} A {P} ------------------ Applying the Hoare Triple Assignment Law (and using the fact that A denotes the command i, sum := 1,0), it suffices to show [H ==> P(i,sum := 1,0)]. As H is true, Gries (3.73) tells us that this reduces to [P(i,sum := 1,0)]. P(i,sum := 1,0) = < defn of P > (sum = (+j | 0<=j 0 = (+j | 0<=j<1 : j) & 0<1<=N+1 = < 0<1 is true; 1<=N+1 follows from assumption N>=0 > 0 = (+j | 0<=j<1 : j) & true = < Gries (3.39); rewrite range > 0 = (+j | 0=j : j) = < Gries (8.23) (one-point rule) > 0 = 0 = < reflexivity of = > true Proof of {P} L {Q} ------------------ As L is a single-guarded repetition command, we name its guard B and its body S. By the Hoare Triple Repetition Law, it suffices to show (1) [P ==> P] (i.e., precondition implies loop invariant) (2) {P & B} S {P} (3) [P & !B ==> Q] (4) {P & B & t=C} S {t t>0] Proof of (1) [P ==> P] ---------------------- Follows from Gries (3.71) (reflexivity of implication) Proof of (2) {P & B} S {P} -------------------------- As S is the catenation sum := sum + i; i := i+1, the Hoare Triple Catenation Law tells us to find an intermediate predicate R and to prove each of {P & B} sum := sum + i {R} and {R} i := i+1 {P} The obvious choice for R is wp.(i:=i+1).P, which is P(i:=i+1). From this choice of R, the Hoare Triple {R} i:=i+1 {P} follows from the Hoare Triple Assignment Law. It remains to show {P & B} sum := sum + i {P(i:=i+1)}. By the Hoare Triple Assignment Law, this is equivalent to [P & B ==> (P(i:=i+1))(sum:=sum+i)] Here is a proof: Assume P and B (P(i:=i+1))(sum:=sum+i) = < defn of P > ((sum = (+j | 0<=j (sum = (+j | 0<=j sum + i = (+j | 0<=j sum + i = (+j | 0<=j sum + i = (+j | 0<=j sum = (+j | 0<=j true Alternative Proof of (2) {P & B} S {P} -------------------------------------- By the relationship between Hoare Triples and wp, which says {P} S {Q} = [P ==> wp.S.Q] we conclude that it suffices to show [P & B ==> wp.(sum := sum+i; i := i+1).P] Assume P and B wp.(sum := sum+i; i := i+1).P = < wp catenation law > wp.(sum := sum+i).(wp.(i := i+1).P) = < wp assignment law > wp.(sum := sum+i).(P(i := i+1)) = < wp assignment law > (P(i := i+1))(sum := sum+i) ...continue beginning with 1st line in first proof Proof of (3) [P & !B ==> Q] ----------------------------- Assume P and !B Q = < defn of Q > sum = (+j | 0<=j<=N : j) = < assumption !B (i.e., i = N+1, or, equivalently, N = i-1) > sum = (+j | 0<=j<=i-1 : j) = < a<=b-1 = a sum = (+j | 0<=j true Proof of (4) {P & B & t=C} S {t wp.(sum := sum + i; i := i+1).(N+1-i < C) Assume P, B, and N+1-i = C wp.(sum := sum + i; i := i+1).(N+1-i < C) = < wp catenation law > wp.(sum := sum + i).(wp.(i := i+1).(N+1-i < C)) = < wp assignment law > wp.(sum := sum + i).((N+1-i < C)(i:=i+1)) = < textual substitution > wp.(sum := sum + i).(N+1-(i+1) < C) = < wp assignment law > (N+1-(i+1) < C)(sum := sum + i) = < textual substitution > N+1-(i+1) < C = < assumption N+1-i = C > N+1-(i+1) < N+1-i = < algebra > -1 < 0 = < arithmetic > true Proof of (5) [P & B ==> t>0] ------------------------------ Assume P and B t > 0 = < defn of t > N+1-i > 0 = < algebra > N+1 > i = < a>b = a>=b & a!=b > N+1 >= i & N+1 != i = < Assumptions i <= N+1 and i != N+1 > true & true = < Gries (3.39) > true