# Search in the document preview

Discrete aths

• Objectives – to show the use of induction for proving properties of code involving loops

• use induction to prove that functions work – introduce pre- and post- conditions,

loop termination

2. Loop Invariants

Docsity.com

Overview

1. What is a Loop Invariant?

2. Three simple examples – they involve while loops

3. Selection Sort

4. Further Information

Docsity.com

1. What is a Loop Invariant?

• A *loop invariant* is an *inductive* statement
which says something which is always true
about a program loop.

• Loop invariants are useful for: – code specification – debugging

*continued*
Docsity.com

• A loop invariant is typically written as an inductive statement S(n), where n is some changing element of the loop. For example: – the loop counter/index – a loop variable which changes on each

iteration

Docsity.com

2.1. Example 1

int square(int val) { int result = 0; int counter = 0; while (counter < val) { result += val; counter++; } return result; }

Problem: does this function work?

Docsity.com

Pre- and Post-conditions

• We assume that val is a positive integer
– the *precondition* for this function

• square() always returns val2
– the *postcondition*
– we will use the loop invariant to show that this is

true

Docsity.com

The Loop Invariant

• To make the proof clearer, let countern and resultn be the values of counter and result after passing round the loop n times.

• Loop invariant S(n): resultn = val * countern – is this true in the loop for all n >= 0?

Docsity.com

Basis

• S(0) is when the loop has not yet been executed. – result0 = counter0 = 0

• So: result0 = val * counter0 – which means that S(0) is true.

Docsity.com

Induction

• We assume that S(k) is true for some k >= 0, which means that: resultk = val * counterk (1)

• After one more pass through the loop: resultk+1 = resultk + val (2) counterk+1 = counterk + 1 (3)

*continued*
Docsity.com

• Substitute the rhs of (1) for the 1st operand of the rhs of (2): resultk+1 = (val * counterk) + val

= val * (counterk + 1) = val * counterk+1 (by using (3))

– this is S(k+1), which is therefore true.

*continued*
Docsity.com

• For the loop, we now know: – S(0) is true – S(k) --> S(k+1) is true

• That means S(n) is true for all n >= 0 – for all n >= 0, the loop invariant is true:

resultn = val * countern

Docsity.com

Termination

• The loop does actually terminate, since counter is increasing, and will reach val.

• At loop termination (and function return): countern = val

• So in S(n): resultn = val * val

= val2

• So the *postcondition is true*.
The function

works!! Docsity.com

2.2. Example 2

int exp(int b, int m) // return bm { int res = 1; while (m > 0) { res = res * b; m = m - 1; } return res; }

Problem: does this function work?

Docsity.com

Pre- and Post-conditions

• We assume b and m are non-negative
integers
– the *preconditions* for this function

• exp() always returns bm
– the *postcondition*
– we will use the loop invariant to show that this

is true

Docsity.com

The Loop Invariant

• To clarify the proof, let resn and mn be the values of res and m after passing round the loop n times.

• Loop invariant S(n): resn * bmn = bm – is this true in the loop for all n >= 0?

Inventing this is the hardest part.

Docsity.com

Basis

• S(0) is when the loop has not yet been executed. – res0 = 1; m0 = m

• So: 1 * bm = bm – which means that S(0) is true.

Docsity.com

Induction

• We assume that S(k) is true for some k >= 0, which means that: resk * bmk = bm (1)

• After one more pass through the loop: resk+1 = resk * b (2) mk+1 = mk - 1 (3)

*continued*
Docsity.com

• Rearrange the equations: resk = resk+1 / b (2’) mk = mk+1 + 1 (3’)

• Substitute the right hand sides of (2’) and (3’) into (1):

( resk+1 / b ) * b(mk+1 + 1 ) = bm which is

resk+1 * b(mk+1 + 1 - 1 ) = bm which is

resk+1 * bmk+1 = bm

*continued*
Docsity.com

• S(k+1) is: resk+1 * bmk+1 = bm (4)

• So we have shown S(k+1) is true by using S(k).

*continued*
Docsity.com

• For the loop, we now know: – S(0) is true – S(k) --> S(k+1) is true

• That means S(n) is true for all n >= 0 – for all n >= 0, the loop invariant is true:

resn * bmn = bm

Docsity.com

Termination

• The loop does actually terminate, since m is decreasing, and will reach 0.

• At loop termination (and function return): mn = 0

• So in S(n): resn * b0 = bm

so resn = bm
• So the *postcondition is true*.

The function works!!

Docsity.com

2.3. Example 3

int factorial(int num) { int i = 2; int fact = 1; while (i <= num) { fact = fact * i; i++; } return fact; }

Problem: does this function work?

Docsity.com

Pre- and Post-conditions

• We assume num is a positive integer
– the *precondition* for this function

• factorial() always returns num!
– the *postcondition*
– we will use the loop invariant to show that this is

true

Docsity.com

The Loop Invariant

• To clarify the proof, let factn and in be the values of fact and i after passing round the loop n times.

• Loop invariant S(n): factn = (in - 1)! – is this true in the loop for all n >= 0?

Docsity.com

Basis

• S(0) is when the loop has not yet been executed. – i0 = 2; fact0 = 1

• So: fact0 = (i0 - 1)! 1 = (2 - 1)!

1 = 1

which means that S(0) is true.

Docsity.com