Jump to content

Universes and Prop

From The Invariance Itself
Revision as of 19:34, 15 October 2026 by PMA Publisher (talk | contribs) (Published from the Principia Machina source)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Plain-language version: Why there is no type of all types
Lean theorem prover: map
Reading the edition
Three levels of reading
Glossary
Notation
Chronology
Reading by level
Start here: What a proof assistant does
The type theory: Terms, types and judgments
How Lean works: Elaboration
The history: Automath
The applications: Research mathematics
Sources
Sources
Bibliography
Further reading
Related
The move to Lean

In Lean every type is itself a term, so every type has a type. The types of types are called universes or sorts. They form a hierarchy: Sort 0, Sort 1, Sort 2 and so on, each a member of the next, with no top. The bottom level, Sort 0, is Prop, the universe of propositions, and it obeys different rules from the levels above it. This page sets out the hierarchy, the rule that assigns a universe to a function type, the operation imax that rule needs, universe polymorphism, and the paradox that makes a hierarchy necessary.

Sorts and their names

Each universe has a level, and Sort u is the universe at level u. Two abbreviations name the cases that matter in practice: Prop is Sort 0, and Type u is Sort (u + 1), with Type alone meaning Type 0, that is, Sort 1.[1]

#check Prop
#check Type
#check Type 3
#check Sort 0
example : Sort 0 = Prop := rfl
example : Sort 1 = Type := rfl
example : Sort (3 + 1) = Type 3 := rfl

Lean prints Prop : Type, Type : Type 1, Type 3 : Type 4 and Prop : Type, and accepts the three equations by rfl: the names are notation for the same terms. The typing rule behind the first four lines is the sort rule of Terms, types and judgments,

Γ⊢Sortu:Sort(u+1)

and nothing else gives a universe a type. In particular no universe is a member of itself:

example : Type := Type

Lean 4.34.1 rejects it:

Type mismatch
  Type
has type
  Type 1
of sort `Type 2` but is expected to have type
  Type
of sort `Type 1`

Lean's universes are also not cumulative: a type in Type 0 is not thereby in Type 1, and each type has exactly one universe.[1] A type is moved up explicitly, by wrapping it:

example : Type 1 := Nat

fails with Type mismatch, reporting that Nat has type Type but is expected to have type Type 1. The standard wrapper is ULift, a structure with one field, down, whose universe parameter says how far to lift:

#check (ULift.{1} Nat)
example : Type 1 := ULift.{1} Nat

Lean prints ULift Nat : Type 1 and accepts the example. Coq, by contrast, has cumulative universes; Carneiro notes that cumulativity breaks the unique-typing theorem his analysis of Lean relies on.[2]

The universe of a function type

A dependent function type (x : A) → B is a type, so it lives in some universe. The formation rule decides which:

Γ⊢A:SortuΓ,x:A⊢B:SortvΓ⊢(x:A)→B:Sort(imaxuv)

where

imaxuv={0if v=0max⁡(u,v)otherwise.

There are two cases.[1][2]

  • The codomain is data (v≥1). The function type lives in the larger of the two universes. A type in Type u may only quantify over types in universes no larger than its own; this is predicativity.
  • The codomain is a proposition (v=0). The function type is a proposition, whatever the domain. A proposition may quantify over all propositions, or over all types at any level, and still be a proposition; this is impredicativity.
#check ∀ (p : Prop), p → p
#check (α : Type) → α → α
#check (α : Type 2) → Prop
#check (n : Nat) → n = n

The output is

∀ (p : Prop), p → p : Prop
(α : Type) → α → α : Type 1
Type 2 → Prop : Type 3
∀ (n : Nat), n = n : Prop

The first statement quantifies over every proposition, including itself, and is a proposition. The second, the type of the polymorphic identity function on Type, quantifies over Type and so lands one level up, in Type 1. The third is a function type into Prop, not a function type whose values are proofs, so it is data: its codomain Prop lives in Sort 1, and the result is in Sort(max⁡(4,1))= Type 3.

Why imax

The two cases could be stated as two rules. A single operation on levels is needed because of universe polymorphism. A definition may be stated for an arbitrary level variable v, and the rule must give the function type a universe without knowing whether v will later be 0. With max alone that is impossible. The obvious candidate, max⁡uv, goes wrong when v is set to 0: a proposition that quantifies over a type in Sort u would land in Sort(max⁡(u,0))=Sortu instead of in Prop, and Prop would not be impredicative. No other expression built from max and successor does better: one that mentions u is never below u, so it is not 0 when v is 0 and u is not, and one that does not mention u cannot equal max⁡(u,v) for every u. imax is the level expression that reduces to the right case once v is known.[1]

Level expressions are built from numerals, variables, successor, max and imax, and two levels are equal when they denote the same number under every assignment of numbers to their variables.[2] Lean will not treat imaxuv as max⁡uv, because the two differ when v is 0:

universe u v

def Fn (α : Sort u) (β : Sort v) : Sort (imax u v) := α → β

#check Fn.{1, 0}
#check Fn.{1, 1}
#check Fn.{0, 2}

The three instances print as Fn : Type → Prop → Prop, Fn : Type → Type → Type and Fn : Prop → Type 1 → Type 1: the same definition gives a proposition-valued result in the first case and data in the other two. Stating the result universe as Sort (max u v) instead is rejected:

universe u v

def Fn2 (α : Sort u) (β : Sort v) : Sort (max u v) := α → β
Type mismatch
  α → β
has type
  Sort (imax u v)
of sort `Type (imax u v)` but is expected to have type
  Sort (max u v)
of sort `Type (max u v)`

Universe polymorphism

A definition may take universe parameters, written after its name as .{u, v}. It is then a schema: each use instantiates the parameters with level expressions, and instantiations at different levels need not be definitionally equal.[1]

set_option pp.universes true in
#check @id
#check @id.{0}
#check List.{0}

Lean prints @id.{u_1} : {α : Sort u_1} → α → α, then @id : ∀ {α : Prop}, α → α for the instance at level 0, where the identity function on proofs is itself a proof of a proposition, and List : Type → Type. This is what lets one identity function, one list type and one equality serve at every level. Without it each would have to be defined once per universe.

Prop

Prop is the universe of propositions. Besides impredicativity, it has properties that the levels above it lack:[3]

  • Definitional proof irrelevance: any two proofs of the same proposition are definitionally equal.
  • Run-time irrelevance: proofs are erased from compiled code.
  • Restricted elimination: except for a class of propositions with at most one proof, a proof cannot be used to produce data, only other proofs.
  • Extensionality: logically equivalent propositions are equal, by the axiom propext.

An impredicative universe of propositions is a feature of the Calculus of Constructions of Coquand and Huet, and the theory implemented by Lean's kernel is a version of that calculus.[4][5][6] Its strength is real: Carneiro observes that impredicativity corresponds, in a set-theoretic model, to having full power sets.[2] The restriction on elimination is how the rules ensure that no computation can tell which proof of a proposition it has received, as proof irrelevance requires;[7] it is treated on Proof irrelevance and subsingleton elimination.

Why there is a hierarchy

The simplest design would be a single universe containing every type, itself included: Type : Type. That design is inconsistent. In 1972 Girard derived a contradiction in a type system called System U, by formalising a paradox in the style of Burali-Forti's paradox of the largest ordinal. The same argument shows that the first version of Martin-Löf's type theory, which had Type : Type, proves falsity; in type theory the argument is known as Girard's paradox.[8][9] The Homotopy Type Theory book makes the same point for a universe that contains itself: every type, including the empty one, becomes inhabited.[10]

Hurkens's paper locates the problem precisely. Higher-order logic, in which propositions may quantify over all propositions, is consistent. Adding a single rule, which lets a type be formed by quantifying over the sort of all types, gives the system called λU−, which Coquand had already shown inconsistent; Hurkens gives a short term in it whose type is falsity.[9] Impredicativity for propositions alone is therefore consistent, and adding it for types as well is not. Lean's design follows the line exactly: Prop is impredicative, and every universe above it is predicative and contained in the next. The plain-language account is Why there is no type of all types.

How strong the resulting hierarchy is, measured against set theory, is the subject of Consistency and the metatheory.

Next

Inductive types and recursors shows how every type other than universes and function types is introduced, and how the universe rules constrain it.

References

  1. ↑ 1.0 1.1 1.2 1.3 1.4 The Lean Language Reference, for Lean 4.34.0, lean-lang.org, 2026, section 4.3, "Universes". https://lean-lang.org/doc/reference/4.34.0/The-Type-System/Universes/
  2. ↑ 2.0 2.1 2.2 2.3 Mario Carneiro, The Type Theory of Lean, MSc thesis, Carnegie Mellon University, 2019. https://github.com/digama0/lean-type-theory/releases/tag/v1.0
  3. ↑ The Lean Language Reference, for Lean 4.34.0, lean-lang.org, 2026, section 4.2, "Propositions". https://lean-lang.org/doc/reference/4.34.0/The-Type-System/Propositions/
  4. ↑ The Lean Language Reference, for Lean 4.34.0, lean-lang.org, 2026, section 2.3, "The Kernel". https://lean-lang.org/doc/reference/4.34.0/Elaboration-and-Compilation/
  5. ↑ Thierry Coquand and Gérard Huet, "The calculus of constructions", Information and Computation 76(2–3), 1988, pp. 95–120. https://doi.org/10.1016/0890-5401(88)90005-3
  6. ↑ Andreas Abel and Thierry Coquand, "Failure of Normalization in Impredicative Type Theory with Proof-Irrelevant Propositional Equality", Logical Methods in Computer Science 16(2), 2020. https://doi.org/10.23638/LMCS-16(2:14)2020
  7. ↑ The Lean Language Reference, for Lean 4.34.0, lean-lang.org, 2026, section 4.4.3.1.1.1, "Subsingleton Elimination". https://lean-lang.org/doc/reference/4.34.0/The-Type-System/Inductive-Types/
  8. ↑ nLab, "Burali-Forti's paradox", section "In type theory: Girard's paradox", revision of 24 November 2023. https://ncatlab.org/nlab/show/Girard%27s+paradox
  9. ↑ 9.0 9.1 Antonius J. C. Hurkens, "A simplification of Girard's paradox", in Typed Lambda Calculi and Applications (TLCA 1995), Lecture Notes in Computer Science 902, Springer, 1995, pp. 266–278. https://doi.org/10.1007/BFb0014058
  10. ↑ The Univalent Foundations Program, Homotopy Type Theory: Univalent Foundations of Mathematics, Institute for Advanced Study, 2013, section 1.3, "Universes and families". https://homotopytypetheory.org/book/