h5i

Chapter 3

Typing Rules

The kernel's job is to decide the judgment "term tt has type AA". This chapter defines that judgment by a small set of inference rules, one for each kind of term and one extra rule that lets computation happen inside types. Reading each rule bottom-up turns it into a recipe for checking a term, and that recipe becomes the algorithm of Chapter 5.

Contexts and judgments

A term such as f  pf\;p cannot be checked in isolation: its type depends on what ff and pp are. A context Γ\Gamma records that information. It is an ordered list of assumptions

Γ  =  x1:A1,  x2:A2,  …,  xn:An,\Gamma \;=\; x_1 : A_1,\; x_2 : A_2,\; \ldots,\; x_n : A_n,

giving the type of each variable in scope, and dom(Γ)\dom(\Gamma) denotes the set of names {x1,…,xn}\{x_1, \ldots, x_n\}. The empty context is written ⋅\cdot.

Order matters. A later type may mention an earlier variable, as in P:Sort 0,  h:PP : \Sort{0},\; h : P: the assumption h:Ph : P only makes sense once PP is known to be a proposition. Names in a context will be required to be distinct, so a context can be used like a dictionary from names to types; but it is a dictionary whose entries depend on each other in sequence.

Two judgments are defined together.

  • ⊢Γ;ok\ctxok{\Gamma} means that the context Γ\Gamma is well formed: each assumed type is a type in the context before it.
  • Γ⊢t:A\Gamma \vdash t : A means that under the assumptions in Γ\Gamma, the term tt has type AA.

Through the Curry-Howard lens, Γ⊢t:A\Gamma \vdash t : A says that tt is a proof of AA from the hypotheses Γ\Gamma.

The rules

Figure 3.1 lists all the rules. Each rule has premises above the line and a conclusion below it; the conclusion holds whenever every premise does. The rule names on the right are used throughout the book.

Figure 3.1. Well-formed contexts (top row) and typing rules.

⊢Γ;ok⊢⋅;ok;(C-Empty)⊢Γ;okΓ⊢A:Sort ux∉dom(Γ)⊢Γ,x:A;ok;(C-Ext)\dfrac{\phantom{\ctxok{\Gamma}}}{\ctxok{\cdot}}\rulename{C-Empty} \qquad \dfrac{\ctxok{\Gamma} \qquad \Gamma \vdash A : \Sort{u} \qquad x \notin \dom(\Gamma)}{\ctxok{\Gamma, x : A}}\rulename{C-Ext}
⊢Γ;okΓ⊢Sort u:Sort (u+1);(T-Sort)⊢Γ;ok(x:A)∈ΓΓ⊢x:A;(T-Var)\dfrac{\ctxok{\Gamma}}{\Gamma \vdash \Sort{u} : \Sort{(u+1)}}\rulename{T-Sort} \qquad \dfrac{\ctxok{\Gamma} \qquad (x : A) \in \Gamma}{\Gamma \vdash x : A}\rulename{T-Var}
Γ⊢A:Sort uΓ,x:A⊢B:Sort vΓ⊢Π(x:A). B:Sort imax(u,v);(T-Pi)\dfrac{\Gamma \vdash A : \Sort{u} \qquad \Gamma, x : A \vdash B : \Sort{v}}{\Gamma \vdash \tPi{x}{A}{B} : \Sort{\imax(u, v)}}\rulename{T-Pi}
Γ⊢A:Sort uΓ,x:A⊢t:BΓ⊢λ(x:A). t:Π(x:A). B;(T-Lam)\dfrac{\Gamma \vdash A : \Sort{u} \qquad \Gamma, x : A \vdash t : B}{\Gamma \vdash \tLam{x}{A}{t} : \tPi{x}{A}{B}}\rulename{T-Lam}
Γ⊢f:Π(x:A). BΓ⊢a:AΓ⊢f  a:B[x↦a];(T-App)\dfrac{\Gamma \vdash f : \tPi{x}{A}{B} \qquad \Gamma \vdash a : A}{\Gamma \vdash f\;a : \subst{B}{x}{a}}\rulename{T-App}
Γ⊢t:AΓ⊢B:Sort uA≡BΓ⊢t:B;(T-Conv)\dfrac{\Gamma \vdash t : A \qquad \Gamma \vdash B : \Sort{u} \qquad A \conv B}{\Gamma \vdash t : B}\rulename{T-Conv}

Two of the rules use operations on terms that the next chapters treat as black boxes.

Substitution. T-App writes B[x↦a]\subst{B}{x}{a} for the result of replacing every free occurrence of xx in BB by aa. For example, (P→P)[P↦Q]=Q→Q\subst{(P \to P)}{P}{Q} = Q \to Q. Replacing names inside binders needs care, which Chapter 11 explains; until then the intuitive meaning is enough.

Definitional equality. T-Conv writes A≡BA \conv B when AA and BB are "the same type" in a sense the kernel can decide mechanically. Two kinds of difference are ignored.

  • The names of bound variables. Π(P:Sort 0). P→P\tPi{P}{\Sort{0}}{P \to P} and Π(Q:Sort 0). Q→Q\tPi{Q}{\Sort{0}}{Q \to Q} state the same proposition. Terms that differ only in this way are alpha-equivalent, written A=αBA \alphaeq B.
  • Computation. If Id=λ(X:Sort 0). X\mathit{Id} = \tLam{X}{\Sort{0}}{X}, then Id  P\mathit{Id}\;P computes to PP by plugging PP in for XX, so a proof of Id  P\mathit{Id}\;P should count as a proof of PP. The computation step (λ(x:A). t)  s→βt[x↦s](\tLam{x}{A}{t})\;s \betared \subst{t}{x}{s} is called beta-reduction.

The kernel decides A≡BA \conv B by computing both sides as far as possible and then checking whether the results are alpha-equivalent. Chapter 12 defines this precisely.

Reading the rules

The rules are best read from the bottom up, as a recipe: to establish the conclusion, establish the premises.

C-Empty and C-Ext. A context is built one assumption at a time, and each new assumption must have a type as its type. The side condition x∉dom(Γ)x \notin \dom(\Gamma) forbids two assumptions with the same name. Since the names of bound variables do not matter, this restricts nothing: a binder that would clash can always be renamed first. Chapter 11 shows what goes wrong in a kernel that skips this condition.

T-Sort. Every universe lives in the next one: Sort 0:Sort 1\Sort{0} : \Sort{1}, Sort 1:Sort 2\Sort{1} : \Sort{2}, and so on. Chapter 13 explains why a universe cannot be its own type.

T-Var. A variable has the type the context assigns to it. Logically: use a hypothesis.

T-Pi. Π(x:A). B\tPi{x}{A}{B} is a type if AA is a type and BB is a type once x:Ax : A is assumed. The resulting universe is imax(u,v)\imax(u, v), which is 00 if v=0v = 0 and max⁡(u,v)\max(u, v) otherwise. In words: a Π\Pi-type is a proposition whenever its body is a proposition, no matter what it quantifies over; otherwise it lives in the larger of the two universes. Logically, this rule says when A→BA \to B and ∀x:A. B\forall x{:}A.\,B are well-formed statements.

T-Lam. To build a function from AA to BB, assume x:Ax : A and build a term tt of type BB. The body's type BB may mention xx, and it is kept as is in the resulting Π\Pi-type, which is where dependency enters. Logically, this is the introduction rule for implication and for the universal quantifier: to prove A→BA \to B, assume AA and prove BB.

T-App. If ff maps each x:Ax : A to an element of BB, and a:Aa : A, then f  af\;a has type BB with xx replaced by aa. When BB does not mention xx this is modus ponens: from A→BA \to B and AA, conclude BB. When it does, it is instantiation of a universal statement. For example, if f:Π(n:Nat). n+0=nf : \tPi{n}{\Nat}{n + 0 = n}, then f  3:3+0=3f\;3 : 3 + 0 = 3 (natural numbers arrive in Chapter 7).

T-Conv. Types that are equal up to computation are interchangeable: from h:Id  Ph : \mathit{Id}\;P we may conclude h:Ph : P. The premise Γ⊢B:Sort u\Gamma \vdash B : \Sort{u} ensures that the new type is itself a type. This is the only rule whose use is not determined by the shape of tt, a fact that matters for the algorithm in Chapter 5.

Why application matters

The rules that build things (T-Lam and T-Pi) may seem more important than T-App, but without application a proof can return a hypothesis without ever using it. Roughly, only propositions whose conclusion is literally one of the hypotheses, such as P→Q→PP \to Q \to P, would be provable. Composition,

(P→Q)→(Q→R)→P→R,(P \to Q) \to (Q \to R) \to P \to R,

has the proof λ(f:P→Q). λ(g:Q→R). λ(p:P). g (f p)\tLam{f}{P \to Q}{\tLam{g}{Q \to R}{\tLam{p}{P}{g\,(f\,p)}}}, which applies ff and then gg. Every proof that does more than restate an assumption goes through T-App, and in a dependent type theory T-App is also where substitution, and therefore most of the subtlety, lives.

A first derivation

A derivation is a tree of rule instances whose root is the judgment being established. Here is the derivation that λ(P:Sort 0). λ(h:P). h\tLam{P}{\Sort{0}}{\tLam{h}{P}{h}} proves Π(P:Sort 0). P→P\tPi{P}{\Sort{0}}{P \to P}. Write Γ1=P:Sort 0\Gamma_1 = P : \Sort{0} and Γ2=Γ1,h:P\Gamma_2 = \Gamma_1, h : P, and omit the well-formedness premises ⊢Γ;ok\ctxok{\Gamma}, which are routine.

⋅⊢Sort 0:Sort 1;(T-Sort)Γ1⊢P:Sort 0;(T-Var)Γ2⊢h:P;(T-Var)Γ1⊢λ(h:P). h:Π(h:P). P;(T-Lam)⋅⊢λ(P:Sort 0). λ(h:P). h:Π(P:Sort 0). Π(h:P). P;(T-Lam)\dfrac{ \dfrac{}{\cdot \vdash \Sort{0} : \Sort{1}}\rulename{T-Sort} \qquad \dfrac{ \dfrac{}{\Gamma_1 \vdash P : \Sort{0}}\rulename{T-Var} \qquad \dfrac{}{\Gamma_2 \vdash h : P}\rulename{T-Var} }{\Gamma_1 \vdash \tLam{h}{P}{h} : \tPi{h}{P}{P}}\rulename{T-Lam} }{\cdot \vdash \tLam{P}{\Sort{0}}{\tLam{h}{P}{h}} : \tPi{P}{\Sort{0}}{\tPi{h}{P}{P}}}\rulename{T-Lam}

The kernel builds this tree. Below, each node is one application of a rule, with the judgment it establishes; switch to the call view to read it top-down as the recursion that produces it. Replace the term with your own to see which rules fire.

Two observations. First, the shape of the tree follows the shape of the term: a λ\lambda at the root, a λ\lambda below it, variables at the leaves. Second, the type at the root is Π(P:Sort 0). Π(h:P). P\tPi{P}{\Sort{0}}{\tPi{h}{P}{P}}, whereas the stated proposition was Π(P:Sort 0). P→P\tPi{P}{\Sort{0}}{P \to P}. These differ only in the name of a bound variable (hh versus the anonymous _ of the arrow), so they are alpha-equivalent, and T-Conv bridges the gap. Chapter 6 revisits this example with the algorithm.

Exercises

Which rule, applied bottom-up, handles each of the following judgments, and what premises does it produce? (a) Γ⊢λ(x:A). x:A→A\Gamma \vdash \tLam{x}{A}{x} : A \to A. (b) Γ⊢Sort 2:Sort 3\Gamma \vdash \Sort{2} : \Sort{3}. (c) Γ⊢f  a:B\Gamma \vdash f\;a : B where f:A→Bf : A \to B.

Solution

(a) T-Lam, with premises Γ⊢A:Sort u\Gamma \vdash A : \Sort{u} for some uu and Γ,x:A⊢x:A\Gamma, x : A \vdash x : A; the latter is T-Var. The resulting type is Π(x:A). A\tPi{x}{A}{A}, which is A→AA \to A up to the binder name. (b) T-Sort, with the single premise ⊢Γ;ok\ctxok{\Gamma}. (c) T-App, with premises Γ⊢f:Π(_:A). B\Gamma \vdash f : \tPi{\_}{A}{B} and Γ⊢a:A\Gamma \vdash a : A. The conclusion is B[_↦a]=B\subst{B}{\_}{a} = B, since _ does not occur in BB.

Using T-Pi, compute the universe of Π(P:Sort 0). P→P\tPi{P}{\Sort{0}}{P \to P} and of Π(A:Sort 1). A→A\tPi{A}{\Sort{1}}{A \to A}.

Solution

For the first, Sort 0:Sort 1\Sort{0} : \Sort{1} so u=1u = 1, and P→P:Sort 0P \to P : \Sort{0} (by T-Pi again with u=v=0u = v = 0) so v=0v = 0. Hence the universe is Sort imax(1,0)=Sort 0\Sort{\imax(1, 0)} = \Sort{0}: a statement quantifying over all propositions is itself a proposition. For the second, u=2u = 2 and A→A:Sort 1A \to A : \Sort{1} so v=1v = 1, giving Sort imax(2,1)=Sort 2\Sort{\imax(2,1)} = \Sort{2}. Chapter 13 explains the asymmetry.

What to remember

  • A context is an ordered list of distinct assumptions x:Ax : A; the judgment Γ⊢t:A\Gamma \vdash t : A says that tt has type AA under those assumptions.
  • There is one rule per kind of term, plus T-Conv, which identifies types up to computation and bound-variable renaming.
  • T-App is where hypotheses are used and where substitution happens; T-Conv is the only rule not triggered by the shape of the term.
  • Substitution and definitional equality are treated as black boxes until Part III.