Prove:  map id x = id x.

-- List all the definitions and equations you use.
-- label each with a name

1 map f [] = []
2 map f (x:xs) = (f x) : (map f xs)

3 id x = x

-- Set up the structure of the proof
Prove 3 things

1) map id [] = id []

2) Assuming:    map id zs = id zs
   Prove:       map id (z:zs)  = id (z:zs)

3) map id bottom = id bottom

-- label each step with the label of the definition
-- or equation that justifes it.

1) map id [] = id []
Proceed by transforming LHS into RHS with meaning preserving steps

 map id [] = []        -->    (By 1)
 [] = id []            -->    (By 3, backwards)
                QED

2) Assuming:    map id zs = id zs
   Prove:       map id (z:zs)  = id (z:zs)

   Proceed by transforming LHS into RHS with meaning preserving steps

map id (z:zs) = (id z): (map id zs)    --> (By 2)
(id z):(map id z) = id z:(id zs)       --> (By induction hyp)
id z:(id zs) = z : zs                  --> (By 3, used twice)
z:zs = id (z:zs)                       --> (By 3 used backwards)

3) map id bottom  = id bottom
Proceed by transforming both sides using laws about
pattern matching on bottom

map id bottom = bottom           (pattern matching on bottom)
bottom = id bottom               (by 3)

--------------------------------------------------------

In general you want to prove some thing about a formula: F
Pick a variable: x (the choice is important) such that
E(x) = F

Now you need to prove 3 things

1) E([])

2) Assuming:    E(zs)
   Prove:       E(z:zs)

3) E(bottom)

----------------------------------------------------------
Lets choose one law from from the Laws worksheet

9) xs ++ []           = xs

Now the choice of variable is easy (there is only 1 variable)

E(x) =  xs++[] = xs

1) E([])                     []++[] = []


2) Assuming:    E(zs)        zs++[] = zs
   Prove:       E(z:zs)      (z:zs)++[] = (z:zs)


3) E(bottom)                 bottom++[] = bottom


------------------------
1) []++[] = []  (Trivial by 3)

2) Assuming:  zs++[] = zs
   Prove:    (z:zs)++[] = (z:zs)

   (z:zs)++[]   -->  (By 4)
   z:(zs++[])   -->  (By IH)
   z:(zs)       -->  (By parenthesis rule)
   z:zs         -->  QED

3) bottom++[] = bottom   (Trivial by pattern matching over bottom rule)

------------------------------------------------
Final Example

length . map f     = length
We'll need a rule for defining composition and length

5  (f . g) x = f(g x)

6 length [] = 0
7 length(x:xs) = 1 + length xs

-----------------------------
-- Set up proof

Reformulate law using law of extensionality.  Forall x f g. (f x)=(g x) iff f=g

(length . map f) x    = length x

E(x) = (length . map f) x    = length x

1) E([])                    (length . map f) []   = length []

2) Assuming:    E(zs)       (length . map f) zs    = length zs
   Prove:       E(z:zs)     (length . map f) (z:zs)    = length (z:zs)

3) E(bottom)                (length . map f) bottom    = length bottom

--------------------------------

1)  (length . map f) []   = length []

(length . map f) []   -->  By 6
[]                    -->  By 6 backwards
length []             QED

2) Assuming: (length . map f) zs    = length zs
   Prove:    (length . map f) (z:zs)    = length (z:zs)

(length . map f) (z:zs)   --> By 5
length(map f (z:zs))      --> By 2
length((f z):map f zs)    --> 7
1 + length(map f zs)      --> By 5
1 + ((length . map f) zs) --> By IH
1+ length zs              --> By 7 backwards
length (z:zs)             QED

3) (length . map f) bottom    = length bottom

(length . map f) bottom    -->  By 5
length(map f bottom)       -->  By pattern match on bottom
length bottom              QED

-----------------------------------------------
-- So what about proofs about trees?

data Tree a = Tip | Node a | Fork (Tree a) (Tree a)

 8 mapTree f Tip = Tip
 9 mapTree f (Node x) = Node(f x)
10 mapTree f (Fork l r) = Fork (mapTree f l) (mapTree f r)

11 depth Tip = 0
12 depth (Node x) = 1
13 depth (Fork l r) = 1 + (max (depth l) (depth r))

--------------------------------------------------
prove: depth(mapTree f x) = depth x

For trees the structure of a proof (E(x) = predicate) is

1) Prove E(Tip)
2) Prove E(Node x)
3) Assuming E(x) and E(y)  Prove E(Node x y)
4) Prove E(bottom)

-------------------------------------------

1) Prove E(Tip)                depth(mapTree f Tip) = depth Tip
depth(mapTree f Tip)  --> By 8
depth Tip             QED


2) Prove E(Node x)             depth(mapTree f (Node x)) = depth (Node x)
depth(mapTree f (Node x))  -->   By 9
depth(Node (f x))          -->  12
1                          -->  12 backwards
depth (Node x)             QED


3) Assuming:  E(x) and         IH1 depth(mapTree f x) = depth x
              E(y)             IH2 depth(mapTree f y) = depth y
   Prove:     E(Fork x y)      depth(mapTree f (Fork x y)) = depth (Fork x y)

depth(mapTree f (Fork x y))                               --> By 10
depth(Fork (mapTree f x) (mapTree f y))                   --> Byb 13
1 + (max (depth(mapTree f x)) (depth(mapTree f y))))      --> By IH1 and IH2
1 + max (depth x) (depth y)                               --> By 13 backwards
depth(Fork x y)                                           QED


4) Prove E(bottom)             depth(mapTree f bottom) = depth bottom
depth(mapTree f bottom)
depth bottom

------------------------------------------------------------
-- Patterns

1) A Datatype with n constructors has (n+1) cases
2) One for each case and one for bottom
3) For every inductive Construuctor you get an IH