Inductive types and trees #
As we have seen, inductive types are given by constructors. To fully understand these, we must understand:
- What are the allowed types of the constructors?
- What are the corresponding types of the
recfunctions? - What identities are satisfied by these?
Since the constructs give elements of T, they must be (dependent) functions with codomain T, or (dependent) functions with codomain (dependent) functions with codomain T, etc. Thus, possible types of constructors are:
T.- If
X(= ... → T) is a possible type andAis defined in the context, thenA → X. - If
X(= ... → T) is a possible type, thenT → X. - If
X(= ... → T) is a possible type andAis defined in the context, then(A → T) → Xis a possible type (we can generalize toA → B → Tetc. and families).
Parameterized inductive types #
We also have parametrized inductive types like lists, where we are defining a family of types List α for each α. In this case, the constructors can depend on the parameter α.
To be precise, a family of types is one of:
- A type
T : Type u. - Given a type
Aand a family of typesX, the typeA → X. - Given a type
A, and, for eacha : A, a family of typesX a, the typeΠ (a : A), X a = (a: A) → X a. - Given a type
Aand a family of typesX, the typeList A → X(this is in Lean, but not, for example in Homotopy Type Theory).
Indexed inductive types #
This is a more subtle notion. We will return to this later. We have already seen an example of this: MyNat.le is an indexed inductive type.
Trees #
We see various kinds of trees, giving various inductive types.
Equations
- instInhabitedBinTree = { default := BinTree.leaf default }
Equations
- BinTree.eg₂ = (BinTree.leaf 3).node (BinTree.leaf 4)
Instances For
Equations
- BinTree.eg₃ = ((BinTree.leaf 3).node (BinTree.leaf 4)).node (BinTree.leaf 5)
Instances For
Equations
- (BinTree.leaf a).toList = [a]
- (a.node a_1).toList = a.toList ++ a_1.toList
Instances For
Equations
- (BinTree.leaf a).sum = a
- (t₁.node t₂).sum = t₁.sum + t₂.sum
Instances For
Equations
- BinTree.sum' = BinTree.rec (fun (a : ℕ) => a) fun (_t₁ _t₂ : BinTree ℕ) (sum₁ sum₂ : ℕ) => sum₁ + sum₂
Instances For
Equations
- instInhabitedBinTree' = { default := BinTree'.leaf default }
Equations
- natListSum [] = 0
- natListSum (head :: tail) = head + natListSum tail
Instances For
Equations
- BoolTree.eg₂ = BoolTree.node fun (x : Bool) => BoolTree.leaf 3
Instances For
Equations
- BoolTree.eg₃ = BoolTree.node fun (b : Bool) => if b = true then BoolTree.leaf 3 else BoolTree.leaf 4
Instances For
Equations
- (BoolTree.leaf a).toList = [a]
- (BoolTree.node f).toList = (f true).toList ++ (f false).toList
Instances For
Equations
- (BoolTree.leaf a).toBinTree = BinTree.leaf a
- (BoolTree.node f).toBinTree = (f true).toBinTree.node (f false).toBinTree
Instances For
Equations
- BoolTree.ofBinTree (BinTree.leaf a) = BoolTree.leaf a
- BoolTree.ofBinTree (a.node a_1) = BoolTree.node fun (b : Bool) => if b = true then BoolTree.ofBinTree a else BoolTree.ofBinTree a_1
Instances For
Equations
- instInhabitedListTree = { default := ListTree.node default }
Equations
Instances For
Equations
Instances For
Equations
- (ListTree.leaf a).toList = [a]
- (ListTree.node []).toList = []
- (ListTree.node (t :: ts)).toList = t.toList ++ (ListTree.node ts).toList
Instances For
Lean is pragmatic and allows imperative programming. We can define the sum of a list. Technically, this is in a monad.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- listSumNat' l = List.foldl (fun (sum : ℤ) (n : ℕ) => sum + ↑n) 0 l
Instances For
Equations
- listTillFlat n = (listTill n).flatMap listTill
Instances For
Equations
- FinTree.ofBinTree (BinTree.leaf a) = FinTree.leaf a
- FinTree.ofBinTree (a.node a_1) = FinTree.node fun (k : Fin 2) => match k with | ⟨0, _pf⟩ => FinTree.ofBinTree a | ⟨1, _pf⟩ => FinTree.ofBinTree a_1
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
The idea of Cantor's theorem is to show that we can define p: T → Bool such that p (node p) ≠ p p. If not for the positivity condition, we could define p (node x) = ¬ x (node x).
Equations
Instances For
Equations
- CantorTree.flip' = Eq.rec (motive := fun (x : Type) (h : CantorTree.T = x) => x → Bool) CantorTree.flip CantorTree.TisT'