```
let rev lst =
let rec tail_rev lst acc = match lst with
| [] -> acc
| h::t -> tail_rev t (h::acc)
in tail_rev lst []
```

To prove that ∀ `ℓ : 'a list`

, `rev ℓ ≡ reverse ℓ`

, we’ll first prove:

**Lemma.**

∀`ℓ₁,ℓ₂ : 'a list`

, `(tail_rev ℓ₁ ℓ₂) ≡ (reverse ℓ₁) @ ℓ₂`

**Inductive Case:** Need to show

```
tail_rev ℓ₁ ℓ₂ ≡ (reverse ℓ₁) @ ℓ₂ ⇒
tail_rev (x::ℓ₁) ℓ₂ ≡ (reverse (x::ℓ₁)) @ ℓ₂
```

Informally we are proving that `P(ℓ)`

is **invariant** over recursive calls.

Can’t you prove *any* (even false) *thing(s)* this way?

Consider “broken” versions of `append`

, `tail_rev`

:

```
let rec badpend l1 l2 = match l1 with
| [] -> l2
| h::t -> badpend l1 l2
```

(IH only tells about `(badpend t l2)`

)

```
let rec fail_rev l1 acc = match l1 with
| [] -> []
| h::t -> fail_rev t (h::acc)
```

## Generalized Induction

For any inductive type of the form:

```
type t = C₀ of b (* b is some other type not referring to t *)
| C₁ of b₁*t
```

The principle of induction for type `t`

is:

For all `x : t`

, `P(x)`

if:

- ∀
`v : b`

, `P(C₀ v)`

, and
- ∀
`x : t, v : b₁`

, `P(x) ⇒ P(C₁(v,x))`

Examples:

`nat`

: ∀ `n : nat`

, `P(n)`

**if** `P(Zero)`

and `∀ m`

, `P(m) ⇒ P(Succ m)`

`'a list`

: ∀ `ℓ : 'a list`

, `P(ℓ)`

**if**

`P([])`

and `∀ x : 'a`

, `∀ ℓ : 'a list`

, `P(ℓ) ⇒ P(x::ℓ)`

More Generalized Induction…

`type bitlist = C0 | C1 | L0 of bitlist | L1 of bitlist`

Principle of structural induction for `bitlist`

:

∀ `ℓ : bitlist`

, `P(ℓ)`

if:

`P(C0)`

, and
`P(C1)`

, and
- ∀ ℓ,
`P(ℓ) ⇒ P(L0 ℓ)`

, and
- ∀ ℓ,
`P(ℓ) ⇒ P(L1 ℓ)`

**Notice:** Here we have *two* base cases, and *two* step cases.

```
let rec bitlen blst = match blst with
| C0 | C1 -> 1
| L0 b | L1 b -> 1 + (bitlen b)
let rec bitweight blst = match blst with
| C0 -> 0
| C1 -> 1
| L0 b -> bitweight b
| L1 b -> 1 + (bitweight b)
```

**Prove:** ∀ `bl : bitlist`

, `bitweight bl <= bitlen bl`

**Prove:** ∀ `bl : bitlist`

, `bitweight bl <= bitlen bl`

`bitweight C0 <= bitlen C0`

`bitweight C1 <= bitlen C1`

**Inductive Cases:** Need to show

```
bitweight ℓ <= bitlen ℓ ⇒
bitweight (L0 ℓ) <= bitlen (L0 ℓ)
```

and

```
bitweight ℓ <= bitlen ℓ ⇒
bitweight (L1 ℓ) <= bitlen (L1 ℓ)
```