\chapter{The Calculus of Inductive Constructions}
\label{chap:tech-intro}

\margintoc

Most of this thesis revolves around \kl[dependent type]{dependent type systems}.
Due to their complexity, there is a high number of
points subject to slight variations
when one tries to give a precise definition of a system.
Some of these variations are unimportant, but some introduce subtle albeit large differences
in the resulting systems. In this chapter we go in details over
the definition of what I refer to as the
\kl{Calculus of Inductive Constructions} (\kl{CIC}) in the rest of this
thesis, where it serves as the base system.
While doing so, I try to give an idea of the trade-offs involved, and of the reasons
behind the choices. Quite a few of those vary during the thesis,
and this is by design: there is no single better choice,
instead one has to adapt to the setting.

For the impatient specialists, let me say now that with \kl{CIC}, I
mean an intensional type theory, with Church-style abstractions,
a predicative hierarchy of universes%
\sidenote[][14em]{
  And only those: by default I do \emph{not} include an impredicative sort of propositions, a feature often associated with the name \kl{CIC}. I still use that name because of
  two characteristics that I feel sets apart the tradition around \kl{CIC} in the dependent type
  theory literature: the definition of \kl{conversion} as an \emph{untyped} relation,
  and the use of Church-style abstractions. See \cref{chap:names} for a longer discussion.}
\textit{à la} Russell, and any amount of inductive types presented by recursors.
% – the ones appearing most often in what comes next being the empty and
% unit types, booleans, natural numbers, dependent sums, lists, vectors and the equality.
Conversion is the reflexive, symmetric, transitive and congruent
closure of βι-reduction, and so in particular it is untyped.

For the others, the present chapter aims at introducing the basic
systems and properties which we refer to in the rest of the text.
\cref{sec:tech-typing} introduces the basic notions;
\cref{sec:tech-ccw} presents a first type system,
the \kl{Calculus of Constructions} (\kl{CCω}),
the purely functional core all our systems rely on;
\cref{sec:tech-conversion} defines the main notions of \kl{conversion} and
\kl{reduction} encountered in the rest of the thesis;
\cref{sec:tech-properties} introduces the main properties our systems should satisfy;
\cref{sec:tech-cic} adds inductive types to \kl{CCω} to build
\kl{CIC}; finally \cref{sec:tech-pcuic} discusses the extra additions to go from
\kl{CIC} to the \kl{Polymorphic, Cumulative Calculus of Inductive Constructions}
(\kl{PCUIC}), a faithful model of the type theory implemented by the
kernel of \kl{Coq}.

\section{Terms and Types}
\label{sec:tech-typing}

\AP Throughout this chapter, type systems are defined by means of a relation
$\Gamma \vdash t \ty T$, which reads “in the context $\Gamma$, the term $t$ has type $T$”.
From the logical point of view, this judgement means that $\Gamma$ is the list of
hypothesis available to deduce the conclusion $T$ by means of the proof $t$.
On the programming side, it means that $t$ is a well-formed program of type $T$,
which uses the variables listed together with their types in $\Gamma$.
Hence, $\Gamma$ is a list of declarations, of the form $x : A$.
We write $\intro*\emptycon$ for the empty context,
$\Gamma, x : A$ for the extension of context $\Gamma$ with the new variable $x : A$,
and $(x : A) \in \Gamma$ to denote that the declaration $x : A$ appears
in the context $\Gamma$.

\begin{marginfigure}
  \ContinuedFloat*
  \begin{mathpar}
  \inferdef{Var}{\vdash \Gamma \\ (x : A) \in \Gamma}{\Gamma \vdash x \ty A}
  \label{rule:cic-var}
  \end{mathpar}
  \caption{Typing rule for a variable}
  \label{fig:cic-var}
\end{marginfigure}

This typing relation itself is defined by means of inference rules,
such as \ruleref{rule:cic-var} opposite. The way to read this rule is that the judgement
underneath the line follows from the one above,
\ie from $(x : A) \in \Gamma$
and $\vdash \Gamma$ –~a judgement that we will soon define asserting that the context
$\Gamma$ is well-formed – we can deduce $\Gamma \vdash x \ty A$.
When objects appear in the hypothesis but not the conclusion, they are implicitly
universally quantified.
Once a set of such inference rules is fixed,
typing is defined as the least relation closed by those
rules. Equivalently, a judgement such as $\Gamma \vdash t \ty T$
holds whenever we can build a tree whose nodes are instances of the inference rules,
and whose root is the judgement in question. A general setting
for this kind of definitions of type systems can be found in \sidetextcite{Bauer2020},
but in our case we restrict to this level of informality for the time being.%
\sidenote{In \arefpart{metacoq}, however, such judgements
are formalized as inductively defined propositions.}

\AP As we have already introduced variables, a word on those as well. Variables are difficult
to account for precisely, because of issues like shadowing – a conflict between two variables
with the same name – or \intro{α-equality} $\mathord{\intro*\alpheq}$~–
the identification between two terms
only differing on variable names. There are multiple techniques to solve these issues
– see the many solutions to the POPLMark Challenge~\sidecite{Aydemir2005} –,
but we again treat these in an informal way, assuming
there is no shadowing whatsoever and identifying α-equal terms when needed.%
\sidenote{A precise treatment is again given in \arefpart{metacoq}, where we
use De Bruijn variables.}

\AP \phantomintro{\into}
A final important building block of all our type theories is \intro{substitution},
that we write $\intro*\subs{t}{x}{u}$. This meta-operation replaces every occurrence of $x$
in $t$ by the term $u$.
Once again, we treat this operation informally, assuming it never creates
shadowing – what is sometimes called “capture-avoiding” substitution.
It is sometimes useful to substitute multiple variable at once in parallel,
which we write $\intro*\multisubs{t}{x_1 \into u_1, \dots, x_n \into u_n}$.

\section{Functional Core: \kl(tit){CCω}}
\label{sec:tech-ccw}

\AP Let us now turn to the core of \kl{CIC}, namely the
\intro{Calculus of Constructions} (\intro{CCω}). Through the \kl{Curry-Howard correspondence},
it is both a typed form of λ-calculus – \ie a kind of purely functional
programming language – and a minimal form
of logic – only containing universal quantification and implication.
Since its introduction by \sidetextcite{Coquand1988}, it has been the subject of intense
theoretical study, modifications, and extensions, so let us fix what we exactly mean
with “\kl{CCω}”.

\subsection{Functions and applications}

Let us start with the basic terms: functions and applications.

\begin{marginfigure}
  \ContinuedFloat
  \begin{mathpar}
    \inferrule{\Gamma \vdash A \ty \uni \\ \Gamma, x : A \vdash t \ty T}
    {\Gamma \vdash \l x : A .\ t \ty A \to T}
    \and
    \inferrule{\Gamma \vdash f \ty A \to T \\ \Gamma \vdash u \ty A }{ \Gamma \vdash f\ u \ty T}
  \end{mathpar}
  \caption{Typing for non-dependent functions}
  \label{fig:cic-nondep-fun}
\end{marginfigure}

Functions, also called λ-abstractions, are written $\l x : A .\ t$. This corresponds
to the mathematical notation $x \mapsto t$: the body $t$ of the function
is a term that might contain the variable $x$,
and the constructor λ abstracts over that variable to build a function.
Conversely, function application is denoted by simple juxtaposition, as in $t\ u$.
The type of functions is written $\to$, as in ordinary mathematics.
You can see those at work in \cref{fig:cic-nondep-fun}: an abstraction builds a term of arrow
type, and application needs its function to be of an arrow type,
whose domain must moreover correspond to the type of the argument.
The side-condition $\Gamma \vdash A \ty \uni$ ensures that the annotation is a valid type,
we will introduce it shortly.
Logically, those rules make sense if $\to$ is read as implication:
if from a hypothesis $A$ one can deduce $T$, then $A \to T$ holds; conversely if $A \to T$
and $A$ both hold, then $T$ does as well.

\begin{marginfigure}
  \ContinuedFloat*
  \begin{mathpar}
    \inferdef{Abs}{\Gamma \vdash A \ty \uni \\ \Gamma, x : A \vdash t \ty T}
    {\Gamma \vdash \l x : A .\ t \ty \P x : A.\ T}
    \label{rule:cic-abs}
    \and
    \inferdef{App}{\Gamma \vdash f \ty \P x : A.\ T \\ \Gamma \vdash u \ty A}{ \Gamma \vdash f\ u \ty \subs{T}{x}{u}}
    \label{rule:cic-app}
  \end{mathpar}
  \caption{Typing for dependent functions}
  \label{fig:cic-dep-fun}
\end{marginfigure}
These arrow types, however, are not as expressive as one could hope for.
Remember that we are in the realms of dependent types, so not only $t$ might mention $x$,
but also $T$. For instance, $T$ might be something like “$x$ is even”. In such a case,
we need to record that dependency, which is the point of Π-types
– or dependent function types –, shown in \cref{fig:cic-dep-fun}.
Seen as function types, they record the fact that the codomain
might vary depending on the argument. This is reflected in the typing rule for application:
since the codomain $T$ might depend on $x$, the type of the application $f\ u$ is $T$
\emph{specialized at the argument $u$}, using substitution.
Seen on the logical side, Π-types correspond to universal quantification
$\operatorname{\forall} x : A.\ T(x)$.
Indeed, if one can show that $T(x)$ holds for an unspecified $x$,
then it must hold for all $x: A$ – this is \ruleref{rule:cic-abs}.
Conversely, if $T$ holds for all $x: A$, then one can deduce $T(u)$ for any specific
$u \ty A$ – this is \ruleref{rule:cic-app}.
The rules of \cref{fig:cic-nondep-fun} are just a special case
of those, in the case where the codomain $T$ does not depend
on the variable $x$, and we use this convention throughout the thesis:
$A \to T$ is shorthand for $\P x : A.\ T$ when $T$ does not mention $x$.

\AP One last thing to note about our functions is that they record the type of their
domain – what is called \intro{Church-style}
abstraction~\sidecite[][Section~3]{Barendregt1992}. There is an alternative –
the \intro{Curry-style} abstractions –, that
does not do so, simply using $\l x.\ t$ for functions.
This difference becomes important as soon as one looks at the bidirectional structure.
Indeed, the annotation is required if one wants to infer types for functions,
rather than barely checking them.
The \kl{Curry-style} option is sensible though,
see for instance the implementation of the proof assistant \kl{Agda} \sidecite[][p.~19]{Norell2007}, \sidetextcite{Abel2017} or \sidetextcite{McBride2022}.
In the end, this is really a design choice between being able to infer a type for any term,
or requiring annotations that in a lot of cases are useless. In this
thesis we stick with the approach used in \kl{Coq}, and annotate our abstractions.

\subsection{Universes}

To be able to express ideas like induction principles or polymorphic functions, it is
extremely useful to use functions and Π-types quantifying over types.
This is what the universe $\intro*\uni$ – read “Type” — is for. It is the type… of a type.
This also means that the border between types and terms is not a syntactic one, because
\eg functions can abstract over a type. Instead, types are simply terms of type $\uni$.
Despite this, we still use upper case letters for terms which we want to think of as types.
Such a universe is called \textit{à la} Russell~\sidecite{Palmgren1998}, by contrast with
universes \textit{à la} Tarski, which regain the distinction between types and terms at
the cost of a somewhat heavier treatment of types.
Since we have not much use for a presentation \textit{à la} Tarski in this thesis,
we use the simpler one.

\begin{marginfigure}
  \ContinuedFloat
  \begin{mathpar}
    \inferdef{Univ}
    {\vdash \Gamma}
    {\Gamma \vdash \uni[i] \ty \uni[\unext{i}]}
    \label{rule:cic-univ}
  \end{mathpar}
  \caption{Typing for universes}
  \label{fig:cic-univ}
\end{marginfigure}

\AP There is an important caveat regarding universes.
Since the paradox exhibited by Russell in \citeauthor{Begriffsschrift}'s
\citetitle{Begriffsschrift}~\sidecite{Begriffsschrift},
logicians know that considering a set of all sets is a great
source of inconsistencies. Type theory is not devoid of this issue:
Girard~\sidecite[][Annex~A]{Girard1972}
shows how having a type with itself as type is inconsistent.
This inconsistency directly applies to the first dependent type system proposed by
Martin-Löf~\sidecite{MartinLoef1972}, which has a single universe $\uni$ and a rule $\uni \ty \uni$.
A common solution to this issue
is to stratify universes into an infinite hierarchy, which gives us \ruleref{rule:cic-univ}.
Note how $\uni$ is indexed by the \intro{universe levels} $i$ and $\unext{i}$.

\begin{marginfigure}
  \ContinuedFloat
  \begin{mathpar}
    \inferdef{ΠTy}
    {\Gamma \vdash A \ty \uni[i] \\ \Gamma, x : A \vdash B \ty \uni[j]}
    {\Gamma \vdash \P x : A.\ B \ty \uni[\umax{i}{j}]}
    \label{rule:cic-prod}
  \end{mathpar}
  \caption{Typing for dependent function types}
  \label{fig:cic-prod}
\end{marginfigure}

Using those universes, \ruleref{rule:cic-prod} gives the typing rule for
Π-types. We can also now give a definition of the $\vdash \Gamma$
judgement, asserting that a context is well-formed, in \cref{fig:cic-con}.
It simply means that all its types
are indeed types. Note that in \ruleref{rule:cic-cons-con}, we did not write down a
\kl{level} for the universe, we do so to mean the existence of some unconstrained one in
order to ease reading.

\begin{marginfigure}
  \ContinuedFloat
  \begin{mathpar}
    \inferdef{Empty}
    { }{\vdash \cdot}
    \label{rule:cic-empty-con} \and
    \inferdef{Ext}
    {\vdash \Gamma \\ \Gamma \vdash A \ty \uni}{\vdash \Gamma, x : A}
    \label{rule:cic-cons-con}
  \end{mathpar}
  \caption{Context well-formation}
  \label{fig:cic-con}
\end{marginfigure}

\AP One last important point regarding universes is the kind of \kl{levels} used.
A simple solution is to rely on natural numbers (of the meta-theory),
with the $\intro*\unextsymb$
and $\intro*\umaxsymb$ operations interpreted by the usual ones.
This is however not strictly necessary: we need levels
to form a (well-founded) pre-order to avoid inconsistency, and operations
such as $\unextsymb$ and $\umaxsymb$ to express our typing rules,
but levels could very well be something different from natural numbers.
In particular, the natural number approach fixes at which exact level a particular construction
is done, which is usually much more rigid than what one would wish for.
A more flexible approach, introduced under the name \intro{typical ambiguity} by
\sidetextcite{Harper1991},
uses level expressions based on level variables, rather than numbers.
This way, one can collect exactly the constraints between levels required for a
term to type-check, without artificially enforcing a
rigid interpretation by fixing their value to a precise number once and for all.
To simplify the presentation, our default \kl{CCω} and \kl{CIC} nonetheless use natural
numbers, but \kl{typical ambiguity} appears at multiple points in this thesis.

\section{50 Shades of Conversion}
\label{sec:tech-conversion}

\begin{marginfigure}
  \ContinuedFloat
  \begin{mathpar}
  \inferdef{Conv}
    {\Gamma \vdash t \ty T \\ \Gamma \vdash T \conv T' \ty \uni}
    {\Gamma \vdash t \ty T'}
  \label{rule:cic-conv}
  \end{mathpar}
  \caption{Conversion rule}
  \label{fig:cic-conv}
\end{marginfigure}

\AP There is one big missing part in the picture so far. Remember we are working with
dependent types, and that those can contain terms, which in turn can be seen as programs.
In the case for instance of the vector type we used in the introduction – and that we are
about to introduce formally –, what happens if a function expects an argument of type
$\Vect(A,3)$, but it is given as argument the output of a concatenation function,
which naturally has type $\Vect(A,2+1)$?
Surely we must have a way to relate both, since after all
the small program $2+1$ ought to compute $3$! This is exactly what
\ruleref{rule:cic-conv}%
\sidenote{This wraps up our typing
rules for \kl{CCω}, collected in \cref{fig:ccw-typing}. The rule for non-dependent functions
is not included, since the one for dependent functions subsumes it.}
is for: it allows to replace a type $T$ with one that is related to it by
\intro{conversion}, written $\intro*\conv$.
As usual, there are two ways to look at this relation. From the point of view of programs,
it incorporates a computational aspect directly inside the type system.
From the point of view of logic, it corresponds to types being the same “by definition”
rather than due to some reasoning
– which is why conversion is also called definitional equality or judgemental equality.
In our vector example, for instance, the two types are the same by virtue of
the definition of addition.

\begin{figure*}[ht]
  \LastFloat

  \begin{mathpar}
    %
    \jform{\vdash \Gamma}
    \inferdef{Empty}
      { }{\vdash \cdot}
    \and
    \inferdef{Ext}
      {\vdash \Gamma \\ \Gamma \vdash A \ty \uni}{\vdash \Gamma, x : A}
    \\\\
    \jform{\Gamma \vdash t \ty T}
    \inferdef{Var}{(x : A) \in \Gamma \\ \vdash \Gamma}{\Gamma \vdash x \ty A}
    \and
    \inferdef{Univ}
      {\vdash \Gamma}
      {\Gamma \vdash \uni[i] \ty \uni[\unext{i}]}
    \and
    \inferdef{ΠTy}
      {\Gamma \vdash A \ty \uni[i] \\ \Gamma, x : A \vdash B \ty \uni[j]}
      {\Gamma \vdash \P x : A.\ B \ty \uni[\umax{i}{j}]}
    \and
    \inferdef{Abs}{\Gamma \vdash A \ty \uni \\ \Gamma, x : A \vdash t \ty T}
    {\Gamma \vdash \l x : A .\ t \ty \P x : A.\ T}
    \and
    \inferdef{App}
      {\Gamma \vdash f \ty \P x : A.\ T \\ \Gamma \vdash u \ty A }
      {\Gamma \vdash f\ u \ty \subs{T}{x}{u}}
    \and
  \inferdef{Conv}
    {\Gamma \vdash t \ty T \\ \Gamma \vdash T \conv T' \ty \uni}
    {\Gamma \vdash t \ty T'}
  \end{mathpar}

  \caption{Collected typing rules for \kl{CCω}}
  \label{fig:ccw-typing}
\end{figure*}

Conversion is a complex relation, arguably the most subtle part of dependent types.
Consequently, there are quite different ways to present it, which in turn serve different
needs.
For this reason, we took care to set the typing rules of
\cref{fig:ccw-typing} up so that nothing has to
be changed in those when one definition of conversion or another is taken. The only
difference is in how the relation $\Gamma \vdash T \conv T' \ty \uni$ is defined.
This way, we can treat conversion as a black box when talking about typing,
making the theory modular.

\AP A first important divide is between \intro(conv){typed} and
\intro(conv){untyped} conversion.
On one side, conversion is seen as an intrinsically typed relation: terms are only convertible
\emph{at a given type}. On the other, conversion is a relation between raw terms,
that does not presuppose any form of typing. \Cref{fig:typed-untyped-conv} gives an
example of the computation rule for functions in both systems.
The “content” of the two rules is the same – they equate $(\l x : A.\ t)\ u$
and $\subs{t}{x}{u}$ – only the side-conditions differ substantially.
\kl{Typed conversion} goes back to the type theory of
\sidetextcite{MartinLoef1972}, and is a recurring feature in its many descendants.
\AP \kl{Untyped conversion} relates strongly to (untyped) λ-calculus%
\sidenote{Barendregt
  for instance uses the name “conversion” for the equational theory of untyped λ-calculus
in his reference work on the subject\cite{Barendregt1985}.}%
\margincite{Barendregt1985}
via the \intro{Pure Type Systems} (\kl{PTS}) \sidecite{Barendregt1991} literature.
In this thesis, we mainly consider untyped conversion, as \kl{Coq}’s meta-theory
has been mostly studied in that tradition.
But the relation between both in the context of
bidirectional typing is the main subject of \cref{chap:bidir-conv}.

\begin{figure}[ht]
  \begin{mathpar}
    \inferrule
      {\Gamma, x : A \vdash t \ty B \\ \Gamma \vdash u \ty A}
      {\Gamma \vdash (\l x : A.\ t)\ u \tdconv \subs{t}{x}{u} \ty \subs{B}{x}{u}}
    \and
    \inferrule{ }{(\l x : A.\ t)\ u \dconv \subs{t}{x}{u}}
  \end{mathpar}
  \caption{Example: typed and untyped β rule for conversion}
  \label{fig:typed-untyped-conv}
\end{figure}

A second axis is about how close the conversion relation is to an implementation.
For instance, conversion should be an equivalence relation,
but there are two approaches to that. The first – and most standard – one
is to simply \emph{define} conversion as an equivalence relation, by adding rules
for \eg transitivity, as the one of \cref{fig:trans-conv}.
\begin{marginfigure}
  \begin{mathpar}
    \inferrule
      {t \dconv t' \\ t' \dconv t''}
      {t \dconv t''}
  \end{mathpar}
  \caption{Example: transitivity rule for conversion}
  \label{fig:trans-conv}
\end{marginfigure}
This ensures that conversion has the right properties, but means it does not directly correspond
to an algorithm, as this transitivity rule cannot be directly implemented,
due to the need to “invent” the middle term $t'$.
% , since its middle term is not recorded in any place.
The λ-calculus theorists have known this issue for a long time, and they
have a solution: characterizing conversion by means of a \kl{reduction} relation $\red$, which
corresponds to the idea of program evaluation \cite{Barendregt1985}.
If this reduction is well-behaved,
%\sidenote{The main one being confluence.}
then two terms are convertible exactly when they reduce to the same third term.
This more operational characterization is closer to what can be implemented.
Turning things around, one can define conversion through reduction,
and only \emph{show} in retrospect that it has the good properties
that were enforced in the first approach – typically, that it is transitive.
\AP Conversion of the first kind we call \intro{declarative conversion}, while for the second
we talk about \intro{algorithmic conversion}.

In the rest of this section we give two presentations of \kl{untyped conversion}.
First, a \kl(conv){declarative} one, which we use to define \kl{CCω}, as is standard.
Second, an \kl(conv){algorithmic} one, anticipating the need for it later on
in Parts \refname{metacoq} and \refname{gradual}.
% in \arefpart{metacoq} where it is used to show decidability of type-checking, and
% in \arefpart{gradual}, where we extend it into a relation that is by design not transitive, so
% that basing it on declarative conversion would be nonsensical.

\subsection{Declarative conversion}
\phantomintro{\dconv}

\begin{marginfigure}
  \ContinuedFloat*
  \begin{mathpar}
    \inferdef{UConv}{\Gamma \vdash T' \ty \uni \\ T \dconv T'}{\Gamma \vdash T \conv T' \ty \uni}
    \label{rule:cic-conv-unty}
  \end{mathpar}
  \caption{Typing constraint on untyped conversion}
\end{marginfigure}

To start our presentation of \kl{untyped conversion},
let us first go back to \ruleref{rule:cic-conv}.
Even if we wish to describe conversion as
an untyped relation, we still enforce a typing constraint in \ruleref{rule:cic-conv},
in order to ensure that, whenever $\Gamma \vdash t \ty T$ is derivable,
$\Gamma \vdash T \ty \uni$ is as well.
This is exactly the content of \ruleref{rule:cic-conv-unty}, which combines conversion
with a check that the target type is indeed a well-formed type.

\begin{marginfigure}
  \ContinuedFloat
  \begin{mathpar}
    \inferdef{βConv}{ }{(\l x : A.\ t)\ u \dconv \subs{t}{x}{u}}
    \label{rule:cic-uconv-beta}
  \end{mathpar}
  \caption{Computation rule for functions}
  \label{fig:cic-uconv-beta}
\end{marginfigure}

Regarding conversion itself, the first rule is \ruleref{rule:cic-uconv-beta},
which corresponds to the computational behaviour
of functions: the variable of an applied λ-abstraction is replaced by the argument, using
substitution.

The rest of the rules ensure conversion has the properties it should. First are the
ones ensuring it forms an equivalence relation: it
is reflexive (\nameref{rule:cic-uconv-refl}), symmetric (\nameref{rule:cic-uconv-sym}),
and transitive (\nameref{rule:cic-uconv-trans}).

\begin{figure}[ht]
  \ContinuedFloat
  \begin{mathpar}
    \inferdef{ConvRefl}{ }{t \dconv t}
    \label{rule:cic-uconv-refl} \and
    \inferdef{ConvSym}{t \dconv t'}{t' \dconv t}
    \label{rule:cic-uconv-sym} \and
    \inferdef{ConvTrans}
      {t \dconv t' \\ t' \dconv t''}
      {t \dconv t''}
    \label{rule:cic-uconv-trans}
  \end{mathpar}
  \caption{Equivalence rules}
  \label{fig:cic-uconv-equiv}
\end{figure}

A second set of rules, collected in \cref{fig:cic-uconv-cong},
asserts that conversion is a congruence, meaning that it is compatible
with all term formers. As for the previous three, these correspond to properties we expect
from the conversion relation, that we simply declare to be true. Note that we include only
congruence rules for term formers with sub-terms – we \eg omit $\uni$. To be exhaustive,
we could have included congruence rules for all term formers, but when they have no
sub-term congruence is simply a special case of \ruleref{rule:cic-uconv-refl}.
Conversely, we could omit \ruleref{rule:cic-uconv-refl}
altogether and derive it from congruence rules,
which can be seen as a generalized form of reflexivity.

\begin{figure}[hb]
  \ContinuedFloat
  \begin{mathpar}
    \inferrule
    % \inferdef{ProdConv}
      {A \dconv A' \\ B \dconv B'}
      {\P x : A.\ B \dconv \P x : A'.\ B'}
    % \label{rule:cic-uconv-prod}
    \and
    \inferrule
    % \inferdef {AbsConv}
      {A \dconv A' \\ t \dconv t'}
      {\l x : A .\ t \dconv \l x : A'.\ t'}
    % \label{rule:cic-uconv-abs}
    \and
    % \inferdef{AppConv}
    \inferrule
      {f \dconv f' \\ u \dconv u' }
      {f\ u \dconv f'\ u'}
    % \label{rule:cic-uconv-app}
  \end{mathpar}
  \caption{Congruence rules}
  \label{fig:cic-uconv-cong}
\end{figure}

\subsection{Algorithmic conversion}
\phantomintro{\aconv}

\AP Before we can describe \kl{algorithmic conversion}, we first need
to have a look at \intro{reduction}. Reduction is in some way an operational version of
conversion. The main difference is that it is oriented, in the direction
corresponding to program evaluation. It itself decomposes into three components.

\AP The first is \intro{top-level reduction} $\intro*\tred$,
\begin{marginfigure}[0em]
  \ContinuedFloat*
  \begin{mathpar}
    \inferdef{βRed}{ }{(\l x : A.\ t)\ u \tred \subs{t}{x}{u}}
    \label{rule:beta-red}
  \end{mathpar}
  \caption{Top-level reduction}
  \label{fig:cic-algo-conv}
\end{marginfigure}
which corresponds purely to computation, without any congruence closure properties.
In \kl{CCω} there is only the single \ruleref{rule:beta-red}.

\AP The second component is the congruent closure of \kl{top-level reduction},
\intro{one-step reduction} $\intro*\ored$. It allows triggering top-level reduction exactly once,
but at any position in a term. Its definition is given in \cref{fig:ccw-ored}.
Note that while we talk about congruent closure both for
\kl(decl){conversion} (\cref{fig:cic-uconv-cong})
and \kl{one-step reduction}, we mean a different form of closure:
in the case of conversion, we demand the relation to recursively hold in all sub-terms,
while for one-step reduction it is allowed in exactly one sub-term.

\begin{figure}[ht]
  \ContinuedFloat
  \begin{mathpar}
    \inferrule
    % \inferdef{TopRed}
      {t \tred t'}
      {t \ored t'}
    % \label{rule:top-red}
    \and
    \inferrule
    % \inferdef{ProdRedDom}
      {A \ored A'}
      {\P x : A.\ B \ored \P x : A'.\ B}
    % \label{rule:red-prod-dom}
    \and
    \inferrule
    % \inferdef{ProdRedCod}
      {B \ored B'}
      {\P x : A.\ B \ored \P x : A.\ B'}
    % \label{rule:red-prod-cod}
    \and
    \inferrule
    % \inferdef{AbsRedDom}
      {A \ored A'}
      {\l x : A .\ t \ored \l x : A'.\ t}
    % \label{rule:red-abs-dom}
    \and
    \inferrule
    % \inferdef{AbsRedBod}
      {t \ored t'}
      {\l x : A .\ t \ored \l x : A.\ t'}
    % \label{rule:red-abs-bod}
    \and
    \inferrule
    % \inferdef{AppRedFun}
      {f \ored f'}
      {f\ u \ored f'\ u}
    % \label{rule:red-app-fun}
    \and
    \inferrule
    % \inferdef{AppRedArg}
      {u \ored u'}
      {f\ u \ored f\ u'}
    % \label{rule:red-app-arg}
  \end{mathpar}
  \caption{One-step reduction}
  \label{fig:ccw-ored}
\end{figure}

\AP Finally, we obtain \kl{reduction} $\intro*\fred$ as the reflexive
transitive closure of one-step reduction, see \cref{fig:red}.

\begin{figure}[ht]
  \ContinuedFloat
  \begin{mathpar}
    % \label{rule:top-red}
    \inferrule{ }{t \fred t}
    \and
    \inferrule
      {t \ored t' \\ t' \fred t''}
      {t \fred t''}
  \end{mathpar}
  \caption{Reduction}
  \label{fig:red}
\end{figure}

We can now get to \kl{algorithmic conversion}: two terms
are convertible whenever they reduce to terms that are \kl{α-equal}.
As for declarative conversion,
we impose a typing condition on the target type. Altogether, this leads to
\ruleref{rule:alg-conv}. For once, we make α-equality explicit to anticipate
its replacement by more complex relations later on.

\begin{figure}[ht]
  \ContinuedFloat
  \begin{mathpar}
    \inferdef{AlgConv}
    {\Gamma \vdash T' \ty \uni \\ T \red U \\ T' \red U' \\ U \alpheq U' }
    {\Gamma \vdash T \aconv T' \ty \uni}
    \label{rule:alg-conv}
  \end{mathpar}
  \caption{Algorithmic conversion}
\end{figure}

To wrap up this section, let us backtrack for a moment on the reason why we separated
the definition of reduction in three layers. This is because reduction as we defined it
is somewhat too unconstrained.\sidenote{In particular, it is non-deterministic.}
In what follows, a recurring need is that of a deterministic notion of reduction
which is able to expose a canonical term former,%
\sidenote{This notion is formally introduced in \cref{sec:tech-properties}.}
if it exists.
\AP There is a way to do so, what is called
\intro{weak-head reduction} $\intro\hred$. It amounts to restricting the place in a term where
\kl{top-level reduction} can be used, by removing some congruence rules compared to reduction. More precisely, λ-abstractions, Π-types and universes are not reduced further,
as they already are canonical forms of their types.
Variables are not reduced either, since they simply cannot be.
Thus, the only reduction that is allowed is in the function position of an application,
with the hope to get a λ-abstraction there that can be further reduced using top-level reduction.
Following these considerations, we arrive at \cref{fig:wh-red}.
When we want to contrast this \kl{weak-head reduction} with the
previously defined one $\mathord{\fred}$, we call the latter \intro{full reduction}.
\begin{figure}[ht]
  \AP \phantomintro{\hored}
  \begin{mathpar}
    \inferrule
    % \inferdef{TopRed}
      {t \tred t'}
      {t \hored t'}
    % \label{rule:top-red}
    \and
    \inferrule
      {f \hored f'}
      {f\ u \hored f'\ u}
    \and
    \inferrule{ }{t \hred t}
    \label{rule:red-refl} \and
    \inferrule
      {t \hored t' \\ t' \hred t''}
      {t \hred t''}
    \label{rule:red-trans}
  \end{mathpar}
  \caption{Weak-head reduction}
  \label{fig:wh-red}
\end{figure}

\section{The Good Properties}
\label{sec:tech-properties}

Before going further into more definitions of type systems, we should stop and consider
what makes these “good”. Designing type systems is a complex endeavour,
and many things can go wrong. What are the properties we expect from a type
system for it to give a valid notion of programming language or logic? How do we know that
a type system is well-behaved?
Let us go over some of these properties,
and some proof techniques that can be employed to establish them.

\subsection{Stability under basic operations}

The most essential properties of a type system are its stability
by basic type theoretic operations.
The first is stability under renaming, which states that a context can be replaced by another
one which contains at least the same variables:

\begin{property}[\intro{Stability under renaming}]
  \label{prop:stab-renaming}
  Whenever the following conditions are met
  \begin{itemize}
    \item $x_1 : A_1 \dots x_n : A_n \vdash t \ty T$
    \item $\vdash \Delta$
    \item for all $i$, there is a variable $y_i$ such that $(y_i : \multisubs{A_i}{x_1 \into y_1 \dots x_n \into y_n}) \in \Delta$%
  \end{itemize}
  we have that $\Delta \vdash \multisubs{t}{x_1 \into y_1 \dots x_n \into y_n} \ty \multisubs{T}{x_1 \into y_1 \dots x_n \into y_n}$.
\end{property}

Given the first premise, the context $x_1 : A_1 \dots x_n : A_n$ must be well-formed,%
\sidenote{This is a consequence of \kl{validity}, another property we are about to see.}
$A_i$ can only depend on variables
$x_1 \dots x_{i-1}$, thus we do not actually need to substitute the variables
$x_{i+1} \dots x_n$ in it. However, this presentation, where the same substitution is applied
to all types even if applies to variables which we know are not present in them,
is easier to work with in practice.

A direct consequence is the \kl{weakening} property:

\begin{minipage}{\textwidth}
  \begin{property}[\intro{Weakening}]
    \label{prop:weakening}
    Whenever $\Gamma \vdash t \ty T$
    and $\Gamma \vdash A \ty \uni$, it holds that $\Gamma, x : A \vdash t \ty T$.
  \end{property}
\end{minipage}

A stronger notion is that of stability under substitution, which allows replacing
variables by arbitrary terms.

\begin{minipage}{\textwidth}
\begin{property}[\intro{Stability under substitution}]
  \label{prop:stab-subst}
  For any substitution $\sigma$ (function from variables to terms)
  such that the following hold
  \begin{itemize}
    \item $x_1 : A_1 \dots x_n : A_n \vdash t \ty T$
    \item for all $x_i$, we have $\Delta \vdash \sigma(x_i) \ty \multisubs{A_i}{\sigma}$
  \end{itemize}
  it is also the case that $\Delta \vdash \multisubs{t}{\sigma} \ty \multisubs{T}{\sigma}$.
\end{property}
\end{minipage}

These two stability properties can be proven by direct induction on the typing derivations,
replacing hypotheses on the first context by hypothesis on the second. Of course, we need to
state and prove similar stability properties for conversion, again by induction.

There is, however, a stronger form of stability under renaming. While not as crucial as the
one above, it is still quite useful, especially to prove correctness of term manipulations,
such as those operated by tactics.

\begin{property}[\intro{Conditional stability under renaming}]
  \label{prop:strong-stab-renaming}
  Whenever the following conditions are met
  \begin{itemize}
    \item $x_1 : A_1 \dots x_n : A_n \vdash t \ty T$
    \item $\vdash \Delta$
    \item for all $i$ \emph{such that $x_i$ appears in $t$}, there is a variable $y_i$ such that $(y_i : \multisubs{A_i}{x_1 \into y_1 \dots x_n \into y_n}) \in \Delta$
  \end{itemize}
  there exists a type $T'$ such that $\Delta \vdash \multisubs{t}{x_1 \into y_1 \dots x_n \into y_n} \ty T'$.
\end{property}

The difference between the two is that we do not ask for all variables appearing in $\Gamma$
to be present in $\Delta$, only those that are “relevant” for $t$.
Thus, the important consequence is the following, which allows removing unused variables
from a context.

\begin{property}[\intro{Strengthening}]
  \label{prop:strengthening}
  If $\Gamma, x : A \vdash t \ty T$ holds and $x$ does not appear in $t$,
  there exists $T'$ such that $\Gamma \vdash t \ty T'$.
\end{property}

Strengthening is not as easy to obtain as \kl{weakening}, and there are some type theories
where it fails \sidecite{Haselwarter2021}.
In general, even if it holds – this is the case in all type theories
presented in this thesis – it cannot be proven by a direct induction on the typing
derivation. This is because of \ruleref{rule:cic-conv}. Indeed, in that rule the target type
$T'$ might very well use the variable $x$, so that we do not have in general
$\Gamma \vdash T' \ty \uni$. Thus, there is a need for further reasoning to prove that such a
type is never actually needed. We show in \cref{thm:strengthening-bidir}
how the bidirectional structure makes proving strengthening straightforward.

\subsection{Properties of types}

A second set of properties pertain to types themselves. They are less crucial than the
previous ones, but assess that the types that can be obtained for a term are well-behaved,
which is often useful to have in proofs of other properties of
the system – such as those in the rest of this section.

The first is \kl{validity},
which asserts that both types and contexts are well-formed whenever they appear in a typing
derivation.

\begin{property}[\intro{Validity}]
  \label{prop:validity}
  Whenever $\Gamma \vdash t \ty T$, we have $\vdash \Gamma$ and $\Gamma \vdash T \ty \uni$.
\end{property}

We set up \kl{CCω} so that it satisfies this property, but another approach – which we use
in the bidirectional setting – is to remove pre-conditions such as $\vdash \Gamma$ in
\ruleref{rule:cic-var} or $\Gamma \vdash T' \ty \uni$ in \ruleref{rule:cic-conv-unty}.
This is possible, but in that case a lot of properties have to be prefixed with extra
hypothesis of context/type well-formation.

The second property is \kl{uniqueness of types}, which relates the different types
of a same term.

\begin{property}[\intro{Uniqueness of types}]
  \label{prop:uniqueness}
  A type theory satisfies \reintro{uniqueness of types up to} a relation $\preceq$
  if whenever $t$ is well-typed in $\Gamma$,%
  \sidenote{\textit{I.e.}\ whenever there exists $S$ such that $\Gamma \vdash t \ty S$.}
  there exists a type $T$ such that $\Gamma \vdash t \ty T$
  and for any $T'$ such that $\Gamma \vdash t \ty T'$, we have $T' \preceq T$.

  We simply say \kl{uniqueness of types} for uniqueness up to \kl{conversion}.
\end{property}

Note that in the case where the relation $\preceq$ is symmetric and transitive,
–~in particular, \kl{conversion} –, \kl{uniqueness of types up to} $\preceq$ simplifies
to the fact that whenever $\Gamma \vdash t \ty T$ and $\Gamma \vdash t \ty T'$,
we have $T \preceq T'$. However, in \kl{PCUIC} we wish to replace \kl{conversion} with
\kl{cumulativity}, which is not symmetric –~it is only a pre-order –,
so the more involved definition is needed.

This property is not so easy to establish,
but as for \kl{strengthening} the bidirectional setting gives a straightforward proof approach,
see \cref{thm:unique-undir}.

\subsection{Subject reduction}

We already mentioned Milner’s slogan that “\textit{Well-typed programs cannot go wrong.}”
In our context, this means that if a term is well-typed, its reduction –~which corresponds to
program evaluation~–, should be well-behaved. This well-behaviour is separated
into multiple properties, the first of which is \kl{subject reduction},
which asserts that typing is preserved by reduction.

\begin{property}[\intro{Subject reduction}]
  \label{prop:sr}
  If $\Gamma \vdash t \ty T$ and $t \red t'$, then also $\Gamma \vdash t' \ty T$.
  This property is also called \reintro{preservation}.
\end{property}

To show that \kl{reduction} preserves typing, it suffices to show that \kl{one-step reduction}
does, by a simple induction. Moreover, using \kl{stability under substitution}, this further
reduces to \kl{top-level reduction} preserving typing. But how do we show this?

Suppose we have a β-redex such that $\Gamma \vdash (\l x : A.\ t)\ u \ty T$.
Analysing the typing
derivation, we can conclude there exists $A'$, $B$ and $B'$ such that
\begin{itemize}
  \item $\Gamma, x : A \vdash t \ty B$
  \item $\P x : A.\ B \dconv \P x : A'.\ B'$
  \item $\Gamma \vdash u \ty A'$
  \item $\subs{B'}{x}{u} \dconv T$
\end{itemize}
If we were able to conclude that $A \dconv A'$ and $B \dconv B'$, we could
deduce $\Gamma \vdash u \ty A$, then using \kl{stability under
substitution} we would get $\Gamma \vdash \subs{t}{x}{u} \ty \subs{B}{x}{u}$,
which would finally lead to $\Gamma \vdash \subs{t}{x}{u} \ty T$ using stability of
conversion under substitution and transitivity of conversion.
Thus, the key property is the following:

\begin{property}[\intro{Injectivity of function types}]
  \label{prop:prod-inj}
  Whenever $\P x : A.\ B \conv \P x : A'.\ B'$, we have $A \conv A'$ and $B \conv B'$.
\end{property}

In the more general setting of \kl{CIC} or \kl{PCUIC}, we do not have only Π-types.
Thus, we more generally talk about \reintro{injectivity of type constructors}.

For \kl{declarative conversion}, transitivity is trivial, but \kl{injectivity of function types}
is not so easy. Indeed, due to transitivity we could have
\[\P x : A.\ B \conv T_1 \conv \dots T_n \conv \P x : A'.\ B'\]
where the $T_i$ have no reason to be Π-types,
and so it is not so easy to relate $A$ and $A'$.
Conversely, for \kl{algorithmic conversion}, \kl{injectivity of function types} is rather
straightforward by induction on \kl{reduction} and \kl{α-equality}, but transitivity is
hard to show. Thus, in both cases \kl{subject reduction} is not direct.
The main missing property, which allows proving equivalence of both notions
of \kl{conversion}, and consequently subject reduction for either one of
the corresponding notions of typing, is \kl{confluence} of reduction.

\begin{marginfigure}
  \[\begin{tikzcd}
    & t \arrow[dl] \arrow[dr] & \\
    t_1 \arrow[dr, dashed] && t_2 \arrow[dl, dashed] \\
    & t'' &
  \end{tikzcd}\]
  \caption{Confluence, as a diagram}
\end{marginfigure}

\begin{property}[\intro{Confluence}]
  \label{prop:confluence}
  If $t \red t_1$ and $t \red t_2$ hold, then there exists some $t''$ such that
  $t_1 \red t''$ and $t_2 \red t''$.
\end{property}

This is a very widely studied property in the context of rewriting systems. A nice
proof technique relies on the definition of a notion of parallel reduction
\sidecite{Takahashi1995}.

\subsection{Progress}

\begin{marginfigure}
  \begin{mathpar}
    % \jform{\nm t}
    \inferrule{ }{\nm \uni}
    \and
    \inferrule{\nm A \\ \nm B}{\nm \P x : A.\ B}
    \and
    \inferrule{\nm A \\ \nm t}{\nm \l x : A .\ t} \and
    \inferrule{\ne t}{\nm t}
    \\
    % \jform{\ne t}
    \inferrule{ }{\ne x} \and
    \inferrule{\ne f \\ \nm u}{\ne f\ u}
  \end{mathpar}
  \caption{Normal and neutral forms}
  \label{fig:ccw-norm-neu}
\end{marginfigure}

\kl{Subject reduction} ensures that when a term reduces, this reduction is type-preserving.
The second important property linked to reduction characterizes which terms reduce.
To state it, we first need to define the $\nm$ and $\ne$ predicates,
characterizing respectively \intro{normal forms} and \intro{neutral forms}.
The inductive rules for those are given in \cref{fig:ccw-norm-neu}.
The idea is that neutral forms are those terms which are stuck on a variable, which blocks
further computation because it is not a λ-abstraction. Normal forms are either neutrals
or \intro{canonical forms},%
\sidenote{Alternatively called values.}
which have finished computing. For instance, a λ-abstraction is
the canonical form for a function. What \kl{progress} says is that these forms accurately
characterize well-typed terms which do not reduce.

\begin{minipage}{\textwidth}
\begin{property}[\intro{Progress}]
  For every well-typed term $t$, either $\nm t$ holds,
  or there is some $t'$ such that $t \ored t'$.
\end{property}
\end{minipage}

To prove progress, one can again resort to induction on the typing derivation. The key point
is to characterize the \kl{normal forms} at a given type,
by proving that they are either \kl{neutral forms}, or \kl{canonical form}
\emph{of the right kind}.
For instance, if $f$ is a normal form and has a function type, then it must be
either a neutral, or a λ-abstraction. Then, if $f$ is applied to $u$, then in the first
case $f\ u$ is a neutral – and thus a normal form –, or it reduces further, by a β step.

One way to understand \kl{progress} – and, indeed, the origin of the name – is that well-typed
terms do not get stuck: either they have finished computing, and thus satisfy $\nm$, or
they should be able to make progress by reducing further.
Put together with \kl{preservation}, progress can be iterated. Indeed,
if a term is well-typed, it is either a normal form, or reduces to a term, which is itself
well-typed by \kl{preservation}, so is either a normal form or reduces, and so on.
This decomposition of program safety into progress and preservation
has been standard since \sidetextcite{Wright1994}.

\begin{property}[\intro{Safety}]
  \kl{Safety} is the combination of \kl{progress} and \kl{preservation}.
  It implies that if $\vdash t \ty T$ and $t \red v \nored$, then $v$ must be a
  canonical form.
\end{property}

\subsection{Normalization}

The last important property, and one which is rather specific to type systems in the context of
proof languages, is \kl{normalization}. It ensures that progress cannot be applied
forever, but that evaluation always ends up reaching a normal form.
The most standard way to phrase this is to say that there is no infinite reduction sequence
starting from a well-typed term. This formulation, however, is constructively too weak,
so we instead use a more adequate – but classically equivalent – definition,
using the following accessibility predicate.

\begin{definition}[\intro{Accessibility}]
  Let $R$ be a relation on $A$. An inhabitant $a$ of $A$ is accessible if all $a'$
  such that $a \mathrel{R} a'$ are.
\end{definition}

In the intuitionistic setting, this way to phrase well-foundedness
is much better behaved because it does not appeal to negation. In particular,
we can do constructions on all accessible terms of a given relation by means of well-founded
induction, something we exploit in \kl{MetaCoq}, where this is the formulation we use for
normalization.

\begin{property}[\intro{Normalization}]
  \label{prop:normalization}
  Every well-typed term is \kl{accessible} for one-step co-reduction $\ocored$,
  the inverse relation of \kl{one-step reduction} $\ored$.
\end{property}

Normalization, combined with \kl{progress} and \kl{preservation},
entails that any well-typed term
eventually reduces to a normal form – which is moreover unique, by \kl{confluence}.
This gives a naive way to decide conversion. Even if one uses a more complex strategy,
normalization is a crucial building block towards decidability of typing.
Thus, it is a property of prime importance if we wish to
implement a type-checker for dependent types.

Another key consequence, of normalization is that,
there are some uninhabited types in the empty context,
for instance $\P A : \uni.\ A$.
This is one way to phrase \kl{logical consistency},%
\sidenote{Thanks to the principle of explosion.}
which has the advantage that it does not put forward one particular “false” type.

\begin{property}[\intro{Logical consistency}]
  \label{prop:log-cons}
  There is a type which is not inhabited in the empty context.
\end{property}

\AP
Indeed, there are no normal forms in the empty context at that type, and since any term
of that type must reduce to such a normal form, there are none.
Thus, normalization ensures our type systems are meaningful as logics,
which we of course care about!

More generally, normalization entails the \kl{canonicity} property for \intro{closed terms}
\sidenote{Terms which are not closed are called \reintro{open}.}
– \eg those that have no free variables, or, equivalently, that are well-typed in the empty
context.

\begin{property}[\intro{Canonicity}]
  \label{prop:canonicity}
  Every term $t$ that is well-typed in the empty context reduces to a \kl{canonical form}.
\end{property}

There is however an issue here: since normalization entails logical consistency, it is a hard
property to prove. In particular, due to Gödel’s incompleteness theorem, we cannot hope
to prove normalization of a type system in the logic given by that system itself…
Still, there are multiple approaches to proving normalization, from the venerable
reducibility method \sidecite{Tait1967} to the recent normalization by evaluation
techniques \sidecite{Abel2013a}. However, due to their complex character,
we do not tackle such proofs of normalization directly in this thesis. Instead, we
either suppose normalization when it is unavoidable,
or prove it relatively to that of another, simpler theory.

\section{Adding Inductive Types: \kl(tit){CIC}}
\label{sec:tech-cic}

\AP Of course, not everything in mathematics or programming is a function.
Although \kl{CCω} is powerful enough to encode many constructions,%
\sidenote{At least if one extends its universe hierarchy with an impredicative
universe.}
such encodings are not fully satisfactory: \sidetextcite{Geuvers2001} shows
that it is impossible to construct%
\sidenote{In a system close to our \kl{CCω}, but again with an impredicative universe.}
an encoding of natural numbers satisfying an induction principle,
which is their defining characteristic!
Because of such limitations of encodings, and in order to faithfully
represent the use of induction in mathematics and pattern-matching in programming languages,
the general class of \intro{inductive types} has been introduced
by \sidetextcite{PaulinMohring1993}.%
\sidenote{
  Earlier type theories, such as \cite{MartinLoef1972,MartinLoef1984}, presented specific
  instances of that class, but not a general scheme.
}%
\margincite{MartinLoef1972,MartinLoef1984}
Adding these to \kl{CCω} results in \intro{CIC},
the \intro{Calculus of Inductive Constructions}.

\subsection{Booleans}
\FloatBarrier

\begin{marginfigure}
  \ContinuedFloat*
  \begin{mathpar}
    \inferdef{BoolTy}{\vdash \Gamma}{\Gamma \vdash \Bool \ty \uni[0]}
    \label{rule:bool-type} \and
  \end{mathpar}
  \caption{The type of booleans}
  \label{fig:bool-type}
\end{marginfigure}

\begin{marginfigure}
  \ContinuedFloat
  \begin{mathpar}
    \inferdef{False}{\vdash \Gamma}{\Gamma \vdash \false \ty \Bool}
    \label{rule:false} \and
    \inferdef{True}{\vdash \Gamma}{\Gamma \vdash \true \ty \Bool}
    \label{rule:true}
  \end{mathpar}
  \caption{The boolean constructors}
  \label{fig:bool-cons}
\end{marginfigure}

\AP Let us start with a very simple example: \intro{booleans}.
To add those to \kl{CCω}, we need to specify three new kinds of term formers.
The first is the type, that we write $\intro*\Bool$ – see \ruleref{rule:bool-type}.
Next we need \intro{constructors}, giving the canonical inhabitants of the type.
In the case of booleans, there are two of them: the false boolean $\intro*\false$
and the true one $\intro*\true$ – this is Rules~\nameref{rule:false} and \nameref{rule:true}.

The last one is a way to use those canonical inhabitants.
For booleans, this corresponds to a conditional,
taking one branch or another depending on the value of the term being used,
whose typing rule is given in \ruleref{rule:bool-ind}.
We call $s$ the \intro{scrutinee}, $P$ the \reintro{predicate}
and $b_{\false}$, $b_{\true}$ the \reintro{branches}.
As was the case for dependent functions, here also there is a generalization with respect to
usual programming languages: the predicate type itself can depend on the
\kl{scrutinee}.
The usual if-then-else conditional thus corresponds to the special case
when $P$ does not depend on the variable $z$.
\AP We call this $\intro*\indop$ term former \intro{induction principle}, as
one can read $\ind{\Bool}{s}{z.P}{b_{\false},b_{\true}}$ as case distinction
on the scrutinee:
to prove that $P$ holds for an arbitrary boolean $s$, it suffices to show that both
$\subs{P}{z}{\false}$ and $\subs{P}{z}{\true}$ do – these are respectively proven by
$b_{\false}$ and $b_{\true}$. The name induction is not really
suitable here because we only have base cases and no induction step, but we get those
as soon as the inductive type itself is recursive.
We also use the name \reintro{recursor} interchangeably with induction principle,
but especially when we want to emphasize the programming point of view.

\begin{figure}[h]
  \ContinuedFloat
  \begin{mathpar}
    \inferdef{BoolInd}
      {\Gamma \vdash s \ty \Bool \\
      \Gamma, z : \Bool \vdash P \ty \uni \\
      \Gamma \vdash b_{\false} \ty \subs{P}{z}{\false} \\
      \Gamma \vdash b_{\true} \ty \subs{P}{z}{\true}}
      {\Gamma \vdash \ind{\Bool}{s}{z.P}{b_{\false},b_{\true}} \ty \subs{P}{z}{s}}
      \label{rule:bool-ind}
  \end{mathpar}
  \caption{Induction principle for booleans}
  \label{fig:bool-typ}
\end{figure}

\begin{marginfigure}[1em]
  \ContinuedFloat
  \begin{mathpar}
    \inferdef{ιFalse}
    { }
    {\ind{\Bool}{\false}{z.P}{b_{\false},b_{\true}} \tred b_{\false}} \and
    \inferdef{ιTrue}
    { }
    {\ind{\Bool}{\true}{z.P}{b_{\false},b_{\true}} \tred b_{\true}}
  \end{mathpar}
  \caption{\kl{Top-level reduction} for booleans (ι-reduction)}
  \label{fig:bool-red}
\end{marginfigure}

One thing is still missing in this picture: computation. The extension of
\kl{top-level reduction} is given in \cref{fig:bool-red} – our first example of
ι-reduction, the reduction of recursors on \kl{constructors}.
These rules pick the branch corresponding to the scrutinee,
which is sensible if $\indop_{\Bool}$ is understood as a conditional.
\kl{Declarative conversion} can be extended in exactly the same way.
Finally, to account for the arguments of the newly introduced term former $\indop_{\Bool}$,
we need to add new congruence rules, see \cref{fig:bool-cong}.
For \kl{one-step reduction} and \kl{declarative conversion},
there is no subtlety, all positions behave the same. The interesting rule is the
one for \kl{weak-head reduction}: there is only one congruence rule, which allows for
reduction of the scrutinee. This is similar to functions, where we allow reduction only in the
position in the term that triggers a computation if it is a canonical form – in the case
of $\indop$, the scrutinee.

\begin{figure*}
  \ContinuedFloat
  \begin{mathpar}
    \inferrule
    {s \dconv s' \\ P \dconv P' \\ b_{\false} \dconv b'_{\false} \\ b_{\true} \dconv b'_{\true}}
    {\ind{\Bool}{s}{z.P}{b_{\false},b_{\true}}
      \dconv \ind{\Bool}{s'}{z.P'}{b'_{\false},b'_{\true}}} \and
    \inferrule
    {s \ored s'}
      {\ind{\Bool}{s}{z.P}{b_{\false},b_{\true}}
        \ored \ind{\Bool}{s'}{z.P}{b_{\false},b_{\true}}} \and
    \inferrule
    {P \ored P'}
      {\ind{\Bool}{s}{z.P}{b_{\false},b_{\true}}
        \ored \ind{\Bool}{s}{z.P'}{b_{\false},b_{\true}}} \and
    \inferrule
    {b_{\false} \ored b'_{\false}}
      {\ind{\Bool}{s}{z.P}{b_{\false},b_{\true}}
        \ored \ind{\Bool}{s}{z.P}{b'_{\false},b_{\true}}} \and
    \inferrule
    {b_{\true} \ored b'_{\true}}
      {\ind{\Bool}{s}{z.P}{b_{\false},b_{\true}}
        \ored \ind{\Bool}{s}{z.P}{b_{\false},b'_{\true}}} \and
    \inferrule
    {s \hored s'}
      {\ind{\Bool}{s}{z.P}{b_{\false},b_{\true}}
        \hored \ind{\Bool}{s'}{z.P}{b_{\false},b_{\true}}} \and
  \end{mathpar}

  \caption{Congruence rules for booleans}
  \label{fig:bool-cong}
\end{figure*}

\subsection{Recursion}

\begin{figure}[h]
  \AP
  \begin{mathpar}
    \inferdef{Nat}{\vdash \Gamma}{\Gamma \vdash \intro*\Nat \ty \uni[0]}
    \label{rule:nat-type} \and
    \inferdef{Zero}{\vdash \Gamma}{\Gamma \vdash \intro*\z \ty \Nat}
    \label{rule:zero-type} \and
    \inferdef{Succ}{\Gamma \vdash n \ty \Nat}{\Gamma \vdash \intro*\S{n} \ty \Nat}
    \label{rule:succ-type} \and
    \inferdef{NatInd}
      {\Gamma \vdash s \ty \Nat \\
      \Gamma, z : \Nat \vdash P \ty \uni \\
      \Gamma \vdash b_{\z} \ty \subs{P}{z}{\z} \\
      \Gamma, y : \Nat, p_{y} : \subs{P}{z}{y} \vdash b_{\Sop} \ty \subs{P}{z}{\S{y}}}
      {\Gamma \vdash \ind{\Nat}{s}{z.P}{b_{\z},y.p_{y}.b_{\Sop}} \ty \subs{P}{z}{s}}
    \label{rule:nat-ind} \and
    \inferdef{ιZero}
    { }
    {\ind{\Nat}{\z}{z.P}{b_{\z},y.p_{y}.b_{\Sop}} \tred b_{\z}}
    \label{rule:iota-zero} \and
    \inferdef{ιSucc}
    { }
    {\ind{\Nat}{\S{n}}{z.P}{b_{\z},y.p_{y}.b_{\Sop}} \tred\\
      \multisubs{b_{\Sop}}{y \into n, p_{y} \into \ind{\Nat}{n}{z.P}{b_{\z},y.p_{y}.b_{\Sop}}}}
    \label{rule:iota-succ}
  \end{mathpar}
  \caption{Natural numbers}
  \label{fig:nat}
\end{figure}

Booleans are very simple, but we of course want more. The first thing to add is recursion.
The simplest example is that of natural numbers, given in \cref{fig:nat}.
The rules are more verbose than those for booleans, but the general idea is very similar:
\ruleref{rule:nat-type} introduces a new type, \ruleref{rule:zero-type}
and \ruleref{rule:succ-type} its constructors, and \ruleref{rule:nat-ind} its induction
principle. This time said induction principle is a real one, as we can see in
the second branch, where an induction hypothesis $p_{y}$ on the predecessor $y$ is available.
Similarly to booleans, the induction principle reduces when its scrutinee is a constructor.
But, again, since we have real recursion,
a recursive call appears in the reduct of \ruleref{rule:iota-succ}.
We do not repeat the congruence rules, as they are similar to those for booleans
(\cref{fig:bool-cong}). The only difference is that now there is also a need for congruence
rules for the term former $\Sop$, since it has a sub-term.

At this point, it might be good to add a note on the way we represent \kl{constructors}:
we enforce them to be \intro{fully applied}, meaning $\Sop$ does not make sense on its own
as a term. \kl{Coq} is slightly more permissive, and allows $\Sop \ty \Nat \to \Nat$.
We forbid this, but one can always consider $\l x : \Nat.\ \S{x}$ instead if needed.
Likewise, inductive types are also enforced to be fully applied.
We also avoid using the $\P$ and $\l$ term formers to represent binding in the predicate
and branches of constructors, rather using contexts directly.
This allows for a clear separation
of concerns, by reducing interactions between the functional fragment and
inductive types. \kl{Coq}'s kernel used to rely on $\P$ and $\l$ abstractions to represent
predicates and branches, but a version close to our presentation has recently replaced it,%
\sidenote{The exact change is documented by pull-request \coqPR{13563}.}
in part due to concerns raised while working on this thesis, that are detailed in
\cref{sec:bidir-pcuic-inductives}.

\subsection{Parameters}

\begin{figure}
  \AP
  \begin{mathpar}
    \inferdef{PairTy}
      {\vdash A \ty \uni[i] \\ \Gamma, x : A \vdash B \ty \uni[j]}
      {\Gamma \vdash \Sb x : A.\ B \ty \uni[\umax{i}{j}]}
    \label{rule:sig-type} \and
    \inferdef{Pair}
    {\Gamma \vdash A \ty \uni \\ \Gamma, x : A \vdash B \ty \uni \\
    \Gamma \vdash t \ty A \\ \Gamma \vdash u \ty \subs{B}{x}{t}}
    {\Gamma \vdash \intro*\pair[A][x.B]{t}{u} \ty \Sb x : A.\ B}
    \label{rule:pair-type} \and
    \inferdef{PairInd}
      {\Gamma \vdash s \ty \Sb x : A.\ B \\
      \Gamma, z : \Sb x : A.\ B \vdash P \ty \uni \\
      \Gamma, y_1 : A, y_2 : \subs{B}{x}{y_1} \vdash b \ty \subs{P}{z}{\pair[A][x.B]{y_1}{y_2}}}
      {\Gamma \vdash \ind{\Sb}{s}{z.P}{y_1.y_2.b} \ty \subs{P}{z}{s}}
      \label{rule:sig-ind} \and
    \inferdef{ιPair}
    { }
    {\ind{\Sb}{\pair[A][x.B]{t}{u}}{z.P}{y_1.y_2.b} \tred \multisubs{b}{y_1 \into t, y_2 \into u}}
    \label{rule:iota-sig}
  \end{mathpar}
  \caption{Inductive dependent pair type}
  \label{fig:sig}
\end{figure}

\AP A second direction for enhancement is the ability to have inductive types with parameters.
The main use of this is for type operators, that is types that take other types as
arguments, for instance the pair type $A \times B$
of \cref{chap:intro-en}. As is probably not very surprising by
now, this type is a restricted instance of a more general type, the
dependent pair type $\intro*\Sb x : A.\ B$.
Logically, its dependency on $A$ means that if we see $B$ as a property,
the whole pair type describes a subset of $A$ – those elements
which validate $B$. The rules are given in \cref{fig:sig}.
Similarly to functions, we need an annotation on
the pair constructor, for the exact same reason: we want to ensure that any term can
infer a type. We also omit congruence rules, as they are again similar to those of
\cref{fig:bool-cong}, although now not only the pair constructor but also the type constructor
$\Sb$ get their congruence rules, since both have sub-terms.

\begin{figure}
\begin{mathpar}
  \inferdef{ListTy}
    {\vdash A \ty \uni[i]}
    {\Gamma \vdash \List(A) \ty \uni[i]}
  \label{rule:list-type} \and
  \inferdef{Nil}
    {\Gamma \vdash A \ty \uni}
    {\Gamma \vdash \intro*\lnil[A] \ty \List(A)}
  \label{rule:nil-type} \and
  \inferdef{Cons}
    {\Gamma \vdash A \ty \uni \\
    \Gamma \vdash a \ty A \\ \Gamma \vdash l \ty \List(A)}
    {\Gamma \vdash \intro*\lcons[A]{a}{l} \ty \List(A)}
  \label{rule:cons-type} \and
  \inferdef{ListInd}
    {\Gamma \vdash s \ty \List(A) \\
    \Gamma, z : \List(A) \vdash P \ty \uni \\
    \Gamma \vdash b_{\lnil} \ty \subs{P}{z}{\lnil} \\
    \Gamma, y_1 : A, y_2 : \List(A), p_{y_2} : \subs{P}{z}{y_2}
      \vdash b_{\lconsop} \ty \subs{P}{z}{\lcons[A]{y_1}{y_2}}}
    {\Gamma \vdash \ind{\List}{s}{z.P}{b_{\lnil},y_1.y_2.p_{y_2}.b_{\lconsop}}
      \ty \subs{P}{z}{s}}
  \label{rule:list-ind} \and
  \inferdef{ιNil}
    { }
    {\ind{\List}{\lnil[A]}{z.P}{b_{\lnil},y_1.y_2.p_{y_2}.b_{\lconsop}} \tred b_{\lnil}}
  \label{rule:iota-nil} \and
  \inferdef{ιCons}
    { }
    {\ind{\List}{\lcons[A]{a}{l}}{z.P}{b_{\lnil},y_1.y_2.p_{y_2}.b_{\lconsop}} \tred \\
      \multisubs{b_{\lconsop}}{y_1 \into a, y_2 \into l, p_{y_2} \into \ind{\List}{l}{z.P}{b_{\lnil},y_1.y_2.p_{y_2}.b_{\lconsop}}}}
  \label{rule:iota-cons}
\end{mathpar}
\caption{List type}
\label{fig:list}
\end{figure}

\AP As an example which combines both recursion and parameters, we have the polymorphic list
type $\intro*\List$, which mainly combines what
we already covered for natural numbers and pairs. The typing and reduction rules are
given in \cref{fig:list}.

% Inductive types using recursion and parameters we call \intro{datatypes},
% as they roughly correspond to what one can find in usual programming languages.
% For instance, they are closely related to the algebraic types of the \kl{OCaml} language.

\subsection{Indices}

There is one feature missing in the previous inductive types. Indeed, in all of them
the return types of constructors are always the same. In some way, they do not exploit
the real possibilities of dependent types. What if we wanted constructors
to specify that they inhabit a type at some specific value? This is exactly the point of
\intro{indexed inductive types}.

\begin{figure}
  \AP
  \begin{mathpar}
  \inferdef{EqType}
    {\Gamma \vdash A \ty \uni[i] \\ \Gamma \vdash a \ty A \\ \Gamma \vdash a' \ty A}
    {\Gamma \vdash \intro*\eqty[A]{a}{a'} \ty \uni[i]}
  \label{rule:eq-type}
  \and
  \inferdef{EqRefl}
    {\Gamma \vdash A \ty \uni[i] \\ \Gamma \vdash a \ty A}
    {\Gamma \vdash \intro*\refl[A][a] \ty \eqty[A]{a}{a}}
  \label{rule:eq-refl}
  \and
  \inferdef{EqInd}
    {\Gamma \vdash s \ty \eqty[A]{a}{a'} \\
    \Gamma, y : A, z : \eqty[A]{a}{y} \vdash P \ty \uni \\
    \Gamma \vdash b \ty \multisubs{P}{y \into a, z \into \refl[A][a]}}
    {\Gamma \vdash \ind{\eqtyop}{s}{y.z.P}{b} \ty \multisubs{P}{y \into a', z \into s}}
  \label{rule:eq-ind} \and
  \inferdef{ιEq}
    { }
    {\ind{\eqtyop}{\refl[A][a]}{y.z.P}{b} \tred b}
  \label{rule:eq-iota}
  \end{mathpar}
  \caption{Equality type}
  \label{fig:eq-type}
\end{figure}

The paradigmatic example here is (propositional) equality, an
inductive meant to represent equality \emph{internally} to the logic, \ie as a notion on
which one can reason – for instance, do proofs by induction –,
rather than an external one such as \kl{conversion}.
Rules for equality are given in \cref{fig:eq-type}. \ruleref{rule:eq-type} does not depart
much from what we have already seen,
apart from the fact that it takes not only a type as a parameter, but
also a term. \ruleref{rule:eq-refl} is already more interesting. Here we can see that
the second argument of type $A$ is fixed to be $a$ by the constructor. This gets
more visible in \ruleref{rule:eq-ind}: in order for the branch $b$
to be typeable, the predicate needs to be abstracted not only on the scrutinee,
but also on that second argument. Such arguments to an inductive type,
whose value depends on the constructor and need to be abstracted over in branches,
are called \reintro{indices}. By contrast, the other arguments that behave uniformly
are called parameters.

As for the logical interpretation, in the simplified case where $P$ only depends on the index,
\ruleref{rule:eq-ind} corresponds to the idea that equal terms should be indiscernible:
whenever both $\eqty[A]{a}{a'}$ and $\subs{P}{y}{a}$ hold, then so does $\subs{P}{y}{a'}$.
In words, every property true of $a$ is also true of $a'$. Paired with the power of
dependent types this presentation of equality gives rise to a very rich theory, and
forms the basis for the whole line of research in Homotopy Type Theory \sidecite{UniFoundationsProgram2013}.

However, in the context of bare \kl{CIC}, this richness is also
a curse, and indexed inductive types can be very tricky to handle. In particular, the
work of \arefpart{gradual} does not extend well to generic indexed inductive types.
There is, however, a somewhat simpler kind of indexed inductive types, where the indices are
not any term of any arbitrary type – as in the case of equality –,
but inhabitants of an inductive type.
Such a case is easier to handle, and is often sufficient, especially for
dependently-typed programming. The prototypical example here is that of vectors, which
we have already encountered in \cref{chap:intro-en}, and is described in
detail in \cref{fig:vect}. They are similar to
lists, but with a natural number index which records the length of the vector in its type.
This allows for finely-grained specification, for instance a head function that takes as input
a vector of length at least one, and is thus ensured to never fail on an empty vector
by mere virtue of typing.

\begin{figure*}
  \AP
  \begin{mathpar}
    \inferdef{VectType}
      {\vdash A \ty \uni[i] \\ \vdash n \ty \Nat}
      {\Gamma \vdash \intro*\Vect(A,n) \ty \uni[i]}
    \label{rule:vect-type} \and
    \inferdef{Vnil}
      {\Gamma \vdash A \ty \uni}
      {\Gamma \vdash \intro*\vnil[A] \ty \Vect(A,\z)}
    \label{rule:vnil-type} \and
    \inferdef{Vcons}
      {\Gamma \vdash A \ty \uni \\ \Gamma \vdash n \ty \Nat \\
      \Gamma \vdash a \ty A \\ \Gamma \vdash l \ty \Vect(A,n)}
      {\Gamma \vdash \intro*\vcons[A][n]{a}{l} \ty \Vect(A,\S n)}
    \label{rule:vcons-type} \and
    \inferdef{VectInd}
      {\Gamma \vdash s \ty \Vect(A,n) \\
      \Gamma, y : \Nat, z : \Vect(A,y) \vdash P \ty \uni \\
      \Gamma \vdash b_{\vnil} \ty \multisubs{P}{y \into \z, z \into \vnil} \\
      \Gamma, y_1 : \Nat, y_2 : A, y_3 : \Vect(A,y_1), p_{y_3} \ty \multisubs{P}{y \into y_1, z \into y_3} \vdash
        b_{\vconsop} \ty \multisubs{P}{y \into \S{y_1}, z \into \vcons[A][y_1]{y_2}{y_3}}}
      {\Gamma \vdash \ind{\Vect}{s}{y.z.P}{b_{\vnil},y_1.y_2.y_3.p_{y_3}.b_{\vconsop}}
        \ty \multisubs{P}{y \into n, z \into s}}
    \label{rule:vect-ind} \and
    \inferdef{ιVnil}
      { }
      {\ind{\Vect}{\vnil[A]}{y.z.P}{b_{\vnil},y_1.y_2.y_3.p_{y_3}.b_{\vconsop}}
        \tred b_{\lnil}}
    \label{rule:iota-vnil} \and
    \inferdef{ιVcons}
      { }
      {\ind{\Vect}{\vcons[A][n]{a}{l}}{y.z.P}{b_{\vnil},y_1.y_2.y_3.p_{y_3}.b_{\vconsop}} \tred \\
        \multisubs{b_{\vconsop}}{y_1 \into n, y_2 \into a, y_3 \into l, p_{y_3} \into \ind{\Nat}{l}{z.P}{b_{\lnil},y_1.y_2.y_3.p_{y_3}.b_{\vconsop}}}}
    \label{rule:iota-vcons}
  \end{mathpar}
  \caption{Vector type}
  \label{fig:vect}
  \end{figure*}

\subsection{The \kl(tit){Calculus of Constructions}}

So far we only gave examples of the inductive types one could wish for.
A description of how to generally define inductive types and construct induction principles
in a way that keeps the good properties of the system would not
very enlightening at this point. Let us simply say that the main restriction – barring typing
constraints – is to ensure, through a criterion called (strict) positivity,
that the recursive structure of the inductive type
is well-founded, so that positing its existence does not endanger \kl{normalization} or
\kl(log){consistency}.

On paper, rather than a difficult to read general presentation we reuse the previous
set of examples to show how our setting adapts to inductive types in their
three main complexities – recursion, parameters and indices.
But the formalization in \kl{MetaCoq} handles the general case,
in the even more complex setting of \kl{PCUIC} as presented in \cref{sec:tech-pcuic}.

In the end, when we talk about \kl{CIC} we mean the extension of \kl{CCω} with any number of
inductive types, valid in the previous sense.
As already explained, in \arefpart{gradual} we need to restrict to
non-indexed inductive types. In that setting, our base system is \intro{CIC-},
the restriction of \kl{CIC} to exclude \kl{indexed inductive types}.

\section{Beyond \kl(tit){CIC}: \kl(tit){PCUIC}}
\label{sec:tech-pcuic}

\kl{CIC} as described in the previous section is already very expressive and powerful.
It is nevertheless
still far from a “real-world” type theory such as that implemented in \kl{Coq} and
formalized in \kl{MetaCoq}, the \intro{Polymorphic, Cumulative Calculus of Inductive Constructions} (\intro{PCUIC}),
which extends \kl{CIC} with many features which are crucial for usability.
As some additions of \kl{PCUIC} are discussed throughout this
thesis, we wish to already give a high level idea of them,
while reserving the technical details for \arefpart{metacoq}.

\subsection{Cumulativity}

The first addition of \kl{PCUIC} is \kl{cumulativity}, which allows some extra flexibility
with universe levels.
To see why this is useful, consider the polymorphic identity function
$\l (A : \uni[i]) (x : A).\ x$, of type $\P A : \uni[i] .\ A \to A$.
If we want to use it at type $\Nat$, we must force $i$ to be $\z$. But this means that we
cannot use it later on at type $\uni[0]$! In a concrete system, where a huge number of
universe levels appear under the hood, this would quickly become unhandy.

\AP Instead, \intro{cumulativity} – written $\intro*\cum$ – is an extension of conversion
with a limited form of subtyping,
generated by the inclusion of a universe $\uni[i]$ in any larger universe $\uni[j]$.
This means that while $\uni[i] \conv \uni[j]$ is true only if $i = j$, cumulativity
allows for $\uni[i] \cum \uni[j]$ as soon as $i \leq j$.
This subtyping can be extended to function types,
by allowing $\P x : A.\ B \cum \P x : A'.\ B$ whenever $A \conv A'$ and $B \cum B'$.
Note that contrarily to other forms of subtyping, this does not allow for contravariant
subtyping on the domain – that would correspond to $A' \cum A$ –, only for equivariant
one – the domains should be convertible. This is because cumulativity is usually modelled
using set inclusion \sidecite{Lee2011}, which straightforwardly handles equivariant
subtyping, but not so easily contravariant subtyping.

\begin{figure}[h]
  \begin{mathpar}
    \inferdef{UnivCum}{i \leq j}{\uni[i] \cum \uni[j]} \label{rule:univ-cum} \and
    \inferdef{ΠCum}{A \conv A' \\ B \cum B'}{\P x : A.\ B \cum \P x : A'.\ B'}
      \label{rule:prod-cum} \and
    \inferdef{ConvCum}{A \conv A'}{A \cum A'} \label{rule:conv-cum} \and
    \inferdef{Refl}{ }{A \cum A} \label{rule:cum-refl} \and
    \inferdef{Trans}{A \cum A' \\ A' \cum A''}{A \cum A''} \label{rule:cum-trans} \and
    \inferdef{UCum}{\Gamma \vdash T' \ty \uni \\ T \cum T'}{\Gamma \vdash T \cum T' \ty \uni}
      \label{rule:cic-ucum} \and
    \inferdef{Cum}{\Gamma \vdash t \ty T \\ \Gamma \vdash T \cum T' \ty \uni}
    {\Gamma \vdash t \ty T'}
      \label{rule:cic-cum}
  \end{mathpar}
  \caption{Rules for declarative cumulativity}
  \label{fig:tech-cumul}
\end{figure}

To adapt the definitions of \kl{declarative conversion} to cumulativity,
the three important rules are given in \cref{fig:tech-cumul}.
The first two rules are the ones we already hinted at:
\ruleref{rule:univ-cum} is the base case for cumulativity, and \ruleref{rule:prod-cum}
is the relaxed congruence rule for Π-types. The next one, \ruleref{rule:conv-cum}, allows
to turn any proof of conversion in a cumulativity one, effectively describing how cumulativity
behaves outside the fragment formed by Π-types and universes.
Next come Rules \nameref{rule:cum-refl} and \nameref{rule:cum-trans}, which assert that cumulativity
is a pre-order. Of course there is no rule for symmetry,
because we do not want cumulativity to be an equivalence relation.
Finally, Rules \nameref{rule:cic-ucum} and \nameref{rule:cic-cum} show how
cumulativity is used: it simply replaces conversion.

\AP
As for \kl{algorithmic conversion}, the important modification is to replace \kl{α-equality}
with an \intro{α-pre-order} $\alphleq$, which extends the former with a rule corresponding to
\ruleref{rule:univ-cum}: $t \alphleq t'$ means that $t$ and $t'$ have the exact
same structure, up to variable names and universe levels, that might be lower in $t$ compared
to $t'$.

\subsection{The sort of propositions}

A second addition in \kl{PCUIC}, and one that has been a distinctive feature of \kl{Coq}
for a very long time – it is already present in \sidetextcite{Coquand1988} –
is the sort $\intro*\Prop$.
This is a universe, like $\uni[i]$, but it is designed to
be a type for propositions – hence the name. It has two main distinctive characteristics.

\begin{marginfigure}
  \begin{mathpar}
    \inferdef{Prop}{\vdash \Gamma}{\Gamma \vdash \Prop \ty \uni[0]}
    \label{rule:cic-prop} \and
    \inferdef{ΠTyProp}{\Gamma \vdash A \ty \uni \\ \Gamma, x : A \vdash P \ty \Prop}
    {\Gamma \vdash \P x : A.\ P \ty \Prop}
    \label{rule:prop-prod} \and
    \inferdef{ΠPropProp}{\Gamma \vdash A \ty \Prop \\ \Gamma, x : A \vdash P \ty \Prop}
    {\Gamma \vdash \P x : A.\ P \ty \Prop}
    \label{rule:prop-prop-prod}
  \end{mathpar}
  \caption{Typing rules for propositions}
  \label{fig:cic-prop}
\end{marginfigure}

\AP The first one is its \intro{impredicativity}, meaning that while $\Prop$ is at the bottom
of the universe hierarchy (\ruleref{rule:cic-prop}), any quantification with a proposition
as codomain is again a proposition (Rules \nameref{rule:prop-prod} and \nameref{rule:prop-prop-prod}).
This means that propositions are able to formalize properties of types at any level.
Due to this impredicative nature, having such a sort of propositions makes the system
much more powerful as a logic, which also makes it much harder to build models of it.
Indeed, those usually prove consistency of the modelled system,
something which requires having an even higher logical strength than it.
Since parts of this thesis – especially \arefpart{gradual} – use such models that do not
scale to an impredicative sort of proposition,
we refrain from including one in our standard \kl{CIC}. In the other cases, including a sort of
propositions makes the system more complex but without raising new interesting questions.

\AP The second defining characteristic of $\Prop$ is \intro{proof irrelevance}.
This means that \kl{PCUIC} has a criterion, called singleton elimination, which maintains
a form of segregation between terms inhabiting types in $\uni$ and
those inhabiting types in $\Prop$, ensuring that terms of the first kind cannot
depend in a relevant way on terms of the second.
For instance, if $P \ty \Prop$, it ensures that it is impossible
to build a function $f \ty P \to \Bool$ and two terms $p_1 \ty P$ and $p_2 \ty P$ such that
$f\ p_1 \conv \false$ and $f\ p_2 \conv \true$. This segregation aims at allowing separation
between the part of the system that should be seen as programs and that which should be
seen as proofs, so that it is possible to write programs decorated with
complex correctness proofs, while later on erasing all the
logical content to keep only the computational content of the program.
This is the erasure procedure we introduced in \cref{sec:intro-metacoq-en},
for which $\Prop$ is crucial.

\subsection{Local definitions}

It is often useful to locally introduce a shorthand to be used repeatedly, and
this is what \kl{PCUIC} allows with a new term former,
\intro{local definitions} $\letin{x}{A}{t}{u}$.
In such a local definition, $x$ can be used in the term $u$ as a shorthand for $t$.

\begin{figure}[ht]
  \ContinuedFloat*
  \begin{mathpar}
    \inferdef{LetIn}{\Gamma \vdash A \ty \uni \\ \Gamma \vdash t \ty A \\
    \Gamma, x \coloneqq t \ty A \vdash u \ty B}
    {\Gamma \vdash \letin{x}{A}{t}{u} \ty \letin{x}{A}{t}{B}}
    \label{rule:pcuic-letin}
  \end{mathpar}
  \caption{Typing for local definitions}
  \label{fig:local-def}
\end{figure}

The main impact of this addition is its effect on contexts: as \ruleref{rule:pcuic-letin}
illustrates, when typing $u$, not only the type of the definition is recorded, but
also its value $t$. This is again due to dependency, because the value of the definition,
and not only its type, might be needed for $u$ to be well-typed.
As an example, suppose we have a function
\[\operatorname{head} \ty \P (A : \uni) (x : \Nat).\ \Vect(A,\S x) \to A\]
and consider
\[\letin{x}{\Nat}{1}{\l v : \Vect(\Bool,x).\ \operatorname{head}\ \Bool\ \z\ v} \]
This term is well-typed only if the fact that $x$ has value $1$ is available in the
right-hand side.

\begin{marginfigure}
  \ContinuedFloat
  \begin{mathpar}
    \inferdef{ζRed}{ }{\Gamma \vdash \letin{x}{A}{t}{u} \\ \tred \subs{u}{x}{t}}
    \label{rule:zeta-red} \and
    \inferdef{δRed}{(x \coloneqq t : A) \in \Gamma}{\Gamma \vdash x \tred t}
    \label{rule:delta-red}
  \end{mathpar}
  \caption{Top-level reduction for local definitions}
  \label{fig:local-def-red}
\end{marginfigure}

This also means that contexts now should be recorded in
\kl{conversion} and \kl{cumulativity}, because those need to access the value of a
variable bound by a definition if we want to enable the behaviour just described.
In the end, there are two \kl{top-level reductions} for definitions, given opposite:
they can be either simplified right away into a substitution (\nameref{rule:zeta-red})%
\sidenote{The notations are a bit misleading here: the local definition is part
of the syntax of terms, while substitution is a meta-level operation. While the former
encodes the latter in the syntax, they are quite different!},
or recorded into the context and simplified only later on
using \ruleref{rule:delta-red}.

\subsection{Global environments}

\kl{PCUIC} offers a second way to record definitions, inside a so-called
\intro{global environment}.
The difference between this and the addition of local definitions in a context we
just saw is motivated by rather concrete considerations.
The (local) context corresponds to definitions and abstractions
encountered when type-checking a single proof or program, and should thus be relatively shallow
– the order of magnitude is a dozen variables – but it might change very often, with variable
being both added and abstracted over.
The \kl{environment}, on the contrary, can become huge –
corresponding to a whole library with thousands of components — but changes less often, and
usually in a monotone way – new definitions are added, but not removed.
Therefore, typing in \kl{PCUIC} actually has an extra parameter: it is of the form
$\Sigma ;;; \Gamma \vdash t \ty T$, with $\Sigma$ corresponding to the \kl{environment}.

This environment is not only used for definitions and assumptions,
but also to keep track of inductive types.
It thus effectively implements our somewhat vague assumption that
\kl{CIC} is extended with “any number of valid inductive types”. Of course, there is a notion
of environment well-formation, which accounts for the fact that it should
only contain objects that are well-typed, together with other constraints, for instance
that inductive types respect the strict positivity criterion.

There is a further use for this environment: it also records the level variables available for
universes, and their constraints. Indeed, in \kl{PCUIC}, universe levels are expressions
rather than simple natural numbers,
and the order between expressions is relative to a given environment $\Sigma$.
There are actually two kinds of those universe variables.
The first are global ones, that are recorded in an ever-growing fashion in the environment.
This is the older approach, that was introduced in \kl{Coq} together with \kl{typical
ambiguity}, following \sidetextcite{Pollack1992}.

This approach is however still not flexible enough, which is why a second kind of variables
were more recently introduced \sidecite{Sozeau2014}. These are attached locally to
an entry in the environment, corresponding to a form of \intro{universe polymorphism},
and each time such a definition is used it can be instantiated with new universe levels.%
\sidenote{
  This is somewhat similar to the Hindley-Milner style of type polymorphism
  \cite{Hindley1969,Milner1978} widely used in the ML family of languages,
  albeit with universe levels rather than types.
}\margincite{Hindley1969}\margincite{Milner1978}
This is for instance useful to have a single (polymorphic) definition of categories,
and still be able to define the category – at level $j$ – of all categories
– at a level $i < j$ –, by instantiating the definition at the two different levels $i$ and $j$.
If there was just one global level $k$, then doing this would result in a constraint $k < k$,
and this definition would not be accepted.

\subsection{Enhanced inductive types}
\label{sec:pcuic-ind}

Of course inductive types in \kl{PCUIC} are also affected by these extensions.
Not only can they be polymorphic, as definitions, they also feature a form of
cumulativity, that makes this polymorphism more seamless – see \sidetextcite{Timany2018}
for a precise description.
This for instance prevents issues with $\lnil[A]$ not being of type $\List(A)$ because of a
mismatch between type variables – those do not appear in our presentation of \kl{CIC},
but are present in \kl{PCUIC} due to the general setting for polymorphic
inductive types.

Moreover, the strict positivity criterion adopted in \kl{PCUIC} is
very general, as it allows mutually defined and nested inductive types.
The former are multiple inductive types defined at the same time,
where a constructor of one type can take a recursive argument of another. For instance,
an inductive oddness/evenness predicate with constructors
$\operatorname{oddS} \ty \P x : \Nat.\ \operatorname{even} x \to \operatorname{odd} \S x$ and $\operatorname{evenS} \ty \P x : \Nat.\ \operatorname{odd} x \to \operatorname{even} \S x$.
The latter are types where a constructor can take a recursive argument mentioning the type
being defined as a parameter to another inductive type –
for instance, a type of tree where a node takes a list of trees as argument.

But the most significant difference is that the induction principles,
such as the ones we gave for \kl{CIC},
are replaced with two new constructions: pattern-matching and fixed-points. The
first corresponds to the non-recursive component of the induction principles, while the
second allows to define a function that calls itself recursively.
To avoid paradoxical definitions, not every recursive definition is accepted, however.
\AP Instead, there is a restriction called the \intro{guard condition}
to how a recursive function
can be defined, which amounts to checking that recursive calls are made on
structurally smaller sub-terms – by means of pattern-matching. This guard condition
theoretically ensures that fixed-points and pattern-matching can always be reduced to
\kl{recursors} \sidecite{Gimenez1995}, which are what proofs of \kl{normalization} and/or
consistency usually consider.
However, in practice the former is much more
flexible and natural to use than the latter.

\subsection{Records and co-inductive types}
\label{sec:pcuic-records}

The last ingredient in \kl{PCUIC} goes beyond inductive types, by adding more primitive types
to the theory.

\AP The first kind are \intro{record types},
a generalization of Σ-types which allows for any number of
named fields. The main addition of record types is the ability to access those fields via
\intro{projections} rather than by using pattern-matching. For the Σ-type as presented in
\cref{sec:tech-cic}, this would mean accessing the two fields of the pair $p$ with two
term formers $p._{1}$ and $p._{1}$. These record types are very useful to package
objects together, be it in programming or in mathematics – where such bundles are ubiquitous,
for instance when formalizing hierarchies of mathematical structures \sidecite{Cohen2020}.

\AP The second kind are \intro{co-inductive types}.
These are somewhat similar to inductive types, but
while the latter correspond to well-founded objects, the former represent
potentially infinite objects, such as streams of values. Because of this flavour of infinity,
co-inductive types pose an inherent threat to good properties of the system, in particular
decidability of type-checking. At the time of their introduction in \kl{Coq}
\sidecite{Gimenez1995}, they were presented in a so-called “positive” fashion – close
to the presentation of \kl{inductive types} –, which
kept \kl{normalization} at the cost of \kl{subject reduction}.
Another presentation, inspired by more recent work on
co-induction, and especially co-patterns \sidecite{Abel2013}, is the “negative” one –
similar to the projection-based presentation of \kl{record types} –,
which regains the good properties of the system. While the older positive presentation
is still present in \kl{Coq}, in part for compatibility reasons,
only the negative one is formalized in \kl{MetaCoq}.