SE 504 Spring 2022
HW #5: Repetition, including Strengthening the Loop Invariant
Due: 3:00pm, Friday, April 1

1. (List Reversal)
Prove the correctness of the program found below, which computes the reverse of 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 is left identity of  | )
Axiom 2: z | empty  =  z     (empty is right identity of  | )
Axiom 3: (b ⊕ z1) | z2  =  b ⊕ (z1 | z2)     (mutual associativity 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)
Theorem 3: rev.z1  |  b ⊕ z2  =  rev.(b⊕z1) | z2     (useful property of rev)
Axiom 6a: length.empty = 0     (defn of length)
Axiom 6b: length.(b⊕z)  =  1 + length.z     (defn of length)
Theorem 4: length.z ≥ 0     (lower bound of length)

Here is the program.

|[ var x, y : list of Elem;  {x = X}
   y := empty;
   {invariant I: X  =  rev.y | x}
   {bound t: length.x}
   do x ≠ empty  ⟶  x,y := tail.x, head.x ⊕ y
   od
   {X = rev.y}
]|


2. (Polynomial Evaluation)
Develop a program that, given as input a real number X and an array B containing the coefficients of a polynomial, 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.

Hint: Be smart in choosing a new conjunct to add to the loop invariant. If, for example, you find that a value of the form α×β is needed during each iteration, introducing fresh variable w and adding any one of the conjuncts w = α×β, w = α, or w = β to the loop invariant makes sense. Suppose, for example, that α was a readily-available value; then w = β could very well be a better choice than w = α×β.

|[ 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≤#B}
   do n ≠ #B ⟶
      y := E;
      {I(n:=n+1)}
      n := n+1;
   od
   {Q: y = (+j | 0≤j<#B : B.j × Xj)}
]|


3. (Recursive Function Evaluation)
Define function g : ℕ → ℕ as follows: g.0 = 1, g.1 = 2, and g.n = 3×g.(n-1) - 2×g.(n-2) (for n≥2).

Derive a solution (and provide an accompanying narrative) to the following programming problem. Not surprisingly, your program should include a loop, the invariant of which you should derive by employing the usual heuristics. During development, you should find it useful to strengthen the loop invariant by introducing a fresh variable.

|[ con N : int;  { N>0 }
   var z : int;

   z := ?;

   {Q: z = g.N }
]|


4. Derive a solution (and provide an accompanying narrative) to the following problem:

|[ con B : array of int;  { #B>0 }
   var r : int;

   r := ?

   {Q: r = (#k | 1≤k<#B : B.k ≥ M.k)}
]| 

where M.k = (MAX i | 0≤i<k : B.i) is the maximum value in the array segment B[0..k). The program computes the number of elements in the array —not including the one at location zero— that are greater than or equal to all those that precede it.