SE 504 Spring 2020
HW #5: Repetition and Strengthening the Invariant
Due: 7:20pm, Thursday, March 5

1. (List Reversal)
Prove the correctness of the program found below, 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 is left identity of  | )
Axiom 2: z | empty  =  z     (empty is right identity 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)     (universality 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: rev.X  =  rev.x | y}
   {bound t: length.x}
   do x ≠ empty  ⟶  x,y := tail.x, head.x ⊕ y
   od
   {rev.X = y}
]|


2. (Binary Numeral Evaluation)
Develop a program that, given as input an array B containing the bits of a binary numeral (in order from most to least significant), computes the integer value that it represents, placing the result into output variable r.

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, 0 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. You should expect E to be something like r + F, for some expression F. In introducing a fresh variable, say s, don't necessarily assume that you should add s = F as a new conjunct to the loop invariant. Rather, if F is a compound expression, say G*H, one might choose s = G (or perhaps s = H) as the new conjunct. Because in this program the update to n is n := n-1, you would want to choose a subexpression G of F such that computing G(n:=n-1) from G is "natural".

|[ con B : array of {0,1};
   var r : real;
   var n : int;

   n,r := F, G;

   {loop invariant I: r = (+j | n≤j<#B : B.j × 2#B-1-j) ∧ 0≤n≤#B}
   {bound t:n}
   do n ≠ 0 ⟶
      {I ∧ n≠0}
      n,r := n-1,E;
      {I}
   od
   {Q: r = (+j | 0≤j<#B : B.j × 2#B-1-j)}
]|

If you have trouble, first try solving the problem under the assumption that the bits in B are in order from least to most significant. In that case, the postcondition would be

{Q: r = (+j | 0≤j<#B : B.j × 2j)}

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.

Notice that the precondition says N>0. Try to weaken it to N≥0 without having to make your program any more complicated. Explain how you did it.

|[ 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 that are greater than all those that precede it.

It may help you to study the web page describing the development of a program to solve the Negative-Positive Array Element Pair Counting problem.