CSCI 2041

ADVANCED PROGRAMMING PRINCIPLES

Reasoning about programs:

Inductive Structures

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
| C₂ of b₂*t*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))
  • x1,x2 : t, v : b₂, P(x1) and P(x2) ⇒ P(C₂(v,x1,x2))

e.g. nat: ∀ n : nat, P(n) if P(Zero) and ∀ m, P(m) ⇒ P(Succ m)

e.g. '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 ℓ)
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

Trees

type 'a btree = Empty
| Node of 'a * 'a btree * 'a btree

For all t : 'a btree, P(t) if:

  • P(Empty), and
  • v, ∀ l,r: P(l) and P(r)P(Node (v,l,r))
let rec sum_tree t = match t with
| Empty -> 0
| Node(v,l,r) -> v + (sum_tree l) + (sum_tree r)

What might we prove about sum_tree?

let rec sum_tree t = match t with
| Empty -> 0
| Node(v,l,r) -> v + (sum_tree l) + (sum_tree r)

let rec flatten t = match t with
| Empty -> []
| Node(v,l,r) -> (flatten l) @ v::(flatten r)

Proposition.t : 'a btree:

sum_list (flatten t) ≡ sum_tree t

Binary Search Trees

let rec search t e = match t with
| Empty -> false
| Node(v,lt,rt) -> if e = v then true else
  if e < v then search lt e
  else search rt e

let rec insert t e = match t with
| Empty -> Node(e, Empty, Empty)
| Node(v,lt,rt) -> if e = v then t else
  if e < v then Node(v,insert lt e, rt)
  else Node(v,lt,insert rt e)

t,e: search e (insert t e) ≡ true

Base Case: t = Empty

Inductive case: three (sub-)cases for v,lt,rt…


type expr = Const of int | Add of expr*expr | Mul of expr*expr

What is the principle of structural induction for type expr?

let rec eval = function
| Const i -> i
| Add (e1,e2) -> (eval e1) + (eval e2)
| Mul (e1,e2) -> (eval e1) * (eval e2)

let rec flip = function
| Const x -> Const x
| Add (e1,e2) -> Add(flip e2, flip e1)
| Mul (e1,e2) -> Mul(flip e2, flip e1)

Theorem:e : expr, eval e ≡ eval (flip e)

cs2041.org

// reveal.js plugins