# 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

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