Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.
-
Upload
august-mills -
Category
Documents
-
view
214 -
download
0
Transcript of Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.
![Page 1: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/1.jpg)
Function Definition by Cases and Recursion
Lecture 2,
Programmeringsteknik del A
![Page 2: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/2.jpg)
Definitions Revisited
A definition
double :: Int -> Int
double x = 2*x
•makes a true statement about the function defined,
(whatever x is, then double x and 2*x are equal)
•gives a way of computing calls of the function.
![Page 3: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/3.jpg)
Quiz
Given the definition
x :: Int
x*x = 4
Is x equal to 2?
![Page 4: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/4.jpg)
Quiz
Given the definition
x :: Int
x*x = 4
Is x equal to 2?
NO! This is not a valid Haskell definition.
It makes a true statement about x, but it does not
give a way of computing x.
![Page 5: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/5.jpg)
Computing with Definitions
A function call is computed by •replacing the call with a copy of the right hand side, •with the argument names replaced by the actual arguments.
double :: Int -> Intdouble x = 2*x
double 8 2*8
16
![Page 6: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/6.jpg)
Evaluation Order
double (3+5)
There may be more than one way to evaluate an expression:
double 8
2*(3+5)
2*8 16
You can use any order of evaluation; they all give the same result. Haskell chooses a suitable one; you don’t need to know which.
![Page 7: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/7.jpg)
Sharing Evaluation
double :: Int -> Intdouble x = x+x
double (3*5)
double 15
15+15
(3*5)+(3*5)
15+(3*5)
30
Is it more work toevaluate the expression
in this order?
![Page 8: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/8.jpg)
Sharing Evaluation
double :: Int -> Intdouble x = x+x
double (3*5)
double 15
15+15
(3*5)+(3*5)
30
NO!Haskell `remembers´that both occurrencesof 3*5 are really thesame, and evaluates
both in one step.
![Page 9: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/9.jpg)
Definition by Cases
Often programs must make decisions, and compute different results in different cases.
Example: Define max x y to return the maximum of its
two arguments.
If x <= y, then max x y should be y.
If x>y, then max x y should be x.
![Page 10: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/10.jpg)
The Type of Booleans
We make a decision by asking: does a condition hold?
(e.g. Does x<=y hold?)
A condition is either true or false: this is a piece of data, a value!
We introduce a new basic type with two values, named after the mathematician George Boole:
True, False :: Bool
Constants begin with a capital letter.
![Page 11: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/11.jpg)
Some Operators Producing Booleans
2 <= 3 True
2 > 3 False
2 < 3 True
2 == 3 False
2 /= 3 True
Note two equals signs, toavoid confusion with a
definition.
Not equals.
![Page 12: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/12.jpg)
Functions Returning Booleans
Functions can return boolean results (or any other type).
Example:
inOrder :: Int -> Int -> Int -> Bool
inOrder x y z = x <= y && y <= z
a && b is True ifboth a and b are True.
![Page 13: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/13.jpg)
Using Booleans to Define Functions by Cases
max :: Int -> Int -> Int
max x y | x <= y = y
max x y | x > y = x
OR
max :: Int -> Int -> Int
max x y | x <= y = y
| x > y = x
A guard: an expression oftype Bool.
If the guard is True,the equation applies.
![Page 14: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/14.jpg)
Evaluation with GuardsTo evaluate a function call,
•evaluate each guard in turn until one is True,
•replace the call with a copy of the right hand side following the true guard.
max :: Int -> Int -> Intmax x y | x <= y = y | x > y = x
max 4 2 ?? 4 <= 2 False
?? 4 > 2 True
4
![Page 15: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/15.jpg)
Is max Correct?
Programming is a very error prone process; programs are rarely correct `first time´.
A large part of the cost of software development goes on finding and correcting errors.
It is essential to test software: try it on a variety of inputs and see if the output is correct.
![Page 16: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/16.jpg)
Choosing Test Data
Test data should be chosen carefully, to include `difficult´ cases that might induce a failure.
The max function should be tested at least with x<y, x==y, x>y, and probably combinations of positive and negative arguments.
Choose enough test examples so that every case in your program is used at least once!
![Page 17: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/17.jpg)
Dijkstra on Testing
”Testing can never demonstrate the absence of errors in software, only their presence”
Edsger W. Dijkstra
(but it is very good at the latter).
![Page 18: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/18.jpg)
Specifications
What do we mean by `max is correct´?
A specification formulates properties we expect max to satisfy.
Property: x <= max x y
Property: y <= max x y
![Page 19: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/19.jpg)
Why Formulate Specifications?
•Helps us clarify what max is supposed to do.
•Can help in testing.
•Enables us to prove programs correct.
![Page 20: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/20.jpg)
Specifications and Testing
We can define function to check whether properties hold.
prop_Max :: Int -> Int -> Bool
prop_Max x y = x <= max x y && y <= max x y
If prop_Max always returns True, then the specification is satisfied.
We can test max on many inputs without needing to inspect the results by hand.
![Page 21: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/21.jpg)
Testing with QuickCheck
QuickCheck is a tool to help you test your programs.
Main> quickCheck prop_Max
OK, passed 100 tests
quickCheck generates random values to test your property thoroughly.
![Page 22: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/22.jpg)
Testing with QuickCheck (2)
What if we make a mistake?
max x y | x <= y = x
| x > y = y
Main> quickCheck prop_Max
Falsifiable, after 0 tests
1
0
![Page 23: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/23.jpg)
Specifications and Proofs
From the definition of max:
x <= y ==> max x y = y
x > y ==> max x y = x
Theorem: x <= max x y
Proof: Consider two cases:
Case x <= y: y = max x y, so x <= max x y.
Case x > y: max x y = x and x <= x, so x <= max x y.
![Page 24: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/24.jpg)
Formal Methods
Proofs are costly and also error-prone, but can guarantee correctness.
Thorough testing is the most common method today.
Customers for safety critical software demand proofs today.
Proofs of correctness will play a growing role, thanks to
•automatic tools to help with proving,
•demand for better quality software.
![Page 25: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/25.jpg)
Quiz
Define
•abs x to return the absolute value of x (e.g. abs 2 = 2, abs (-3) = 3.
•sign x to return 1 if x is positive, and -1 if x is negative.
State (and prove?) a property relating abs and sign.
![Page 26: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/26.jpg)
Quiz Answer
abs x | x <= 0 = -x
| x > 0 = x
sign x | x < 0 = -1
| x > 0 = 1
| x == 0 = 0
Property: x == sign x * abs x
Did you consider this case?This can also be written
sign 0 = 0
![Page 27: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/27.jpg)
Recursion
Problem: define fac :: Int -> Int
fac n = 1 * 2 * … * n
What if we already know the value of fac (n-1)?
Then fac n = 1 * 2 * … * (n-1) * n
= fac (n-1) * n
![Page 28: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/28.jpg)
A Table of Factorials
n fac n
0 1
1 1
2 2
3 6
4 24
...
Must start somewhere:we know that fac 0 = 1.
So fac 1 = 1 * 1.
So fac 2 = 1 * 2.
So fac 3 = 2 * 3.
![Page 29: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/29.jpg)
A Recursive Definition of Factorial
fac :: Int -> Int
fac 0 = 1
fac n | n > 0 = fac (n-1) * n
Base case.
Recursive case.
![Page 30: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/30.jpg)
Evaluating Factorials
fac :: Int -> Int
fac 0 = 1
fac n | n > 0 = fac (n-1) * n
fac 4 ?? 4 == 0 False
?? 4 > 0 True
fac (4-1) * 4
fac 3 * 4
fac 2 * 3 * 4
fac 1 * 2 * 3 * 4
fac 0 * 1 * 2 * 3 * 4
1 * 1 * 2 * 3 * 4
24
![Page 31: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/31.jpg)
There is No Magic!
What if we define
fac :: Int -> Int
fac n = div (fac (n+1)) (n+1) ?
fac 4 div (fac 5) 5
div (div (fac 6) 6) 5
div (div (div (fac 7) 7) 6) 5
...
A true statement.
Not a usefuldefinition.
![Page 32: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/32.jpg)
Primitive Recursion
Define
•f n in terms of f (n-1), for n > 0.
•f 0 separately.
What if I already know the value of f (n-1)?
Can I compute f n from it?
![Page 33: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/33.jpg)
Quiz
Define a function power so that
power x n == x * x * … * x
n times
(Of course, power x n == x^n, but you should define power without using ^).
![Page 34: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/34.jpg)
Quiz
Define a function power so that
power x n == x * x * … * x
n times
power x 0 = 1
power x n | n > 0 = power x (n-1) * x
Don’t forget the base case!
Since this equals(x * x * … * x) * x
n-1 times
![Page 35: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/35.jpg)
General Recursion
What if I know the values of f x for all x less than n?
Can I compute f n from them?
Example
x^(2*n) == (x*x)^n
x^(2*n+1) == (x*x)^n * x
![Page 36: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/36.jpg)
Power Using General Recursion
power :: Int -> Int -> Int
power x 0 = 1
power x n
| n `mod` 2 == 0 = power (x*x) (n `div` 2)
| n `mod` 2 == 1 = power (x*x) (n `div` 2) * x
Base case is still needed.
Two recursive cases.
Why might this definition of power be preferred?
![Page 37: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/37.jpg)
Comparing the Versions
First Version
power 3 5
power 3 4 * 3
power 3 3 * 3 * 3
power 3 2 * 3 * 3 * 3
power 3 1 * 3 * 3 * 3 * 3
power 3 0 * 3 * 3 * 3 * 3 * 3
1 * 3 * 3 * 3 * 3 * 3
243
Second Version
power 3 5
power 9 2 * 3
power 81 1 * 3
power 81 0 * 81 * 3
1 * 81 * 3
243
6 function calls, 5 multiplications.
4 function calls,4 multiplications.
![Page 38: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/38.jpg)
A More Difficult Example
Define prime :: Int -> Bool, so that prime n is True if n is a prime number.
What if we know whether (n-1) is prime?
What if we know whether each smaller number is prime?
NO HELP!
![Page 39: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/39.jpg)
Generalise the Problem!
n is prime means No k in the range 2<=k<ndivides n.
GeneralisationReplace 2 by a variable.
Define
factors m n == True if Some k in the range m<=k<ndivides n.
So prime n = not (factors 2 n)
not x is True if x is False,and vice versa.
![Page 40: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/40.jpg)
Recursive Decomposition
Problem: Does any k in the range m<=k<n divide n?
What if we know whether any k in a smaller range divides n?
Some k in the range m<=k<n divides n
if m divides n,
or some k in the range m+1<=k<n divides n.
![Page 41: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/41.jpg)
Recursive Solution
factors :: Int -> Int -> Bool
factors m n
| m == n = False
| m < n = divides m n || factors (m+1) n
divides :: Int -> Int -> Bool
divides m n = n `mod` m == 0
There is no k in therange n<=k<n.
x || y is True if x is True or y is True.
![Page 42: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/42.jpg)
What is Getting Smaller?
The range m<=k<n contains n-m elements. Call this the problem size.
factors m n
| m == n = False
| m < n = divides m n || factors (m+1) n
Base case: n-m == 0
Recursive case: n-(m+1) == (n-m)-1
The problem size gets smaller in each call, until it reaches zero. So recursion terminates.
![Page 43: Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.](https://reader035.fdocuments.us/reader035/viewer/2022070415/5697bff41a28abf838cbd249/html5/thumbnails/43.jpg)
Lessons
•Recursion lets us decompose a problem into smaller subproblems of the same kind -- a powerful problem solving tool in any programming language!
•A more general problem may be easier to solve recursively than a `simpler´ one, because the recursive calls can do more.
•To ensure termination, define a `problem size´ which must be greater than zero in the recursive cases, and decreases by at least one in each recursive call.