Lecture 1: Recursion and Induction

Lecture 1: Recursion and Induction
COMP11212
David Lester
2013
David Lester
Lecture 1
2013
1 / 23
Outline
1
Recursion and Induction over N
2
Recursive Data Structures
3
Operations on Lists
David Lester
Lecture 1
2013
2 / 23
Introduction
In this part of the course we will be concerned with recursive definitions, of
both functions and data structures, and inductive proofs.
David Lester
Lecture 1
2013
3 / 23
Recursion and Induction over N
A recursive definition of this can be expressed as:
x ˆ0
= 1
x ˆ(n + 1) = x × x ˆn
David Lester
Lecture 1
2013
4 / 23
Example
Example
How does the definition help us to evaluate 2ˆ4? In full this works
as follows:
2ˆ(3 + 1) = 2 × 2ˆ(2 + 1)
= 4 × 2ˆ(1 + 1)
= 8 × 2ˆ(0 + 1)
= 16 × 2ˆ0
= 16
David Lester
Lecture 1
2013
5 / 23
Important Observations
The important thing to notice is that there is a base case, and a recursive
case to the definition of exponentiation.
We can think of this as an unrolling operation from n down to 0, or
alternatively as a construction starting at 0 and stopping at n. We can
prove properties of exponentiation by first showing that the property is
true for 0 and then showing that if it is already true for a particular n then
it must also be true for n + 1.
David Lester
Lecture 1
2013
6 / 23
Example
Prove that if x > 0 then x ˆn > 0.
Proof
Base case We consider n = 0. Then x ˆ0 = 1 by definition,
and 1 > 0.
Inductive Case We will assume that the theorem is true for
some fixed natural number n. Thus x ˆn > 0; we
will refer to this as the inductive hypothesis.
Now x ˆ(n + 1) = x × x ˆn, from the definition ofˆ.
But x > 0, and by the induction hypothesis
x ˆn > 0, so multiplying two positive numbers
gives a positive result.
David Lester
Lecture 1
2013
7 / 23
Recursive Data Structures
We will use Haskell to express our recursive definitions.
David Lester
Lecture 1
2013
8 / 23
Recursive Data Structures
We will use Haskell to express our recursive definitions.
You are not expected to be able to program in this language, nor to
know its syntax.
David Lester
Lecture 1
2013
8 / 23
Recursive Data Structures
We will use Haskell to express our recursive definitions.
You are not expected to be able to program in this language, nor to
know its syntax.
You are expected to be able to read and interpret definitions.
David Lester
Lecture 1
2013
8 / 23
Recursive Data Structures
We will use Haskell to express our recursive definitions.
You are not expected to be able to program in this language, nor to
know its syntax.
You are expected to be able to read and interpret definitions.
If you wish to learn the language, I suggest getting hold of a copy of
hugs: “Haskell under gofer system”.
David Lester
Lecture 1
2013
8 / 23
Lists
Lists are somewhat like sets, but:
David Lester
Lecture 1
2013
9 / 23
Lists
Lists are somewhat like sets, but:
we can have repeated occurences, and
David Lester
Lecture 1
2013
9 / 23
Lists
Lists are somewhat like sets, but:
we can have repeated occurences, and
the order in which elements of the list appear, matters.
David Lester
Lecture 1
2013
9 / 23
Lists
Lists are somewhat like sets, but:
we can have repeated occurences, and
the order in which elements of the list appear, matters.
Thus [1, 1] 6= [1] and [1, 2] 6= [2, 1].
David Lester
Lecture 1
2013
9 / 23
In Haskell we have a number of ways to write lists.
Directly The list containing 1, 2, and 3 in that order can be written:
[1, 2, 3]
Similarly the list containing the characters ‘a’, ‘b’ and ‘c’ is
written:
[’a’, ’b’, ’c’]
We would normally write this list as a string: ”abc”.
David Lester
Lecture 1
2013
10 / 23
In Haskell we have a number of ways to write lists.
Directly The list containing 1, 2, and 3 in that order can be written:
[1, 2, 3]
Similarly the list containing the characters ‘a’, ‘b’ and ‘c’ is
written:
[’a’, ’b’, ’c’]
We would normally write this list as a string: ”abc”.
Iterations We can write sequences of integers as:
[0 . . . 10]
This is the list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]. There is
one other form of sequence that can be useful:
[0 . . .]
is the list of all natural numbers. Be prepared to hit ↑-C!
David Lester
Lecture 1
2013
10 / 23
Comprehensions These are very similar to set expressions, and are best
described by examples.
[x × x | x ← [1 . . . 10], even x]
Gives the list [4, 16, 36, 64, 100]
We should read the original expression as “the list of values
x × x, where x is drawn from the list [1 . . . 10], and x is even.
We can have more than one generator. The earlier
generators vary more slowly than later ones, and later
generators can depend on earlier ones.
[(x, y ) | x ← [0, 1, 2], y ← [4, 5]]
is [(0, 4), (0, 5), (1, 4), (1, 5), (2, 4), (2, 5)].
This is a cross product operation, on the lists.
David Lester
Lecture 1
2013
11 / 23
Append
Two lists can be “stuck together” by using the append operation ++. In
ascii, we write two + symbols next to one another.
[1, 2, 3] ++ [4, 5] = [1, 2, 3, 4, 5]
Note that the operation ++ is associative, and has an identity element [].
The ++ function is defined recursively as follows:
(++) :: [α] → [α] → [α]
[] ++ ys
= ys
(x : xs) ++ ys = x : (xs ++ ys)
David Lester
Lecture 1
2013
12 / 23
Length
The length function length, returns the length of a list. It is defined
recursively as:
length :: [α] → N
length []
= 0
length (x : xs) = 1 + length xs
David Lester
Lecture 1
2013
13 / 23
Head and Tail
The function head selects the first element of a list, tail returns the
remainder after the first element is removed. These are partial functions as
they do not always return. They are defined as follows:
head :: [α] → α
head (x : xs) = x
tail :: [α] → [α]
tail (x : xs) = xs
Notice that there is no pattern for either if the list is empty.
David Lester
Lecture 1
2013
14 / 23
Init and Last
At the other end of the list we have two functions init, and last, which
give the initial list less the last element, and the last element of a list.
They are defined recursively as:
init :: [α] → [α]
init [x]
= []
init (x : xs) = x : init xs
last :: [α] → α
last [x]
= x
last (x : xs) = last xs
Notice that these functions – like head and tail – are partial functions,
as they have no value when the empty list is used as their argument.
David Lester
Lecture 1
2013
15 / 23
Map
We can apply a function f to every element of a list xs using the map
function.
map :: (α → β) → [α] → [β]
map f []
= []
map f (x : xs) = f x : map f xs
An alternative way to express this using comprehensions is as
[f x | x ← xs]
David Lester
Lecture 1
2013
16 / 23
Filter
We can select elements of a list xs with a predicate (or boolean fuction) p
using the filter function.
filter :: (α → B) → [α] → [α]
filter p []
= []
filter p (x : xs) = if p x then x : filter p xs else filter p xs
An alternative way to express this using comprehensions is as
[x | x ← xs, p x]
David Lester
Lecture 1
2013
17 / 23
Take and Drop
The function take takes as arguments a non-negative integer n and a list
xs, and returns the first n elements of a list; if n is greater than the length
of the list xs, then the returned list xs. The function drop satisfies the
equation
∀n, xs. xs = take n xs ++ drop n xs
and so “drops” the first n elements of a list.
David Lester
Lecture 1
2013
18 / 23
Take and Drop examples
Example
take 3 [1 . . .] = [1, 2, 3]
Note that taking a finite initial part of an infinite list terminates.
Example
take 3 [1, 2] = [1, 2]
Note that there are only two elements in the list.
David Lester
Lecture 1
2013
19 / 23
Take and Drop definitions
The functions take and drop are recursively defined as:
take, drop :: N → [α] → [α]
take 0 xs
= []
take (n + 1) []
= []
take (n + 1) (x : xs) = x : take n xs
drop 0 xs
= xs
drop (n + 1) []
= []
drop (n + 1) (x : xs) = drop n xs
There is also a function splitAt, which returns a pair of lists satisfying:
splitAt n xs = (take n xs, drop n xs)
David Lester
Lecture 1
2013
20 / 23
Reading Guide
Bird and Wadler, “Introduction to Functional Programming”, Prentice
Hall 1992.
David Lester
Lecture 1
2013
21 / 23
Lecture Summary
We have looked at induction over the natural numbers and list functions in
Haskell
David Lester
Lecture 1
2013
22 / 23
Next Lecture
We will look at structural induction over lists.
David Lester
Lecture 1
2013
23 / 23