Mottoes:
nat, there aren’t values that can’t be expressed using finite combination of zero and succnat, zero ≠ succ xgeneralization of math induction to inductive types.
P[n] for natural numbers n, prove:
P[0]∀k, P[k] → P[k+1]P[[]]∀y ys, P[ys] → P[y :: ys]Example proof:
lemma nat.succ_neq_self (n : Ν) :
nat.succ n ≠ n :=
begin
induction' n,
{ simp },
{ simp [ih] }
end
You can use case to supply custom names and/or reorder cases.
Form of recursion where you can peel off constructors from value. Hence only call themselves finitely many times.
Example:
def fact : Ν → Ν
| 0 := 1
| (n+1) := (n+1) * fact n
match lets you do nonrecursive pattern matching
match term_1, term_2, ..., term_n with
| pattern_1, ..., pattern_m := result_1
...
| pattern_k1, ..., pattern_km := result_k
end
You can define records/structures, essentially nonrecursive single-constructor inductive types.
structure rgb := (red green blue : Ν)
def red : rgb :=
{ red := 0xff,
green := 0x00,
blue := 0x00 }
structure rgba extends rgb := (alpha : Ν)
def semitransparent_red : rgba :=
{ alpha := 0x7f,
..pure_red }
cases does a case distinction on a term, giving rise to as many subgoals as constructors in definition of term’s type.
Structure type combining abstract constants and their properties. Type can be declared instance of type class by (1) providing concrete definitions for constants and (2) proving that properties hold.
for example, for class:
class inhabited (α : Sort u) := (default [] : α)
you can declare an instance like this:
@[instance] def nat.inhabited : inhabited Ν := { default := 0 }
@[instance] def list.inhabited : {α : Type} : inhabited (list α) := { default := [] }
Inductive polymorphic types constructed from nil and cons.
cases' can be used on hypothesis of form l = r. Matches r against l, replaces all occurrences of vars in r with corresponding terms in l globally across goal.
it can also do case distinction on proposition, yielding one subgoal where the prop is true, and one where it’s false.
list.map applies function element-wise to list.
list.tail gets everything but first element.
list.head gets first element.
list.zip takes two lists, and creates list of pairs.
list.length returns number of elements.
Inductive types with constructors taking recursive arguments. Have nodes with max two children.
inductive btree (α : Type) : Type
| empty {} : btree
| node : α → btree → btree → btree