# Loop Invariants - Discrete Math - Lecture Slides, Slides for Discrete Mathematics. Allahabad University

PDF (413 KB)
56 pages
1000+Number of visits
Description
Some concept of Discrete Math are Unique Path, Addition Rule, Clay Mathematics, Complexity Theory, Correspondence Principle, Discrete Mathematics, Group Theory, Random Variable, Major Concepts. Main points of this lectur...
20points
this document
Preview3 pages / 56
Writing Web Pages

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

Induction

• We assume that S(k) is true for some k >= 0, which means that: factk = (ik-1)! (1)

• After one more pass through the loop: factk+1 = factk * ik (2) ik+1 = ik + 1 (3)

continued Docsity.com

• Substitute the rhs of (1) for the 1st operand of the rhs of (2): factk+1 = (ik - 1)! * ik

= (ik)! = (ik+1 - 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:

factn = (in - 1)!

Docsity.com

Termination

• The loop does actually terminate, since i is increasing, and will reach num+1.

• At loop termination (and function return): in = num+1

• So in S(n): – factn = (in - 1)!

= (num + 1 - 1)! = num! • So the postcondition is true.

The function works!!

Docsity.com

3. Selection Sort void selectionSort(int A[], int num)

{ int i, j, small, temp; for (i=0; i < num-1; i++) { small = i; for( j= i+1; j < num; j++) if (A[j] < A[small]) small = j; temp = A[small]; A[small] = A[i]; A[i] = temp; } }

swap A[small] and A[i]

put index of smallest value in A[i .. num-1]

into small

Docsity.com

Execution Highlights

A 0 1 2 3

25 30 20 10

Start 1st iteration:

A 0 1 2 3

25 30 20 10

sorted

A 0 1 2 3

25 30 20 10

sorted

Start 4th iteration: A 0 1 2 3

25 30 20 10

sorted

Start 2nd iteration:

Start 3rd iteration:

selectionSort(A, 4);

Docsity.com

Pre- and Post-conditions

• We assume num is a positive integer, which contains the number of elements in the array – the precondition for this function

• selectionSort() sorts the array into ascending order – the postcondition – we will use the loop invariant to show that this is

true

Docsity.com

3.1. Consider the Inner Loop

small = i; for( j= i+1; j < num; j++) if (A[j] < A[small]) small = j;

Put index of smallest value in A[i .. num-1] into small

Docsity.com

Pre- and Post-conditions

• We assume i is a positive integer, which is an index into the array – the precondition for this part of the code

• This code finds the index of the smallest value in A[i..num-1] – the postcondition – we will use the loop invariant to show that this is

true

Docsity.com

The Inner Loop Invariant

• To clarify the proof, let smalln and jn be the values of small and j after passing round the loop n times.

• Loop invariant S(n): smalln is the index of the smallest

of A[i .. jn-1] – is this true in the loop for all n >= 0?

Docsity.com

Execution Highlights A 0 1 2 3

25 30 20 10 Start 1st pass: small 0

j A 0 1 2 3

25 30 20 10 small 0

j A 0 1 2 3

25 30 20 10 small 2

j A 0 1 2 3

25 30 20 10 small 3

j

Start 2nd pass:

Start 3rd pass:

Start 4th pass: loop ends

Docsity.com

Basis • S(0) is when the loop has not yet been

executed. – small0 = i; j0 = i+1

• So: small0 is the index of the smallest of A[i .. j0-1] which is A[i..(i+1-1)], or A[i..i], or A[i]

• That means that S(0) is true.

Docsity.com

Induction

• We assume that S(k) is true for some k >= 0, which means that: smallk is the index of the smallest

of A[i .. jk -1]

• The pass through the loop involves two possible branches because of the if.

continued Docsity.com

Case 1. If A[jk] is not smaller than the smallest of A[i.. jk -1] – then smallk+1 = smallk (no change)

Case 2. If A[jk] is smaller than the smallest of A[i.. jk -1] – then smallk+1 = jk

continued Docsity.com

• At the end of the pass: – smallk+1 is the index of the smallest of A[i..jk] – jk+1 = jk + 1

• S(k+1) is: – smallk+1 is the index of the smallest of A[i .. jk+1-1]

• So S(k+1) is true.

continued Docsity.com

• For the inner 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 inner loop invariant is true:

smalln is the index of the smallest of A[i .. jn -1]

Docsity.com

Termination

• The loop does actually terminate, since j is increasing, and will reach num.

• At loop termination: jn = num

• So in S(n): – smalln is the index of the smallest

of A[i .. jn-1], or A[i..num-1] • So the postcondition is true.

The inner loop is proved.

Docsity.com

3.2 The Outer Loop

void selectionSort(int A[], int num) { int i, j, small, temp; for (i=0; i < num-1; i++) { small = i; for( j= i+1; j < num; j++) if (A[j] < A[small]) small = j; temp = A[small]; A[small] = A[i]; A[i] = temp; } }

proved

Docsity.com

The Outer Loop Invariant

• To clarify the proof, let im be the value of i after passing round the loop m times.

• Informal loop invariant T(m): im indicates that we have selected m of the

smallest elements and sorted them at the beginning of the array.

Docsity.com

Graphically

A 0

Sorted <

m m-1

current sort position i

num-1

e.g.

10 12 15 20 22 21 19

i

m

smaller values in array

larger values in array

Docsity.com

More Formally

• Loop invariant T(m): – a) A[0..im-1] are in sorted order;

– b) All of A[im..num-1] are >= all of A[0..im-1]

Docsity.com

Basis

• T(0) is when the loop has not yet been executed. i0=0 – a) Range is A[0..-1], which means no

elements. – b) Range is A[0..num-1] which means

everything > A[0..-1]

• So T(0) is true.

Docsity.com

Induction

• We assume that T(k) is true for some k >= 0, which means that: – a) A[0..ik-1] are in sorted order;

– b) All of A[ik..num-1] are >= all of A[0..ik-1]

continued Docsity.com

• By the end of the inner loop, we know that A[small] is the smallest element in A[ik..num-1] – the postcondition of the inner loop

• The next three lines swap A[small] and A[ik] – now A[ik] contains the smallest element

continued Docsity.com

Graphically

A 0

Sorted <

k k-1

current sort position ik

num-1

10 12 15 20 22 21 19

ik

k

small

swapped

small e.g.

continued Docsity.com

• By the end of the outer loop, we know: – a) A[0..ik] are in sorted order;

– b) All of A[ik+1..num-1] are >= all of A[0..ik]

– ik+1 = ik +1

• This shows that T(k+1) is true.

continued Docsity.com

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

• That means T(m) is true for all m >= 0 – a) A[0..im-1] are in sorted order;

– b) All of A[im..num-1] are >= all of A[0..im-1]

Docsity.com

Termination

• The outer loop does actually terminate, since i is increasing, and will reach num-1.

• At loop termination (and function return): im = num-1

continued Docsity.com

• So in T(m): – a) A[0..im-1] are in sorted order – so A[0..num-1-1] is sorted – so A[0..num-2] is sorted

– all the array up to the last element is sorted

continued Docsity.com

– b) All of A[im..num-1] are >= all of A[0..im-1] – so, A[num-1..num-1] >= all A[0..num-1-1] – so, A[num-1] >= all A[0..num-2]

– so the last element is bigger than all the other array elements

• So the function does sort the array into ascending order: the postcondition is true

Docsity.com

4. Further Information

Discrete Mathematics Structures in Computer Science B. Kolman & R. C. Busby Prentice-Hall, 1987, 2nd ed. Section 1.6

Docsity.com