SE 504 Spring 2019
HW #6: Strengthening the Invariant, Array Assignment, Tail Recursion
Due: 6pm, April 26

1. Develop a program with the specification shown below, and provide a narrative that describes the steps you took in doing so. The inputs to the program are the constant array B of reals and the constant real number X. The goal is to establish

y = B.0   +   B.1 × X   +   B.2 × X2   +   ... +   B.N × XN

where N = #B-1.

Obviously, you should assume that our programming language lacks an exponentiation operator (or an analogous function/method), or else it would be trivial to devise a solution. (Even if the programming language had an exponentiation operator, your solution will be superior to one that uses it, in terms of efficiency.)

In deriving a candidate loop invariant from the postcondition, use the replace a constant by a fresh variable heuristic. But this time replace the constant 0 rather than, say, #B, which is the more obvious one to replace. (Notice that the postcondition is written with two occurrences of 0, including one that would normally be omitted.)

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

   y := ?

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

It may be helpful to recall that multiplication distributes over addition. That is,

u(v1 + v2 + ... + vk) = uv1 + uv2 + ... + uvk

In terms of quantification, we would put it this way:

Theorem (Multiplication Distributes over Summation): Provided that z does not occur free in U,

U·(+z | R : V)  =  (+z | R : U·V).


2. Calculate (and simplify as much as possible)
(a) wp.(b.j := k).(b.j ≠ b.k)
(b) wp.(b.(b.k) := b.j).(b.j = b.k)

In simplifying, make sure to exploit the theorems of the family of if functions. For example,

    x = if(R,y,z)

=      < (if.3b) >

    if(R,x=y,x=z)

=      < (if.4b) >

    (R ∧ x=y) ∨ (¬R ∧ x=z)


3. 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.) Of course, E refers to an unknown expression. Assume that max exists as a binary operator in our programming language.

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. Don't forget that B is a rigid variable and therefore cannot be mentioned in any command.

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


4. Consider this tail recursive definition of function f : ℕ × ℕ → ℕ:

f.m.n = { m max n   if m min n = 0
f.(m-1).(n-1)    otherwise

Using this definition, follow the standard procedure (as covered in lecture) by which to derive a program that satisfies the specification below (in which M and N are the inputs).

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

   z := ?

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


5. Consider this pseudo-tail recursive function definition of R : list<T> → list<T>, which uses the list notation introduced in a previous homework (HW #4).

R.x = { empty   if x = empty
R.(tail.x)  |  [head.x]    otherwise

Using this definition, follow the standard procedure (as covered in lecture) by which to derive a program that satisfies the specification below (in which T stands for an arbitary data type).

As an intermediate step, from the given definition of function R you can derive a (fully) tail recursive definition for function R' such that (for all lists x) R'.x.empty = R.x.

Notice that in the recursive case of the definition, the application of R is the left operand of the concatenate (or append, if you prefer) operator, not the right operand. This is the opposite of the template that we covered in lecture, which means that the roles being played by the two operands here are reversed, which you must take account of.

|[ con X : list<T>;
   var z : list<T>;

   z := ?

   {Q': z = R'.X.empty }
   {Q: z = R.X }
]|