# Induction on `nat`

``∀ n1 : nat, ∀n2 : nat, to_int (mul_nat n1 n2) ≡ (to_int n1) * (to_int n2)``

Base Case `n1 = Zero`:

``∀n2, to_int (mul_nat Zero n2) ≡ to_int Zero ≡ 0 ≡ (to_int Zero) * (to_int n2)``

Inductive Case:

``````to_int (mul_nat (Succ n) n2)
≡ to_int (plus_nat n2 (mul_nat n n2)) (* eval mul_nat *)
≡ (to_int n2) + (to_int (mul_nat n n2))  (* plus_nat theorem *)
≡ (to_int n2) + (to_int n) * (to_int n2) (* IH *)
≡ (1 + (to_int n)) * (to_int n2) (* distributive property *)
≡ (to_int (Succ n)) * (to_int n2) (* reverse eval to_int *)``````

# 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::ℓ)`
``````let rec sum lst = match lst with
| [] -> 0
| n::ls -> n + (sum ls)``````

Claim: ∀ `ℓ : int list`, `(sum ℓ)` ≡ ∑ii

Base Case: `(sum []) ≡ 0`, ∑i []i = 0.

Inductive case: let `ℓ' = x::ℓ`, then

`(sum x::ℓ)``x + (sum ℓ)`
`          ``x` + ∑ii
`          ` ≡ ∑i ℓ’i.

# Code specifications

To avoid doubt about “properties of lists” we can state properties using code:

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

let rec sum = function [] -> 0
| h::t -> h + (sum t)``````

Claim:`ℓ₁ : int list`:

`ℓ₂ : int list`,

`sum (append ℓ₁ ℓ₂) ≡ (sum ℓ₁) + (sum ℓ₂)`

Base Case: `ℓ₁ = []`.

Inductive Case: Need to show that:

``````sum (append ℓ₁ ℓ₂) ≡ (sum ℓ₁) + (sum ℓ₂) ⇒
sum (append (x::ℓ₁) ℓ₂) ≡ (sum (x::ℓ₁)) + (sum ℓ₂)``````

# `cs2041.org`

// reveal.js plugins