Chapter 13
Universes: Why Sort u?
Chapter 4 showed that the typing rules implement a logic, and that the system is acceptable only if it is consistent. This chapter asks a question that has been deferred since Chapter 2: what is the type of ? The simplest answer, a single universe that contains itself, makes the system inconsistent. Lean's answer, a hierarchy with an impredicative bottom universe, does not. Along the way the chapter explains the one odd-looking piece of T-Pi, the function .
What is the type of Sort 0?
A proposition variable appears in the type theory as an assumption . It can occur in two places: in a context, as in the left judgment below, or bound by or , as in the right one:
The left judgment proves for one fixed supplied from outside. The right one is a single closed term that proves it for every , and it can be applied later to any particular proposition; this is what the rows of Figure 4.1 need.
Both forms require to be a type. C-Ext, which adds to a context, and T-Lam and T-Pi, which bind , all have the premise for the type of the new variable. With , this premise reads for some : the universe of propositions must itself have a type. The question is which.
Type is not a type
Suppose we replace all universes by a single universe that contains itself:
Translate as . Then ranges over a collection that contains itself and every type built from it. Such a collection is the type-theoretic analogue of the set of all sets, and naive set theory shows that such collections lead to contradictions. The best-known example is Russell's paradox: for , both and lead to a contradiction.
Type theory has no membership test like , so Russell's argument does not carry over word for word. Girard instead adapted a related paradox about the collection of all well-orderings, due to Burali-Forti [Girard 1972], and Hurkens simplified the resulting term [Hurkens 1995]. The result is a closed term with
so the system is inconsistent: has no proof, yet has a term, and a kernel built on these rules accepts a proof of every statement. The essential ingredient is a type that quantifies over all of while being a member of , which lets contain a copy of its own double power set, something no set can do. Appendix C gives in full, explains how it works, and shows how to reproduce the result by changing one line of the kernel.
The damage reaches the algorithm as well. Subject reduction still holds, so if had a normal form, it would be a normal closed term of type . The part of the consistency proof in Appendix D that analyses normal terms does not use strong normalization and carries over to ; it shows that no such normal term exists. Hence has no normal form, strong normalization fails, and runs forever on it. A kernel with is not only unsound but also, on some inputs, non-terminating.
A hierarchy with an impredicative bottom
The second answer is that lives in a larger universe, which lives in a larger one still:
No universe contains itself. A -type takes an argument from one universe and returns a type in another, so T-Pi must also say which universe the -type itself belongs to. Lean's answer uses the function :
The case split in makes a -type impredicative when its body is a proposition, and predicative otherwise. Pick the universes of and below and watch where the -type lands.
Propositions are impredicative. If the body is a proposition (), the whole is a proposition, whatever it quantifies over. In particular is in , although it quantifies over all of . A universe that contains types quantifying over itself is called impredicative. Because every translated formula lies in , the premise of -elim always holds, so a universal statement can be instantiated with any proposition, even with itself. For example, with ,
so is well typed, with type . The same case makes a proposition, even though lives in ; Chapter 7 relied on this for induction.
# "Every proposition implies itself" is itself a proposition, # so it can be instantiated with itself. def id : forall (P : Sort 0), P -> P := fun (P : Sort 0) => fun (h : P) => h def self : forall (P : Sort 0), P -> P := id (forall (P : Sort 0), P -> P) id # The analogous statement one level up is NOT its own instance: # forall (A : Sort 1), A -> A lives in Sort 2, not Sort 1. def idT : forall (A : Sort 1), A -> A := fun (A : Sort 1) => fun (a : A) => a def selfT : forall (A : Sort 1), A -> A := idT (forall (A : Sort 1), A -> A) idT
Types are predicative. If the body is not a proposition (), the lives in the larger of the two universes. A type that quantifies over then lives in , which is never :
This property is called predicativity. For example, the identity on types has type , which lives in , so it cannot be applied to its own type; a copy at can. Each level holds the level beneath it, and in practice a few levels suffice; higher levels appear when one quantifies over large collections, such as the category of all small categories.
Why this is safe. Impredicativity looks like the self-reference that the previous section warned against, but it is confined: contains types that quantify over , yet is not a member of itself. Coquand showed that one impredicative universe at the bottom is consistent [Coquand 1988], whereas Girard's paradox can already be derived once two levels are impredicative [Hurkens 1995]. With these rules the system is consistent and strongly normalizing (Chapter 14).
Comparison with Lean
In Lean [de Moura and Ullrich 2021], is Prop, is Type u, and -types are assigned universes with as above. Two differences remain.
First, Prop in Lean has definitional proof irrelevance: any two proofs of the same proposition are definitionally equal. Our conversion does not identify proofs; adding this would make conversion depend on types, so the simple "normalize and compare" check of Chapter 12 would no longer suffice.
Second, Lean has universe polymorphism, so definitions can be stated once for all levels , and then matters for level variables as well, with constraints such as solved symbolically. In our system every level is a concrete number.
The table summarizes the design space.
| Design | Quantifies over | Drawback |
|---|---|---|
| No universes | values only | cannot say "for every proposition" |
| everything | inconsistent | |
| Two sorts | only | itself has no type |
| with | any level | over propositions is not a proposition |
| with (Lean) | any level | normalization is harder to prove |
Exercises
Compute the universe of , the statement "every predicate on every type holds everywhere" (which is false but well formed).
Solution
Innermost: , so . Next, has universe (its body has type ), so the middle has universe . Finally and the body is in , giving . The whole statement is a proposition. With instead of it would land in .
Explain why the selfT definition in the playground is rejected, by naming the rule and the two universes involved.
Solution
idT expects an argument . The argument supplied is , whose universe by T-Pi is , so compares with and fails: the kernel reports a type mismatch at the application. This is predicativity: a type that quantifies over is not in .
What to remember
- needs a type, because proposition variables are bound by and .
- A universe containing itself is inconsistent (Girard, Hurkens) and breaks normalization.
- The hierarchy avoids self-containment; makes propositions impredicative and everything else predicative.
- One impredicative universe at the bottom is safe; two are not. Lean adds proof irrelevance and universe polymorphism on top of the same design.