MAT Program Verification Designing a Program and its Proof Together Antero Kangas
Applications for Proving Program verification, i.e. proving, should be used in the most critical parts, and usually in pseudo-code level Usually the final code is not correct, thus proving cannot succeed But A proof trial is a useful means of review: problems in proof trials give easily a counter example, i.e. a test case that reveals on error (the previous lecture) Proving can be used as a design method Antero Kangas
Designing a Program and its Proof together It is worth to design a difficult part of program together with its proof to document the main ideas of the progression of the program by writing predicates that describe the interphases to design a loop, and its invariant and bound function together (The first example was to design an efficient implementation for Horner’s Rule) Antero Kangas
Second example: Compute cube Task: Compute the cube of a natural number in one loop without raising to a power nor multiplication operations. Specification n is fixed n ≥ 0 Compute_cube r = n 3 n is the input variable and r is the output variable (result) Antero Kangas
A Preliminary Task Designing the program and its proof together – how? ⇒ we can use the already familiar means for program verification Task: Discuss a moment with your partner about what kind of strategy we could use, e.g. what kind of program statements and structures What kind of program verification techniques we have and could use Antero Kangas
n ≥ 0 Compute_cube r = n 3 n ≥ 0 inv: r = i 3 while do i := expr3; r := expr4 end while r = n 3 Start of Design One loop structure, where Cube of a variable (e.g.) i is computed in every cycle. Invariant candidate would be r = i 3 Loop must terminate when i = n, and then it would be r = i 3 ∧ i=n, which implies the post condition The variables i and r must be initialised Antero Kangas n ≥ 0 i := expr1; r := expr2; inv: r = i 3 while i < n do i := expr3; r := expr4 end while r = i 3 ∧ i=n r = n 3
n ≥ 0 i := expr1; r := expr2; inv: r = i 3 while i < n do i := expr3; r := expr4 end while r = i 3 ∧ i=n r = n 3 n ≥ 0 i := 0; r := expr2; inv: r = i 3 while i < n do i := expr3; r := expr4 end while r = i 3 ∧ i=n r = n 3 n ≥ 0 i := 0; r := 0; inv: r = i 3 while i < n do i := expr3; r := expr4 end while r = i 3 ∧ i=n r = n 3 n ≥ 0 i := 0; r := 0; inv: r = i 3 while i < n do i := i + 1; r := expr4 end while r = i 3 ∧ i=n r = n 3 Solving expressions 1 to 3 i must be initialised to 0 to compute cube when n=0 inv must hold in the beginning ⇒ r must be initialised to 0 Loop terminates ⇒ i must be increased in every cycle Antero Kangas
n ≥ 0 i := 0; r := 0; inv: r = i 3 while i < n do inv ∧ i < n i := i + 1; r := expr4 inv end while r = i 3 ∧ i=n r = n 3 n ≥ 0 i := 0; r := 0; inv: r = i 3 ∧ s=3i 2 +3i+1 while i < n do inv ∧ i < n i := i + 1; r := expr4 inv end while r = i 3 ∧ i=n r = n 3 n ≥ 0 i := 0; r := 0; inv: r = i 3 ∧ s=3i 2 +3i+1 while i < n do inv ∧ i < n i := i + 1; r := r + s inv end while r = i 3 ∧ i=n r = n 3 n ≥ 0 i := 0; r := 0; s := expr5; inv: r = i 3 ∧ s=3i 2 +3i+1 while i < n do inv ∧ i < n i := i + 1; r := r + s; s := expr6 inv end while r = i 3 ∧ i=n r = n 3 Solving expression 4 How? Hint: expr4 is the new value of r, and r is in invariant inv ∧ i < n ⇒ wp(i :=i+1; r := expr4, inv ) Let inv ∧ i < n hold, thus wp(i :=i+1; r := expr4, r = i 3 ) ⇔ expr4 = (i+1) 3 = i 3 +3i 2 +3i+1 inv ⇔ r = i 3, thus expr4 = r+3i 2 +3i+1 strengthen the invariant by s = 3i 2 +3i+1 ⇒ expr4 = r + s s must be initialized and maintained in every cycle Antero Kangas =: s
Initialise s := 1 inv ∧ i < n i := i + 1; r := r + s; s := expr6 inv must hold wp(i := i + 1; r := r + s; s := expr6, r = i 3 ∧ s=3i 2 +3i+1) ⇔ wp(i := i + 1; r := r + s, r = i 3 ∧ expr6 =3i 2 +3i+1) ⇔ wp(i := i + 1; r+s = i 3 ∧ expr6 =3i 2 +3i+1 ⇔ r+s = (i+1) 3 ∧ expr6 =3(i+1) 2 +3(i+1)+1 Since inv ⇒ r+s = (i+1) 3, we get expr6 = 3(i+1) 2 +3(i+1)+1 = 3i 2 +9i+7, and since s = 3i 2 +3i+1, we get expr6 = s + 6i + 6 = s + i + i + i + i + i + i + 6 This suffices but let us make it more elegant by introducing a new variable t so that we can write expr6 = s + t Strengthen the invariant by t = 6i + 6 Initialise t := 6 for that the new invariant would hold Solving expression 6 Antero Kangas inv ⇔ r = i 3 ∧ s=3i 2 +3i+1 =: t
Solving expression7 How? inv ∧ i < n i := i + 1; r := r + s; s := s+t; t := expr7 inv must hold wp(i := i + 1; r := r + s; s := s + t; t := expr7, r = i 3 ∧ s=3i 2 +3i+1 ∧ t = 6i+6) ⇔ r+s = (i+1) 3 ∧ s+t = 3(i+1) 2 +3(i+1)+1 ∧ expr7 = 6(i+1)+6 ⇒ (look invariant) expr7 = 6(i+1)+6 = 6i+12 = t + 6 The program and its proof are ready ! Our cube program this far: n ≥ 0 i := 0; r := 0; s := 1; t:= 6 inv: r = i 3 ∧ s=3i 2 +3i+1 ∧ t = 6i+6 while i < n do inv ∧ i < n i := i + 1; r := r + s; s := s + t; t := expr7 inv end while r = i 3 ∧ i=n r = n 3 Antero Kangas Final code: n ≥ 0 i := 0; r := 0; s := 1; t:= 6 inv: r = i 3 ∧ s=3i 2 +3i+1 ∧ t = 6i+6 while i < n do inv ∧ i < n i := i + 1; r := r + s; s := s + t; t := t + 6 inv end while r = i 3 ∧ i=n r = n 3
Last words The proof can be checked and kept with the code The loop variable i is used only for counting cycles ⇒ it can be done also at the end of the loop Therefore Compute cube can be implemented using a for-loop =======> The main idea was to ”lower the power” by introducing a new variable, strenghtening the invariant, initialising, it so that inv holds in the beginning, etc. A similar program can be designed at the same way for any polynom, if we know its degree and coefficients n ≥ 0 r := 0; s := 1; t := 6; for i := 0 to n─1 do r := r + s; s := s + t; t := t + 6 end for r = n 3 Antero Kangas Test run: irstirst