260 likes | 365 Views
Lecture #11, Nov. 4, 2002. Todays Topics Using Calculation to prove 2 functions are equal An example from class drawPic Laws about Monads Laws about sequence Using Calculation to improve functions An example from the first Homework assignment Read Chapter 11 - Proofs by induction
E N D
Lecture #11, Nov. 4, 2002 • Todays Topics • Using Calculation to prove 2 functions are equal • An example from class drawPic • Laws about Monads • Laws about sequence • Using Calculation to improve functions • An example from the first Homework assignment • Read Chapter 11 - Proofs by induction • Read Chapter 12 – Qualified types
Proof from Class drawPic :: Window -> Picture -> IO () drawPic w (Region c r) = drawReg w (c,r) drawPic w (p1 `Over` p2) = do { drawPic w p2 ; drawPic w p1 } drawPic w EmptyPic = return () flattenPict :: Picture -> [(Color,Region)] flattenPict EmptyPic = [] flattenPict (Region c r) = [(c,r)] flattenPict (p1 `Over` p2) = flattenPict p2 ++ flattenPict p1 draw2 w p = sequence (map (drawReg w) (flattenPict p))
We would like to Prove drawPict w p = draw2 w p • We can draw a picture OR • We can flatten a picture, then draw each of the regions in the order they appear in the flattened list. • This is important, because for some applications we want to maintain the list of regions for other reasons. • Recall the structure of a picture: data Picture = Region Color Region | Picture `Over` Picture | EmptyPic
Structure of the proof • To Prove : drawPic w p = draw2 w p • Prove 3 cases • case 1) p = EmptyPic prove:drawPic w EmptyPic = draw2 w EmptyPic • case 2) p = (Region c r) prove:drawPic w (Region c r) = draw2 w (Region c r) • case 3) p = (p1 `Over` p2) assume: a) drawPic w p1 = draw2 w p1 b) drawPic w p2 = draw2 w p2 prove:drawPic w (p1 `Over` p2) = draw2 w (p1 `Over` p2)
First a few laws • Laws about do and return (we saw these when we first studied monads) Monad1: do { a <- x; return a } = x Monad2: do { x <- return y; e } = e[y/x] Monad3: do { a <- do { b <- e; c}; d } = do { b <- e; a <- c; d } provided b not in FreeVars(d) Monad4: do { x<- a; b} = do {a; b} provided x not in FreeVars(b)
Draw2 uses sequence • Definition sequence :: [ IO () ] -> IO () S1: sequence [] = return () S2: sequence (x:xs) = do { x; sequence xs } • Lemmas Lemma 1: sequence [ x ] = x Lemma 2: sequence(a ++ b) = do {sequence a; sequence b} Lemma 3: map f x ++ map f y = map f (x ++ y)
Proof Lemma1 Lemma 1: sequence [ x ] = x sequence [ x ] = By def of [ x ] syntax sequence (x : []) = by def of sequence rule s2 do { x; sequence [] } = by def of sequence rule S1 do { x; return () } = by Monad4 backwards do { a <- x; return () } = Since a has type (), and () is unique do { a <- x; return a } = by Monad1 x
Lemma 2: sequence(a ++ b) = do {sequence a; sequence b} P{a} = sequence(a ++ b) = do {sequence a; sequence b} Proof by induction over the structure of a Base Case - Prove: sequence([] ++ b) = do {sequence []; sequence b} sequence([] ++ b) = by def of ++ sequence(b) = by Monad2 (backwards) do { x <- return (); sequence b } = by def sequence do { x <- sequence []; sequence b } = Monad4 do {sequence []; sequence b }
Induction Step • Assume: sequence(xs ++ b) = do {sequence xs; sequence b} • Prove: sequence((x:xs) ++ b) = do {sequence (x:xs); sequence b} sequence((x:xs) ++ b) = by def of ++ sequence( x : (xs ++ b)) = by def of sequence do { x; sequence (xs ++ b) } = by IH do { x; do {sequence xs; sequence b} } = by Monad3 do { do {x; sequence xs}; sequence b } = def of sequence do { sequence (x:xs); sequence b }
Back to the main proof • To Prove : drawPic w p = draw2 w p • Prove 3 cases • case 1) p = EmptyPic prove:drawPic w EmptyPic = draw2 w EmptyPic • case 2) p = (Region c r) prove:drawPic w (Region c r) = draw2 w (Region c r) • case 3) p = (p1 `Over` p2) assume: a) drawPic w p1 = draw2 w p1 b) drawPic w p2 = draw2 w p2 prove:drawPic w (p1 `Over` p2) = draw2 w (p1 `Over` p2)
case 1. p = EmptyPic drawPic w EmptyPic = draw2 w EmptyPic drawPic w EmptyPic = by def drawPict return () = by def sequence sequence [] = by def map sequence (map (drawReg w) []) = by def flattenPict sequence (map (drawReg w) (flattenPict EmptyPic)) = by def draw2 draw2 w EmptyPic
case 2. p = (Region c r) drawPic w (Region c r) = draw2 w (Region c r) drawPic w (Region c r) = by def drawPic drawReg w (c,r) = by Lemma1 sequence [ drawReg w (c,r) ] by def of map sequence (map (drawRegion w) [(c,r)]) by def flattenPict sequence (map (drawRegion w) (flattenPict (Region c r))) by def draw2 draw2 w (Region c r)
case 3. p = (a `Over` b) assume: a) drawPic w a = draw2 w a b) drawPic w b = draw2 w b prove: drawPic w (a `Over` b) = draw2 w (a `Over` b) drawPic w (a `Over` b) = by def drawPic do { drawPic w b; drawPic w a } = by IH do { draw2 w b; draw2 w a } = by def draw2 do { sequence (map (drawReg w) (flattenPict b)); sequence (map (drawReg w) (flattenPict a)) } =
Case 3. continued = by Lemma2 sequence ( (map (drawReg w) (flattenPict b)) ++ (map (drawReg w) (flattenPict a)) ) = by Lemma3 sequence (map (drawReg w) (flattenPict b ++ flattenPict a)) = def of flattenPict sequence (map (drawReg w) (flattenPict (a `Over` b))) = by def of draw2 draw2 (a `Over` b)
Ex2. Recall String to Integer • A function which converts a string of digits into an Int. Uses the function which ord which takes a Char as input and returns its ascii code ord ‘1’ --> 49 • Follows the "pipeline" analysis "167" --> ['1','6','7'] --> [49,54,55] --> [1,6,7] --> [(1,100),(6,10),(7,1)] --> [100, 60, 7] --> 167
String to Int (cont) • Then str2int is an easy composition str2int :: String -> Int str2int = sum . map (uncurry (*)) . explist . map (\ z -> z -(ord '0')) . map ord • The Key is the function explist explist [5,3,4] --> [(5,100),(3,10),(4,1)]
Key Function Explist • Useful intermediates reverse [1,10,100] [1,10,100] --> [100,10,1] zip [3,4] [100, 10, 1] --> [(3,100), (4,10)] • Definition explist zs = zip zs [ power 10 x | x <- reverse [0 .. n-1] ] where n = length zs
Another explist (we use this one in the improvement) explist = fst . foldr g ([],1) where z `g` (zs,n) = ((z,n) : zs, n * 10) • Suppose we start with [5,3,2] • Folding g leaves • 5 `g` (3 `g` (2 `g` ([],1))) • 5 `g` (3 `g` ((2,1):[],10)) • 5 `g` (3 `g` ([(2,1)],10)) • 5 `g` ((3,10):[(2,1)],100) • 5 `g` ([(3,10),(2,1)],100) • ([(5,100),(3,10),(2,1)],1000)
Using theory to improve functions Given the definitions: sum: sum = foldr (+) 0 uncurry: uncurry f (x,y) = f x y and the laws: map1: map f . map g = map (f . g) lambda1: (\ x -> e) . f = (\ x -> e[(f x)/x]) lambda2: f . (\ x -> e) = (\ x -> f e) mapfoldr: foldr c e . map f = (let d x y = c (f x) y in foldr d e) Improve the definition of str2int
Improvement 1 str2int = sum . map (uncurry (*)) . explist . map (\ z -> z -(ord '0')) . map ord • by map1 str2int = sum . map (uncurry (*)) . explist . map ((\z -> z -(ord '0')) . ord)
Improvement 2 str2int = sum . map (uncurry (*)) . explist . map ((\z -> z -(ord '0')) . ord) • by lambda1 str2int = sum . map (uncurry (*)) . explist . map (\ z -> ord z -(ord '0'))
Improvement 3 • by definition of sum str2int = foldr (+) 0 . map (uncurry (*)) . explist . map (\ z -> ord z -(ord '0')) • by mapfoldr str2int = (let d x y = (+)(uncurry (*) x) y in foldr d 0) . explist . map (\ z -> ord z -(ord '0'))
Improvement 4 str2int = (let d x y = (+)(uncurry (*) x) y in foldr d 0) . explist . map (\ z -> ord z -(ord '0')) • by operator use : (+) x y = x + y str2int = (let d x y = (uncurry (*) x) + y in foldr d 0) . explist . map (\ z -> ord z -(ord '0'))
Improvement 5 • patterns and definition of uncurry str2int = (let d (a,b) y = a*b + y in foldr d 0) . explist . map (\ z -> ord z -(ord '0')) • rearranging str2int = (foldr d 0) . explist . map f where d (a,b) y = a*b + y f z = ord z -(ord '0')
Improvement 6 • Using def of explist explist = fst . foldr g ([],1) where z `g` (zs,n) = ((z,n) : zs, n * 10)
Improvement 7 str2int = (foldr d 0) . fst . (foldr g ([],1)) . map f where d (a,b) y = a*b + y f z = ord z -(ord '0') z `g` (zs,n) = ((z,n) : zs, n * 10) • Using mapfoldr again str2int = (foldr d 0).fst.(foldr d2 ([],1)) where d (a,b) y = a*b + y d2 z (zs,n) =((ord z - ord ‘0’,n)::zs, n*10)