Lecture 15

In this lecture we will see more examples on establishing and proving loop invariants.

Dot_Product.

double dot_product ( int nelt, double *v1, double *v2 ) {

int i;

double t = 0.0;

for ( i= 0; i < nelt; i++ ) {

t += v1[i] * v2[i];

}

return t;

}

To establish the invariant first look into the specifications of the dot_product routine, i.e. the pre-conditions and the post-conditions.

Pre-conditions: nelt > 0;

v1, v2 are vectors of length nelt.

Post-conditions: The routine must return ånelt - 1 v1[i] * v2[i]

i=0

Hence, the loop invariant is:

t = sum so far

=  å i - 1 v1[j] * v2[j]

j=0

Initially, i = 0 and t = 0.0.

Simulating the execution,

Assume t = å  i - 1 v1[j] * v2[j]

j=0

t' = t + v1[i] * v2[i]

i' = i + 1

Now, t' = å j = i - 1 v1[j] * v2[j] + v1[i] * v2[i]

j=0

= å j = i  v1[j] * v2[j]

j=0

But i = i' - 1

Therefore, t' = åi’ - 1 v1[j] * v2[j]

j=0

The loop terminates when i = nelt and hence:

t = å j = nelt - 1 v1[j] * v2[j]

j=0

which satisfies the post-condition.

Loop Invariant for an if statement:

double exp ( double b, int e ) {

double x = 1.0, y = b;

// Imagine i=0

while ( 0 != e ) {

if ( e odd ) {

x = x * y;

}

y = y * y;

e = e div 2; // imagine i = i+ 1

}

return x;

}

Explanation of strategy:

The binary expansion of e is e = e31 e30…e1 e0 = å31 2i * ei

i = 0

ð      be = b raised to ( å31 2i * ei )

i = 0

= Õ31 ( ( b raised to 2i ) raised to ei )

i=0

= ( b raised to e0 ) * ( ( b2 ) raised to e1) * ( ( b4 ) raised to e2 )…

Loop Invariant:

For all i from 0 to 31,            x = Õi ( ( b raised to 2j ) raised to ej )                   y = b raised to 2j

j = 0

At every iteration, y’ = y * y = y2 = ( (b raised to 2i) raised to 2 ) = b raised to 2i + 1

The only values of ei are 0 or 1.

if ei = 0,

x’ = x

When, i’ = i +1

x’ = Õi-1 ( ( b raised to 2j ) raised to ej ) * y

j=0

= ( Õi-1 ( ( b raised to 2j ) raised to ej ) ) * ( ( b raised to 2i ) raised to ei )

j=0

= Õi ( (  b raised to 2j ) raised to ej )

j=0

= Õi’-1 ( ( b raised to 2j ) raised to ej )

j=0

if ei = 1

x’ = x * y

= Õi-1( ( b raised to 2j ) raised to ej ) * ( ( b raised to 2i ) raised to ei )

j=0

= Õi ( ( b raised 2j ) raised to ej )

j=0