These notes re-present the proofs from lecture.
## Proof 1
```
let rec length = function
| [] -> 0
| _::xs -> 1 + length xs
let rec append xs1 xs2 = match xs1 with
| [] -> xs2
| h::t -> h :: append t xs2
Theorem.
for all lists xs and ys, length (append xs ys) ~ length xs + length ys.
Proof: by induction on xs
Case: xs = []
Show: for all ys, length (append [] ys) ~ length [] + length ys
length (append [] ys)
~ length ys (eval)
~ 0 + length ys (math)
~ length [] + length ys (eval,symm.)
Case: xs = h::t
Show: for all ys, length (append (h::t) ys) ~ length (h::t) + length ys
IH: for all ys, length (append t ys) ~ length t + length ys
length (append (h::t) ys)
~ length (h :: append t ys) (eval)
~ 1 + length (append t ys) (eval)
~ 1 + length t + length ys (IH,congr.)
~ length (h::t) + length ys (eval,symm.,congr.)
QED
```
We'll start omitting facts about ~ in proofs now, unless they are
especially non-obvious. So symmetry, congruence, and transitivity
aren't going to show up too much more.
## Proof 2
```
let (@@) f g x = f (g x)
let map = List.map
Theorem: for all functions f and g, (map f) @@ (map g) ~ map (f @@ g).
Proof:
By extensionality, we need to show that for all xs,
((map f) @@ (map g)) xs ~ map (f @@ g) xs.
By eval, ((map f) @@ (map g)) xs ~ map f (map g xs).
So by transitivity, it suffices to show that
map f (map g xs) ~ map (f @@ g) xs.
We do so by induction on xs.
Case: xs = []
Show: map f (map g []) ~ map (f @@ g) []
map f (map g [])
~ [] (eval)
~ map (f @@ g) [] (eval)
Case: xs = h::t
Show: map f (map g (h::t)) ~ map (f @@ g) (h::t)
IH: map f (map g t) ~ map (f @@ g) t
We include hints, below, as to what eval steps
are being taken.
map f (map g (h::t))
~ map f ((g h)::map g t) (eval map)
~ (f (g h))::map f (map g t) (eval map)
~ ((f @@ g) h)::map f (map g t) (eval @@)
~ ((f @@ g) h)::map (f @@ g) t (IH)
~ map (f @@ g) (h::t) (eval map)
QED
```
## Proof 3
```
Theorem: for all trees t, reflect(reflect t) ~ t.
Proof: by induction on t.
Case: t = Leaf
Show: reflect(reflect Leaf) ~ Leaf
reflect(reflect Leaf)
~ Leaf (eval)
Case: t = Branch(x,l,r)
Show:
reflect(reflect(Branch(x,l,r))) ~ Branch(x,l,r)
IH:
1. reflect(reflect l) ~ l
2. reflect(reflect r) ~ r
reflect(reflect(Branch(x,l,r)))
~ reflect(Branch(x, reflect r, reflect l)) (eval)
~ Branch(x, reflect(reflect l), reflect(reflect r)) (eval)
~ Branch(x, l, reflect(reflect r)) (IH 1)
~ Branch(x, l, r) (IH 2)
QED
```