80 likes | 372 Vues
Functional Programming Lecture 14 - induction on algebraic data types and lazy evaluation. We can reason, using induction, over any inductively defined set. That includes algebraic data types. Proof by induction on Trees. data Tree a = Nil | Node a (Tree a) (Tree a)
E N D
Functional ProgrammingLecture 14 - induction on algebraic data typesandlazy evaluation
We can reason, using induction, over any inductively defined set. That includes algebraic data types.
Proof by induction on Trees data Tree a = Nil | Node a (Tree a) (Tree a) To prove a property P of Tree a, we use the Principle of (Structural) Induction: base case: prove P(Nil), ind. case: Prove P(Node x t1 t2), assuming P(t1) and P(t2).
size Nil = 0 s.0 size (Node x t1 t2) = 1+size t1 + size t2 s.1 depth Nil = 0 d.0 depth (Node x t1 t2) =1+max (depth t1) (depth t2) d.1 Theorem: For all finite trees. size t < 2depth t. Proof: By induction on t. Base Case: Prove (size Nil) < 2depth Nil. l.h.s. size Nil = 0 by s.0 0 < (20 = 1) by d.0, arith. Ind Case: Assume size t1 < 2depth t1, size t2 < 2depth t2. Show size (Node x t1 t2) < 2depth (Node x t1 t2). size (Node x t1 t2) = 1+size t1 + size t2. by s.1 Case depth t1>depth t2: 2depth (Node x t1 t2) = 21 + depth t1 by d.1
1 + size t1 + size t2 << 1+ 2depth t1 + 2depth t2 by ass. and << << 1 + 2depth t1 + 2depth t1 by depth t1>=depth t2 << 1 + 21+ depth t1 by 2n+2n=21+n < < 1 + 2depth (Node x t1 t2) by d.1 < 2depth (Node x t1 t2) by arith QED Note: if x<y and u<v, then x+u << y+v, i.e. x+u < y+v-1 (e.g. 4<5 and 6<7, so 10<<12 and 10<11)
Lazy evaluation Recall that expressions are evaluated. But does the order matter? f x y = x + y f (9-3) (f 34 3) => f 6 37 => 43 or => (9-3) + (f 34 3) => 6 + 37 When do we evaluate arguments fully? f x y = x + x f (9-3) (f 34 3) => f 6 37 => 6 + 6 => 12 or => (9-3) + (9-3) => 6 + 6 The second is more efficient because it only evaluates arguments when it needs them. Moreover, operands can be shared. . + . . + . (9-3) (9-3) (9-3)
Lazy evaluation ensures that an argument is never evaluated more than once. Lazy evaluation - arguments to functions are only evaluated when it is necessary for evaluation to continue, - an argument is not necessarily evaluated fully; only the parts that are needed are examined, - an argument is evaluated at most only once. Evaluation order - from the outside in, and then left to right. E.g. f (h e1) (g e2 17) => (h e1) + (g e2 17) => ...
Lazy evaluation means that we can have infinite data structures! Infinite lists: [3 ..] = [3,4,5,6,7,...] [3,5 ..] = [3,5,7,9,…] ones = 1:ones = [1,1,1,1, …] powers :: Int->[Int] powers n = [n^x| x <- [0..]] We can evaluate head [3 ..] => 3 firsttwo (x:y:zs) = x + y firsttwo [3 .. ] => 3+4 => 7 Note that induction is only defined over finite lists and data structures.