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.

Simplest ones are enumerations

inductive Bool : Type where
  | false : Bool
  | true : Bool

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 -- ℕ #check Nat.succ -- ℕ → ℕ

Two more inductive types:

abbrev Unit : Type := PUnit

inductive PUnit : Sort u where
  | unit : PUnit

inductive Empty : Type

Disallowed types #

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
| f => ¬ f x

Apply this to x:= diag to get

diag ( diag) = ¬ diag ( diag)

A non-trivial positive occurence, which is hence allowed, is in the following binary tree.

inductive 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.

    inductive InfiniteTree (α : Type u) :
    Instances For
      inductive FiniteTree (α : Type u) :
      Instances For
        partial def FiniteTree.flatten {α : Type u} :
        FiniteTree αList α

        Indexed inductive type #

        We define types Vec α n for α : Type u and n: ℕ with terms of Vec α n n-tuples in α.

        inductive Vec (α : Type u) :
        Type (u+1)
        Instances For
          def Vec.to_list {α : Type u} {n : } :
          Vec α nList α

          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 : 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 recursor can be conveniently used by pattern matching.

          def egFamily (b : Bool) :