\section{Programming and Proving in Cubical Agda} \label{agda-intro} Agda \citep{norellDependentlyTypedProgramming2008} is a dependently-typed, pure,
functional programming language and proof assistant.
In this section we will introduce the language with some basic examples, and
explain a little about how to program and prove in Agda.
Some Haskell knowledge will help, as much of the syntax (any many concepts) are
similar, but it is possible to struggle through without it.
It is recommended to try out the code examples in your own editor, or to look at
them in the real Agda files in the source.
The source is rendered and structured to be read alongside this document: it can
be found at \mbox{\url{https://doisinkidney.com/code/masters-thesis/README.html}}.

Agda is first and foremost a functional programming language, similar in syntax
and design to Haskell.
It is pure, meaning that it doesn't allow undeclared side effects, and
\emph{lazy}, meaning that expressions are not evaluated until they are needed
(although this has no effect on Agda's semantics: since Agda is total, both lazy
and strict evaluation will result in the same output).

While Agda can be compiled (to Haskell, or to JavaScript), it is usually just
type-checked: this is because Agda is also a \emph{proof assistant}.
Programs written in Agda correspond to proofs in the formal language of
Martin-Löf Type Theory \citep{martin-lofIntuitionisticTypeTheory1980}, in the
style of ``Propositions as Types'' \citep{wadlerPropositionsTypes2015}.
Types in Agda correspond to formal propositions; the programs which inhabit
those types correspond to proofs of those propositions.
\begin{figure}
  \centering
  \begin{tikzcd}
    \text{Proposition} \ar[r, leftrightsquigarrow] & \text{Type} \\
    \text{Proof} \ar[r, leftrightsquigarrow] \ar[u, "\text{proves}"
    description]& \text{Program} \ar[u, "\text{inhabits}" description]
  \end{tikzcd}
\end{figure}
\subsection{Basic Functional Programming in Agda}
The basic unit of functionality in Agda is the \emph{type}.
Let's define a type: the type of booleans (we include the equivalent code in
Haskell on the right).
\begin{agdalisting} \label{bool-def}
  \begin{multicols}{2} \centering
    \ExecuteMetaDataInline[agda/Snippets/Bool.tex]{bool-def} \columnbreak
    \ExecuteMetaDataInline[haskell/Bool.tex]{bool-def}
  \end{multicols}\vspace{-2\baselineskip}
\end{agdalisting}
There's a lot of syntax wrapped up in this small snippet.
In prose, it provides four basic pieces of information:
\begin{samepage}
\begin{enumerate}
  \item We are defining a new \AgdaKeyword{data} type.
  \item Its name is \AgdaDatatype{Bool}.
  \item \AgdaDatatype{Bool} is a \AgdaFunction{\(\text{Type}_0\)} kind of thing.
  \item There are two ways to construct values of type \AgdaDatatype{Bool}:
    \AgdaInductiveConstructor{false} and \AgdaInductiveConstructor{true}.
\end{enumerate}
\end{samepage}
Let's explain each piece one by one.

\paragraph{Data Types}
We first say that we're defining a new \AgdaKeyword{data} type.
Using the ``\AgdaKeyword{data}'' keyword is just one of the many ways of
defining types: it basically means that we are going to define the type by
listing all of its constructors (all of the ways to construct values of the
type).
There are other ways to define types: with the \AgdaKeyword{record} keyword, for
instance, which we'll see later; or we can define types by referencing other
types, creating a synonym.
Here, for instance, we define the \AgdaFunction{Boolean} type:
\begin{agdalisting*}
  \begin{multicols}{2} \centering
    \ExecuteMetaDataInline[agda/Snippets/Bool.tex]{boolean} \columnbreak
    \ExecuteMetaDataInline[haskell/Bool.tex]{boolean-synonym}
  \end{multicols}\vspace{-\baselineskip}
\end{agdalisting*}
This snippet says ``I am defining a new thing called \AgdaFunction{Boolean}, it
is a \AgdaFunction{\(\text{Type}_0\)}, and it is equal to \AgdaDatatype{Bool}''.
Of course this isn't a very interesting declaration: as the equals sign implies,
\AgdaFunction{Boolean} is the same as \AgdaFunction{Bool} (other than the
spelling).
We've basically defined a synonym for the old type.

Notice that in Haskell we needed a special keyword in order to define this type
synonym: in Agda, types are first-class values, which we can manipulate just as
we would functions or numbers.
As such, defining a type synonym is exactly the same as defining a new variable:
it doesn't need any special syntax.
\paragraph{Type Names}
The second point is pretty straightforward: the name of the type we've defined
is \AgdaDatatype{Bool}.
The only thing to watch out for here is that Agda has relatively few
restrictions on type names, unlike, say, Haskell.
This type could have included Unicode symbols (Agda supports roughly 50 Unicode
mathematical symbols), it could have started with a lowercase letter, etc.

\paragraph{Type\textsubscript{0}}
The third point is the most interesting: we say that \AgdaDatatype{Bool} is a
``\AgdaFunction{\(\text{Type}_0\)}'' kind of thing.
What does this mean?

Well, we've seen that we can assign types to variables just as easily as we
might assign values to variables: this is what was happening in the
\AgdaFunction{Boolean} example.
In fact, in Agda, there is no real distinction between ``types'' and ``values'':
types like \AgdaDatatype{Bool} \emph{are} values, just as much as
\AgdaInductiveConstructor{true} or \AgdaInductiveConstructor{false}!
This means that our types must themselves have types: hence we say that
\AgdaFunction{Boolean} has type \AgdaFunction{\(\text{Type}_0\)}.

But why the subscript 0?
Well we know that types are values in Agda, and so they themselves have types.
We know that the type of \AgdaDatatype{Bool} is
\AgdaFunction{\(\text{Type}_0\)}.
But what's the type of \AgdaFunction{\(\text{Type}_0\)}?
It turns out that if we say:
\begin{agdalisting*}
  \(\AgdaFunction{\(\text{Type}_0\)} :  \AgdaFunction{\(\text{Type}_0\)}\)
\end{agdalisting*}
We actually introduce a paradox into the language: Girard's paradox
\citep{girardInterpretationFonctionelleElimination1972}.
This is the type-theoretic analogue of Russell's paradox, and, if present, it
would allow us to prove things that are not true.
So we disallow it.

Dependently-types programming languages have many different ways of resolving
the issue: Agda's approach is called \emph{universe polymorphism}.
Basically, we say that the type of \AgdaInductiveConstructor{true} is
\AgdaDatatype{Bool}, the type of \AgdaDatatype{Bool} is
\AgdaFunction{\(\text{Type}_0\)}, the type of \AgdaFunction{\(\text{Type}_0\)}
is \AgdaFunction{\(\text{Type}_1\)}, the type of \AgdaFunction{\(\text{Type}_1\)}
is \AgdaFunction{\(\text{Type}_2\)}, and so on.

To be honest, avoiding Girard's paradox is one of things that isn't done
especially well in dependently-typed languages: most approaches require quite a
bit of tedious busywork from the programmer, and it's quite rare that a
programmer would run into a genuine universe size issue that exposes a deep
logical impossibility (we will run into one of the few cases in this paper).
Most of the time, managing universe levels amounts to bookkeeping.
For that reason, and also because the current system of universe polymorphism in
Agda is quite under flux and likely to be changed soon, we won't spend too much
time on the topic.
Every code example provided is as universe-polymorphic as possible, though.

\paragraph{Constructors}
The last point is the simplest: we have listed the ways to construct values of
type \AgdaDatatype{Bool}.
Two ways, in fact, \AgdaInductiveConstructor{true} and
\AgdaInductiveConstructor{false}, and they're called the constructors.
We can use these constructors in programs by (for instance) assigning them to
variables.
\begin{multicols}{2}\centering
  \ExecuteMetaDataInline[agda/Snippets/Bool.tex]{bool-val}\columnbreak
  \ExecuteMetaDataInline[haskell/Bool.tex]{bool-val}
\end{multicols}\vspace{-2\baselineskip}\noindent
Here we've declared a variable\footnotemark\;called \AgdaFunction{a-boolean} with
the type \AgdaDatatype{Bool}, and said it is equal to the value
\AgdaInductiveConstructor{true}.

\footnotetext{Note that although we use the term ``variable'', the value of the
  variable \AgdaFunction{a-boolean} can not change.
  We couldn't reassign it on the following line.}

\subsection{Some Functions}
That's quite a lot of information on how to define things in Agda: let's look a
little about how to do computation.
What we need is a function:
\begin{multicols}{2}\centering
  \ExecuteMetaDataInline[agda/Snippets/Bool.tex]{not-def}\columnbreak
  \ExecuteMetaDataInline[haskell/Bool.tex]{not-func}
\end{multicols}\vspace{-2\baselineskip}\noindent
This function is defined by pattern-matching: when the clause on the
left-hand-side of the equals sign is seen, the right-hand-side is what's
computed.

This syntax with the equals sign is actually just syntactic sugar for a \(\lambda\).
The identity function, for instance, could be written as follows:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Implicits.tex]{id-lambda}
\end{agdalisting*}
The \AgdaFunction{not} function could also have been written with a \(\lambda\).
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Bool.tex]{lambda-not}
\end{agdalisting*}

For a more complex example, we're going to need a more complex type:
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Snippets/Nat.tex]{nat-def}
\end{agdalisting}
This is the type of the natural numbers.
With \AgdaDatatype{Bool} (\Cref{bool-def}) we were able to list all the
actual values in the type: doing so for the natural numbers would somewhat bloat
the page count of this paper.
Instead, we list the two ways to construct natural numbers: first,
\AgdaInductiveConstructor{zero} is a natural number.
Next, if you have a natural number, its successor
(\AgdaInductiveConstructor{suc}) is a natural number.

Agda has special syntax for constructing natural numbers: we can write
\AgdaNumber{3} instead of
\(\AgdaInductiveConstructor{suc}\;(\AgdaInductiveConstructor{suc}\;(\AgdaInductiveConstructor{suc}\;\AgdaInductiveConstructor{zero}))\).

There are several small pieces of information we'll need to understand in order
to write functions in Agda.
We'll go through them one by one.
\paragraph{Multi-Argument Functions}
Agda, like Haskell, doesn't really have a built-in notion of ``multi-argument''
functions.
Instead, multiple arguments are kind of simulated with \emph{currying}.

Here's how we define the addition of two natural numbers:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Nat.tex]{text-add}
\end{agdalisting*}
Instead of taking two \Nat s and returning a third, this function takes a
\Nat, and returns a function which takes a \Nat and returns a
\Nat.
\AgdaFunction{add}\;\AgdaNumber{0} returns a function which
adds \AgdaNumber{0} to a number; \AgdaFunction{add}\;\AgdaNumber{2} returns a
function which adds \AgdaNumber{2} to a number.
\paragraph{Operators}
Here's a function on the natural numbers:
\begin{agdalisting} \label{sub-def}
  \ExecuteMetaDataInline[agda/Snippets/Nat.tex]{sub-def}
\end{agdalisting}
We've defined subtraction.

Notice that this function is defined as an operator: for the function
declaration (the line with the type signature), we put underscores where we
expect the arguments to the operator to go.

We can also specify the precedence and fixity of the operator:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Nat.tex]{sub-fix}
\end{agdalisting*}
\paragraph{Total Functions}
In the introduction, we described Agda as a ``total'' programming language.
This means that if we give a function the type \(A \rightarrow B\), then we have
also \emph{proven} that, given an \(A\), it will produce a \(B\) (in finite
time).

Practically speaking, this means that Agda will perform some checks on our
code to ensure that every function is indeed total.
There are three checks that Agda performs that we will run into in this paper:
coverage, termination, and productivity.
\subparagraph{Coverage}
This is the simplest check that Agda performs: it's also performed by GHC (if
\verb+-Wall+ is turned on).
This check ensures that functions are defined for all inputs.

Our definition of subtraction above (\Cref{sub-def}), for instance,
truncates to zero when there's arithmetic underflow.
In other words \(5 - 6 = 0\), according to our definition.
We could have removed the clause which allows for this:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Nat.tex]{bad-sub}
\end{agdalisting*}
But now the expression \(5 - 6\) is undefined.
\subparagraph{Termination}
The other major check that Agda will preform on our function definitions is for
\emph{termination} (or productivity, which we will see later).
This checks that no function we write accidentally contains an infinite loop.
Most of the time, we won't butt heads with the
termination checker, but it does happen occasionally, so it's helpful to
understand a little how it works. When we define the following function
(addition on the natural numbers):
\begin{agdalisting} \label{add-def}
  \ExecuteMetaDataInline[agda/Snippets/Nat.tex]{add-def}
\end{agdalisting}
Agda checks that the argument to the recursive call is \emph{structurally
  smaller} than the argument given to the outer function.
``Structurally smaller'' effectively means that the smaller thing must be a
subexpression of the larger: here, \(n\) is subexpression of
\(\AgdaInductiveConstructor{suc}\;n\).

Structural recursion is actually surprisingly powerful: a great many algorithms
can be converted to forms where the recursive calls recurse on some substructure
of their arguments.
It does require careful definitions, though.
For instance, the following will \emph{not} pass the termination checker:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Nat.tex]{bad-add}
\end{agdalisting*}
Though it defines the same function as \Cref{add-def}, it doesn't make
it absolutely obvious to the termination checker that the first argument to the
recursive call (\(n - 1\)) is structurally smaller than the outer argument
(\(n\)).

Occasionally a function can't be refactored to the extent where it will be
obviously structurally terminating to Agda.
In those cases, there are facilities to describe more complex termination
conditions (although we should stress that these facilities are not
built in to the compiler or anything: they're actually just extremely clever
ways to express structural recursion), but if you have to reach for those
facilities it's usually a sign you've gone wrong.
We won't use them here.
\subparagraph{Productivity}
Productivity isn't something we'll describe just yet, but we will give a hint as
to its purpose.
Often when describing total programming languages like Agda people make the
mistake of saying that they are ``not Turing complete''.
This is in fact not true, partly because Agda has the ability to describe non
terminating (and infinite) computations.
This allows us to implement, for instance, a Turing machine or
\(\lambda\)-calculus interpreter
\citep{mcbrideTuringCompletenessTotallyFree2015}, or more prosaic things like a
web server or repl.

While these things don't ``terminate'', Agda still needs to check that they are
valid with regards to computation in another sense.
This sense is \emph{productivity}: they need to always be able to produce
another piece of information in finite time, even if they never ``finish''
producing pieces of information.
\subparagraph{What's it all For?}
One thing we haven't answered is \emph{why} we bother checking for termination
or totality.
The answer is that it's necessary for Agda to be a valid proof assistant.
Imagine if we could construct a type for ``proofs of the Riemann hypothesis''.
We might call it \AgdaFunction{RiemannIsTrue}.
In a language like Haskell, the following is a completely valid program:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Nat.tex]{riemann-proof}
\end{agdalisting*}
But of course we \emph{haven't} provided a proof of the Riemann hypothesis (and
if we had we certainly wouldn't have buried the lead to this extent).
The termination checker is vital to rule out these kinds of ``proofs'': that's
why it's an integral part of Agda.
\subsection{An Expression Evaluator}
Let's put all of the different things we've learned into a more complex example.
We're going to write a small evaluator for arithmetic expressions.
Later, we'll use this to help us solve the Countdown problem
\citep{huttonCountdownProblem2002}.

We want to define a language of arithmetic expressions.
With countdown in mind, we'll only need to support four operators, which we can
define in a simple data type:
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{op-def}
\end{agdalisting}
Next, we'll define the actual type of expressions.
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{expr-def}
\end{agdalisting}
What we've defined here is actually a simple leafy binary tree.
The syntax for the second constructor is not so simple, however: it defines a
\emph{mixfix} operator.
Each underscore in \AgdaInductiveConstructor{\(\_\langle \_ \rangle\_\)}
represents a hole which expressions can be put into.
This allows us to use the constructor like so:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{example-expr}
\end{agdalisting*}

Evaluation of an expression is done by the following function:
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{incorrect-eval}
\end{agdalisting}
We've introduced the \AgdaKeyword{with} syntax here: it functions somewhat like
a case expression in Haskell.
Basically, it allows us to pattern-match on the result of applying a function to
one of the input arguments without defining a new function.
\subsection{Safe Evaluation With Maybe}
The evaluator we have written isn't exactly correct.
It implies things like \(4 - 5 = 0\), or \(10 \div 3 = 3\), or \(2 \div 0 = 0\);
this doesn't make the function ``wrong'' per se, but it might be more desirable
to have expressions like \(2 \div 0\) be undefined.
It's especially important for countdown, as division by zero (or any of the
other equations) isn't permitted.

To remedy the problem we're going to introduce a new type.
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Data/Maybe/Base.tex]{maybe-def}
\end{agdalisting}
\AgdaDatatype{Maybe} is a container that can contain at most one item.
It's the first \emph{parameterised} type we have seen: \AgdaDatatype{Maybe} can
contain an item of any type.
Here, for instance, is a \AgdaDatatype{Maybe} which contains the number 2:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Maybe.tex]{maybe-two}
\end{agdalisting*}
Or here is a \AgdaDatatype{Maybe} which doesn't contain anything, but whose type
says it could contain a function from \Nat to \Nat:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Maybe.tex]{maybe-nat-to-nat}
\end{agdalisting*}

Maybe is used often in functional programming to represent partiality: if you
have a function which is undefined for certain inputs, you can wrap
\AgdaDatatype{Maybe} around its return type, and return
\AgdaInductiveConstructor{nothing} for the cases where those inputs are given.
We can use it here, for instance, to define a version of subtraction which
doesn't truncate arithmetic underflow:
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{safe-sub}
\end{agdalisting}
It's often also used for similar purposes as \verb+null+ is in imperative
programming, although it is of course far safer since it's impossible to forget
to check for \AgdaInductiveConstructor{nothing} by definition.

We can use \AgdaDatatype{Maybe} in our evaluator for expressions, so that we
return \AgdaInductiveConstructor{nothing} on expressions which evaluate to
undefined values.
That changes the type to the following:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{eval-ty}
\end{agdalisting*}
The first case is relatively simple:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{lit-case}
\end{agdalisting*}

The second two cases are slightly more complex: the result of evaluating each
sub-tree is \(\AgdaDatatype{Maybe}\;\Nat\), not \Nat, so we will
have to pattern-match on the outputs to check for
\AgdaInductiveConstructor{nothing}.
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{add-helper}
\end{agdalisting*}
Code like this is quite tedious.
Luckily, there's a common pattern we can abstract out: whenever we have a
multi-argument function, we can apply it to arguments wrapped in
\AgdaDatatype{Maybe} using the following two functions.
\begin{multicols}{2} \null \vfill
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Data/Maybe/Sugar.tex]{pure}
  \end{agdalisting*} \vfill \null \columnbreak
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Data/Maybe/Sugar.tex]{ap}
  \end{agdalisting*}
\end{multicols} \noindent
Any type which implements these functions (in a certain law-abiding way) is said
to be an ``Applicative Functor''
\citep{mcbrideApplicativeProgrammingEffects2008}, a full explanation of which is
beyond the scope of this paper.

It might not be immediately clear how those two functions can help us.
Basically, we can replace the \AgdaFunction{add-helper} function with the
following:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{add-helper-app}
\end{agdalisting*}
And, as it happens, Agda has special syntax which will automatically insert the
\AgdaFunction{pure} and \AgdaFunction{\_<*>\_} operators for us, making both the
addition and multiplication cases the following:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{appl-cases}
\end{agdalisting*}

Next, we have to handle subtraction.
In contrast to addition and multiplication, subtraction itself can produce a
\AgdaInductiveConstructor{nothing}: instead of having type
\(\Nat\rightarrow\Nat\rightarrow\Nat\), it has type
\(\Nat\rightarrow\Nat\rightarrow\AgdaDatatype{Maybe}\;\Nat\).
To construct multi-argument functions of this particular type, we'll need
another function:
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Data/Maybe/Sugar.tex]{bind}
\end{agdalisting}
Types which implement this function (along with \AgdaFunction{pure}), modulo
some laws, are called Monads \citep{moggiNotionsComputationMonads1991a}.
This function will allow us to easily chain together several maybes even with
functions that return \AgdaDatatype{Maybe}.
It's used like this:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{sub-bind}
\end{agdalisting*}
And of course Agda also provides a syntax (do notation, just like Haskell) to
express the same:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{sub-case}
\end{agdalisting*}

Finally, we will handle the division case.
Here, we want to pattern-match on the returned value of the recursive call.
Agda also provides syntax for that:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{div-case}
\end{agdalisting*}
The \AgdaKeyword{where} keyword here lets us match on zero within the
\AgdaKeyword{do}-notation.
\subsection{Statically Proving the Evaluation is Safe}
Using this evaluator in practice can be a little annoying:
because it always returns a \AgdaDatatype{Maybe}, simple expressions which are
obviously valid still need to be checked at run-time.
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{example-eval}
\end{agdalisting*}
This is where Agda can add a little to the usual example for monads of an
expression evaluator: using dependent types, we can actually statically (and
automatically) prove that a given expression is valid, and evaluate it without
checking for \AgdaInductiveConstructor{nothing} safely.

First, we will need the following function:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{is-just}
\end{agdalisting*}
This simple function can tell us if the result of evaluating an expression is
successful or not.
In other words, it can test if an expression is valid.

To use this statically, however, we will need to employ the following
\emph{dependent} function:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{tee}
\end{agdalisting*}
This function turns our boolean values into types: \agdatop\;(tautology), or
\agdabot\;(impossibility).
These types are defined like so:
\begin{multicols}{2}
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{bot}
  \end{agdalisting*}  \columnbreak
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{top}
  \end{agdalisting*}
\end{multicols}
The first type here, \agdabot, has no constructors: there are no values which
inhabit the type \agdabot.
Logically speaking, it is the type of falsehoods.
It is quite useful in practice: any function of type \(A \rightarrow \agdabot\)
we know can never return, so we know that it must be impossible to call such a
function.
In other words, the type \(A\) must not have any values which inhabit it.
As such, we can use \agdabot\;to define a notion of ``not'' for types:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{not}
\end{agdalisting*}

The second type, \agdatop, is a \AgdaKeyword{record}.
Types defined using \AgdaKeyword{record} are quite like classes or structs
in an imperative programming language: instead of listing the constructors, we list
the \emph{fields} of these types.

Of course, in this case, our type doesn't have any fields.
Perhaps a more instructive example of a record is the following:
\begin{agdalisting} \label{pair-def}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{pair}
\end{agdalisting}
Here we've defined the type of \emph{pairs}.

Types defined with \AgdaKeyword{data} and types defined with
\AgdaKeyword{record} are in some sense duals of each other: to \emph{consume} a
\AgdaKeyword{data} type, we have to handle each of the constructors; to
\emph{construct} a \AgdaKeyword{record} type, we have to handle each of the
fields.
Another way to say this same thing is that \AgdaKeyword{data} types are sum
types, and \AgdaKeyword{record} types are products.
What we have in \agdabot\;and \agdatop\;is the identity for sums and products,
respectively.

Now, to be completely clear, we could absolutely have defined \agdatop\;as a
\AgdaKeyword{data} type with one constructor:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{data-top}
\end{agdalisting*}
We use the \AgdaKeyword{record} definition simply because it tends to work a
little better in terms of ergonomics: basically, to construct a
\AgdaKeyword{record} type automatically, Agda attempts to construct all of its
\emph{fields} one by one.
Since \agdatop\;has no fields, this is an easy task, and hence Agda will be able
to automatically construct a value of type \agdatop\;in many situations
(We can ask Agda to construct something for us automatically by supplying an
underscore in place of where the value should go).
Agda is more conservative about automatically constructing \AgdaKeyword{data}
types, so there are fewer situations where it will do it automatically.

So, now that we have a way of turning booleans into their logical equivalents
we can define a type for proofs that a given
expression is valid:
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{valid}
\end{agdalisting}
A value of type \(\AgdaFunction{Valid}\;e\), for some expression \(e\), is a
proof that \(e\) doesn't have (for example) any divisions by zero, or
arithmetic underflows.

Now we can write a function that takes an expression \(e\) and a proof that that
expression is valid; then, when we pattern-match on evaluating the expression
Agda will automatically rule out the case where it evaluates to
\AgdaInductiveConstructor{nothing}.
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{static-eval-explicit}
\end{agdalisting*}

A way to make calling this function a little cleaner (syntactically speaking) is
to use an implicit argument:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{static-eval}
\end{agdalisting*}
By surrounding the argument here in braces we are basically going to pass around
the argument invisibly and automatically (as much as is possible).
Though it's invisible, it's clearly still usable as a variable: in this case the
proof still rules out the clause where the evaluation returns
\AgdaInductiveConstructor{nothing}.
The real use of this feature, however, is that the argument is \emph{passed}
invisibly.
\begin{agdalisting} \label{example-static-eval}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{example-static-eval}
\end{agdalisting}
What's happened here is that the type of \(\AgdaFunction{Valid}\;e\) uniquely
determines one value: Agda can derive this, and it can also derive the value
determined.
As a result, it provides it automatically.
The precise rules for when Agda can ``provide something automatically'' are
actually a little tricky (it's quite important that we defined \agdatop\;as a
\AgdaKeyword{record}, for instance): a fuller explanation is available in the
Agda manual.

Two more things about implicit arguments: first, it is possible to retrieve an
argument even when it's supplied implicitly, with the following syntax:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{retrieve-implicit}
\end{agdalisting*}
Here we have bound the proof that the expression is valid to the variable
\AgdaBound{valid}.

Secondly, we have actually been using implicit arguments throughout the paper,
in combination with automatically generalised variables.
These two features are quite natural to most programmers (especially to
Haskellers), so it might come as a surprise that we've been using them, but it's
true.
Take the following definition of the identity function:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Implicits.tex]{id-def}
\end{agdalisting*}
This is the same function with all implicit arguments made explicit:
\begin{agdalisting} \label{id-expl}
  \ExecuteMetaDataInline[agda/Snippets/Implicits.tex]{id-expl}
\end{agdalisting}
We have hidden the universe level of the type (\(a\)) and the type itself
(\(A\)).

Furthermore, not only have we made these things implicit, we haven't actually
specified them in the type at all!
We're able to do this because at the top of our Agda file we say the following:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Level.tex]{level-var-decl}
\end{agdalisting*}
This \AgdaKeyword{variable} declaration means that if we ever refer to  \(A\) in
a function signature without defining it beforehand, Agda will automatically
insert the implicit arguments present in \Cref{id-expl}.
\subsection{Equalities}
We actually have encountered our first ``proof'' with dependent types: we have
proven that a given expression is valid or not.
Now we're going to look at another kind of proof: one that shows that an
expression is \emph{equal} to something.
To do so we'll first have to explore path types in Cubical Agda.
\begin{definition}[Path Types]
  A proof that two values are equal in Cubical Agda is represented by a
  \emph{path}.
  This path will be denoted with the symbol \AgdaFunction{\(\equiv\)}.
  In other words, a value of type \(x\;\AgdaFunction{\(\equiv\)}\;y\) is a proof
  that \(x\) equals \(y\).
\end{definition}

Equalities as paths is the first topic we have reached where Cubical Type Theory
begins to differ from traditional Martin-Löf Type Theory.
There, we would usually define the type of proofs of equality like so:
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Snippets/Equality.tex]{equality-def}
\end{agdalisting}
This is an inductive \AgdaKeyword{data} type, with one constructor: the
constructor can only be used when the two parameters to the type are the same,
meaning a value of this type contains a proof that they are the same.
We can retrieve this proof by pattern-matching on that constructor.

This is actually a perfectly usable equality type in CuTT, although the
elimination rule is a little complex and we won't look into it just yet.
However we prefer to represent equalities in a slightly more primitive way, as
it turns out to be a little more flexible.
This is the \emph{path} representation.

When represented as a path, an equality between two values of type \(A\)
actually behaves more like a function from \AgdaDatatype{I} to \(A\).
\AgdaDatatype{I} here is the type of the interval: it ranges from
\AgdaInductiveConstructor{i0} to \AgdaInductiveConstructor{i1}.
So, as a function then, when the path \(x\;\AgdaFunction{\(\equiv\)}\;y\) is
applied to \AgdaInductiveConstructor{i0}, it returns \(x\), and when it is
applied to \AgdaInductiveConstructor{i1}, it returns \(y\).

\begin{marginfigure}
  \begin{tikzpicture}
    \node [anchor=base] at (-1.5 , 2.7) {$p :$};
    \node [anchor=base] at (-1   , 2.7) {$x$};
    \node [anchor=base] at ( 0   , 2.7) {\AgdaFunction{\(\equiv\)}};
    \node [anchor=base] at ( 1   , 2.7) {$y$};
    \node [anchor=base] at (-1.15, 2.1) {\footnotesize$p\;\AgdaFunction{i0} = x$};
    \node [anchor=base] at ( 0.85, 2.1) {\footnotesize$p\;\AgdaFunction{i1} = y$};
    \draw (-1,2.5) -- (1,2.5);
    \filldraw[black] (-1,2.5) circle (2pt);
    \filldraw[black] ( 1,2.5) circle (2pt);

    \node [anchor=base] at (-1.8, 0.2) {$\AgdaFunction{sym}\;p :$};
    \node [anchor=base] at (-1  , 0.2) {$y$};
    \node [anchor=base] at ( 0  , 0.2) {\AgdaFunction{\(\equiv\)}};
    \node [anchor=base] at ( 1  , 0.2) {$x$};
    \node [anchor=base] at (-1.4,-0.8) {\linespread{0}\footnotesize
      $\begin{aligned}
        \AgdaFunction{sym}\;p\;\AgdaFunction{i0} &= \\
        p\;(\AgdaOperator{\AgdaPrimitive{\textasciitilde{}}}\;\AgdaFunction{i0}) &= \\
        p\;\AgdaFunction{i1} &= y
      \end{aligned}$
    };
    \node [anchor=base] at ( 0.6,-0.8) {\linespread{0}\footnotesize
      $\begin{aligned}
        \AgdaFunction{sym}\;p\;\AgdaFunction{i1} &= \\
        p\;(\AgdaOperator{\AgdaPrimitive{\textasciitilde{}}}\;\AgdaFunction{i1}) &= \\
        p\;\AgdaFunction{i0} &= x
      \end{aligned}$
    };
    \draw (-1  ,0) -- ( 1,0);
    \filldraw[black] (-1,0) circle (2pt);
    \filldraw[black] (1,0) circle (2pt);

    \draw[-stealth] ( 1,2) to[out=-90, in=90] (-1,0.5);
    \draw[-stealth] (-1,2) to[out=-90, in=90] ( 1,0.5);
  \end{tikzpicture}
  \caption{Diagram of \(\AgdaFunction{sym}\;p\)}
  \label{sym-diagram}
\end{marginfigure}

Already we can manipulate paths in some interesting ways.
First, we can manipulate values in the interval: we can take the inverse of a
point in the interval, for instance.
It's worth thinking about what this ``inverse'' corresponds to in the equality:
we will name it in the next listing.
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Equality.tex]{sym-def}
\end{agdalisting*}
We will see some more intricate ways to manipulate paths later on, but for now
the ``function from an interval'' intuition is enough to understand the basics.

\subsection{Some Proofs of Equality}
So now that we know something about the equality type, let's put it to some use.
We can construct equality proofs of things which are ``obviously equal'' with
the following function:
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Snippets/Equality.tex]{refl-def}
\end{agdalisting}
With this we can prove that the output from Equation.~\ref{example-static-eval}
is 8:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Expr.tex]{example-static-proof}
\end{agdalisting*}

Of course, these proofs aren't very interesting.
Something a little more complex might be the following:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Data/Nat/Properties.tex]{plus-assoc}
\end{agdalisting*}
Unfortunately we can't look at much more complex proofs without building up some
more machinery around path types: we can't currently compose paths, for
instance.
\subsection{Quotients}
We've seen that data types can be defined by listing their constructors, where
each constructor is just a function whose return type is the type being defined.
However, we've also seen that equalities are just functions from the interval.
If we combine these two notions, we can actually define a \emph{higher
  inductive} type.
\begin{definition}[Higher Inductive Type]
  A normal inductive type (like \AgdaDatatype{Bool}, or \Nat) is a type
  where its \emph{point} constructors are listed.
  A higher inductive type can have point constructors, but it can also have
  \emph{path} constructors: instead of adding new values to the type, these
  constructors add new equalities to the type.
\end{definition}

One of the nice aspects of CuTT is that higher inductive types arise naturally
from the ``function from an interval'' interpretation of path types.
Expand out the definition of \AgdaFunction{\(\equiv\)} in the following type,
for instance:
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Snippets/Circle.tex]{circle-def}
\end{agdalisting}
We see that the \AgdaInductiveConstructor{loop} constructor, though odd looking,
still does represent a function whose return value is
\AgdaDatatype{\(\text{S}^1\)}.

Just with regards to this \AgdaDatatype{\(\text{S}^1\)} type: it's actually the
HoTT representation of the \emph{circle}.
We won't examine its more interesting properties all that much: however it is a
good example of the simplest type with complex homotopy, so we will use it to
demonstrate several HoTT principles.
\subsection{Basic Type Formers}
So far a lot of our descriptions of Agda have mixed Agda's type theory with its
syntax.
If this were a paper presenting the core type theory of Agda to an audience of
type theorists we probably would describe things in a slightly different way,
which has a lot less fancy syntax: we would instead present the core \emph{type
  formers} in Agda, and describe their semantics.
These type formers are basic types from which all other types can be built
(although it's usually much more ergonomic to use the syntax that we have been
using up until now: working with these type formers exclusively can feel a
little low-level at times).

We're going to explore them a little here: as the kind of basic subatomic
particles that make up every other type, they reveal a lot about the way types
work in general in Agda.
Also they can be useful in their own right: we've actually used all but one of
these types already.

The types \agdabot, \agdatop, and \AgdaDatatype{Bool} are three of the basic
type formers in MLTT.
Often they're called 0, 1, and 2; they're named for the number of elements which
inhabit them.

The next basic type is usually called \(\Pi\): it's the type of \emph{dependent
  functions}.
We've seen this type already, but here we should define it in a little more
depth.
\begin{definition}[Dependent Functions]
  A dependent function is one where the return type \emph{depends} on the value
  of the input.
  Here's a silly example:
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Snippets/Formers.tex]{nat-or-string}
  \end{agdalisting*}
  When supplied with \AgdaInductiveConstructor{true}, the return type of this
  function is \Nat; when given \AgdaInductiveConstructor{false}, the
  return type is \AgdaDatatype{String}.
\end{definition}

Dependent functions are a built-in type in Agda, and they get the built-in
syntax that looks like the following:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{pi-syntax-2}
\end{agdalisting*}
If the \(A\) can be inferred, we could alternatively use the following syntax:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{pi-syntax-3}
\end{agdalisting*}
Finally, if we wanted to avoid syntactic sugar altogether, we can use the
\(\Pi\) symbol:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{pi-syntax-1}
\end{agdalisting*}
All three of these expressions denote the same type.

As the symbol suggests, \AgdaFunction{\(\Pi\)} types are \emph{product} types.
This might seem strange at first: a product type is usually a tuple,
i.e. the pair type we saw in \Cref{pair-def}.
As it happens, given the basic type formers we've defined so far, we can
actually make the pair type:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Formers.tex]{pair-def}
\end{agdalisting*}
This type has all the functions we might need on a standard pair:
\begin{multicols}{3}
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Snippets/Formers.tex]{fst-def}
  \end{agdalisting*} \columnbreak
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Snippets/Formers.tex]{snd-def}
  \end{agdalisting*} \columnbreak
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Snippets/Formers.tex]{mk-pair}
  \end{agdalisting*}
\end{multicols}

Now that we have the type of dependent products, it's natural to ask if we have
a type for dependent sums.
This is a type we \emph{haven't} seen before, although we have all the pieces
needed to define it.
\begin{definition}[The Dependent Sum]
  Dependent sums are denoted with the usual \(\Sigma\) symbol, and has the
  following definition in Agda:
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{sigma}
  \end{agdalisting*}
  The dependent sum is like the constructive version of the existential
  quantifier: the expression \(\AgdaDatatype{\(\Sigma\)}\;A\;B\) can be
  interpreted as ``there exists an \(A\) such that \(B\)''.
\end{definition}

There are a number of different syntactic ways to express
\(\AgdaDatatype{\(\Sigma\)}\;A\;B\).
The following are all equivalent:
\begin{multicols}{4}
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{sigma-syntax-1}
  \end{agdalisting*} \columnbreak
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{sigma-syntax-3}
  \end{agdalisting*} \columnbreak
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{sigma-syntax-4}
  \end{agdalisting*} \columnbreak
  \begin{agdalisting*}
    \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{sigma-syntax-2}
  \end{agdalisting*}
\end{multicols} \vspace{-1\baselineskip}

Though we have shown that the dependent function type is suitable as a pair
type, \AgdaDatatype{\(\Sigma\)} is actually a little easier to use as our basic
pair type.
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Snippets/Formers.tex]{pair-sigma}
\end{agdalisting}
So how, then, is \AgdaDatatype{\(\Sigma\)} a sum type?
Sum types in non-dependent type theory are the disjoint unions:
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{disj-union}
\end{agdalisting}
It turns out that we can actually use a quite similar trick to how we got the
pair from \AgdaDatatype{\(\Pi\)}:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Introduction.tex]{sigma-disj-union}
\end{agdalisting*}
\subsection{The Menagerie of Foundational Theories}
So far we have mentioned four different foundational theories: Martin-Löf Type
Theory, Homotopy Type Theory, Cubical Type Theory, and Zermelo-Fraenkel set theory.
We have given some hints as to the differences between these theories, but now
We have enough background information to give a fuller explanation as to their
difference and historical context.

Firstly we have Zermelo-Fraenkel set theory, or ZFC, where the C stands for
``choice'', i.e. the axiom of choice.
This is the standard foundational system for most mathematics these days: it's a
set theoretic foundation, and it's \emph{classical}, by which we mean
non-constructive.
This means that it has the law of the excluded middle (for any given
proposition, the proposition is either true or false), and the axiom of choice
(the product of a collection of non-empty sets is non-empty).

We won't describe ZFC in much detail here, we only mention it to contrast it
with type theory.
Type theory is less extensional than set theory: in set theory we construct sets
by saying which things they contain.
These things exist ambiently, independent of the set (or sets) which contain
them.
To define the set of the natural numbers, for example, we first need there to
exist objects which represent each of the numbers.
Before defining \(\mathbb{N}\), we need to have defined 1 and 2.

Type theory is quite different in this sense.
The analogous construct to the set (the type) constructs its contents in its
definition.
So the type of the natural numbers contains the definition (or construction) of
its contents.
It doesn't make sense to define a type which contains items in other types: in
fact it's not possible.

So that is the difference in mechanics between type theory and set theory: other
than the non-constructive components of set theory, though, the two theories are
equivalent.

Within type theory then we have three different systems: MLTT, HoTT, and CuTT
(of course there are many more type theories than just these three: these are
only the theories we will study here).
The first of these was one of the first type theories to be defined: Per
Martin-Löf's intuitionistic type theory
\citep{martin-lofIntuitionisticTypeTheory1980} defined the basics of dependent
types as we use them in Agda today.
This early theory had the \(\Sigma\) and \(\Pi\) types we have above, as
well as the boolean types, and \(\top\) and \(\bot\).
With some changes to the system (the addition of universe levels prompted by
Girard's paradox), it's basically the core of Agda today.

HoTT \citep{hottbook} is a type theory which stems in many ways from MLTT, but
mixes it with homotopy theory.
The fundamental addition of HoTT is the univalence axiom, which allows for
isomorphic types to be treated as equivalent.
CuTT \citep{cohenCubicalTypeTheory2016} is closely related to HoTT: it is the
theory which allows us to use univalence in Agda while retaining the
computational properties that we would expect in a constructive system.
\subsection{Comparing Classical And Constructive Proofs in Agda}
The dependent sum is a great example of the difference between ``classical'' and
``constructive'' mathematics: the closest analogue in classical mathematics to
\AgdaDatatype{\(\Sigma\)} is \(\exists\), but the semantics of the two
constructs are subtly different.
If I say ``there exists an integer larger than 10'' I'm making a rather
trivially true statement; to provide a proof that
\(\AgdaDatatype{\(\Sigma\)}\;\Nat\;\lambda\;\AgdaBound{n}\rightarrow
\AgdaNumber{10}\;\AgdaFunction{<}\;\AgdaBound{n}\) is more akin to providing a
natural number, and proving that it's bigger than 10.

More formally speaking, there are a number of axioms which we don't have access
to constructively.
One such axiom is double negation elimination:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Classical.tex]{doubleneg-elim}
\end{agdalisting*}
One way to ``do'' classical mathematics within Agda, then, would be to write all
of the proofs assuming these axioms.
We don't have to break the guarantees Agda provides, either: we could say
``given the axiom of choice, law of the excluded middle, etc., the following is
true\textellipsis'', although this is a little clunky.

Instead, using this axiom of double negation, we can actually provide a type for
classical computation.
\begin{agdalisting}
  \ExecuteMetaDataInline[agda/Snippets/Classical.tex]{classical-def}
\end{agdalisting}
In the ``propositions-as-types'' sense, a value of type
\(\AgdaFunction{Classical}\;A\) is a classical proof of the proposition \(A\).
This translation between classical and constructive proofs using double negation
is sometimes called the double-negation translation.

We can prove, inside this type, things like the law of the excluded middle:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Classical.tex]{lem-proof}
\end{agdalisting*}
This type forms a monad, meaning that it implements the following functions:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Classical.tex]{monad}
\end{agdalisting*}
This gives us a convenient syntax to work with classical proofs.

Finally, in HoTT we have a notion of \emph{stability}.
Certain types do support double-negation elimination:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Relation/Nullary/Stable.tex]{stable-def}
\end{agdalisting*}
We will see a use for this notion later on, but we mention it here to point out
that we do have a way of describing types which can be pulled out of classical
proofs.

The purpose of this last subsection was to demonstrate that constructive
mathematics, far from being constrained in comparison to classical, are
technically \emph{more} capable.
We can actually use systems to Agda to check and verify classical proofs just as
much as we can constructive.
\subsection{Computational Behaviour}
Up until this point we have been suspiciously quiet on the issue of performance
or efficiency.
While everything we're doing is absolutely valid as a purely theoretical
exercise, it is nonetheless interesting to ask what these proofs and programs
perform like on a computer.

The first thing to note is that Agda is a \emph{lazy} language.
This means that expressions are not evaluated until they're needed.
Take the following function:
\begin{agdalisting*}
  \ExecuteMetaDataInline[agda/Snippets/Complexity.tex]{f-def}
\end{agdalisting*}
Since this function ignores its argument, Agda won't \emph{compute} its
argument.
If we called, for instance,
\(\AgdaFunction{f}\;(\AgdaNumber{1000}\;\AgdaFunction{+}\;\AgdaNumber{1000})\),
we wouldn't ever have to pay the cost of computing
\(\AgdaNumber{1000}\;\AgdaFunction{+}\;\AgdaNumber{1000}\).

It's important to note that this difference in performance is usually \emph{not}
observable in actual computation.
Unless we are working with coinductive types (which we will not do in this
thesis), Agda's semantics are agnostic as to evaluation strategy.
A program that terminates with lazy evaluation will also terminate with strict.
It's just that one might take a much longer (but still finite!) amount of time
to do so.

The second thing to note is that, in order to make proofs easier, we often work
with inefficient forms of certain data types.
The natural numbers, for instance, we represent as basically a singly-linked
list; there are no flat arrays to be found anywhere in Agda; and recursion
(albeit tail-call optimised recursion) is the tool of choice for iterative
computation.
There is some help: in certain cases Agda will optimise the natural numbers to
actual binary numbers (arbitrary precision Haskell integers), and Agda's purity
allows for a certain degree of optimisation.
Overall, though, unfortunately Agda is quite slow.
Computing an expression like \(\AgdaBound{n}\;\AgdaFunction{+}\;\AgdaBound{m}\)
will usually take \(\mathcal{O}(\AgdaBound{n})\) time, and there's not really a
great way to get around it.

%%% Local Variables:
%%% mode: latex
%%% TeX-master: "../paper"
%%% End:


\documentclass[11pt,paper=a4]{report}

\usepackage[a4paper,landscape]{geometry}

%Chapter caption is somewhere in the center of the page, so move the shit ;)
%\renewcommand*\chapterheadstartvskip{\vspace*{-1cm}}

%If you have a new chapter, the pagestyle will be plain (only pagenumber) according to koma
%To use ur setting redefine the chaperstyle
%\renewcommand*{\chapterpagestyle}{scrheadings}

%Settings for head and foot

%\usepackage[myheadings]{fullpage}
%\pagestyle{myheadings}

\usepackage{fancyhdr}
%\fancyhead{}
%\fancyhead[CO,CE]{---Draft---}
\pagestyle{fancy}
\rhead{}

%\usepackage{scrpage2}
%\clearscrheadfoot
%\pagestyle{scrheadings}

%\ihead{top left}
%\chead{top center}
%\ohead{top right}

%\ifoot{bottom left}
%\cfoot{bottom center}
%\ofoot{bottom right}

\usepackage{amsmath}
\usepackage{color}
\usepackage{graphicx}
\usepackage{cancel}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{chngcntr}
\usepackage{natbib}

\usepackage{hyperref}
\hypersetup{
        colorlinks = true,
        linkcolor = blue,
        anchorcolor = red,
        citecolor = blue,
        filecolor = red,
        urlcolor = red
}

\newcommand{\Msun}{\mbox{M$_\odot$\,}}         % M_sun

\newcommand{\eht}{\overline}
\newcommand{\fht}{\widetilde}
\newcommand{\dr}{\frac{\partial}{\partial r}}
\newcommand{\dt}{\frac{\partial}{\partial t}}
\newcommand{\dth}{\frac{\partial}{\partial \theta}}
\newcommand{\dph}{\frac{\partial}{\partial \phi}}

\newcommand{\fav}{\widetilde}
\newcommand{\av}{\overline}

\def\ef#1{#1'}
\def\ff#1{#1''}
\def\fhtc#1{\left\{#1\right\}}
\def\erho{\eht{\rho}}

\newcommand{\dgr}{\mbox{$^\circ$}}           % degrees

\counterwithout{section}{chapter}

\usepackage{titling}
\newcommand{\subtitle}[1]{%
  \posttitle{%
    \par\end{center}
    \begin{center}\large#1\end{center}
    \vskip0.5em}%
}

\title{{\bf ransX framework}}
\subtitle{Implementation Guide}
\author{
        Miroslav Moc\'ak, Casey Meakin, Simon Campbell, Cyril Georgy, Maxime Viallet, Dave Arnett
}

\date{\today}

\begin{document}

\bibliographystyle{plainnat}
%\begin{landscape}
\maketitle

\tableofcontents

\newpage

\section{Introduction}

This implementation guide describes all parts of our analysis framework for multi-fluid compressible hydrodynamic simulation targeted at all of you, who wants to implement it to your hydrodynamic codes and use our post-processing software to display its results.\\

ransX or rans(eXtreme) framework is a theoretical and programmatic suite allowing for comprehensive analysis of statistical averages of all sort of hydrodynamic properties from 3D simulations in spherical and Cartesian geometry. It consists of three main parts:

\begin{itemize}
\item theoretical derivation of 1D Reynolds-averaged Navier-Stokes (RANS) mean-field equations for transport/flux/variance of mass, momenta, kinetic/internal/total energy, temperature, enthalpy, pressure and chemical composition (see ransXtheoryGuide.pdf for more details)
\item calculation of required mean-fields for construction of terms in the RANS equations at runtime of hydrodynamic simulations
\item construction of terms in the RANS equations and their plotting
\end{itemize}

\par We obtain our 1D RANS equations by introducing two types of averaging:  statistical averaging and  horizontal averaging \citep{Besnard1992,VialletMeakin2013}. In practice, statistical averages are computed by performing a time average. Therefore, the combined average of a quantity $q$ is defined for spherical geometry as

\begin{align}\label{eq:eht}
\eht{q}(r,t) = \frac{1}{T\Delta\Omega}\int_{t- T/2}^{t+T/2} q(r,\theta,\phi,t')~d\Omega~dt'
\end{align}

\noindent where $d \Omega = \sin \theta d \theta d \phi$ is the solid angle in spherical coordinates, $T$ is the averaging time period, and $\Delta\Omega$ is total solid angle being averaged over. The quantity $q$ is defined for cartesian geometry as

\begin{align}\label{eq:eht}
\eht{q}(x,t) = \frac{1}{T \Delta y \Delta z}\int_{t- T/2}^{t+T/2} q(x,y,z,t')~dy~dz~dt'
\end{align}

\noindent where $\Delta y$ and $\Delta z$ is total number of grid zones in $y$ and $z$ direction.\\

\par The flow variables are then decomposed into mean and fluctuation $q = \eht{q} + q'$, noting that $\eht{q'} = 0$ by construction. Similarly, we introduce Favre (or density weighted) averaged quantities by

\begin{align}
\fht{q} = \frac{\eht{\rho q}}{\eht{\rho}}
\end{align}

\noindent which defines a complimentary decomposition of the flow into mean and fluctuations according to $q = \fht{q} + \ff{q}$. Here, $\ff{q}$ is the Favrian fluctuation and its mean is zero when Favre averaged $\fht{\ff{q}} = 0$. For a more complete elaboration on the algebra of these averaging procedures we refer the reader to \citet{Chassaing2010}

\section{Calculation of ransX mean fields}

We perform the calculation of required mean-fields at runtime of hydrodynamic simulations and exploit various identities between terms in our RANS equations and space-time averaged thermodynamic quantities or their products. For example, mass flux $\eht{\rho'u'_r} = \eht{\rho u_r} - \eht{\rho} \ \eht{u_r} $, so in order to calculate the mass flux, we need $\eht{\rho u_r}$, $\eht{\rho}$, $\eht{u_r}$. The following subsections describe this methodology implemented to the multi-fluid compressible hydrodynamic code PROMPI of \citep{MeakinArnett2007} and post-processing tool tailored for its output written in Python \href{https://github.com/mmicromegas/ransX}{https://github.com/mmicromegas/ransX}. This github repository contains also PROMPI's subroutines that deal with RANS averaging and storage located in directory UTILS/FOR\_YOUR\_HYDRO. {\bf Feel free to use them in your hydrodynamic codes as well. We hope it speeds up integration of our ransX framework to your research projects.} The directory contains also README file, that will provide you with more details about how and where we use the subroutines in PROMPI.

\subsection{Initialization and calculation in hydrodynamic code PROMPI}

Our main array for storage of space-time averages between two consecutives data dumps is called $havg$. It is a three dimensional array declared as $havg(4,nrans,qqx)$. First index referes to identification position of horizontal averages of three-dimensional thermodynamic quantities required either at initialization or update stage of hydrodynamic simulation. The seconds index is the number of RANS mean-fields we calculate. The third index is number of grid points in radial or $x$ direction (depending on geometry).

The main subroutine, where we calculate $havg$ is called {\bf rans\_avg.f90}. It requires an input of one parameter called $imode$, which tells it where in hydrodynamic simulation it is being called and whether it should be initializing $havg$ or updating it (Fig.\ref{havg:init}). If in initialization mode ($imode.eq.0$), it initializes also an array called $ransname$ (Fig.\ref{havg:calc}), which holds names of horizontally-averaged variables. The $havg$ data is stored in a binary file with extension ransdat, whether variables like $ransname$ to a text file with extension ranshead together with other variables like resolution and dump times.

\begin{figure}[!h]
\centerline{
\includegraphics{initialize_havg.png}}
\caption{Initialization of $havg$ array in {\bf rans\_avg.f90}}
\label{havg:init}
\end{figure}

After the initialization, horizontal averages are being computed as show in the example in Fig.\ref{havg:calc} according to Equation \ref{eq:horizontal}  and stored in the $havg$ array where the identification position index is set to 2 i.e. $havg(2,ifield,i)$. The scaling factor in case of spherical geometry $\sin \theta d \theta d \phi / \Delta \Omega$ is the variable $fsteradjk$. In case of cartesian geometry, this factor will be equal to one.

\begin{align}
\label{eq:horizontal}
\langle q \rangle (r,t) = \frac{1}{\Delta \Omega} \int \int q(r,\theta,\phi,t)~\sin \theta d \theta d \phi
\end{align}

\begin{figure}[!h]
\centerline{
\includegraphics{rans_avg_snippet.png}}
\caption{Demonstration loop of horizontal averaging (Eq.\ref{eq:horizontal}), where $\langle q \rangle$(r,t) is $havg(2,ifield,i)$ taking geometry into account with scaling variable $fsteradjk$}
\label{havg:calc}
\end{figure}

After calculation of these horizontal averages, they are turned into a variable that we call running averages defined in Equation \ref{eq:runaverage} and stored in $havg$ array with identification position index set to 3 i.e. $havg(3,ifield,i)$ (Fig.\ref{fig:runaverage}). These running averages are horizontal averages, that are additionally averaged further taking into account previous hydro sweep stored in $havg$ with identification position index set to 1 and updated as shown in Fig.\ref{havg:init}.
%\begin{figure}[!h]
%\centerline{
%\includegraphics{prompi_havg_detail.png}}
%\caption{Calculation of running average }
%\end{figure}

\begin{align}
  q_{\mbox{run}} = \sum_i \left(\langle q^n \rangle_i + \langle q^n \rangle_{i-1} \right) \ 0.5 \ \Delta t_i
\label{eq:runaverage}
\end{align}

\begin{figure}[!h]
\centerline{
\includegraphics{update_running_average.png}}
\caption{Calculation of running averages (Eq.\ref{eq:runaverage}), where $q_{\mbox{run}}$ is $havg(3,n,i)$.}
\label{fig:runaverage}
\end{figure}

The running averages are later used in a subroutine {\bf write\_rans\_data.f90} to calculate statistical average according to Equation \ref{eq:stataverage} at the time of data dump as show in the Figure \ref{fig:stataverage}.

\begin{align}
  \overline{q} =  \frac{q_{\mbox{run}}}{\sum_i \Delta t_i}
\label{eq:stataverage}
\end{align}

\begin{figure}[!h]
\centerline{
\includegraphics{prompi_havg.png}}
\caption{Calculation of statistical average (Eq.\ref{eq:stataverage}), where $\overline{q}$ is $havg\_sum\_tot\_global(3,k,i)$. $rans\_tavg$ calculation is shown in Figure \ref{fig:runaverage}.}
\label{fig:stataverage}
\end{figure}

\subsection{Post-processing in Python}

The statistical averages calculated according to Eq.\ref{eq:stataverage} are only between two consecutives data dumps, that typically cover time much shorter than a convective turnover timescale (TO). In order to get robust statistical averages, we need to calculate the averages over at least three TOs. For that we use python script called $rans\_tseries.py$, that is using calculated $q$s stored in ransdat files according to Equation \ref{eq:tseries} shown in Figure \ref{fig:tseries}.

The script takes advantage of ranshead files, that contain names of the RANS mean fields in exact order as they are stored in $havg$ array and stores the final mean fields in a dictionary variable called $eht$. The dictionary is at the end stored in python's $npy$ file, that can be easily read by RANS equations classes, which calculate and plot terms of ransX framework equations.

\begin{align}
  \overline{Q} = \frac{\overline{q} \ \Delta t_{\mbox{dumps}}}{\sum_{\mbox{dumps}} \Delta t_{\mbox{dumps}}}
\label{eq:tseries}
\end{align}

\begin{figure}[!h]
\centerline{
\includegraphics{tseries_averaging.png}}
\caption{Statistical averages as calculated by {\bf ransx\_tseries.py} and Eq.\ref{eq:tseries} over time interval between $timec[i]-tavg/2$ and $timec[i]+tavg/2$. The $timec[i]$ is central time around which we can calculate statistical average over time specified by $tavg$. The $eht$ is $\overline{Q}$, the $q$ is loaded into a list called $eh$, the time between consecutives dumps is $dt$, the total time over which we need the statistical average is $sumdt$.}
\label{fig:tseries}
\end{figure}

\section{Implementation of ransX equations}

Mean-fields RANS equations are in our framework implemented using python classes each dedicated to one equation. All the classes are stored in directory EQUATIONS. Every class has almost the same structure inheriting some methods from classes CALCULUS.py and ALIMIT.py and consisting of a constructor method $\_init\_$, where we initialize whole class with data read from the $npy$ file and use them to construct all terms in RANS equations using various identities as shown in Section \ref{sect:usefulidentities} at the end of this document. The second method plots mean-field thermodynamic quantity for which we want to see RANS equation implemented in the class. Terms in these equations are then shown by third method \footnote{Warning: Labels of plot lines are not adjusted for simulation in Cartesian geometry yet.}. Sometimes, such a class contains fourth method, that calculates integral budget for each of the mean-field of the equations according to volume integral Equation \ref{eq:integralbudget}

\begin{align}
  I_{\mbox{budget}} = \int_r 4 \pi r^2 \ \overline{Q}_{\mbox{RANS}} / dr
\label{eq:integralbudget}
\end{align}

Next subsections contain description of some EQUATIONs classes and implementation/calculation of RANS equations terms for hydrodynamic simulation in spherical geometry.  The folder EQUATIONS contain also classes for plotting of some background quantities like temperature gradient, degeneracy or Brunt-Vaisalla frequency, but we skip those for now.

\subsection{Continuity Equation with Mass FLux}

Following lines describe exact mapping between actual physical mean-fields and their counterparts in the ContinuityEquationWithMassFlux.py. A snippet of the code is shown in Figure \ref{fig:cont_mass_flux}.

\begin{align}
  \fht{D}_t \eht{\rho} = & - \nabla_r f_\rho + (f_\rho / \eht{\rho})\partial_r \eht{\rho} - \eht{\rho}\eht{d} \\
  \partial_t \eht{\rho} + \fht{u}_r \partial_r \eht{\rho} = & -\nabla_r \eht{\rho'u'_r} + ( \eht{\rho'u'_r}/\eht{\rho})\partial_r \eht{\rho} - \eht{\rho} \nabla_r \eht{u}_r) \nonumber \\
  \partial_t t\_dd + ddux/dd \partial_r dd = & -\nabla_r (ddux - dd*ux) + ((ddux-dd*ux)/dd) \partial_r dd - dd \nabla_r ux) \nonumber  \\
  \partial_t t\_dd + fht\_ux \ \partial_r dd = & -\nabla_r fdd + (fdd/dd) \ \partial_r dd - dd \nabla_r ux) \nonumber
\end{align}

\begin{figure}[!h]
\centerline{
\includegraphics{ransx_continuity_with_mass_flux.png}}
\caption{Continuity equation with mass flux $f_\rho$ as programmed into ContinuityEquationWithMassFlux.py}
\label{fig:cont_mass_flux}
\end{figure}

\subsection{Continuity Equation with Favrian Dilatation}

Following lines describe exact mapping between actual physical mean-fields and their counterparts in the ContinuityEquationWithFavrianDilatation.py. A snippet of the code is shown in Figure \ref{fig:cont_dil}.

\begin{table}[!h]
\label{tab:rans-xtrans}
\begin{align}
% continuity equation
  \fht{D}_t \eht{\rho} = & -\eht{\rho}\fht{d} \\
  \partial_t \eht{\rho} + \fht{u}_r \partial_r \eht{\rho} = & -\eht{\rho}\fht{d} \nonumber \\
  \partial_t t\_dd + ddux/dd \ \partial_r dd = & -dd * \nabla_r \ ddux/dd \nonumber \\
  \partial_t t\_dd + fht\_ux \ \partial_r dd = & -dd * \nabla_r \ fht\_ux \nonumber
\end{align}
\end{table}

\begin{figure}[!h]
\centerline{
\includegraphics{ransx_continuity_with_favrian_dilatation.png}}
\caption{Continuity equation with favrian dilatation $\fht{q}$ as programmed into ContinuityEquationWithFavrianDilatation.py}
\label{fig:cont_dil}
\end{figure}

%\subsection{Momentum Equation X}

%\subsection{Momentum Equation Y}

%\subsection{Momentum Equation Z}

%\subsection{Reynolds Stress XX}

%\subsection{Reynolds Stress YY}

%\subsection{Reynolds Stress ZZ}

%\subsection{Turbulent Kinetic Energy Equation}

%\subsection{Radial Turbulent Kinetic Energy Equation}

%\subsection{Horizontal Turbulent Kinetic Energy Equation}

%\subsection{Internal Energy Equation}

%\subsection{Internal Energy Flux Equation}

%\subsection{Internal Energy Variance Equation}

%\subsection{Kinetic Energy Equation}

%\subsection{Total Energy Equation}

%\subsection{Entropy Equation}

%\subsection{Entropy Flux Equation}

%\subsection{Entropy Variance Equation}

%\subsection{Pressure Equation}

%\subsection{Pressure Flux Equation}

%\subsection{Pressure Variance Equation}

%\subsection{Temperature Equation}

%\subsection{Temperature Flux Equation}

%\subsection{Temperature Variance Equation}

%\subsection{Enthalpy Equation}

%\subsection{Enthalpy Flux Equation}

%\subsection{Enthalpy Variance Equation}

%\subsection{Density Variance Equation}

%\subsection{Turbulent Mass Flux Equation}

%\subsection{Density-specific Volume Covariance Equation}

\subsection{Composition Transport Equation}
\label{sect:xtranseq}

XtransportEquation.py

\begin{align}
% composition transport
\erho\fav{D}_t \fav{X}_i = & -\nabla_r f_i + \erho \fav{\dot{X}}_i^{\rm nuc} \\
\erho\partial_t \fav{X}_i + \erho \fav{u}_r \partial_r \fav{X}_i = & -\nabla_r \erho \fav{X''_i u''_r} +  \erho \fav{\dot{X}}_i^{\rm nuc} \nonumber \\
\partial_t \erho \fav{X}_i + \partial_r \erho \fav{u}_r \fav{X}_i = & -\nabla_r \erho \fav{X''_i u''_r} +  \erho \fav{\dot{X}}_i^{\rm nuc} \nonumber \\
\partial_t \erho \fav{X}_i + \partial_r \erho \fav{u}_r \fav{X}_i = & -\nabla_r \erho (\fav{X_i u_r} - \fav{X_i}\fav{u_r}) +  \erho \fav{\dot{X}}_i^{\rm nuc} \nonumber \\
\partial_t \ \erho \ \eht{\rho X_i}/\eht{\rho} + \partial_r \ \erho \ \eht{\rho u_r}/\eht{\rho} \ \eht{\rho X_i}/\eht{\rho} = & -\nabla_r \left(\eht{\rho X_i u_r} - \eht{\rho X_i}\eht{\rho u_r}/\eht{\rho} \right) +  \eht{\rho \dot{X}_i^{\rm nuc}} \nonumber \\
\partial_t \left( t\_dd * t\_ddxi/t\_dd \right) + \partial_r \left( dd * ddux/dd * ddxi/dd \right) = & -\nabla_r \left(ddxiux - ddxi*ddux/dd  \right) + ddxidot \nonumber \\
\partial_t \left( t\_dd * t\_fht\_xi \right) + \partial_r \left( dd * fht\_ux * fht\_xi \right) = & -\nabla_r fxi + ddxidot \nonumber
\end{align}

%\subsection{Composition Flux Equation}
%\label{sect:xflxeq}

%\begin{align}
  % composition flux
%\erho \fav{D}_t (f_i / \eht{\rho}) = &  -\nabla_r f_i^r  - f_i \partial_r \fht{u}_r - \fht{R}_{rr} \partial_r \fht{X}_i -\eht{X''_i} \partial_r \eht{P} - \eht{X''_i \partial_r P'} + \overline{u''_r \rho \dot{X}_i^{\rm nuc}} + {\mathcal G_i} \\
%\eht{\rho} \partial_t \fht{X''_i u''_r} + \eht{\rho}\fht{u}_r \partial_r \fht{X''_i u''_r} = &  -\nabla_r \eht{\rho} \fht{X''_i u''_r u''_r} - \eht{\rho}\fht{X''_i u''_r}\partial_r \fht{u_r} - \eht{\rho}\fht{u''_r u''_r}\partial_r \fht{X}_i - \eht{X''_i} \partial_r \eht{P} - \eht{X''_i \partial_r P'} + \eht{u''_r \rho \dot{X}_i^{\rm nuc}} + \eht{G_r^i} - \eht{X''_i G_r^M} \nonumber \\
%\eht{\rho} \partial_t \fht{X''_i u''_r} + \eht{\rho}\fht{u}_r \partial_r \fht{X''_i u''_r} = &  -\nabla_r \eht{\rho} \fht{X''_i u''_r u''_r} - \eht{\rho}\fht{X''_i u''_r}\partial_r \fht{u_r} - \eht{\rho}\fht{u''_r u''_r}\partial_r \fht{X}_i - \eht{X''_i} \partial_r \eht{P} - \eht{X''_i \partial_r P'} + \eht{u''_r \rho \dot{X}_i^{\rm nuc}} \nonumber \\
%& - \eht{\rho X''_i u''_\theta u''_\theta/r} - \eht{\rho X''_i u''_\phi u''_\phi/r} + \eht{\rho X''_i u_\theta u_\theta/r} + \eht{\rho X''_i u_\phi u_\phi/r} \nonumber \\
%\eht{\rho} \partial_t (\fht{X_i u_r} - \fht{X_i} \fht{u}_r) + \eht{\rho}\fht{u}_r \partial_r (\fht{X_i u_r} - \fht{X_i} \fht{u_r})  = &  -\nabla_r (\eht{\rho X_i u_r u_r} -\fht{X_i}\eht{\rho u_r u_r} - 2 \fht{u_r} \eht{\rho X_i u_r} + 2\eht{\rho}\fht{X_i}\fht{u_r}\fht{u_r}) \nonumber \\
%& - \eht{\rho}(\fht{X_i u_r} -\fht{X_i}\fht{u}_r)\partial_r \fht{u}_r - \eht{\rho}(\fht{u_r u_r} - \fht{u}_r \fht{u}_r)\partial_r \fht{X}_i \nonumber \\
%& - (\eht{X_i} \partial_r \eht{P} - \fht{X_i} \partial_r \eht{P}) - (\eht{X_i \partial_r P} - \eht{X_i}\partial_r \eht{P})  + (\eht{u_r \rho \dot{X}_i^{\rm nuc}} - \fht{u_r} \eht{\rho \dot{X}_i^{\rm nuc}}) \nonumber \\
%& - (\eht{\rho X_i u_\theta u_\theta} -\fht{X_i}\eht{\rho u_\theta u_\theta} - 2 \fht{u}_\theta \eht{\rho X_i u_\theta} + 2\eht{\rho}\fht{X_i}\fht{u}_\theta\fht{u}_\theta)/r \nonumber \\
%& - (\eht{\rho X_i u_\phi u_\phi} -\fht{X_i}\eht{\rho u_\phi u_\phi} - 2 \fht{u}_\phi \eht{\rho X_i u_\phi} + 2\eht{\rho}\fht{X_\phi}\fht{u}_\phi\fht{u}_\phi)/r \nonumber \\
%& + (\eht{\rho X_i u_\theta u_\theta} - \fht{X_i} \eht{\rho u_\theta u_\theta})/r \nonumber \\
%& + (\eht{\rho X_i u_\phi u_\phi} - \fht{X_i} \eht{\rho u_\phi u_\phi})/r \nonumber
%\end{align}

%\begin{align}
%dd \ \partial_t (ddxiux/dd - ddxi*ddux/dd*dd) + ddux \ \partial_r (ddxiux/dd - ddxi*ddux/dd*dd) = \nonumber \\
%- \nabla_r (ddxiuxux - ddxi/dd*dduxux - 2*ddux/dd*ddxiux +2*ddxi*ddux*ddux/dd*dd) \nonumber \\
%- (ddxiux - ddxi*ddux/dd) * \partial_r ddux/dd - (dduxux - ddux*ddux/dd) * \partial_r ddxi/dd \nonumber \\
%- (xi \ \partial_r \ pp - ddxi/dd \ \partial_r \ pp) - (xigradxpp - xi \ \partial_r \ pp) + (ddxidotux - ddux/dd * ddxidot) \nonumber \\
%- (ddxiuyuy - ddxi/dd*dduyuy - 2*dduy/dd*ddxiuy + 2*ddxi*dduy*dduy/dd*dd)/r \nonumber \\
%- (ddxiuzuz - ddxi/dd*dduzuz - 2*dduz/dd*ddxiuz + 2*ddxi*dduz*dduz/dd*dd)/r \nonumber \\
%+ (ddxiuyuy - ddxi/dd*dduyuy)/r \nonumber \\
%+ (ddxiuzuz - ddxi/dd*dduzuz)/r \nonumber
%\end{align}

%\subsection{Composition Variance Equation}
%\label{sect:xvareq}

%\begin{table}[!h]
%\label{tab:rans-xvar}

%\begin{align}
% composition sigma
%\eht{\rho} \fht{D}_t \sigma_i = & -\nabla_r f_i^r - 2 f_i \partial_r \fht{X}_i + 2 \eht{X''_i \rho \dot{X}_i^{\rm nuc}} \\
%\eht{\rho} \fht{D}_t \fht{X''_i X''_i} = & -\nabla_r (\eht{\rho X''_i X''_i u''_r} ) - 2 \eht{\rho}\fht{X''_i u''_r} \partial_r \fht{X}_i + 2 \eht{X''_i \rho \dot{X}_i^{\rm nuc}} \nonumber \\
%\eht{\rho} \partial_t (\fht{X_i X_i} - \fht{X_i}\fht{X_i}) + \eht{\rho}\fht{u}_r \partial_r (\fht{X_i X_i} - \fht{X_i}\fht{X_i}) = &  -\nabla_r (\eht{\rho X_i X_i u_r} - 2 \fht{X_i} \eht{\rho X_i u_r} - \fht{u}_r \eht{\rho X_i X_i} + 2 \fht{X}_i \fht{X}_i \eht{\rho u_r} ) \nonumber \\
%& - 2 \eht{\rho} (\fht{X_i u_r} - \fht{X}_i \fht{u}_r) \partial_r \fht{X}_i + (\eht{X_i \rho \dot{X}_i} - \fht{X}_i \eht{\rho \dot{X}_i}) \nonumber \\
%dd \ \partial_t \ (ddxisq/dd - ddxi*ddxi/dd*dd) & \nonumber \\
%+ \ ddux \ \partial_r \ (ddxisq/dd - ddxi*ddxi/dd*dd) = & -\nabla_r (ddxisqux - 2*ddxi/dd*ddxiux - ddux/dd*ddxisq + 2*ddxi*ddxi*ddux/dd*dd) \nonumber \\
%& - \ 2*dd \ (ddxiux/dd - ddxi*ddux/dd*dd) * \partial_r \ ddxi/dd \nonumber \\
%& + 2 * (ddxixidot - ddxi/dd * ddxidot) \nonumber
%\end{align}
%\end{table}

\subsection{Density-specific Volume Covariance}

DensitySpecificVolumeCovarianceEquation.py

\begin{align}
  \eht{D}_t b = &  +\eht{v} \nabla_r \eht{\rho} \eht{u''_r} -\eht{\rho}\nabla_r (\eht{u'_r v'}) + 2\eht{\rho}\eht{v'd'} \label{eq:rans_b}  \\
  \partial_t b + \eht{u}_r \partial_r b = & \ \eht{v} \nabla_r \eht{\rho}(\eht{u}_r - \fht{u}_r) - \eht{\rho} \nabla_r (\eht{u_r v} - \eht{u}_r \eht{v}) + 2 \eht{\rho} (\eht{vd} -\eht{v}\eht{d}) \nonumber \\
  \partial_t \eht{v'\rho'} + \eht{u}_r \partial_r (\eht{v'\rho'}) = & \ \eht{v} \nabla_r \eht{\rho}(\eht{u}_r - \fht{u}_r) - \eht{\rho} \nabla_r (\eht{u_r v} - \eht{u}_r \eht{v}) + 2 \eht{\rho} (\eht{vd} -\eht{v}\eht{d})  \nonumber \\
  \partial_t (\underbrace{\eht{v \rho}}_\text{1} - \eht{v} \ \eht{\rho}) + \eht{u}_r \partial_r (\underbrace{\eht{v \rho}}_\text{1} - \eht{v} \ \eht{\rho}) = & \ \eht{v} \nabla_r \eht{\rho}(\eht{u}_r - \fht{u}_r) - \eht{\rho} \nabla_r (\eht{u_r v} - \eht{u}_r \eht{v}) + 2 \eht{\rho} (\eht{vd} -\eht{v}\eht{d})   \nonumber \\
  -\partial_t (\eht{v} \ \eht{\rho}) - \eht{u}_r \partial_r (\eht{v} \ \eht{\rho}) = & \ \eht{v} \nabla_r \eht{\rho}(\eht{u}_r - \fht{u}_r) - \eht{\rho} \nabla_r (\eht{u_r v} - \eht{u}_r \eht{v}) + 2 \eht{\rho} (\eht{vd} -\eht{v}\eht{d})  \nonumber \\
  \partial_t (1-t\_sv*t\_dd) - ux \ \partial_r (1-sv*dd) = & \ sv * \nabla_r dd*(ux - ddux/dd) - dd \ \nabla_r (svux - sv*ux) + 2*dd*(svdivu - sv*divu)  \nonumber \\
  \partial_t \ t\_b - ux \ \partial_r \ b = & \ sv * \nabla_r \ dd*(ux - ddux/dd) - dd \ \nabla_r (svux - sv*ux) + 2*dd*(svdivu - sv*divu)  \nonumber \\
   \partial_t \ t\_b - ux \ \partial_r \ b = & \ sv * \nabla_r \ dd*(ux - fht\_ux) - dd \ \nabla_r (svux - sv*ux) + 2*dd*(svdivu - sv*divu)  \nonumber
\end{align}

%\subsection{Density Variance Equation}

%\begin{align}
% sigma density
%  \fht{D}_t \sigma_\rho =  &  - \nabla_r \eht{(\rho' \rho ' u''_r)}  - 2\eht{\rho} \ \eht{\rho'd''} - 2 \eht{\rho'u''_r} \partial_r \eht{\rho} - 2 \fht{d} \ \sigma_\rho - \eht{\rho'\rho'd''} \\
%  \partial_t \eht{\rho'\rho'} + \fht{u}_r \partial_r \eht{\rho'\rho'} =  &  - \nabla_r \eht{(\rho' \rho ' u''_r)}  - 2\eht{\rho} \ \eht{\rho'd''} - 2 \eht{\rho'u''_r} \partial_r \eht{\rho} - 2 \fht{d}\eht{\rho'\rho'}  - \eht{\rho'\rho'd''} \\
%  \partial_t (\eht{\rho\rho} - \eht{\rho} \ \eht{\rho}) + \fht{u}_r \partial_r (\eht{\rho\rho} - \eht{\rho} \ \eht{\rho}) = & -\nabla_r (\eht{\rho \rho u_r} - 2\eht{\rho u_r} \ \eht{\rho} + \eht{\rho} \eht{\rho} \ \eht{u_r} - \eht{\rho \rho}\fht{u}_r + \eht{\rho} \ \eht{\rho} \fht{d}) \\
%  & -2\eht{\rho}(\eht{\rho d} - \eht{\rho}\fht{d} - \eht{\rho} \ \eht{d} + \eht{\rho}\fht{d}) \\
%  & -2(\eht{\rho u_r} - \eht{\rho}\fht{u}_r - \eht{\rho} \ \eht{u}_r + \eht{\rho}\fht{u}_r)\partial_r \eht{\rho} \\
%  & -2 \fht{d} (\eht{\rho \rho} - \eht{\rho} \ \eht{\rho}) - (\eht{\rho \rho u_r} - 2\eht{\rho u_r} \ \eht{\rho}+ \eht{\rho} \ \eht{\rho} \eht{u}_r -\eht{\rho \rho}\fht{u}_r + \eht{\rho} \ \eht{\rho} \fht{d}) \\
%  \partial_t (ddsq - dd*dd) & \\
%  + ddux/dd \partial_r (ddsq - dd*dd) = & \nonumber \\
%  & - \nabla_r (ddddux - 2*ddux*dd + ddsq*ux - ddsq*ddux/dd + dd*dd*ddux/dd) \nonumber \\
%  & -2*dd*(-dd*divu + dddivu) -2*(-dd*ux + ddux) \partial_r dd \nonumber \\
%  & -2*dddivu/dd * (ddsq - dd*dd) \nonumber \\
%  & -(dddddivu - 2*dddivu*dd + ddsq*divu - ddsq*dddivu/dd + dd*dddivu) \nonumber
%\end{align}

%\subsection{Internal Energy Variance Equation}

%\begin{align}
% sigma internal energy
%  \eht{\rho} \fht{D}_t \sigma_{\epsilon I} = &  -\nabla_r (\eht{\rho \epsilon''_I \epsilon''_I u''_r} ) - 2 f_I \partial_r \fht{\epsilon_I} - 2\overline{\epsilon''_I}\ \eht{P} \ \fht{d} - 2\eht{P} \ \eht{\epsilon''_I d''} - 2\fht{d} \ \eht{\epsilon''_I P'} - 2\overline{\epsilon''_I P' d''} + 2\eht{\epsilon''_I {\mathcal S}} \\
%  \eht{\rho} \fht{D}_t \fht{\epsilon''_I \epsilon''_I} = &  -\nabla_r (\eht{\rho \epsilon''_I \epsilon''_I u''_r} ) - 2 \eht{\rho} \fht{\epsilon''_I u''_r} \partial_r \fht{\epsilon_I} - 2\overline{\epsilon''_I}\ \eht{P} \ \fht{d} - 2\eht{P} \ \eht{\epsilon''_I d''} - 2\fht{d} \ \eht{\epsilon''_I P'} - 2\overline{\epsilon''_I P' d''} + 2\eht{\epsilon''_I \rho \varepsilon_{nuc}} \\
%  \eht{\rho} \partial_t \fht{\epsilon''_I \epsilon''_I} + \eht{\rho} \fht{u_r} \nabla_r (\fht{\epsilon''_I \epsilon''_I})  = &  -\nabla_r (\eht{\rho \epsilon''_I \epsilon''_I u''_r} ) - 2 \eht{\rho} \fht{\epsilon''_I u''_r} \partial_r \fht{\epsilon_I} - 2\overline{\epsilon''_I}\ \eht{P} \ \fht{d} - 2\eht{P} \ \eht{\epsilon''_I d''} - 2\fht{d} \ \eht{\epsilon''_I P'} - 2\overline{\epsilon''_I P' d''} + 2\eht{\epsilon''_I \rho \varepsilon_{nuc}}
%\end{align}

%\begin{align}
%  dd*\partial_t (ddeiei/dd - ddei*ddei/(dd*dd)) + & \nonumber \\
%  ddux*\nabla_r  (ddeiei/dd - ddei*ddei/(dd*dd)) & = \nonumber \\
%  & -\nabla_r (ddeieiux/dd - 2 * ddei/dd * ddeiux/dd - ddux/dd*ddeiei/dd \nonumber \\
%  & + 2*ddei*ddei*ddux/(dd*dd*dd)) \nonumber \\
%  & -2*dd*(ddeiux/dd - ddei*ddux/(dd*dd))\partial_r ddei/dd \nonumber \\
%  & -2*(ei - ddei/dd)*pp*dddivu/dd \nonumber \\
%  & -2*pp*(eidd - ei*dddivu/dd - ddei/dd*divu + ddei*dddivu/dd) \nonumber \\
%  & -2*dddivu/dd*(eippdivu - eidivu*pp - ddei/dd*ppdivu \nonumber \\
%  & + ddei/dd*pp*dd - eipp*dddivu/dd + ei*pp*dddivu/dd) \nonumber \\
%  & + 2*(eiddenuc - ddei/dd*(ddenuc1+ddenuc2))
%\end{align}

%\subsection{Mean Number of Nucleon per Isotope a.k.a Abar Equation}

%\subsection{Mean Number of Nucleon per Isotope Flux a.k.a Abar Flux Equation}

%\subsection{Mean Charge per Isotope a.k.a Zbar Equation}

%\subsection{Mean Charge per Isotope Flux a.k.a Zbar Flux Equation}

%\subsection{Hydrodynamic Stellar Structure Equations}

%\subsubsection{Continuity Equation}

%\subsubsection{Momentum Equation}

%\subsubsection{Luminosity Equation}

%\subsubsection{Temperature Equation}

%\subsubsection{Composition Equation}

%\subsection{MLT Velocity}

%\begin{align}
%u_{MLT} \equiv (u'_{rms}) & = \frac{F_c}{\alpha_E c_P (T'_{rms})} = \frac{\erho \fht{h''u''_r}}{\alpha_E \fht{c_P} (\fht{TT} - \fht{T}\fht{T})^{1/2}} \sim \frac{\erho \eht{h'u'_r}}{\alpha_E \eht{c_P} (\eht{TT} - \eht{T} \ \eht{T})^{1/2}} \mbox{?} \\
%u_{MLT} \equiv (u'_{rms}) & = \frac{\erho (\fht{h u_r} - \fht{h}\fht{u_r})}{\alpha_E \fht{c_P} (\fht{TT} - \fht{T}\fht{T})^{1/2}} \sim \frac{\erho (\eht{h u_r} -\eht{h} \eht{u_r})}{\alpha_E \eht{c_P} (\eht{TT} - \eht{T} \ \eht{T})^{1/2}} \nonumber \\
%u_{MLT} \equiv (u'_{rms}) & = \frac{ddhhux - ddhh*ddux/dd}{\alpha_E * ddcp/dd \ (ddttsq/dd - ddtt*ddtt/dd*dd)^{1/2}} \sim \frac{dd*hhux - dd*hh*ux}{\alpha_E * cp \ (ttsq - tt*tt)^{1/2}} \nonumber
%\end{align}

\subsection{Usefull Identities}
\label{sect:usefulidentities}

\begin{align}
\eht{a''} = & \ \eht{a - \fht{a}} = \eht{a} - \fht{a}   \\
\fht{a''b''} = & \ \fht{(a-\fht{a})*(b-\fht{b})} = \fht{ab} - \fht{a}\fht{b} \\
\eht{a'b'} = & \ \eht{(a - \eht{a})*(b-\eht{b})} = \eht{ab}-\eht{a}\eht{b} = \eht{a'b''}\\
\fht{a''b''c''} = & \ \fht{(a-\fht{a})*(b-\fht{b})*(c-\fht{c})} = \fht{abc} - \fht{a}\fht{bc} - \fht{b}\fht{ac} - \fht{c}\fht{ab} + 2\fht{a}\fht{b}\fht{c} \\
\eht{a'b'c''} = & \eht{(a-\eht{a})*(b-\eht{b})*(c-\fht{c})} = \eht{abc} - \eht{ac} \ \eht{b} - \eht{a} \ \eht{bc} + \eht{a} \ \eht{b} \ \eht{c} - \eht{ab} \ \fht{c} + \eht{a} \ \eht{b} \fht{c} \\
\eht{a''b'c''} = & \eht{(a-\fht{a})*(b-\eht{b})*(c-\fht{c})} = \eht{abc} - \eht{ac}\eht{b} - \fht{a}\eht{bc} + \fht{a}\eht{b}\eht{c} - \eht{ab}\fht{c} + \eht{a}\eht{b}\fht{c} \\
\eht{a''bc} = & \ \eht{(a-\fht{a})bc} = \eht{abc} - \fht{a}\eht{bc} \\
\eht{a''\partial_r b'} = & \ \eht{(a-\fht{a})\partial_r b'} = \eht{a \partial_r b'} - \cancelto{0}{\fht{a}\partial_r \eht{b'}} = \eht{a \partial_r b} - \eht{a}\partial_r\eht{b}
\end{align}

%\section{Definitions}

%- only for basic quantities, without overbar e.g dd is density, ux is x velocity, ei internal energy etc.

\bibliography{referenc}

\end{document}


\documentclass[RNAAS]{aastex631}
\usepackage{hyperref}
\let\tablenum\relax
\usepackage[output-exponent-marker = \text{e}]{siunitx}

%% Define new commands here
\newcommand\latex{La\TeX}

\graphicspath{{./}{figures/}}
\shortauthors{Lucas et al.}

\begin{document}

\title{Yeehaw: A Roundup of Probabilistic Transit Modeling Packages}

\correspondingauthor{Miles Lucas}
\email{mdlucas@hawaii.edu}

\author[0000-0001-6341-310X]{Miles Lucas}
\affiliation{Institute for Astronomy, University of Hawai'i, USA}

\begin{abstract}
In this research note we report on the statistical outputs of popular transit modeling packages: \texttt{exoplanet}, \texttt{BATMAN}, \texttt{PyTransit}, \texttt{Juliet}, and \texttt{EXOFASTv2}. We use a circular Keplerian orbit with a quadratic limb-darkening law to generate data with additive white noise and then perform statistical inference using the packages' implementations of transit curves and statistical models. Our results show that none of the packages we tested significantly biases the posterior results away from the true value, although \texttt{EXOFASTv2} had slightly different posteriors due to different prior parameterizations.
\end{abstract}

\section{Introduction}

The method of transit photometry has proven indispensable in the detection and characterization of thousands of exoplanets over the past few decades \citep{2007prpl.conf..701C,2009IAUS..253...99W,2010exop.book...55W,2010trex.book.....H}. These quantities all have to be inferred using a computed model of the planetary transit. Model accuracy directly affects the inference of these parameters and a recent study by \citet{2020AJ....159..123A} has improved numerical accuracy of the popular quadratic limb-darkening law \citep{2002ApJ...580L.171M} to within $\mathcal{O}(10^{-15})$ along with analytical derivatives. The rapid growth of the exoplanet community means not every user who uses a given package will understand, in full, the statistical implications of their choices, and it is important to make sure the transit modeling ecosystem is not imparting bias into exoplanet studies. We seek to improve upon the work by \citet{2020AJ....159..123A} and study how different packages affect the statistical inference of astrophysical parameters.

The following packages provide limb-darkened transit curves: \texttt{exoplanet} \citep{2019ascl.soft10005F}, \texttt{BATMAN} \citep{2015PASP..127.1161K}, \texttt{PyTransit} \citep{Parviainen2015}, and \texttt{EXOFASTv2} \citep{2019arXiv190709480E}. From these packages we use the quadratic limb-darkening law from \citet{2002ApJ...580L.171M}. In addition, \texttt{exoplanet} and \texttt{EXOFASTv2} have entire statistical modeling frameworks built into or on top of the transit curves. We also test \texttt{Juliet} \citep{2019MNRAS.490.2262E}, which adds a statistical modeling framework to the \texttt{BATMAN} transit models.

\section{Modeling}

To begin, we used the highly accurate \citet{2020AJ....159..123A} transit models to simulate a light curve. The ground truth parameters were chosen to roughly mock the Kepler-101b transit \citep{2014A&A...572A...2B} and are shown in \autoref{table}. We built a hierarchical model using \texttt{PyMC3} \citep{2016ascl.soft10016S} and \texttt{exoplanet} with the following parameters: the semi-major axis ($aR_*$), orbital period ($P$), time of inferior conjunction ($t_0$), ratio of planet to stellar radii ($R_P/R_*$), limb-darkening coefficients ($u_1,u_2$), and out-of-transit noise ($\sigma$). This parameterization is supported (at least indirectly) by all packages tested and has the benefit of no correlations in the orbital parameters, which can degrade accuracy and performance of inference methods. We built this model in a generic way that could substitute different limb-darkening laws between \texttt{exoplanet}, \texttt{BATMAN}, and \texttt{PyTransit}.

The prior parameterization is chosen to be slightly uninformative, but some tuning was done to ensure consistent outputs. For the period and semi-major axis we use log-Normal priors, for the time of inferior conjunction we use a Normal prior, for the limb-darkening coefficients we use uninformative triangular sampling \citep{2013MNRAS.435.2152K} provided by \texttt{exoplanet}, and finally for the noise term we use a half-Cauchy distribution. The simulated data is compared to the models using a Gaussian likelihood without any additional noise model. For performing statistical inference with \texttt{PyMC3}, we use both the No-U-Turn Sampler (NUTS; \citealp{2011arXiv1111.4246H}) and Metropolis-Hastings (MH). Analytical derivatives are required for NUTS, and therefore we only tested it with the \texttt{exoplanet} light curve models.

For \texttt{Juliet} we needed to change the parameterization slightly-- in the previous models the error is completely modeled by the noise term inside the Gaussian likelihood, but we had to skip modeling this term for \texttt{Juliet} because it fails to evaluate a finite likelihood if the error in its data model is 0. We followed the \texttt{Juliet} documentation for building our model-- the main differences are that period and semi-major axis are sampled using a Normal distribution rather than a log-Normal. For inference, \texttt{Juliet} uses \texttt{DYNESTY} \citep{2020MNRAS.493.3132S} to perform nested sampling (NS; \citealp{2004AIPC..735..395S}) providing both posterior samples and an estimate of the Bayesian evidence for our model.

For \texttt{EXOFASTv2} we also had to alter the parameterization slightly; rather than fitting the semi-major axis directly, we had to fit the stellar mass and fix the planetary mass. Similar to our \texttt{Juliet} setup, we use a Normal prior for period and time of inferior conjunction rather than log-Normal priors, and we also use a Uniform prior for the noise \textit{variance}. Importantly, the limb-darkening coefficients use an informative prior from \citet{2011A&A...529A..75C}. For inference \texttt{EXOFASTv2} uses a differential evolution Metropolis-Hastings algorithm (DEMH; \citealp{2006S&C....16..239T}) which uses an ensemble of walkers which query each other between steps to temper their proposal scales.

\section{Results}

We performed inference on all of our models, starting with a numerical optimization to decrease the time taken to converge on a solution during the MCMC inference. For the NUTS sampler we used \num{5,000} tuning steps and \num{5,000} samples. For the MH sampler we used \num{5,000} burn-in steps and \num{10,000} samples. In all cases this was enough samples to produce a Gelman-Rubin statistic close to 1.0, which implies that the chains are \textit{well-mixed}, Nested sampling samples until convergence \citep[see][\S 2.4]{2020MNRAS.493.3132S}, which produced \num{29,000} samples which were equally resampled using their statistical weights. \texttt{EXOFASTv2} was set to sample until the Gelman-Rubin statistic for the DEMH walkers was below 1.01, which generated \num{50,500} samples.

The posteriors from all of our inferences are tabulated in \autoref{table}. The table shows the median value of all posterior samples along with the 68\% highest-posterior-density interval (HDI). This is similar to a ``1-sigma confidence interval" but in a Bayesian context. Every model and inference combination \textit{except} for \texttt{EXOFASTv2} was consistent with each other and fits the data very well. A key parameter, the relative radius ($R_P/R_*$) is recovered and almost identically distributed for all our models. We believe the differences in posteriors from \texttt{EXOFASTv2} are from the different limb-darkening prior used.

\input{table.tex}

% \acknowledgments

% \software{
% astropy \citep{2013A&A...558A..33A,2018AJ....156..123A},
% numpy \citep{harris2020array},
% scikit-image \citep{2014arXiv1407.6245V},
% }

\bibliography{references}{}
\bibliographystyle{aasjournal}

\end{document}


\par
\chapter{{\tt Pencil}: Matrix pencil}
\par
This object stores a matrix pencil $A + \sigma B$.
$A$ and $B$ are both stored as {\tt InpMtx} objects.
Many of the {\tt Pencil} methods simply call the equivalent {\tt
InpMtx} method.