\subsection{Some Preliminaries in Agda}
\label{sec:appl:agda-preliminaries}

\AgdaHide{
\begin{code}
{-# OPTIONS --without-K #-}
\end{code}
}

This first section is devoted to the introduction of the propositions-as-types
interpretation in Agda syntax.
We will interleave the given Agda code with the necessary explanation.
All the indented code is formally verified in Agda and will be explained as we
go.

We start off by introducing the propositions-as-types interpretation in its own
module called \AgdaModule{PropsAsTypes}.
Agda allows the separation of code into modules that can be imported in other
files, as we will see later.
\begin{code}
module PropsAsTypes where
\end{code}

Inside the module, we now introduce our first type, which implements the
dependent sum that we encountered earlier.
The following code declares a new inductive data type called $\Sigma$
with two parameters $I$ and $X$.
So far, we denoted the universe of valid types by $\univ{i}$, whereas Agda uses
the notation \AgdaFunction{Set} instead.
Thus, $I$ is a type parameter.
The parameter $X$, on the other hand, is a family of types.
In our syntax, we would denote this by $X : \pType[(i : I)]$ and instantiation
of $X$ with a parameter $t$ would be written as $X \inst t$.
Agda uses for types with parameters the same notation as for the
function space,\endnote{%
  In fact, $X \from I \to \mathrm{Set}$ is a function in Agda, only that it is
  a type in the universe $\mathrm{Set}_1$.
  This is similar to the situation in category theory, where a family of sets
  can be given by a functor from $I$, seen as a discrete category, to the
  category of sets.
  Such a functor is then an object in the large category of functors between
  categories.
}
so that the instantiation of $X$ is written as $X \> t$.

Another mechanism of Agda that appears in the definition of $\Sigma$ is that
$I$ is an implicit parameter, signified by the curly braces, and that $X$ is
an explicit parameter.
The idea of the implicit parameter mechanism is that Agda ought to be able to
infer the argument $I$ from the context.
For example, if we have a type $U : \NatT \to \mathrm{Set}$, then Agda can
infer from the instantiation $\Sigma \> U$ that $I$ needs to be instantiated
with $\NatT$.
Should this inference not be possible, then one can always resort to writing
$\Sigma \> \{\NatT\} \> U$ to explicitly give the parameter $I$.
We will see this below in the definition of the binary product.

The type $\Sigma$ itself has one constructor ``$,$'' with two arguments, where
the argument positions are marked by the underscores.
This allows us to write $(i, x)$ if $i : I$ and $x : X \> i$, thereby resembling
the pairing notation that we used before.
\begin{code}
data Σ {I : Set} (X : I  Set) : Set where
  _,_ : (i : I)  X i  Σ X
\end{code}

In \exRef{exists-quant-encode}, we denoted the type $\Sigma$ by $\exists$ to
emphasise its relation to existential quantification.
This was done in the light of the fact that the iteration scheme for that
type corresponded exactly to the usual elimination rule the existential
quantifier.
Later we introduced dependent iteration, which we could use in
\exRef{dep-it-exist-quant} to define both projections from the existential
type.
In this section, we will distinguish between $\Sigma$ as a data type, which
has both projections, and the existential quantifier as a proposition.
The latter will only come with the non-dependent elimination principle.

We now give the dependent iteration scheme for the dependent sum type
$\Sigma$.
Let $A$ be a type family that depends on $\Sigma \> X$, that is,
$A : \Sigma \> X \to \mathrm{Set}$.
Recall from \exRef{dep-it-exist-quant} that, if we want to eliminate
$\Sigma \> X$ into $A$, then we need to provide a term of type $A \> (i , x)$
with parameters $i : I$ and $x : X \> i$.
Such a term can equivalently be given as a dependent function $f$ of type
$\PiT{i : I} \PiT{x : X \> i} A \> (i, x)$.
In Agda, this function type is written as
\AgdaSymbol{(}\AgdaBound{i} \AgdaSymbol{:} \AgdaBound{I}\AgdaSymbol{)} \AgdaSymbol{→} \AgdaSymbol{(}\AgdaBound{x} \AgdaSymbol{:} \AgdaBound{X} \AgdaBound{i}\AgdaSymbol{)} \AgdaSymbol{→} \AgdaBound{A} \AgdaSymbol{(}\AgdaBound{i} \AgdaInductiveConstructor{,} \AgdaBound{x}\AgdaSymbol{)},
in the style of de~Bruijn's telescopes~\cite{deBruijn1968:LangAutomath}.
Conveniently, we can define the dependent iteration scheme in Agda then
by using pattern matching as follows.
\begin{code}
drec-Σ :  {I : Set} {X : I  Set} {A : Σ X  Set} 
          ((i : I)  (x : X i)  A (i , x)) 
          (u : Σ X)  A u
drec-Σ f (i , x) = f i x
\end{code}

It is also straightforward to define, as we did in \exRef{dep-it-exist-quant},
the two projections for the dependent sum by appealing to dependent iteration.
\begin{code}
π₁ : {I : Set} {X : I  Set}  Σ X  I
π₁ = drec-Σ  i x  i)

π₂ : {I : Set} {X : I  Set}  (u : Σ X)  X (π₁ u)
π₂ = drec-Σ  i x  x)
\end{code}

From the dependent sum type we can also derive the binary product type.
Note that we introduced this type before as a coinductive type.
It saves us here, however, some work to define the binary product in terms of
the dependent sum.
\begin{code}
_×_ : Set  Set  Set
A × B = Σ {A} λ _  B
\end{code}

In the propositions-as-types interpretation, one uses a type system to
represent logical propositions.
To make clear whenever we write a proof of a proposition that has been
internalised into Agda, we will use \AgdaFunction{Prop} instead of
\AgdaFunction{Set}.
Thus, if $\varphi$ is a proposition that we encoded in Agda, we will
denote this as $\varphi : \AgdaFunction{Prop}$.
This notation is introduced by the following definition.
\begin{code}
Prop = Set
\end{code}

An important logical connective that we will need later is conjunction.
Even though conjunction is defined in terms the binary product, we use
separate notations to emphasise its logical nature.
\begin{code}
_∧_ : Prop  Prop  Prop
A  B = A × B

∧-elim₁ : {A₁ A₂ : Prop}  A₁  A₂  A₁
∧-elim₁ = π₁

∧-elim₂ : {A₁ A₂ : Prop}  A₁  A₂  A₂
∧-elim₂ = π₂

∧-intro : {A₁ A₂ : Prop}  A₁  A₂  A₁  A₂
∧-intro a₁ a₂ = (a₁ , a₂)
\end{code}

As already mentioned, we also introduce a separate notation for the existential
quantifier.
\begin{code}
 : {X : Set}  (A : X  Prop)  Prop
 = Σ
\end{code}

Agda allows us to provide a syntax for the existential quantifier that matches
the usual notation with explicit quantification domain.
It is not so relevant to precisely understand the following definition, the
reader should just remember that we can write ∃[ x ∈ X ] A instead of
$\exist{x : X} A$ for propositions $A$ with a free occurrence of $x$.
\begin{code}
∃-syntax :  X  (X  Prop)  Prop
∃-syntax X A =  A

syntax ∃-syntax X  x  A) = ∃[ x ∈ X ] A
\end{code}

From the pairing constructor and the iteration scheme for
the dependent sum type we obtain the usual introduction and elimination
rules for the existential quantifier that we already discussed in
\exRef{exists-quant-encode}.
For convenience, we also provide a scheme for the simultaneous elimination
of two existential quantifiers.
None of these definitions should come at a surprise to the reader at this
stage.
\begin{code}
∃-intro : {X : Set} {A : X  Prop}  (x : X)  A x  ∃[ x  X ] (A x)
∃-intro x a = (x , a)

∃-elim :  {X : Set} {A : X  Prop} {B : Prop} 
          ((x : X)  A x  B)  ∃[ x  X ] (A x)  B
∃-elim = drec-Σ

∃₂-elim :  {X Y : Set} {A : X  Prop} {B : Y  Prop} {C : Prop} 
           ((x : X) (y : Y)  A x  B y  C) 
           ∃[ x  X ] (A x)  ∃[ x  Y ] (B x)  C
∃₂-elim f p q = ∃-elim  x p'  ∃-elim  y q'  f x y p' q') q) p

\end{code}

\AgdaHide{
\begin{code}
infix 3 _⇔_
\end{code}
}

Finally, we define bi-implication between propositions, which is is of
course just given as the conjunction of implications in both directions.
\begin{code}
_⇔_ : Prop  Prop  Prop
A  B = (A  B)  (B  A)

equivalence : {A B : Prop}  (A  B)  (B  A)  A  B
equivalence = ∧-intro
\end{code}

Having set up the necessary definitions of the propositions-as-types
interpretation, we can now move to more interesting topics.

%%% Local Variables:
%%% ispell-local-dictionary: "british"
%%% End: