168 lines
4.8 KiB
Text
168 lines
4.8 KiB
Text
#import "prooftree.typ": *
|
|
#import "@preview/showybox:2.0.1": showybox
|
|
#set page(width: 5.6in, height: 9in, margin: 0.4in)
|
|
|
|
= Type theory crash course
|
|
|
|
== MLTT + Sets
|
|
|
|
Important features in MLTT:
|
|
|
|
#let Nat = $sans("Nat")$
|
|
#let Vect = $sans("Vect")$
|
|
|
|
- Dependent types and functions.
|
|
e.g $ "concatenate": Pi_(m,n:"Nat") Vect(m) -> Vect(n) -> Vect(m+n) $
|
|
- Function arrows always associate to the right.
|
|
- All functions are total.
|
|
|
|
Goal: to write well-typed programs. (implementing an algorithm and proving a mathematical statement are the same)
|
|
|
|
=== Judgements
|
|
|
|
$ "context" tack.r "conclusion" $
|
|
|
|
#let defeq = $equiv$
|
|
|
|
#table(
|
|
columns: 2,
|
|
stroke: gray,
|
|
$Gamma$, [sequence of variable declarations (contexts are always well-formed)],
|
|
$Gamma tack.r A$, [$A$ is well-formed *type* in context $Gamma$],
|
|
$Gamma tack.r a : A$, [*term* $a$ is well-formed and of type $A$],
|
|
$Gamma tack.r A defeq B$, [types $A$ and $B$ are *convertible*],
|
|
$Gamma tack.r a defeq b : A$, [$a$ is convertible to $b$ in type $A$],
|
|
)
|
|
|
|
Example:
|
|
|
|
$ "isZero?"& : Nat -> "Bool" \
|
|
"isZero?"& (n) :defeq "??"
|
|
$
|
|
|
|
At this point, looking for $(n: Nat) tack.r "isZero?"(n) : "Bool"$.
|
|
|
|
=== Inference rules
|
|
|
|
#prooftree(
|
|
axiom($J_1$),
|
|
axiom($J_2$),
|
|
axiom($J_3$),
|
|
rule(n: 3, $J$),
|
|
)
|
|
|
|
For example:
|
|
|
|
#prooftree(
|
|
axiom($Gamma tack.r a defeq b : A$),
|
|
rule($Gamma tack.r b defeq a : A$),
|
|
)
|
|
|
|
#let subst(name, replacement, expr) = $#expr [ #replacement \/ #name ]$
|
|
|
|
=== Interpreting types as sets
|
|
|
|
You can interpret types as sets, where $a : A$ is interpreted as $floor(a) : floor(A)$.
|
|
|
|
- Univalent mathematics can _not_ be interpreted as sets. There are extra axioms that breaks the interpretation.
|
|
- The judgement $a : A$ cannot be proved or disproved.
|
|
- For ex. 2 of natural numbers and 2 of integers can be converted but are inherently different values.
|
|
|
|
=== Convertibility
|
|
|
|
If $x : A$ and $A defeq B$, then $x : B$. We are thinking of these types as literally the same.
|
|
|
|
If $a defeq a'$ then $f @ a defeq f @ a'$.
|
|
|
|
=== Declaring types and terms
|
|
|
|
4 types of rules:
|
|
|
|
#let typeIntroTable(formation, introduction, elimination, computation) = table(
|
|
columns: 2,
|
|
stroke: 0in,
|
|
[#text(fill: blue, [Formation])], [#formation],
|
|
[#text(fill: blue, [Introduction])], [#introduction],
|
|
[#text(fill: blue, [Elimination])], [#elimination],
|
|
[#text(fill: blue, [Computation])], [#computation],
|
|
)
|
|
|
|
#typeIntroTable(
|
|
[a way to construct a new type],
|
|
[way to construct *canonical terms* of the type],
|
|
[how to use a term of the new type to construct terms of other types],
|
|
[what happens when one does Introduction followed by Elimination],
|
|
)
|
|
|
|
Example (context $Gamma$ are elided):
|
|
|
|
#typeIntroTable(
|
|
[If $A$ and $B$ are types, then $A -> B$ is a type
|
|
#prooftree(axiom($Gamma tack.r A$), axiom($Gamma tack.r B$), rule(n: 2, $Gamma tack.r A -> B$))],
|
|
[If $(x : A) tack.r b : B$, then $tack.r lambda (x : A) . b(x) : A -> B$
|
|
- $b$ is an expression that might involve $x$],
|
|
[If we have a function $f : A -> B$, and $a : A$, then $f @ a : B$ (or $f(a) : B$)],
|
|
[What is the result of the application? $(lambda(x : A) . b(x)) @ a defeq subst(a, x, b)$
|
|
- Substitution $subst(a, x, b)$ is built-in],
|
|
)
|
|
|
|
Questions:
|
|
|
|
- *What does the lambda symbol mean?* Lambda is just notation. It could also be written $tack.r "lambda"((x:A), b(x)) : A -> B$.
|
|
|
|
Another example: the singleton type
|
|
|
|
#let unit = $bb(1)$
|
|
#let tt = $t t$
|
|
#let rec = $sans("rec")$
|
|
|
|
#typeIntroTable(
|
|
[$unit$ is a type],
|
|
[$tt : unit$],
|
|
[If $x : unit$ and $C$ is a type and $c : C$, then $rec_unit (C, c, x) : C$],
|
|
[$rec_unit (C, c, t) defeq c$
|
|
- Interpretation in sets: a one-element set],
|
|
)
|
|
|
|
- Question: *How to construct this using lambda abstraction?*
|
|
- (Structural rule: having $tack.r c : C$ means $x : unit tack.r c : C$, which by the lambda introduction rule gives us $lambda x.c : unit -> C$)
|
|
|
|
Booleans
|
|
|
|
#let Bool = $sans("Bool")$
|
|
#let tru = $sans("true")$
|
|
#let fls = $sans("false")$
|
|
|
|
#typeIntroTable(
|
|
[$Bool$ is a type],
|
|
[$tru : Bool$ and $fls : Bool$],
|
|
[If $x : Bool$ and $C$ is a type and $c, c' : C$, then $rec_Bool (C, c, c', x) : C$],
|
|
[$rec_Bool (C, c, c', tru) defeq c$ and $rec_Bool (C, c, c', fls) defeq c'$],
|
|
)
|
|
|
|
Empty type
|
|
|
|
#let empty = $bb(0)$
|
|
|
|
#typeIntroTable(
|
|
[$empty$ is a type],
|
|
[_(no introduction rule)_],
|
|
[If $x : empty$ and $C$ is a type, then $rec_empty (C, x) : C$],
|
|
[_(no computation rule)_],
|
|
)
|
|
|
|
Natural numbers
|
|
|
|
#let zero = $sans("zero")$
|
|
#let suc = $sans("suc")$
|
|
|
|
#typeIntroTable(
|
|
[$Nat$ is a type],
|
|
[- $zero : Nat$
|
|
- If $n : Nat$, then $suc(n) : Nat$],
|
|
[If $C$ is a type and $c_0:C$ and $c_s:C->C$ and $x: Nat$, then $rec_Nat (C,c_0,c_s,x) : C$],
|
|
[- $rec_Nat (C, c_0, c_s, zero) defeq c_0$
|
|
- $rec_Nat (C, c_0, c_s, suc(n)) defeq c_s @ (rec_Nat (C, c_0, c_s, n))$
|
|
We can define computation rule on naturals using a universal property],
|
|
)
|
|
|