SE 504
Computing N3 without using multiplication or exponentiation

Problem: Develop a solution to the following specification. In order to make it interesting, assume that the programming language has no multiplication or exponentiation operations.

|[ con N : int;  { N>=0 } 
   var r : int; 
   compute_cube 
   { post: r = N3 } 
]|

Because we are not to use multiplication or exponentiation, it would seem that a solution will include at least one loop. Applying the "replace a constant by a variable" heuristic to arrive at a possible loop invariant, we get

r = n3

as a possible invariant. The loop should terminate when n=N, at which time we will have r=n3 & n=N, which implies (by (3.84)) the postcondition. From this discussion, the program has been refined to the following:

|[ con N : int;  { N>=0 }
   var r : int;
   var n : int;

   n,r := E0, E1;
   { P : r=n3 }
   do n != N  --->
      n,r := F0,F1;
   od
   { r=n3 & n=N }
   { Q : r = N3 }
]|

To what values should n and r be initialized? To truthify the loop invariant, we need to establish r=n3. The only two obvious choices are to set n to either 0 or 1. (For any other value of n, it is not clear how we could initialize r to n3 without using multiplication, exponentiation, or another loop.) The fact that n will be initialized to a "small" value suggests that it be incremented each time around the loop. The fact that N could be zero suggests that we initialize n to zero rather than one. Our refined program is

|[ con N : int;  { N>=0 }
   var r : int;
   var n : int;

   n,r := 0,0;
   { P : r=n3 }
   do n != N  --->
      n,r := n+1,F;
   od
   { r=n3 & n=N }
   { Q : r = N3 }
]|

It remains to calculate F. We need F to be an expression that truthifies the following Hoare triple (in accord with item (ii) on loop checklist):

{P & B} n,r := n+1,F {P}

Equivalently, this is [P & B ==> wp.(n,r := n+1,F).P]. So, we assume P & B and attempt to prove wp.(...).P:

     wp.(n,r := n+1,F).P

  =    < wp assignment law, defn of P, textual sub. >

     F = (n+1)3

  =    < algebra >

     F = n3 + 3n2 + 3n + 1

  =    < assumption: r = n3 >

     F = r + 3n2 + 3n + 1

At this point, we use the strengthen the invariant heuristic, by which we augment the invariant to include s = 3n2 + 3n + 1 as a new conjunct, where s is a fresh variable. Continuing from above, we get

  =    < assumption: s = 3n2 + 3n + 1 >

     F = r + s

But now we must insert code that correctly initializes s and that correctly updates s during each iteration of the loop. Our updated program is

|[ con N : int;  { N>=0 }
   var r : int;
   var n,s : int;

   n,r,s := 0,0,E;
   { P : r=n3  &  s = 3n2 + 3n + 1 }
   do n != N  --->
      n,r,s := n+1,r+s,F;
   od
   { r=n3 & n=N }
   { Q : r = N3 }
]|

Clearly, the correct choice for E is 1. To calculate F, we attempt to find an expression F that truthifies the Hoare triple

{P & B} n,r,s := n+1,r+s,F {P}

(where P is the updated version that includes s = 3n2 + 3n + 1 as a conjunct).

    
     wp.(n,r,s := n+1,r+s,F).P

  =    < wp assignment law, defn of P, textual sub. >

     r+s = (n+1)3  &  F = 3(n+1)2 + 3(n+1) + 1

  =    < 1st conjunct follows from earlier derivation, (3.39) >

     F = 3(n+1)2 + 3(n+1) + 1

  =    < algebra >

     F = 3n2 + 9n + 7

  =    < assumption: s = 3n2 + 3n + 1 > 

     F = s + 6n + 6

  =    < 6n =  n + n + n + n + n + n >

     F = s + n + n + n + n + n + n + 6

Thus, we could plug in for F the expression derived above in order to complete the program. However, this expression is not very elegant. So, instead, let's strengthen the invariant once again by introducing a fresh variable t:

     F = s + 6n + 6

  =    < assumption: t = 6n + 6 >

     F = s + t

Of course, we must initialize t and update it on each loop iteration. Our updated program is

|[ con N : int;  { N>=0 }
   var r : int;
   var n,s,t : int;

   n,r,s,t := 0,0,1,E;
   { P : r=n3  &  s = 3n2 + 3n + 1  &  t = 6n + 6 }
   do n != N  --->
      n,r,s,t := n+1,r+s,s+t,F;
   od
   { r=n3 & n=N }
   { Q : r = N3 }
]|

Clearly, the correct choice for E is 6. To calculate F, we attempt to find an expression F that truthifies the Hoare triple

{P & B} n,r,s,t := n+1,r+s,s+t,F {P}

(where P is the updated version that includes t = 6n + 6 as a conjunct).

    
     wp.(n,r,s,t := n+1,r+s,s+t,F).P

  =    < wp assignment law, defn of P, textual sub. >

     r+s = (n+1)3  &  s+t = 3(n+1)2 + 3(n+1) + 1  &  F = 6(n+1) + 6 

  =    < earlier derivations showed 1st two conjuncts, (3.39) >

     F = 6(n+1) + 6

  =    < algebra >

     F = 6n + 12

  =    < algebra >

     F = 6n + 6 + 6

  =    < assumption: t = 6n + 6 >

     F = t + 6
The final program is
|[ con N : int;  { N>=0 }
   var r : int;
   var n,s,t : int;

   n,r,s,t := 0,0,1,7;
   { P : r=n3  &  s = 3n2 + 3n + 1  &  t = 6n + 6 }
   do n != N  --->
      n,r,s,t := n+1,r+s,s+t,t+6;
   od
   { r=n3 & n=N }
   { Q : r = N3 }
]|