recursion - cs190 functional programming techniques · 2008-12-15 · general forms of recursion...

Post on 06-Jul-2020

28 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

RecursionCS190 Functional Programming Techniques

Dr Hans Georg Schaathun

University of Surrey

Autumn 2008 – Week 3

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 1 / 34

This session

After this session, you shouldunderstand the principle of recursionbe able to use recursion over integers to solve simple problemsbe familiar with different approaches to software testing

ReferenceThompson, Chapter 4

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 2 / 34

ASCII Characters

Outline

1 ASCII Characters

2 Modular programming

3 Primitive recursion

4 General forms of recursion

5 Error handling

6 Program testing

7 Conclusion

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 3 / 34

ASCII Characters

The ASCII table

Each character has a number

0 1 2 3 4 5 6 7 8 9 A B C D E F0 NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI1 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US2 SP ! " # $ % & ’ ( ) * + , - . /3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?4 @ A B C D E F G H I J K L M N O5 P Q R S T U V W X Y Z [ \ ] ^ _6 ‘ a b c d e f g h i j k l m n o7 p q r s t u v w x y z { | } ~ DEL

H e l l o W o r l d !48 65 6C 6C 6F 20 57 6F 72 6C 64 21

Hexadecimal notation (base 16)6F = 6 · 16 + 15 · 1 = 111

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 4 / 34

ASCII Characters

ASCII numbers in Haskell

import Char (load module, at start of your file)ord :: Char -> Int

chr :: Int -> Char

Hugs> :load CharChar> ord ’a’97Char> ord ’A’65Char> chr 100’d’

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 5 / 34

ASCII Characters

Offsetting ASCII characters

0

. . . A

65

B

66

. . . Z

90

. . . a

97

b

99

. . . z

122

- ord ’a’

+ ord ’A’

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 6 / 34

Modular programming

Outline

1 ASCII Characters

2 Modular programming

3 Primitive recursion

4 General forms of recursion

5 Error handling

6 Program testing

7 Conclusion

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 7 / 34

Modular programming

Software development

The key to problem solvingSplit the task into smaller and manageable problems

Software development is the sameEach subproblem gives a function

Many subproblems apply to different tasksWrite the functions such that they can be reused

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 8 / 34

Modular programming

Planning the development

If i had all the functions in the world, which would i use?

1 This question points to subproblems2 Then move to the key functions – one at a time3 Apply the same question to them

This idea apply in a myriad of waysTodays main topic is a special case

known as recursion

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 9 / 34

Modular programming

Planning the development

If i had all the functions in the world, which would i use?

1 This question points to subproblems2 Then move to the key functions – one at a time3 Apply the same question to them

This idea apply in a myriad of waysTodays main topic is a special case

known as recursion

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 9 / 34

Modular programming

Planning the development

If i had all the functions in the world, which would i use?

1 This question points to subproblems2 Then move to the key functions – one at a time3 Apply the same question to them

This idea apply in a myriad of waysTodays main topic is a special case

known as recursion

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 9 / 34

Primitive recursion

Outline

1 ASCII Characters

2 Modular programming

3 Primitive recursion

4 General forms of recursion

5 Error handling

6 Program testing

7 Conclusion

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 10 / 34

Primitive recursion

A recursive definition

A recursive function is defined in terms of itself.

Factorial: n! = 1 · 2 · 3 · . . . · nRecursive definition:

0! = 1 (1)n! = n · (n − 1)! for n > 0 (2)

A recursive function is defined in terms of itself.

Why is this not a circular definition?

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 11 / 34

Primitive recursion

A recursive definition

A recursive function is defined in terms of itself.

Factorial: n! = 1 · 2 · 3 · . . . · nRecursive definition:

0! = 1 (1)n! = n · (n − 1)! for n > 0 (2)

A recursive function is defined in terms of itself.

Why is this not a circular definition?

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 11 / 34

Primitive recursion

A recursive definition

A recursive function is defined in terms of itself.

Factorial: n! = 1 · 2 · 3 · . . . · nRecursive definition:

0! = 1 (1)n! = n · (n − 1)! for n > 0 (2)

A recursive function is defined in terms of itself.

Why is this not a circular definition?

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 11 / 34

Primitive recursion

A recursive definition

A recursive function is defined in terms of itself.

Factorial: n! = 1 · 2 · 3 · . . . · nRecursive definition:

0! = 1 (1)n! = n · (n − 1)! for n > 0 (2)

A recursive function is defined in terms of itself.

Why is this not a circular definition?

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 11 / 34

Primitive recursion

The basic components

The recursive case (n! = (n − 1)! · n)large cases (for n) are reduced to a smaller case (n − 1)

The base case (0! = 1)some small case must be solved explicitely

Without the base case, recursion would never endn, n − 1, n − 2, . . . , 1, 0,−1, . . . ,−∞

Without the recursive case, everything would be explicitone line for every n (0, 1, 2, . . . ,∞)

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 12 / 34

Primitive recursion

The basic components

The recursive case (n! = (n − 1)! · n)large cases (for n) are reduced to a smaller case (n − 1)

The base case (0! = 1)some small case must be solved explicitely

Without the base case, recursion would never endn, n − 1, n − 2, . . . , 1, 0,−1, . . . ,−∞

Without the recursive case, everything would be explicitone line for every n (0, 1, 2, . . . ,∞)

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 12 / 34

Primitive recursion

The basic components

The recursive case (n! = (n − 1)! · n)large cases (for n) are reduced to a smaller case (n − 1)

The base case (0! = 1)some small case must be solved explicitely

Without the base case, recursion would never endn, n − 1, n − 2, . . . , 1, 0,−1, . . . ,−∞

Without the recursive case, everything would be explicitone line for every n (0, 1, 2, . . . ,∞)

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 12 / 34

Primitive recursion

The basic components

The recursive case (n! = (n − 1)! · n)large cases (for n) are reduced to a smaller case (n − 1)

The base case (0! = 1)some small case must be solved explicitely

Without the base case, recursion would never endn, n − 1, n − 2, . . . , 1, 0,−1, . . . ,−∞

Without the recursive case, everything would be explicitone line for every n (0, 1, 2, . . . ,∞)

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 12 / 34

Primitive recursion

Recursion in Haskell

Haskell supports recursive definitionsfactorial :: Int -> Int

factorial 0 = 1

factorial n = n * (factorial (n-1))

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 13 / 34

Primitive recursion

For example

factorial4 (3)=4 · (factorial3) (4)=4 · 3 · (factorial2) (5)=4 · 3 · 2 · (factorial1) (6)=4 · 3 · 2 · 1 · (factorial0) (7)=4 · 3 · 2 · 1 · 1 (8)=24 (9)

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 14 / 34

Primitive recursion

Why recursion?

Fundamental principle in mathematics and in computerprogrammingUsed in all programming paradigms

you will see it in Java next yearRecursion tends to make it simple to

1 prove correctness2 define and understand algorithms

It often makes computationally efficient algorithms

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 15 / 34

Primitive recursion

Primitive recursion

What if we knew the value of f (n − 1). How would we definef (n)?

1 f 0 = ...2 f n = ... f (n-1) ...

The recursive case depends onf (n-1)expressions independent of f

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 16 / 34

General forms of recursion

Outline

1 ASCII Characters

2 Modular programming

3 Primitive recursion

4 General forms of recursion

5 Error handling

6 Program testing

7 Conclusion

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 17 / 34

General forms of recursion

Many forms of recursion

Sometimes the recursive case does not call n − 1

For which values of k would f (k) help us define f (n)?

Sometimes we need f (n − 1) and f (n − 2)

Sometimes we can work with f (n/2)

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 18 / 34

General forms of recursion

Split-and-Conquer

qn = q · q · . . . · q (10)

How do you compute this efficiently?n − 1 multiplications is quite expensive

q0 = 1, (11)

q1 = q, (12)

qn =

{(qbn/2c)2, if n is even(qbn/2c)2 · q, if n is odd

(13)

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 19 / 34

General forms of recursion

Split-and-Conquer

qn = q · q · . . . · q (10)

How do you compute this efficiently?n − 1 multiplications is quite expensive

q0 = 1, (11)

q1 = q, (12)

qn =

{(qbn/2c)2, if n is even(qbn/2c)2 · q, if n is odd

(13)

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 19 / 34

General forms of recursion

A Haskell example

myExp q 0 = 1myExp q 1 = qmyExp q n| n ‘mod‘ 2 == 0 = h*h| n ‘mod‘ 2 == 1 = h*h*qwhere h = myExp q (n ‘div‘ 2)

where allows you to define a variable for internal use in thedefinition

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 20 / 34

General forms of recursion

Split-and-Conquer

This is a split-and-conquer algorithmeach recursive step halves the problemreaches base case in 2 log2 n steps.

2 log2 n << n − 1 (except for small n)

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 21 / 34

General forms of recursion

Fibonacci numbers

Fibonacci sequence

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, . . .

Each number is the sum of the two preceeding numbersHow do we write this in recursive form?For example

fib 1 = 1fib 2 = 1fib n = fib (n-1) + fib (n-2)

Each step requires two preceeding numbers

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 22 / 34

General forms of recursion

Fibonacci numbers

Fibonacci sequence

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, . . .

Each number is the sum of the two preceeding numbersHow do we write this in recursive form?For example

fib 1 = 1fib 2 = 1fib n = fib (n-1) + fib (n-2)

Each step requires two preceeding numbers

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 22 / 34

General forms of recursion

Efficiency

fib n = fib (n-1) + fib (n-2)fib (n-2) is calculated twice

once for fib (n-1) and once for fib n

fib (n-3) is calculated three timesonce for fib (n-2) and twice (!) for fib (n-1)

The compiler/interpreter may or may not optimisei.e. remember and reuse previous calculation

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 23 / 34

General forms of recursion

Efficiency

fib n = fib (n-1) + fib (n-2)fib (n-2) is calculated twice

once for fib (n-1) and once for fib n

fib (n-3) is calculated three timesonce for fib (n-2) and twice (!) for fib (n-1)

The compiler/interpreter may or may not optimisei.e. remember and reuse previous calculation

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 23 / 34

General forms of recursion

Efficiency

fib n = fib (n-1) + fib (n-2)fib (n-2) is calculated twice

once for fib (n-1) and once for fib n

fib (n-3) is calculated three timesonce for fib (n-2) and twice (!) for fib (n-1)

The compiler/interpreter may or may not optimisei.e. remember and reuse previous calculation

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 23 / 34

Error handling

Outline

1 ASCII Characters

2 Modular programming

3 Primitive recursion

4 General forms of recursion

5 Error handling

6 Program testing

7 Conclusion

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 24 / 34

Error handling

Erroneous callsFactorial

factorial (-2)What happens?

(−2)(−3)(−4)(−5) . . . (−∞)You never reach any base case

n! is undefined for n < 0factorial (-2) is an error

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 25 / 34

Error handling

Erroneous callsFactorial

factorial (-2)What happens?

(−2)(−3)(−4)(−5) . . . (−∞)You never reach any base case

n! is undefined for n < 0factorial (-2) is an error

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 25 / 34

Error handling

Erroneous callsFactorial

factorial (-2)What happens?

(−2)(−3)(−4)(−5) . . . (−∞)You never reach any base case

n! is undefined for n < 0factorial (-2) is an error

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 25 / 34

Error handling

Declaring an error

The error clause

fac :: Int -> Intfac n| n < 0 = error "Undefined for negative numbers"| n == 0 = 1| n > 0 = n * fac (n-1)

The error clausehalts the programissues the given error message

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 26 / 34

Program testing

Outline

1 ASCII Characters

2 Modular programming

3 Primitive recursion

4 General forms of recursion

5 Error handling

6 Program testing

7 Conclusion

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 27 / 34

Program testing

Is your program correct?

Mistakes are easy to makehow do you know that your program (function) is correct?

Two approaches1 Testing2 Mathematical proof

Which is most useful?

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 28 / 34

Program testing

Principles of Software TestingBlack and White Boxes

Test each function separatelystarting with the most fundamental ones

Test every conceivable variation and combinationBlack box testing

oblivious to the implementationWhite box testing

design test cases based on the implementation

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 29 / 34

Program testing

Black Box Testing

maxThree :: Int -> Int -> Int -> Int

Returns the largest of three integersWhich inputs do we have to test?

Three different numbers(small,middle,large); (small,large,middle); (large,middle,small); etc.Two equal + one smallerTwo equal + one largerThree equal

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 30 / 34

Program testing

Black Box Testing

maxThree :: Int -> Int -> Int -> Int

Returns the largest of three integersWhich inputs do we have to test?

Three different numbers(small,middle,large); (small,large,middle); (large,middle,small); etc.Two equal + one smallerTwo equal + one largerThree equal

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 30 / 34

Program testing

A sample function implementation

maxThree x y z| x > y && x > z = x| y > x && y > z = y| otherwise = z

Is it correct?

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 31 / 34

Program testing

White Box Testing

Remember principles from black box testing.... but also consider the guards

The two first look correct; look at the third... otherwise includes all cases with two equal variablesThese are the cases we need to focus on

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 32 / 34

Conclusion

Outline

1 ASCII Characters

2 Modular programming

3 Primitive recursion

4 General forms of recursion

5 Error handling

6 Program testing

7 Conclusion

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 33 / 34

Conclusion

Concluding remarks

Recursion is a fundamental method in function definitionsgo away and practice using it

(Pure) Functional languages do not have loopsrecursion is used insteadeven when loops are available, recursion may be easier to read

In two weeks, we will return to recursion on listsand recursion will be used in many later exercises

Dr Hans Georg Schaathun Recursion Autumn 2008 – Week 3 34 / 34

top related