.. index:: single: Set (sort) single: SProp single: Prop single: Type .. _sorts: Sorts ~~~~~~~~~~~ .. insertprodn sort universe_expr .. prodn:: sort ::= Set | Prop | SProp | Type | Type @%{ _ %} | Type @%{ @universe %} universe ::= max ( {+, @universe_expr } ) | @universe_expr universe_expr ::= @universe_name {? + @natural } The types of types are called :gdef:`sorts `. All sorts have a type and there is an infinite well-founded typing hierarchy of sorts whose base sorts are :math:`\SProp`, :math:`\Prop` and :math:`\Set`. The sort :math:`\Prop` intends to be the type of logical propositions. If :math:`M` is a logical proposition then it denotes the class of terms representing proofs of :math:`M`. An object :math:`m` belonging to :math:`M` :term:`witnesses ` the fact that :math:`M` is provable. An object of type :math:`\Prop` is called a :gdef:`proposition`. We denote propositions by :n:`@form`. This constitutes a semantic subclass of the syntactic class :n:`@term`. The sort :math:`\SProp` is like :math:`\Prop` but the propositions in :math:`\SProp` are known to have irrelevant proofs (all proofs are equal). Objects of type :math:`\SProp` are called :gdef:`strict propositions `. See :ref:`sprop` for information about using :math:`\SProp`, and :cite:`Gilbert:POPL2019` for meta theoretical considerations. The sort :math:`\Set` intends to be the type of small sets. This includes data types such as booleans and naturals, but also products, subsets, and function types over these data types. We denote specifications (program types) by :n:`@specif`. This constitutes a semantic subclass of the syntactic class :n:`@term`. :math:`\SProp`, :math:`\Prop` and :math:`\Set` themselves can be manipulated as ordinary terms. Consequently they also have a type. Because assuming simply that :math:`\Set` has type :math:`\Set` leads to an inconsistent theory :cite:`Coq86`, the language of |Cic| has infinitely many sorts. There are, in addition to the base sorts, a hierarchy of universes :math:`\Type(i)` for any integer :math:`i ≥ 1`. Like :math:`\Set`, all of the sorts :math:`\Type(i)` contain small sets such as booleans, natural numbers, as well as products, subsets and function types over small sets. But, unlike :math:`\Set`, they also contain large sets, namely the sorts :math:`\Set` and :math:`\Type(j)` for :math:`j