Laws and Induction
Finish the proof of
reverse . reverse = id
from the lecture.-- claim: reverse . reverse = id -- by extensional reasoning, it is enough to show that -- (reverse . reverse) zs = id zs -- for all lists zs -- we distinguish the cases zs = [] and zs = x:xs -- and prove the claim by induction on zs -- base case zs = []: reverse.reverse) [] (= -- def (.) reverse (reverse []) = -- def reverse reverse [] = -- def reverse [] = -- def id id [] -- inductive case zs = x:xs: -- we assume the induction hypothesis (I.H.) (reverse . reverse) xs = id xs -- then reverse.reverse) (x:xs) (= -- def (.) reverse (reverse (x:xs)) = -- def reverse reverse (reverse xs ++ [x]) = -- lemma 1 reverse [x] ++ reverse (reverse xs) = -- lemma 2 ++ reverse (reverse xs) [x] = -- def (.) ++ (reverse.reverse) xs [x] = -- induction hypothesis ++ id xs [x] = -- def id ++ xs [x] = -- sugar [x] :[]) ++ xs (x= -- def ++ : ([] ++ xs) x = -- def ++ : xs x = -- def id id (x : xs) -- The claim now follows by induction on zs. -- We used two lemmas in this proof, which we prove next. -- lemma 2 : reverse [x] = [x] reverse [x] = -- sugar [x] reverse (x : []) = -- def reverse reverse [] ++ [x] = -- def reverse ++ [x] [] = -- def ++ [x] -- lemma 1 : reverse (zs ++ ys) = reverse ys ++ reverse zs -- we prove this lemma by induction on zs, distinguishing the -- cases zs = [] and zs = x:xs -- base case zs = []: reverse ([] ++ ys) = -- def ++ reverse ys = -- lemma 3 reverse ys ++ [] = -- def reverse reverse ys ++ reverse [] -- inductive case zs = x:xs -- we assume the induction hypothesis -- reverse (xs ++ ys) = reverse ys ++ reverse xs reverse ((x:xs) ++ ys) = -- def ++ reverse (x : (xs ++ ys)) = -- def reverse reverse (xs ++ ys) ++ [x] = -- induction hypothesis reverse ys ++ reverse xs) ++ [x] (= -- Lemma 4 reverse ys ++ (reverse xs ++ [x]) = -- def reverse reverse ys ++ reverse (x:xs) -- Lemma 2 now follows by induction on zs. -- The proof of lemma 1 above depended on a third and fourth lemma, -- which we prove now. -- lemma 3: zs ++ [] == zs -- we prove this by induction on zs, ditinguishing the cases -- zs = [] and zs = y:ys -- base case: zs = [] ++ [] [] = - def ++ [] -- inductive case: zs = y:ys -- we assume the induction hypothesis ys ++ [] = ys :ys) ++ [] (y= -- def ++ : (ys ++ []) y = -- induction hypothesis : ys y -- Lemma 3 now follows by induction on ys. -- Lemma 4: xs ++ (ys ++ zs) = (xs ++ ys) ++ zs -- We prove this by induction on xs, distinguishing the cases xs = [] and xs = w:ws -- Base case xs = [] ++ (ys ++ zs) [] = -- def ++ ++ zs ys = -- def ++ ++ ys) ++ zs ([] -- Inductive case xs = w : ws . -- We assume the induction hypothesis ws ++ (ys ++ zs) = (ws ++ ys) ++ zs :ws) ++ ys) ++ zs ((w= def ++ : (ws ++ ys)) ++ zs (w = def ++ : ((ws ++ ys) ++ zs) w = I.H. : (ws ++ (ys ++ zs)) w = def ++ : ws) ++ (ys ++ zs) (w -- Lemma 4 now follows by induction on xs.
Prove the following laws about list functions.
Hint: if you get stuck, the proofs can be found in Chapter 13 of the Lecture Notes.
-- Laws about list length length . map f = length length (xs ++ ys) = length xs + length ys length . concat = sum . map length -- Laws about sum sum (xs ++ ys) = sum xs + sum ys sum . concat = sum . map sum -- Laws about map map f . concat = concat . map (map f) -- Hard!
Prove that
sum (map (1+) xs) = length xs + sum xs
for all listsxs
.- State a similar law for a linear function
sum (map ((k+) . (n*)) xs) = ??
. - Prove the law from (a).
- Which laws from the previous exercise can be deduced from the general law?
- State a similar law for a linear function
Prove the following law: if
op
is an associative operator ande
its neutral element, thenfoldr op e . concat = foldr op e . map (foldr op e)
Find a function
g
and a valuee
such thatmap f = foldr g e
Prove the equality between both sides.
-- We claim that = f x : acc g x acc = [] e -- does the trick. -- By extensional reasoning, it suffices to prove that map f xs = foldr g e xs -- for all lists xs -- We prove this by induction on xs, distinguishing -- the cases xs = [] and xs = z:zs -- Base case: xs = [] map f [] = -- def map [] = -- def e e= -- def foldr foldr g e [] -- Inductive case: xs = z:zs -- where we assume the induction hypothesis map f zs = foldr g e zs map f (z:zs) = -- def map : map f zs f z = -- def g map f zs) g z (= -- I.H. foldr g e zs) g z (= -- def foldr foldr g e (z:zs) -- The claim now follows by induction on xs.
Prove that addition is commutative, that is,
add n m = add m n
.- Hint: you might need as lemmas that
add n Zero = n
andadd n (Succ m) = Succ (add n m)
.
- Hint: you might need as lemmas that
Prove that multiplication is commutative, that is,
mult n m = mul m n
.- Hint: you need lemmas similar to the previous exercise.
Prove that for all trees
size t = length (enumInfix t)
, wheredata Tree a = Leaf a | Node (Tree a) a (Tree a) size :: Tree a -> Int Leaf = 0 size Node l x r) = size l + 1 + size r size ( enumInfix :: Tree a -> [a] Leaf = [] enumInfix Node l x r) = enumInfix l ++ [x] ++ enumInfix r enumInfix (
- Hint: you might needs some of the laws in exercise 2 as lemmas.
Prove that
length . catMaybes = length . filter isJust
, wherecatMaybes :: [Maybe a] -> [a] = [] catMaybes [] Nothing : xs) = catMaybes xs catMaybes (Just x : xs) = x : catMaybes xs catMaybes ( isJust :: Maybe a -> Bool Just _) = True isJust (Nothing = False isJust
- Hint: proceed by induction on the list, and in the
z:zs
case distinguish betweenz
beingNothing
orJust w
.
- Hint: proceed by induction on the list, and in the