Lecture 13 CS 1813 Discrete Mathematics Induction Induction Induction 1
Concatenating Sequences (++) :: [a] -> [a] -> [a] (x: xs) ++ ys = x: (xs ++ ys) (++).: [ ] ++ ys = ys (++).[] Proposition P(n) (universe of discourse: n N ) length xs = n length(xs ++ ys) = length xs + length ys P(0): length xs = 0 length(xs++ys) = length xs + length ys length(xs ++ ys) = length([ ] ++ ys) len 0 [ ] = length ys (++).[] = 0 + length ys 2 nd -grade arithmetic = length xs + length ys hypothesis of implication Next, prove P(n) P(n+1) next slide 2
Concatenating Sequences the inductive case P(n+1): length xs = n+1 length(xs++ys) = (length xs) + (length ys) length(xs++ys) = length((z:zs) ++ ys) xs = (z: zs) {see note} = length(z: (zs ++ ys)) (++).: = 1 + length(zs ++ ys) (length).: = 1 + length zs + length ys P(n), since length zs = n = 1 + n + length ys (length zs) = n {see note} = n + 1 + length ys +comm = length xs + length ys hypothesis in P(n+1) Note: z. zs. (xs = (z: zs)) ((length zs) = n) (:len) corollary 3
Proved: P(0) Concatenating Sequences applying the principle of induction Proved: P(n) P(n+1) Conclude n N. P(n) by the principle of induction P(n): length xs = n length(xs ++ ys) = length xs + length ys qed 4
Concatenating a List of Sequences the big ++ concat :: [[a]] -> [a] concat(xs: xss) = xs ++ concat xss concat[ ] = [ ] (concat).: (concat).[] Theorem: n N. P(n) where P(n) is defined as follows: P(n) ( k {1, 2, n}. length(xs k ) N ) length(concat [xs 1, xs 2, xs n ]) = sum[length xs 1, length xs 2, length xs n ] List Comprehension like set comprehension, but for sequences [sequence-element generator, optional-constraint] [x - 2 x <- [12, 9, 27, 19, 13]] = [10, 7, 25, 17, 11] [x x <- [12, 9, 27, 19, 13], x < 15] = [12, 9, 13] [x + 3 x <- [12, 9, 27, 19, 13], x < 15] = [15, 12, 16] Proof Induction on n All this stuff is starting to look alike, isn t it? 5
shuffle shuffle :: [a] -> [a] -> [a] Examples shuffle [1, 2, 3, 4, 5] [6, 7, 8, 9, 10] = [1, 6, 2, 7, 3, 8, 4, 9, 5, 10] shuffle [1, 2, 3, 4, 5] [6, 7, 8] = [1, 6, 2, 7, 3, 8, 4, 5] shuffle [1, 2, 3, 4] [6, 7, 8, 9, 10] = [1, 6, 2, 7, 3, 8, 4, 9, 10] Pattern of computation shuffle [x 1, x 2, x n ] [y 1, y 2, y n ] = [x 1, y 1, x 2, y 2, x n, y n ] Note: extra elements in either sequence appended to the end Definition shuffle (x: xs) (y: ys) = [x, y] ++ shuffle xs ys shuffle [ ] ys = shuffle xs [ ] = ys xs 6
shuffle :: [a] -> [a] -> [a] shuffle Works shuffle (x: xs) (y: ys) = [x, y] ++ shuffle xs ys shuffle [ ] ys = ys (shf).[] L shuffle xs [ ] = xs (shf).[] R Theorem (shuffle works) n N.P(n) where P(n) shuffle [x 1, x 2, x n ] [y 1, y 2, y n ] = [x 1, y 1, x 2, y 2, x n,y n ] P(0) = shuffle [ ] [ ] = [ ] Why? Because (shf).[] L That s why! P(n+1) shuffle [x 1, x 2, x n+1 ] [y 1, y 2, y n+1 ]=[x 1, y 1, x 2, y 2, x n+1, y n+1 ] Proof of P(n+1) shuffle [x 1, x 2, x n+1 ] [y 1, y 2, y n+1 ] = shuffle (x 1 : [x 2, x 3, x n+1 ] ) (y 1 : [y 2, y 3, y n+1 ] ) (: ) (twice) = [x 1, y 1 ] ++ shuffle [x 2, x 3, x n+1 ] [y 2, y 3, y n+1 ] (shf).: = [x 1, y 1 ] ++ [x 2, y 2, x 3, y 3, x n+1, y n+1 ] P(n) = x 1 : (y 1 : [x 2, y 2, x 3, y 3, x n+1,y n+1 ] ) (++).: (twice) = [x 1, y 1, x 2, y 2, x n+1,y n+1 ] (: ) (twice) (shf).: 7
Indexing (!!) (!!):: [a] -> Int -> a (x: xs)!! 0 = x (!!).0 (x: xs)!! (n+1) = xs!! n (!!).n+1 Note: n N N = {0, 1, 2, } Pattern of computation [x 0, x 1, x 2, ]!! k = x k What do the (!!)-equations say about the following formula? [ ]!! 0 How about this formula? [ ]!! k How about these? (x: xs)!! (-1) xs!! (-1) 8
shuffle Works more formally shuffle (x: xs) (y: ys) = [x, y] ++ shuffle xs ys (shf).: Theorem (shuffle works) n N.P(n) where P(n) ( ((length xs) > n) ((length ys) > n) ) ( k, 0 k n. (((shuffle xs ys)!! (2*k)) = (xs!! k)) (((shuffle xs ys)!! (2*k + 1)) = (ys!! k)) ) P(0) ( ((length xs) > 0) ((length ys) > 0) ) ( k, 0 k 0. (((shuffle xs ys)!! (2*k)) = (xs!! k)) (((shuffle xs ys)!! (2*k + 1)) = (ys!! k)) ) = ( ((length xs) > 0) ((length ys) > 0) ) ( (((shuffle xs ys)!! 0) = (xs!! 0)) (((shuffle xs ys)!! 1) = (ys!! 0)) ) {finite -universe} = ( ( x. ws. xs = (x: ws)) ( y. zs. ys = (y: zs)) ) ( (((shuffle (x: ws) (y: zs))!! 0) = ((x: ws)!! 0)) (((shuffle (x: ws) (y: zs))!! 1) = ((y: zs)!! 0)) ) {(:), len 0 [ ], arith} = ( ( x. ws. xs = (x: ws)) ( y. zs. ys = (y: zs)) ) ( ((([x, y] ++ shuffle ws zs)!! 0) = ((x: ws)!! 0)) ((([x, y] ++ shuffle ws zs)!! 1) = ((y: zs)!! 0)) ) {(shf).:} = ( ( x. ws. xs = (x: ws)) ( y. zs. ys = (y: zs)) ) ( (x = x ) (y = y) ) { (++).:,, (!!).n+1, (!!).0} = True {= reflexive, id, Thm: (a True) = True } end of base case 9
shuffle Works more formally inductive case P(n+1) ( ((length xs) > n+1) ((length ys) > n+1) ) ( k, 0 k n+1. (((shuffle xs ys)!! (2*k)) = (xs!! k)) (((shuffle xs ys)!! (2*k + 1)) = (ys!! k)) ) = ( ( x. ws.xs=(x:ws) ((length ws) > n) ) ( y. zs.ys=(y:zs) ((length zs) > n)) ) ( k, 0 k n+1. (((shuffle xs ys)!! (2*k)) = (xs!! k)) (((shuffle xs ys)!! (2*k + 1)) = (ys!! k)) ) {len 0 [ ], } = ( ( x. ws.xs=(x:ws) ((length ws) > n) ) ( y. zs.ys=(y:zs) ((length zs) > n)) ) (( k, 0 k n.( (((shuffle xs ys)!! (2*k)) = (xs!! k)) (((shuffle xs ys)!! (2*k + 1)) = (ys!! k)) ) (((shuffle (x:ws) (y:zs))!!(2*(n+1))) = ((x:ws)!!(n+1))) (((shuffle (x:ws) (y:zs))!!(2*(n+1)+1)) = ((y:zs)!!(n+1))) ) {subst, finite -univ} = ( ( x. ws.xs=(x: ws) ((length ws) > n)) ( y. zs.ys=(y: zs) ((length zs) > n))) ( k, 0 k n.( (((shuffle xs ys)!! (2*k)) = (xs!! k)) (((shuffle xs ys)!! (2*k + 1)) = (ys!! k)) ) (((shuffle ws zs)!!(2*n)) = (ws!!n)) (((shuffle ws zs)!!(2*n+1)) = (zs!!n)) ) {(shf).:, (++).:,, (!!).n+1} = ( ( x. ws.xs=(x: ws) ((length ws) > n)) ( y. zs.ys=(y: zs) ((length zs) > n))) (True True True) {P(n)} = True { id, Thm: (a True) = True} qed 10
End of Lecture 11