Inductive Types #
We see more precisely what are valid (and not valid) definitions for inductive types. We will also see the weak and strong generalizations: parametric inductive types and indexed inductive types.
We have constructed a few examples. We first see some more from Lean core.
In general, the construtors let us construct terms of the inductive type being introduced using terms of that type.
inductive Nat where
| zero : Nat
| succ (n : Nat) : Nat
#check Nat.zero -- ℕ #check Nat.succ -- ℕ → ℕ
Two more inductive types:
abbrev Unit : Type := PUnit
inductive PUnit : Sort u where
| unit : PUnit
inductive Empty : Type
Disallowed types #
- constructors should have resulting type the inductive type being introduced.
The above is disallowed because with a construction of the above form, we would have an injection (in this case a biection) from the power set on the Cantor set to itself.
If we had such an inductive type, we could define
diag (x :Cantor): Bool := match x with
| Cantor.mk f => ¬ f x
Apply this to x:= Cantor.mk diag
to get
diag (Cantor.mk diag) = ¬ diag (Cantor.mk diag)
A non-trivial positive occurence, which is hence allowed, is in the following binary tree.
- leaf: ℕ → NatBinTree
- node: (Bool → NatBinTree) → NatBinTree
Instances For
Parametrized inductive types #
Here we define a family of inductive types. However each member of the family is "separately defined", i.e., all constructors only involve that parameter.
- leaf: {α : Type u} → α → InfiniteTree α
- node: {α : Type u} → (ℕ → InfiniteTree α) → InfiniteTree α
Instances For
- leaf: {α : Type u} → α → FiniteTree α
- node: {α : Type u} → List (FiniteTree α) → FiniteTree α
Instances For
Indexed inductive type #
We define types Vec α n
for α : Type u
and n: ℕ
with terms of Vec α n
n-tuples in α
.
α
will be a parameter.n
will be an index.
Equations
- Vec.to_list Vec.nil = []
- Vec.to_list (Vec.cons head tail) = head :: Vec.to_list tail
Instances For
List
is a parametrized inductive type #
inductive List (α : Type u) where
/-- `[]` is the empty list. -/
| nil : List α
/-- If `a : α` and `l : List α`, then `cons a l`, or `a :: l`, is the
list whose first element is `a` and with `l` as the rest of the list. -/
| cons (head : α) (tail : List α) : List α
Sometimes types include conditions
structure Fin (n : Nat) where
/-- If `i : Fin n`, then `i.val : ℕ` is the described number. It can also be
written as `i.1` or just `i` when the target type is known. -/
val : Nat
/-- If `i : Fin n`, then `i.2` is a proof that `i.1 < n`. -/
isLt : LT.lt val n
Conditions can be given by a subtype of the type.
def Vector (α : Type u) (n : ℕ) :=
{ l : List α // l.length = n }
When an (indexed) inductive type is introduced,
- the type (or family of types) is defined.
- the constructors are defined.
- a recursor is defined.
- a rule for simplification of applications of the recursor is introduced.
The recursor can be conveniently used by pattern matching.