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 α
          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 : 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.

            Instances For
              def egFamily (b : Bool) :
              Instances For
                Instances For