SE 504 Spring 2022
HW #7: Tail Recursion
Due: 6:30pm, Tuesday, April 26

1. Consider this tail recursive definition of the (two-argument) function f : ℕ × ℕ → ℕ (where ℕ denotes the set of nonnegative integers):

f.m.n = { n   if m = 0
f.(m−1).(n+1)    otherwise (i.e., m ≠ 0)

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). (Make sure that your program is appropriately annotated to include a loop invariant and bound function.) That M is declared to be of type nat means that M ≥ 0 is an implicit precondition.

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

|[ con M, N : nat; 
   var k : nat;

   k := ?

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


2. Consider this pseudo-tail recursive function definition, which describes a function having signature ℕ ⟶ ℕ (where ℕ denotes the set of nonnegative integers).

f.n = { 0    if n = 0
n + f.(n−1)    otherwise (i.e., n ≠ 0)

From this definition, use the procedure covered in class by which to derive a program that computes the function. That is, complete the program specified below, in which N is to be interpreted as being the input. (Make sure that your program is appropriately annotated to include a loop invariant and bound function.)

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 every positive integer n) f'.n.e = f.n, 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 N : nat; 
   var k : nat;

   k := ?

   {Q: k = f.N }
]|


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

Rev.x = { empty   if x = empty
Rev.(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). (Make sure that your program is appropriately annotated to include a loop invariant and bound function.)

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

Notice that in the recursive case of the definition, the application of Rev 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 = Rev'.X.empty }
   {Q: z = Rev.X }
]|