2018-05-02 15:02:46 +00:00
\chapter { Cubical Agda}
\section { Propositional equality}
2018-05-15 14:08:29 +00:00
Judgmental equality in Agda is a feature of the type system. Its 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
2018-05-15 14:08:29 +00:00
normal definition of judgmental equality is an inductive data type. Cubical Agda
2018-05-09 16:13:36 +00:00
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-15 14:08:29 +00:00
In Agda this is defined as an inductive data type with the single constructor
2018-05-09 16:13:36 +00:00
for any $ a \tp A $ :
2018-05-02 15:02:46 +00:00
%
\begin { align}
\refl \tp a \equiv a
\end { align}
%
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-15 14:08:29 +00:00
This is likewise defined as an inductive data type with a single constructors
2018-05-09 16:13:36 +00:00
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
%
2018-05-15 14:08:29 +00:00
$ I $ is a special data type (\TODO { that also has special computational properties
2018-05-02 15:02:46 +00:00
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
2018-05-15 14:08:29 +00:00
$ I $ . I will sometimes refer to $ P $ as the \nomenindex { path space} of some path $ p \tp
2018-05-02 15:02:46 +00:00
\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-16 09:01:07 +00:00
behind this is that $ \Path $ describes paths in $ \MCU $ -- i.e.\ between types. For
2018-05-02 15:02:46 +00:00
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,
2018-05-15 14:08:29 +00:00
$ 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-15 14:08:29 +00:00
The notion of \nomenindex { homogeneous equalities} is recovered when $ P $ does not
depend on its argument. That is for $ A \tp \MCU $ , $ a _ 0 , a _ 1 \tp A $ the
homogenous equality between $ a _ 0 $ and $ a _ 1 $ is the type:
2018-05-02 15:02:46 +00:00
%
$$
a_ 0 \equiv a_ 1 \defeq \Path \ (\lambda i \to A)\ a_ 0\ a_ 1
$$
%
2018-05-15 14:08:29 +00:00
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
2018-05-15 14:08:29 +00:00
$ \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-15 14:08:29 +00:00
Here the path space is $ P \defeq \lambda i \to A $ and it satsifies $ P \ i = A $
2018-05-09 16:13:36 +00:00
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;
2018-05-16 09:01:07 +00:00
i.e.\ the path that stays at $ a $ at any index $ i $ .
2018-05-02 15:02:46 +00:00
2018-05-09 16:34:05 +00:00
It is also surpisingly easy to show functional extensionality with which we can
2018-05-10 13:28:33 +00:00
construct a path between $ f $ and $ g $ -- the functions defined in the
introduction (section \S \ref { sec:functional-extensionality} ). 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 $ :
2018-05-09 16:13:36 +00:00
%
\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-15 14:08:29 +00:00
%
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:47:12 +00:00
do not have any interesting structure. This is referred to as Uniqueness of
2018-05-15 14:08:29 +00:00
Identity Proofs (UIP). Unfortunately it is not possible to have a type theory
2018-05-09 16:13:36 +00:00
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''.
2018-05-15 14:08:29 +00:00
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-15 14:08:29 +00:00
One can think of $ \isProp \ A $ as the set of true and false propositions. And
2018-05-09 16:13:36 +00:00
indeed both $ \top $ and $ \bot $ are propositions:
%
\begin { align*}
λ \var { tt} \ \var { tt} → refl & \tp \isProp \ ⊤ \\
λ\varnothing \ \varnothing & \tp \isProp \ ⊥
\end { align*}
%
2018-05-15 14:08:29 +00:00
The term $ \varnothing $ is used 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
2018-05-09 16:13:36 +00:00
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:47:12 +00:00
I will not give an example of a set at this point. It turns out that proving
2018-05-16 09:01:07 +00:00
e.g.\ $ \isProp \ \bN $ is not so straight-forward (see \cite [\S3.1.4] { hott-2013} ).
2018-05-09 16:13:36 +00:00
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
2018-05-09 16:47:12 +00:00
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-09 16:47:12 +00:00
As the reader may have guessed the next step in the hierarchy is 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-15 14:08:29 +00:00
hierarchy, the contractible types, is said to be a \nomen { -2-type} { homotopy
levels} , propositions are \nomen { -1-types} { homotopy levels} , (homotopical)
sets are \nomen { 0-types} { homotopy levels} and so on\ldots
2018-05-02 15:02:46 +00:00
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
2018-05-15 14:08:29 +00:00
type family indexed by a path by only considering if said path is $ \refl $ (the
\nomen { base case} { path induction} ). 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:
%
$$
2018-05-10 13:28:33 +00:00
D \tp \prod _ { b \tp A} \prod _ { p \tp a ≡ b} \MCU
2018-05-02 15:02:46 +00:00
$$
%
2018-05-10 13:28:33 +00:00
And an inhabitant of $ D $ at $ \refl $ :
2018-05-02 15:02:46 +00:00
%
$$
2018-05-10 13:28:33 +00:00
d \tp D\ a\ \refl
2018-05-02 15:02:46 +00:00
$$
%
We have the function:
%
2018-05-09 16:13:36 +00:00
\begin { equation}
2018-05-10 13:28:33 +00:00
\pathJ \ D\ d \tp \prod _ { b \tp A} \prod _ { p \tp a ≡ b} D\ a\ p
2018-05-09 16:13:36 +00:00
\end { equation}
2018-05-02 15:02:46 +00:00
%
2018-05-10 13:28:33 +00:00
A simple application of $ \pathJ $ is for proving that $ \var { sym } $ is an
involution. Namely for any set $ A \tp \MCU $ , points $ a, b \tp A $ and a path
between them $ p \tp a \equiv b $ :
%
\begin { equation}
\label { eq:sym-invol}
\var { sym} \ (\var { sym} \ p) ≡ p
\end { equation}
%
The proof will be by induction on $ p $ and will be based at $ a $ . That is, $ D $
will be the family:
%
\begin { align*}
2018-05-11 11:07:47 +00:00
D & \tp \prod _ { b' \tp A} \prod _ { p \tp a ≡ b'} \MCU \\
2018-05-10 13:28:33 +00:00
D\ b'\ p' & \defeq \var { sym} \ (\var { sym} \ p') ≡ p'
\end { align*}
%
2018-05-15 14:08:29 +00:00
The base case will then be:
2018-05-10 13:28:33 +00:00
%
\begin { align*}
d & \tp \var { sym} \ (\var { sym} \ \refl ) ≡ \refl \\
d & \defeq \refl
\end { align*}
%
The reason $ \refl $ proves this is that $ \var { sym } \ \refl = \refl $ holds
definitionally. In summary \ref { eq:sym-invol} is inhabited by the term:
%
\begin { align*}
2018-05-11 11:07:47 +00:00
\pathJ \ D\ d\ b\ p
2018-05-10 13:28:33 +00:00
\tp
\var { sym} \ (\var { sym} \ p) ≡ p
\end { align*}
%
2018-05-11 11:07:47 +00:00
Another application of $ \pathJ $ is for proving associativity of $ \trans $ . That
is, given a type $ A \tp \MCU $ , elements of $ A $ , $ a, b, c, d \tp A $ and paths
between them, $ p \tp a \equiv b $ , $ q \tp b \equiv c $ and $ r \tp c \equiv d $ we
have the following:
%
\begin { equation}
\label { eq:cum-trans}
\trans \ p\ (\trans \ q\ r) ≡ \trans \ (\trans \ p\ q)\ r
\end { equation}
%
In this case the induction will be based at $ c $ (the left-endpoint of $ r $ ) and
over the family:
%
\begin { align*}
T & \tp \prod _ { d' \tp A} \prod _ { r' \tp c ≡ d'} \MCU \\
T\ d'\ r' & \defeq \trans \ p\ (\trans \ q\ r') ≡ \trans \ (\trans \ p\ q)\ r'
\end { align*}
%
2018-05-15 14:08:29 +00:00
So the base case is proven with $ t $ which is defined as:
2018-05-11 11:07:47 +00:00
%
\begin { align*}
\trans \ p\ (\trans \ q\ \refl ) & ≡
\trans \ p\ q \\
& ≡
\trans \ (\trans \ p\ q)\ \refl
\end { align*}
%
Here we have used the proposition $ \trans \ p \ \refl \equiv p $ without proof. In
conclusion \ref { eq:cum-trans} is inhabited by the term:
%
\begin { align*}
\pathJ \ T\ t\ d\ r
\end { align*}
%
2018-05-15 14:08:29 +00:00
We shall see another application on path induction in \ref { eq:pathJ-example} .
2018-05-09 16:13:36 +00:00
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$ :
%
$$
2018-05-15 14:08:29 +00:00
\lemPropF \ \var { propP} \ p \tp \Path \ (\lambda \; i \mto P\ (p\ i))\ p_ 0\ p_ 1
2018-05-02 15:02:46 +00:00
$$
%
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
%
2018-05-09 16:34:05 +00:00
$ \sum $ -types preserve propositionality whenever its first component is a
proposition, and its second component is a proposition for all points of in the
2018-05-02 15:02:46 +00:00
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 )
$$