Recursion COM1022 Functional Programming Techniques Professor Steve - - PowerPoint PPT Presentation

recursion
SMART_READER_LITE
LIVE PREVIEW

Recursion COM1022 Functional Programming Techniques Professor Steve - - PowerPoint PPT Presentation

Recursion COM1022 Functional Programming Techniques Professor Steve Schneider University of Surrey Autumn 2009 Week 10 Professor Steve Schneider Recursion Autumn 2009 Week 10 1 / 35 This session After this session, you should understand


slide-1
SLIDE 1

Recursion

COM1022 Functional Programming Techniques Professor Steve Schneider

University of Surrey

Autumn 2009 Week 10

Professor Steve Schneider Recursion Autumn 2009 Week 10 1 / 35

slide-2
SLIDE 2

This session

After this session, you should

understand the principle of recursion be able to use recursion over integers to solve simple problems

Reference

Thompson, Chapter 4

[based on slides by Dr Hans Georg Schaathun]

Professor Steve Schneider Recursion Autumn 2009 Week 10 2 / 35

slide-3
SLIDE 3

Modular programming

Outline

1

Modular programming

2

Primitive recursion

3

General forms of recursion

4

Iteration

5

Error handling

6

Conclusion

Professor Steve Schneider Recursion Autumn 2009 Week 10 3 / 35

slide-4
SLIDE 4

Modular programming

Software development

The key to problem solving

Split the task into smaller and manageable problems

Software development is the same

Each subproblem gives a function

Many subproblems apply to different tasks

Write the functions such that they can be reused

Professor Steve Schneider Recursion Autumn 2009 Week 10 4 / 35

slide-5
SLIDE 5

Modular programming

Planning the development

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

1

This question points to subproblems

2

Then move to the key functions – one at a time

3

Apply the same question to them This idea apply in a myriad of ways Todays main topic is a special case

known as recursion

Professor Steve Schneider Recursion Autumn 2009 Week 10 5 / 35

slide-6
SLIDE 6

Primitive recursion

Outline

1

Modular programming

2

Primitive recursion

3

General forms of recursion

4

Iteration

5

Error handling

6

Conclusion

Professor Steve Schneider Recursion Autumn 2009 Week 10 6 / 35

slide-7
SLIDE 7

Primitive recursion

A recursive definition

A recursive function is defined in terms of itself. Factorial: n! = 1 · 2 · 3 · . . . · n Recursive 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?

Professor Steve Schneider Recursion Autumn 2009 Week 10 7 / 35

slide-8
SLIDE 8

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 end

n, n − 1, n − 2, . . . , 1, 0, −1, . . . , −∞

Without the recursive case, everything would be explicit

  • ne line for every n (0, 1, 2, . . . , ∞)

Professor Steve Schneider Recursion Autumn 2009 Week 10 8 / 35

slide-9
SLIDE 9

Primitive recursion

Recursion in Haskell

Haskell supports recursive definitions. Two different styles: Pattern matching: factorial :: Int -> Int factorial 0 = 1 factorial n = n * factorial (n-1)

  • r by cases:

factorial :: Int -> Int factorial n | n == 0 = 1 | otherwise = n * factorial (n-1)

Professor Steve Schneider Recursion Autumn 2009 Week 10 9 / 35

slide-10
SLIDE 10

Primitive recursion

For example

factorial 4 = 4 · (factorial 3) = 4 · 3 · (factorial 2) = 4 · 3 · 2 · (factorial 1) = 4 · 3 · 2 · 1 · (factorial 0) = 4 · 3 · 2 · 1 · 1 = 24

Professor Steve Schneider Recursion Autumn 2009 Week 10 10 / 35

slide-11
SLIDE 11

Primitive recursion

Why recursion?

Fundamental principle in mathematics and in computer programming Used in all programming paradigms

you will see it in Java

Recursion tends to make it simple to

1

prove correctness

2

define and understand algorithms

It often makes computationally efficient algorithms

Professor Steve Schneider Recursion Autumn 2009 Week 10 11 / 35

slide-12
SLIDE 12

Primitive recursion

Primitive recursion

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

1

f 0 = ...

2

f n = ... f (n-1) ... The recursive case depends on

f (n-1) expressions independent of f

Professor Steve Schneider Recursion Autumn 2009 Week 10 12 / 35

slide-13
SLIDE 13

Primitive recursion

Integer square root

The integer square root of a number n is the greatest integer whose square is less than or equal to n. Examples intsqrt 15 = 3 intsqrt 16 = 4 Exercise: Define intsqrt using primitive recursion. intsqrt 0 = ??? handset question intsqrt n = ...(intsqrt (n-1))... If you know intsqrt (n-1) then how can that help you work out intsqrt n ?

Professor Steve Schneider Recursion Autumn 2009 Week 10 13 / 35

slide-14
SLIDE 14

Primitive recursion

Cuts and pieces

Exercise: How many pieces can the 2-d plane be separated into with n lines? pieces 0 = ??? handset question pieces n = ??? If you know pieces (n-1) then how can that help you work out pieces n ?

Professor Steve Schneider Recursion Autumn 2009 Week 10 14 / 35

slide-15
SLIDE 15

Primitive recursion

Summing a function

Exercise: Given a function f :: Int -> Int, how do I calculate Σn

i=1f(i) ?

sigma f 0 = ??? handset question sigma f n = ??? If you know sigma f (n-1) then how can that help you work out sigma f n ? Observe that sigma is a higher-order function. This means that it can take another function f as an argument. Question: What is the type of sigma ? handset question

Professor Steve Schneider Recursion Autumn 2009 Week 10 15 / 35

slide-16
SLIDE 16

General forms of recursion

Outline

1

Modular programming

2

Primitive recursion

3

General forms of recursion

4

Iteration

5

Error handling

6

Conclusion

Professor Steve Schneider Recursion Autumn 2009 Week 10 16 / 35

slide-17
SLIDE 17

General forms of recursion

Many forms of recursion

Sometimes the recursive case does not call n − 1 More generally: 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) In general we look for f on some ‘smaller’ arguments

Professor Steve Schneider Recursion Autumn 2009 Week 10 17 / 35

slide-18
SLIDE 18

General forms of recursion

Divisors

How many times can a factor p divide into a number m? For given p and m, want the largest n such that pn divides m. Examples powerdiv 2 8 = 3 powerdiv 3 8 = 0 powerdiv 3 18 = 2 powerdiv 3 1 = 0 powerdiv 2 1000 = 3 Define powerdiv p m in terms of powerdiv on ‘smaller’ arguments. What’s the base case? What’s the recursive case? [note that powerdiv p (m-1) does not help towards powerdiv p m]

Professor Steve Schneider Recursion Autumn 2009 Week 10 18 / 35

slide-19
SLIDE 19

General forms of recursion

Split-and-Conquer

qn = q · q · . . . · q (3) How do you compute this efficiently?

Primitive recursion can be used here: but n − 1 multiplications is quite expensive

q0 = 1, (4) q1 = q, (5) qn =

  • (q⌊n/2⌋)2, if n is even

(q⌊n/2⌋)2 · q, if n is odd (6)

Professor Steve Schneider Recursion Autumn 2009 Week 10 19 / 35

slide-20
SLIDE 20

General forms of recursion

A Haskell example

myExp q 0 = 1 myExp q 1 = q myExp q n | n ‘mod‘ 2 == 0 = h*h | n ‘mod‘ 2 == 1 = h*h*q where h = myExp q (n ‘div‘ 2) where allows you to define a variable for internal use in the definition

Professor Steve Schneider Recursion Autumn 2009 Week 10 20 / 35

slide-21
SLIDE 21

General forms of recursion

Split-and-Conquer

This is a split-and-conquer algorithm

each recursive step halves the problem reaches base case in 2 log2 n steps.

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

Professor Steve Schneider Recursion Autumn 2009 Week 10 21 / 35

slide-22
SLIDE 22

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 numbers How do we write this in recursive form? For example

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

Each step requires two preceeding numbers

Professor Steve Schneider Recursion Autumn 2009 Week 10 22 / 35

slide-23
SLIDE 23

General forms of recursion

Efficiency

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

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

fib (n-3) is calculated three times

  • nce for fib (n-2) and twice (!) for fib (n-1)

The compiler/interpreter may or may not optimise

i.e. remember and reuse previous calculation

Professor Steve Schneider Recursion Autumn 2009 Week 10 23 / 35

slide-24
SLIDE 24

Iteration

Outline

1

Modular programming

2

Primitive recursion

3

General forms of recursion

4

Iteration

5

Error handling

6

Conclusion

Professor Steve Schneider Recursion Autumn 2009 Week 10 24 / 35

slide-25
SLIDE 25

Iteration

Space considerations

Recursion can be expensive in terms of space. Each recursive call must keep track of the context it was called in, until the final computation once the base case is reached. Recall: factorial 4 = 4 · (factorial 3) = 4 · 3 · (factorial 2) = 4 · 3 · 2 · (factorial 1) = 4 · 3 · 2 · 1 · (factorial 0) = 4 · 3 · 2 · 1 · 1 = 24

Professor Steve Schneider Recursion Autumn 2009 Week 10 25 / 35

slide-26
SLIDE 26

Iteration

Iteration

If a recursive call has no surrounding context, then the space requirements will not grow. A recursive definition of this form is called an iterative definition. ??? But f n = f (n-1) is not much use ??? Generally more arguments are required: f m n = f (...m...n...) (n-1)

Professor Steve Schneider Recursion Autumn 2009 Week 10 26 / 35

slide-27
SLIDE 27

Iteration

Factorial revisited

partfact tot 0 = tot partfact tot n = partfact (tot * n) (n-1) factorial n = partfact 1 n factorial 4 = partfact 1 4 = partfact 4 3 = partfact 12 2 = partfact 24 1 = partfact 24 0 = 24

Professor Steve Schneider Recursion Autumn 2009 Week 10 27 / 35

slide-28
SLIDE 28

Iteration

Highest Common Factor

The highest common factor of m and n — the highest number that divides into both of them. Examples hcf 3 8 = 1 hcf 4 6 = 2 hcf 4 12 = 4 hcf 91 299 = 13 hcf 5 5 = 5 Question: Give an iterative definition of hcf m n: Base case ? Recursive call (on ‘smaller’ arguments) ? [think about which of the examples above are a base case — where the answer is immediate ?]

Professor Steve Schneider Recursion Autumn 2009 Week 10 28 / 35

slide-29
SLIDE 29

Iteration

hcf base case — worked example

Professor Steve Schneider Recursion Autumn 2009 Week 10 29 / 35

slide-30
SLIDE 30

Iteration

hcf inductive step — worked example

Professor Steve Schneider Recursion Autumn 2009 Week 10 30 / 35

slide-31
SLIDE 31

Error handling

Outline

1

Modular programming

2

Primitive recursion

3

General forms of recursion

4

Iteration

5

Error handling

6

Conclusion

Professor Steve Schneider Recursion Autumn 2009 Week 10 31 / 35

slide-32
SLIDE 32

Error handling

Erroneous calls

Factorial

factorial (-2) What happens?

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

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

Professor Steve Schneider Recursion Autumn 2009 Week 10 32 / 35

slide-33
SLIDE 33

Error handling

Declaring an error

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

halts the program issues the given error message

Professor Steve Schneider Recursion Autumn 2009 Week 10 33 / 35

slide-34
SLIDE 34

Conclusion

Outline

1

Modular programming

2

Primitive recursion

3

General forms of recursion

4

Iteration

5

Error handling

6

Conclusion

Professor Steve Schneider Recursion Autumn 2009 Week 10 34 / 35

slide-35
SLIDE 35

Conclusion

Concluding remarks

Recursion is a fundamental method in function definitions

go away and practice using it

(Pure) Functional languages do not have loops

recursion is used instead even when loops are available, recursion may be easier to read

We will later return to recursion on lists

and recursion will be used in many later exercises

Professor Steve Schneider Recursion Autumn 2009 Week 10 35 / 35