universe-levels.lagda.rst 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. ..
  2. ::
  3. module language.universe-levels where
  4. open import Agda.Builtin.Unit
  5. .. _universe-levels:
  6. ***************
  7. Universe Levels
  8. ***************
  9. .. _universe-polymorphism:
  10. Agda' type system includes an infinite hierarchy of universes ``Setᵢ :
  11. Setᵢ₊₁``. This hierarchy enables quantification over arbitrary types
  12. without running into the inconsistency that follows from ``Set :
  13. Set``. These universes are further detailed on the page on
  14. :ref:`Agda's sort system <sort-system>`.
  15. However, when working with this hierarchy it can quickly get tiresome
  16. to repeat the same definition at different universe levels. For
  17. example, we might be forced to define new datatypes ``data List (A :
  18. Set) : Set``, ``data List₁ (A : Set₁) : Set₁``, etc. Also every
  19. function on lists (such as ``append``) must be re-defined, and every
  20. theorem about such functions must be re-proved, for every possible
  21. level.
  22. The solution to this problem is universe polymorphism. Agda provides a
  23. special primitive type ``Level``, whose elements are possible levels
  24. of universes. In fact, the notation for the ``n`` th universe,
  25. ``Setₙ``, is just an abbreviation for ``Set n``, where ``n : Level``
  26. is a level. We can use this to write a polymorphic ``List`` operator
  27. that works at any level. The library ``Agda.Primitive`` must be
  28. imported to access the ``Level`` type. The definition then looks like
  29. this:
  30. ::
  31. open import Agda.Primitive
  32. data List {n : Level} (A : Set n) : Set n where
  33. [] : List A
  34. _::_ : A → List A → List A
  35. This new operator works at all levels; for example, we have
  36. .. code-block:: agda
  37. List Nat : Set
  38. List Set : Set₁
  39. List Set₁ : Set₂
  40. Level arithmetic
  41. ----------------
  42. Even though we don't have the number of levels specified, we know that
  43. there is a lowest level ``lzero``, and for each level ``n``, there
  44. exists some higher level ``lsuc n``; therefore, the set of levels is
  45. infinite. In addition, we can also take the least upper bound ``n
  46. ⊔ m`` of two levels. In summary, the following (and only the
  47. following) operations on levels are provided:
  48. .. code-block:: agda
  49. lzero : Level
  50. lsuc : (n : Level) → Level
  51. _⊔_ : (n m : Level) → Level
  52. This is sufficient for most purposes; for example, we can define the
  53. cartesian product of two types of arbitrary (and not necessarily
  54. equal) levels like this:
  55. ::
  56. data _×_ {n m : Level} (A : Set n) (B : Set m) : Set (n ⊔ m) where
  57. _,_ : A → B → A × B
  58. With this definition, we have, for example:
  59. .. code-block:: agda
  60. Nat × Nat : Set
  61. Nat x Set : Set₁
  62. Set × Set : Set₁
  63. Intrinsic level properties
  64. --------------------------
  65. .. _intrinsic-level-properties:
  66. Levels and their associated operations have some properties
  67. which are internally and automatically solved by the compiler.
  68. This means that we can replace some expressions with others,
  69. without worrying about the expressions
  70. for their corresponding levels matching exactly.
  71. For example, we can write::
  72. _ : {F : (l : Level) → Set l} {l1 l2 : Level} → F (l1 ⊔ l2) → F (l2 ⊔ l1)
  73. _ = λ x → x
  74. and Agda does the conversion from ``F (l1 ⊔ l2)`` to ``F (l2 ⊔ l1)`` automatically.
  75. Here is a list of the level properties:
  76. * Idempotence: ``a ⊔ a`` is the same as ``a``.
  77. * Associativity: ``(a ⊔ b) ⊔ c`` is the same as ``a ⊔ (b ⊔ c)``.
  78. * Commutativity: ``a ⊔ b`` is the same as ``b ⊔ a``.
  79. * Distributivity of ``lsuc`` over ``⊔``: ``lsuc (a ⊔ b)`` is the same as ``lsuc a ⊔ lsuc b``.
  80. * Neutrality of ``lzero``: ``a ⊔ lzero`` is the same as ``a``.
  81. * Subsumption: ``a ⊔ lsuc a`` is the same as ``lsuc a``.
  82. Notably, this also holds for arbitrarily many ``lsuc`` usages:
  83. ``a ⊔ lsuc (lsuc a)`` is also the same as ``lsuc (lsuc a)``.
  84. ``forall`` notation
  85. -------------------
  86. From the fact that we write ``Set n``, it can always be inferred that
  87. ``n`` is a level. Therefore, when defining universe-polymorphic
  88. functions, it is common to use the `∀` (or `forall`) notation. For
  89. example, the type of the universe-polymorphic ``map`` operator on
  90. lists can be written
  91. .. code-block:: agda
  92. map : ∀ {n m} {A : Set n} {B : Set m} → (A → B) → List A → List B
  93. which is equivalent to
  94. .. code-block:: agda
  95. map : {n m : Level} {A : Set n} {B : Set m} → (A → B) → List A → List B
  96. .. _set-omega:
  97. Expressions of sort ``Setω``
  98. ----------------------------
  99. In a sense, universes were introduced to ensure that every Agda
  100. expression has a type, including expressions such as ``Set``,
  101. ``Set₁``, etc. However, the introduction of universe polymorphism
  102. inevitably breaks this property again, by creating some new terms that
  103. have no type. Consider the polymorphic singleton set ``Unit n :
  104. Setₙ``, defined by
  105. ::
  106. data Unit (n : Level) : Set n where
  107. <> : Unit n
  108. It is well-typed, and has type
  109. .. code-block:: agda
  110. Unit : (n : Level) → Set n
  111. However, the type ``(n : Level) → Set n``, which is a valid Agda
  112. expression, does not belong to any universe in the ``Set`` hierarchy.
  113. Indeed, the expression denotes a function mapping levels to sorts, so
  114. if it had a type, it should be something like ``Level → Sort``, where
  115. ``Sort`` is the collection of all sorts. But if Agda were to support a
  116. sort ``Sort`` of all sorts, it would be a sort itself, so in
  117. particular we would have ``Sort : Sort``. Just like ``Type : Type``,
  118. this would leads to circularity and inconsistency.
  119. Instead, Agda introduces a new sort ``Setω`` that stands above all
  120. sorts ``Set ℓ``, but is not itself part of the hierarchy. For example,
  121. Agda assigns the expression ``(n : Level) → Set n`` to be of type
  122. ``Setω``.
  123. ``Setω`` is itself the first step in another infinite hierarchy
  124. ``Setωᵢ : Setωᵢ₊₁``. However, this hierarchy does not support universe
  125. polymorphism, i.e. there are no sorts ``Setω ℓ`` for ``ℓ : Level``.
  126. Allowing this would require a new universe ``Set2ω``, which would then
  127. naturally lead to ``Set2ω₁``, and so on. Disallowing universe
  128. polymorphism for ``Setωᵢ`` avoids the need for such even larger
  129. sorts. This is an intentional design decision.
  130. Pragmas and options
  131. -------------------
  132. .. _type-in-type:
  133. * The option ``--type-in-type`` disables the checking of universe level
  134. consistency for the whole file.
  135. .. _omega-in-omega:
  136. * The option ``--omega-in-omega`` enables the typing rule ``Setω :
  137. Setω`` (thus making Agda inconsistent) but otherwise leaves universe
  138. checks intact.
  139. .. _no_universe_check-pragma:
  140. * The pragma ``{-# NO_UNIVERSE_CHECK #-}`` can be put in front of a
  141. data or record type to disable universe consistency checking
  142. locally. Example:
  143. ::
  144. {-# NO_UNIVERSE_CHECK #-}
  145. data U : Set where
  146. el : Set → U
  147. This pragma applies only to the check that the universe level of the
  148. type of each constructor argument is less than or equal to the
  149. universe level of the datatype, not to any other checks.
  150. .. versionadded:: 2.6.0
  151. The options ``--type-in-type`` and ``--omega-in-omega`` and the pragma
  152. ``{-# NO_UNIVERSE_CHECK #-}`` cannot be used with `--safe`.