SE 504 Formal Methods and Models
Spring 2020
HW #7: Strengthening the Invariant, Assignment to Arrays, Tail Recursion
Due: April 6

1. Complete the development of the program below and show a proof of (ii) from the loop checklist. (The four other items on the list are clearly true.) Notice that the loop guard and the central conjunct of its invariant were obtained using the replace a constant in the postcondition by a fresh variable heuristic.

Of course, E refers to an unknown expression that is to be "calculated". You will need to augment the loop invariant with a third conjunct in a way similar to what was done in solving the Prefix Sums problem. (See the relevant web page.) Don't forget that B is a rigid variable and therefore can be mentioned in comments/assertions but not in (executable) commands.

|[ con N : int;  {N≥0}
   var b : array[0..N] of int; {b = B}
   var k : int;
   k := 0;
   {loop invariant I: (∀i | 0≤i<k : b.i = B.i + B.(i+1)) ∧ b.N = B.N ∧ 0≤k≤N }
   {bound function t: N - k}
   do k ≠ N ⟶ k,b := k+1,b(k:E)
   od
   {Q': (∀i | 0≤i<k : b.i = B.i + B.(i+1)) ∧ b.N = B.N ∧ k=N}
   {Q:  (∀i | 0≤i<N : b.i = B.i + B.(i+1)) ∧ b.N = B.N }
]| 


2. Complete the development of the program below and show a proof of (ii) from the loop checklist. (The four other items on the list are clearly true, with the exception of item (i) with respect to any fresh variables that you might introduce.) As in the previous problem, the usual heuristic was used in obtaining the loop's guard and the central conjunct of its invariant.

Of course, E refers to an unknown expression that is to be "calculated". You will need not only to augment the loop invariant as in the previous problem but also to strengthen it by introducing a fresh variable. You should find that using a multiple assignment command is very convenient. Don't forget that B is a rigid variable and therefore can be mentioned in comments/assertions but not in (executable) commands.

|[ con N : int;  {N>0}
   var b : array[0..N) of int; {b = B}
   var k : int;
   k := 1;
   {loop invariant I: (∀i | 1≤i<k : b.i = B.(i-1) + B.i)) ∧ 1≤k≤N }
   {bound function t: N - k}
   do k ≠ N ⟶ k,b := k+1,b(k:E)
   od
   {Q': (∀i | 1≤i<k : b.i = B.(i-1) + B.i) ∧ b.0 = B.0 ∧ k=N}
   {Q:  (∀i | 1≤i<N : b.i = B.(i-1) + B.i) ∧ b.0 = B.0 }
]| 


3. Consider this tail recursive function definition, which describes a function g having signature ℕ × ℕ ⟶ ℕ (where ℕ denotes the set of natural numbers (i.e., nonnegative integers)):

g.k.m = { k max m    if k min m = 0
g.(k-m).m    if k≥m>0
g.k.(m-k)    if 0<k≤m

From this definition, use the procedure covered in class by which to derive a program that computes the function. That is, complete the specification below, in which K and M are to be interpreted as being the inputs.

|[ con K,M : int;  { K,M ≥ 0 }
   var z : int;

   z := ?

   {Q: z = g.K.M }
]|


4. Consider this pseudo-tail recursive function definition, which describes a function having signature ℕ × ℕ ⟶ ℕ (where ℕ denotes the set of natural numbers (i.e., nonnegative integers)):

f.k.m = { 0    if k=0
f.(k/2).(2m)    if k≠0 ∧ isEven.k
m + f.(k-1).m    if ¬isEven.k

From this definition, use the procedure covered in class by which to derive a program that computes the function. That is, complete the specification below, in which K and M are to be interpreted as being the inputs.

As an intermediate step, you could derive from the pseudo-tail recursive definition of f a (fully) tail recursive definition for function f' such that (for all natural numbers k and m) f'.k.m.e = f.k.m, where e is the appropriate identity element.

If you don't recognize the function f upon first glance at its definition, you should recognize it sometime thereafter.

|[ con K,M : int;  { K,M ≥ 0 }
   var z : int;

   z := ?

   {Q: z = f.K.M }
]|