2018-05-02 15:02:46 +00:00
\chapter { Cubical Agda}
\section { Propositional equality}
2018-05-09 16:13:36 +00:00
Judgmental equality in Agda is a feature of the type-system. It's something that
can be checked automatically by the type-checker: In the example from the
2018-05-02 15:02:46 +00:00
introduction $ n + 0 $ can be judged to be equal to $ n $ simply by expanding the
definition of $ + $ .
2018-05-09 16:13:36 +00:00
On the other hand, propositional equality is something defined within the
language itself. Propositional equality cannot be derived automatically. The
normal definition of judgmental equality is an inductive data-type. Cubical Agda
discards this type in favor of a new primitives that has certain computational
properties exclusive to it.
2018-05-02 15:02:46 +00:00
2018-05-08 14:22:51 +00:00
Exceprts of the source code relevant to this section can be found in appendix
2018-05-09 16:13:36 +00:00
\S \ref { sec:app-cubical} .
2018-05-08 14:22:51 +00:00
2018-05-02 15:02:46 +00:00
\subsection { The equality type}
The usual notion of judgmental equality says that given a type $ A \tp \MCU $ and
two points of $ A $ ; $ a _ 0 , a _ 1 \tp A $ we can form the type:
%
\begin { align}
a_ 0 \equiv a_ 1 \tp \MCU
\end { align}
%
2018-05-09 16:13:36 +00:00
In Agda this is defined as an inductive data-type with the single constructor
for any $ a \tp A $ :
2018-05-02 15:02:46 +00:00
%
\begin { align}
\refl \tp a \equiv a
\end { align}
%
For any $ a \tp A $ .
2018-05-09 16:13:36 +00:00
There also exist a related notion of \emph { heterogeneous} equality which allows
2018-05-02 15:02:46 +00:00
for equating points of different types. In this case given two types $ A, B \tp
\MCU $ and two points $ a \tp A$ , $ b \tp B$ we can construct the type:
%
\begin { align}
a \cong b \tp \MCU
\end { align}
%
2018-05-09 16:13:36 +00:00
This is likewise defined as an inductive data-type with a single constructors
for any $ a \tp A $ :
2018-05-02 15:02:46 +00:00
%
\begin { align}
\refl \tp a \cong a
\end { align}
%
In Cubical Agda these two notions are paralleled with homogeneous- and
heterogeneous paths respectively.
%
\subsection { The path type}
2018-05-09 16:13:36 +00:00
Judgmental equality in Cubical Agda is encapsulated with the type:
2018-05-02 15:02:46 +00:00
%
2018-05-09 16:13:36 +00:00
\begin { equation}
2018-05-08 00:01:17 +00:00
\Path \tp (P \tp I → \MCU ) → P\ 0 → P\ 1 → \MCU
2018-05-09 16:13:36 +00:00
\end { equation}
2018-05-02 15:02:46 +00:00
%
$ I $ is a special data-type (\TODO { that also has special computational properties
AFAIK} ) called the index set. $ I $ can be thought of simply as the interval on
the real numbers from $ 0 $ to $ 1 $ . $ P $ is a family of types over the index set
$ I $ . I will sometimes refer to $ P $ as the ``path-space'' of some path $ p \tp
\Path \ P\ a\ b$ . By this token $ P\ 0$ then corresponds to the type at the
left-endpoint and $ P \ 1 $ as the type at the right-endpoint. The type is called
2018-05-07 22:25:34 +00:00
$ \Path $ because it is connected with paths in homotopy theory. The intuition
2018-05-02 15:02:46 +00:00
behind this is that $ \Path $ describes paths in $ \MCU $ -- i.e. between types. For
a path $ p $ for the point $ p \ i $ the index $ i $ describes how far along the path
2018-05-09 16:13:36 +00:00
one has moved. An inhabitant of $ \Path \ P \ a _ 0 \ a _ 1 $ is a (dependent-) function,
$ p $ , from the index-space to the path-space:
2018-05-02 15:02:46 +00:00
%
$$
2018-05-09 16:13:36 +00:00
p \tp \prod _ { i \tp I} P\ i
2018-05-02 15:02:46 +00:00
$$
%
Which must satisfy being judgmentally equal to $ a _ 0 $ (respectively $ a _ 1 $ ) at the
endpoints. I.e.:
%
\begin { align*}
p\ 0 & = a_ 0 \\
p\ 1 & = a_ 1
2018-05-07 08:53:22 +00:00
\end { align*}
2018-05-02 15:02:46 +00:00
%
2018-05-09 16:13:36 +00:00
The notion of ``homogeneous equalities'' is recovered when $ P $ does not depend
on it's argument:
2018-05-02 15:02:46 +00:00
%
$$
a_ 0 \equiv a_ 1 \defeq \Path \ (\lambda i \to A)\ a_ 0\ a_ 1
$$
%
For $ A \tp \MCU $ , $ a _ 0 , a _ 1 \tp A $ . I will generally prefer to use the notation
2018-05-09 16:13:36 +00:00
$ a \equiv b $ when talking about non-dependent paths and use the notation
$ \Path \ ( \lambda i \to P \ i ) \ a \ b $ when the path-space is of particular
2018-05-02 15:02:46 +00:00
interest.
With this definition we can also recover reflexivity. That is, for any $ A \tp
\MCU $ and $ a \tp A$ :
%
2018-05-08 00:00:23 +00:00
\begin { equation}
\begin { aligned}
2018-05-02 15:02:46 +00:00
\refl & \tp \Path (\lambda i \to A)\ a\ a \\
\refl & \defeq \lambda i \to a
2018-05-08 00:00:23 +00:00
\end { aligned}
\end { equation}
2018-05-02 15:02:46 +00:00
%
2018-05-09 16:13:36 +00:00
Here the path-space is $ P \defeq \lambda i \to A $ and it satsifies $ P \ i = A $
definitionally. So to inhabit it, is to give a path $ I \to A $ which is
judgmentally $ a $ at either endpoint. This is satisfied by the constant path;
i.e. the path that stays at $ a $ at any index $ i $ .
2018-05-02 15:02:46 +00:00
2018-05-09 16:13:36 +00:00
It's also surpisingly easy to show functional extensionality with which we can
construct a path between $ f $ and $ g $ -- the function defined in the introduction
(section \S \ref { sec:functional-extensionality} ).
%% module _ {ℓ a ℓ b} {A : Set ℓ a} {B : A → Set ℓ b} where
%% funExt : {f g : (x : A) → B x} → ((x : A) → f x ≡ g x) → f ≡ g
Functional extensionality is the proposition, given a type $ A \tp \MCU $ , a
family of types $ B \tp A \to \MCU $ and functions $ f, g \tp \prod _ { a \tp A }
B\ a$ :
%
\begin { equation}
\label { eq:funExt}
2018-05-09 16:24:07 +00:00
\funExt \tp \prod _ { a \tp A} f\ a \equiv g\ a \to f \equiv g
2018-05-09 16:13:36 +00:00
\end { equation}
2018-05-02 15:02:46 +00:00
%
2018-05-09 16:13:36 +00:00
%% p = λ i a → p a i
So given $ p \tp \prod _ { a \tp A } f \ a \equiv g \ a $ we must give a path $ f \equiv
g$ . That is a function $ I \to \prod _ { a \tp A} B\ a$ . So let $ i \tp I$ be given.
We must now give an expression $ \phi \tp \prod _ { a \tp A } B \ a $ satisfying
$ \phi \ 0 \equiv f \ a $ and $ \phi \ 1 \equiv g \ a $ . This neccesitates that the
expression must be a lambda-abstraction, so let $ a \tp A $ be given. Now we can
apply $ a $ to $ p $ and get the path $ p \ a \tp f \ a \equiv g \ a $ . And this exactly
satisfied the conditions for $ \phi $ . In conclustion \ref { eq:funExt} is inhabited
by the term:
%
\begin { equation}
\label { eq:funExt}
2018-05-09 16:24:07 +00:00
\funExt \ p \defeq λ i\ a → p\ a\ i
2018-05-09 16:13:36 +00:00
\end { equation}
%
With this we can now prove the desired equality $ f \equiv g $ from section
\S \ref { sec:functional-extensionality} :
%
\begin { align*}
p & \tp f \equiv g \\
2018-05-09 16:24:07 +00:00
p & \defeq \funExt \ \lambda n \to \refl
2018-05-09 16:13:36 +00:00
\end { align*}
%
Paths have some other important properties, but they are not the focus of
this thesis. \TODO { Refer the reader somewhere for more info.}
2018-05-02 15:02:46 +00:00
\section { Homotopy levels}
In ITT all equality proofs are identical (in a closed context). This means that,
in some sense, any two inhabitants of $ a \equiv b $ are ``equally good'' -- they
2018-05-09 16:13:36 +00:00
don't have any interesting structure. This is referred to as Uniqueness of
Identity Proofs (UIP). Unfortunately it is not possible to have a type-theory
with both univalence and UIP. In stead we have a hierarchy of types with an
increasing amount of homotopic structure. At the bottom of this hierarchy we
have the set of contractible types:
2018-05-02 15:02:46 +00:00
%
\begin { equation}
2018-05-08 00:00:23 +00:00
\begin { aligned}
%% \begin{split}
2018-05-09 16:13:36 +00:00
& \isContr & & \tp \MCU \to \MCU \\
2018-05-02 15:02:46 +00:00
& \isContr \ A & & \defeq \sum _ { c \tp A} \prod _ { a \tp A} a \equiv c
2018-05-08 00:00:23 +00:00
%% \end{split}
\end { aligned}
2018-05-02 15:02:46 +00:00
\end { equation}
%
The first component of $ \isContr \ A $ is called ``the center of contraction''.
Under the propositions-as-types interpretation of type-theory $ \isContr \ A $ can
2018-05-09 16:13:36 +00:00
be thought of as ``the true proposition $ A $ ''. And indeed $ \top $ is
contractible:
\begin { equation*}
\var { tt} , \lambda x \to \refl \tp \isContr \ \top
\end { equation*}
%
It is a theorem that if a type is contractible, then it is isomorphic to the
unit-type.
2018-05-02 15:02:46 +00:00
The next step in the hierarchy is the set of mere propositions:
%
\begin { equation}
2018-05-08 00:00:23 +00:00
\begin { aligned}
2018-05-02 15:02:46 +00:00
& \isProp & & \tp \MCU \to \MCU \\
& \isProp \ A & & \defeq \prod _ { a_ 0, a_ 1 \tp A} a_ 0 \equiv a_ 1
2018-05-08 00:00:23 +00:00
\end { aligned}
2018-05-02 15:02:46 +00:00
\end { equation}
%
2018-05-09 16:13:36 +00:00
$ \isProp \ A $ can be thought of as the set of true and false propositions. And
indeed both $ \top $ and $ \bot $ are propositions:
%
\begin { align*}
λ \var { tt} \ \var { tt} → refl & \tp \isProp \ ⊤ \\
λ\varnothing \ \varnothing & \tp \isProp \ ⊥
\end { align*}
%
I've used $ \varnothing $ here to denote an impossible pattern. It is a theorem
that if a mere proposition $ A $ is inhabited, then so is it contractible. If it
is not inhabited it is equivalent to the empty-type (or false
proposition).\TODO { Cite!!}
2018-05-02 15:02:46 +00:00
I will refer to a type $ A \tp \MCU $ as a \emph { mere} proposition if I want to
stress that we have $ \isProp \ A $ .
Then comes the set of homotopical sets:
%
\begin { equation}
2018-05-08 00:00:23 +00:00
\begin { aligned}
2018-05-02 15:02:46 +00:00
& \isSet & & \tp \MCU \to \MCU \\
& \isSet \ A & & \defeq \prod _ { a_ 0, a_ 1 \tp A} \isProp \ (a_ 0 \equiv a_ 1)
2018-05-08 00:00:23 +00:00
\end { aligned}
2018-05-02 15:02:46 +00:00
\end { equation}
%
2018-05-09 16:13:36 +00:00
I won't give an example of a set at this point. It turns out that proving e.g.
$ \isProp \ \bN $ is not so straight-forward (see \S 3.1.4 in \ref { hott-2013} ).
There will be examples of sets later in this report. At this point it should be
noted that the term ``set'' is somewhat conflated; there is the notion of sets
from set-theory, in Agda types are denoted \texttt { Set} . I will use it
consistently to refer to a type $ A $ as a set exactly if $ \isSet \ A $ is
a proposition.
2018-05-02 15:02:46 +00:00
2018-05-07 22:25:34 +00:00
The next step in the hierarchy is, as the reader might've guessed, the type:
2018-05-02 15:02:46 +00:00
%
\begin { equation}
2018-05-08 00:00:23 +00:00
\begin { aligned}
2018-05-02 15:02:46 +00:00
& \isGroupoid & & \tp \MCU \to \MCU \\
& \isGroupoid \ A & & \defeq \prod _ { a_ 0, a_ 1 \tp A} \isSet \ (a_ 0 \equiv a_ 1)
2018-05-08 00:00:23 +00:00
\end { aligned}
2018-05-02 15:02:46 +00:00
\end { equation}
%
And so it continues. In fact we can generalize this family of types by indexing
them with a natural number. For historical reasons, though, the bottom of the
2018-05-07 22:25:34 +00:00
hierarchy, the contractible types, is said to be a \nomen { -2-type} , propositions
2018-05-02 15:02:46 +00:00
are \nomen { -1-types} , (homotopical) sets are \nomen { 0-types} and so on\ldots
Just as with paths, homotopical sets are not at the center of focus for this
thesis. But I mention here some properties that will be relevant for this
exposition:
Proposition: Homotopy levels are cumulative. That is, if $ A \tp \MCU $ has
homotopy level $ n $ then so does it have $ n + 1 $ .
Let $ \left \Vert A \right \Vert = n $ denote that the level of $ A $ is $ n $ .
Proposition: For any homotopic level $ n $ this is a mere proposition.
%
\section { A few lemmas}
Rather than getting into the nitty-gritty details of Agda I venture to take a
2018-05-07 22:25:34 +00:00
more ``combinator-based'' approach. That is, I will use theorems about paths
2018-05-02 15:02:46 +00:00
already that have already been formalized. Specifically the results come from
the Agda library \texttt { cubical} (\TODO { Cite} ). I have used a handful of
results from this library as well as contributed a few lemmas myself.\footnote { The module \texttt { Cat.Prelude} lists the upstream dependencies. As well my contribution to \texttt { cubical} can be found in the git logs \TODO { Cite} .}
2018-05-07 22:25:34 +00:00
These theorems are all purely related to homotopy theory and cubical Agda and as
2018-05-02 15:02:46 +00:00
such not specific to the formalization of Category Theory. I will present a few
of these theorems here, as they will be used later in chapter
\ref { ch:implementation} throughout.
\subsection { Path induction}
2018-05-03 12:18:51 +00:00
\label { sec:pathJ}
2018-05-02 15:02:46 +00:00
The induction principle for paths intuitively gives us a way to reason about a
type-family indexed by a path by only considering if said path is $ \refl $ (the
2018-05-07 22:25:34 +00:00
``base-case''). For \emph { based path induction} , that equality is \emph { based}
2018-05-02 15:02:46 +00:00
at some element $ a \tp A $ .
Let a type $ A \tp \MCU $ and an element of the type $ a \tp A $ be given. $ a $ is said to be the base of the induction. Given a family of types:
%
$$
P \tp \prod _ { a' \tp A} \prod _ { p \tp a ≡ a'} \MCU
$$
%
And an inhabitant of $ P $ at $ \refl $ :
%
$$
p \tp P\ a\ \refl
$$
%
We have the function:
%
2018-05-09 16:13:36 +00:00
\begin { equation}
2018-05-02 15:02:46 +00:00
\pathJ \ P\ p \tp \prod _ { a' \tp A} \prod _ { p \tp a ≡ a'} P\ a\ p
2018-05-09 16:13:36 +00:00
\end { equation}
2018-05-02 15:02:46 +00:00
%
2018-05-09 16:13:36 +00:00
I will not give an example of using $ \pathJ $ here. But we'll see an application
of it in \ref { eq:pathJ-example} .
2018-05-02 15:02:46 +00:00
\subsection { Paths over propositions}
2018-05-03 12:18:51 +00:00
\label { sec:lemPropF}
2018-05-02 15:02:46 +00:00
Another very useful combinator is $ \lemPropF $ :
To `promote' this to a dependent path we can use another useful combinator;
$ \lemPropF $ . Given a type $ A \tp \MCU $ and a type family on $ A $ ; $ P \tp A \to
\MCU $ . Let $ \var { propP} \tp \prod _ { x \tp A} \isProp \ (P\ x)$ be the proof that
$ P $ is a mere proposition for all elements of $ A $ . Furthermore say we have a
path between some two elements in $ A $ ; $ p \tp a _ 0 \equiv a _ 1 $ then we can built
a heterogeneous path between any two elements of $ p _ 0 \tp P \ a _ 0 $ and $ p _ 1 \tp
P\ a_ 1$ :
%
$$
\lemPropF \ \var { propP} \ p \defeq \Path \ (\lambda \; i \mto P\ (p\ i))\ p_ 0\ p_ 1
$$
%
This is quite a mouthful. So let me try to show how this is a very general and
useful result.
Often when proving equalities between elements of some dependent types
$ \lemPropF $ can be used to boil this complexity down to showing that the
dependent parts of the type are mere propositions. For instance, saw we have a type:
%
$$
2018-05-08 00:01:17 +00:00
T \defeq \sum _ { a \tp A} P\ a
2018-05-02 15:02:46 +00:00
$$
%
For some proposition $ P \tp A \to \MCU $ . If we want to prove $ t _ 0 \equiv t _ 1 $
for two elements $ t _ 0 , t _ 1 \tp T $ then this will be a pair of paths:
%
%
\begin { align*}
p \tp & \fst \ t_ 0 \equiv \fst \ t_ 1 \\
& \Path \ (\lambda i \to P\ (p\ i))\ \snd \ t_ 0 \equiv \snd \ t_ 1
\end { align*}
%
Here $ \lemPropF $ directly allow us to prove the latter of these:
%
$$
\lemPropF \ \var { propP} \ p
\tp \Path \ (\lambda i \to P\ (p\ i))\ \snd \ t_ 0 \equiv \snd \ t_ 1
$$
%
\subsection { Functions over propositions}
2018-05-03 12:18:51 +00:00
\label { sec:propPi}
2018-05-02 15:02:46 +00:00
$ \prod $ -types preserve propositionality when the co-domain is always a
proposition.
%
$$
\mathit { propPi} \tp \left (\prod _ { a \tp A} \isProp \ (P\ a)\right ) \to \isProp \ \left (\prod _ { a \tp A} P\ a\right )
$$
\subsection { Pairs over propositions}
2018-05-03 12:18:51 +00:00
\label { sec:propSig}
2018-05-02 15:02:46 +00:00
%
$ \sum $ -types preserve propositionality whenever it's first component is a
proposition, and it's second component is a proposition for all points of in the
left type.
%
$$
\mathit { propSig} \tp \isProp \ A \to \left (\prod _ { a \tp A} \isProp \ (P\ a)\right ) \to \isProp \ \left (\sum _ { a \tp A} P\ a\right )
$$