SE 504 Formal Methods and Models
Spring 2009
HW #7: More Repetition, Including Strengthening the Invariant
Due: Thursday, April 2

1. Apply the replace a constant by a variable heurisic to rewrite the postcondition Q in the program below. Specifically, replace 0 by the variable k and add the new conjunct k=0 to obtain a stronger postcondition Q'. (Repeating: Replace 0 by k; do not replace #B by k.)

Then develop code (in place of the label Compute_Ary_Product) so that the resulting program is correct. Clearly, such code should include a loop. Take one of the conjuncts of Q' to be a loop invariant and the negation of the other conjunct to be the loop guard.

Supply an assignment command to initialize k and prod so as to truthify the loop invariant. Then provide a loop body whose execution preserves the truth of the invariant and "makes progress towards termination". Of course, to show the latter will require you to describe a bound function, and to show that this function cannot go below zero without falsifying the loop guard may require you to include in the loop invariant a conjunct that imposes lower and upper bounds upon k.

In developing the loop body, it may be useful to derive part of it through calculation.

Show your completed program and give an account of the steps you made in developing it.


   |[ con B : array of int;
      var prod : int;
      var k : int;

      Compute_Ary_Product

      { Q:  prod = (×j | 0≤j<#B : B.j) }
   ]|


2. (List Reversal)
Prove the correctness of the following program, which reverses a list. Regarding notation,

You may make use of the following axioms and theorems: For all b:elem and z,z1,z2 : list of elem,

    Axiom 1:   empty | z  =  z                           (empty: left id of |)
    Axiom 2:   z | empty  =  z                           (empty: right id of |)
    Axiom 3:   (b ⊕ z1) | z2  =  b ⊕ (z1 | z2)           (mutual assoc of ⊕, |)
    Theorem 1: (b ⊕ empty) | z  =  b ⊕ z                 (from Axioms 1,3)
    Theorem 2: (z1 | z2) | z3  =  z1 | (z2 | z3)         (associativity of |)
    Axiom 4:   (z != empty) ==> (z = head.z ⊕ tail.z)    (defn of head, tail)
    Axiom 5a:  rev.empty = empty                         (defn of rev)
    Axiom 5b:  rev.(b ⊕ z) = rev.z | (b ⊕ empty)         (defn of rev)
    Axiom 6a:  length.empty = 0                          (defn of length)
    Axiom 6b:  length.(b⊕z) = 1 + length.z               (defn of length)
    Theorem 3: length.z >= 0
Here is the program.
  |[ var x, y : list of elem  {x = X};
     y := empty;
     {invariant I: rev.X  =  rev.x | y}
     {bound t: length.x}
     do x != empty  --->  x,y := tail.x, head.x ⊕ y
     od
     {rev.X = y}
  ]|


3. (Polynomial Evaluation)
Develop a program that, given as input an array B representing a polynomial and a real number X, evaluates that polynomial at X, placing the result into y. That is, the program should establish

y = b0   +   b1 × X   +   b2 × X2   +   ... +   bN × XN

where N = #B-1 and, for all i, bi = B.i.

Some of the development has already been done. In particular, the loop's invariant and guard were obtained using the replace a constant by a fresh variable heuristic (and putting the obvious bounds upon the fresh variable). (Specifically, #B was replaced by fresh variable n.)

What remains is to determine the right-hand sides of a few assignment commands. You are to assume, in doing so, that the programming language has no exponentiation operator. With this restriction, you should find that applying the strengthen the loop invariant heuristic is useful in attempting to calculate E. Show this.

  |[ con X : real;
     con B : array of real;
     var y : real;
     var n : int;

     y,n := F, G;

     {loop invariant I: y = (+j | 0 ≤ j < n : B.j × Xj)   ∧   0 ≤ n ≤ N}
     do n != #B --> 
        y := E;
        {I(n:=n+1)}
        n := n+1;
     od
     {Q: y = (+j | 0 ≤ j < #B : B.j × Xj)}
  ]|


4. Do problem 3 again, but this time take the postcondition to be (the equivalent)

Q: y = (+j | 0 ≤ j < #B : B.j × Xj-0)

Notice that the superscript j from the original postcondition has been written as j-0. Now apply the replace a constant by a fresh variable heuristic again, but this time replace both occurrences of zero by fresh variable n. Derive the program based upon the resulting loop invariant and loop guard.