\documentclass{llncs} %include lhs2TeX.fmt %include lhs2TeX.sty %if anyMath %format ~ = "~" %format ! = "{}" %format . = ".~" %format Set = "\Set" %format Type = "\Type" %format == = "==" %format ** = "×" %format : = "\mathrel{:}" \newcommand \zero {\mathsf{z}} \newcommand \suc {\mathsf{s}} %format zero = "\zero" %format suc = "\suc" %format refl = "\mathsf{refl}" %format === = "\equiv" %format of_ = "\mathit{of}" %format iota = "ι" %format sigma = "σ" %format delta = "δ" %format gamma = "γ" %format eps = "ε" %format beta = "β" %format eta = "η" %format eps_I = "ε_I" %format inl = "\mathsf{inl}" %format inr = "\mathsf{inr}" %format Even' = "\mathit{Even}^{*}" %format evenZ = "\mathsf{evenZ}" %format evenSS = "\mathsf{evenSS}" %format evenZ' = "\mathsf{evenZ}^{*}" %format evenSS' = "\mathsf{evenSS}^{*}" %format elim_Even = "\mathit{elim}_{\Even}" %format elim_Even' = "\mathit{elim}_{\Even^{*}}" \newcommand \Even {\mathit{Even}} %format pi0 = "π_0" %format pi1 = "π_1" %format elim0 = "\mathit{case}_0" %format elim2 = "\elimBool" %format Elim2 = "\ElimBool" \newcommand \elimBool {\mathit{case}_2} \newcommand \ElimBool {\mathit{case}^{\mathit{type}}_2} %format OP = "\mathit{OP}" %format OPg = "\mathit{OP}^g" %format OPr = "\mathit{OP}^r" %format Fin_n = "\mathit{Fin}_n" %format Args_IE = "\mathit{Args}_{I,E}" %format index_IE = "\mathit{index}_{I,E}" %format IndArg_IE = "\mathit{IndArg}_{I,E}" %format IndIndex_IE = "\mathit{indIndex}_{I,E}" %format Ind_IE = "\mathit{ind}_{I,E}" %format IndHyp_IE = "\mathit{IndHyp}_{I,E}" %format indHyp_IE = "\mathit{indHyp}_{I,E}" %format elimUrg = "\mathit{elim}{-}U^r_γ" %format elimUreg = "\mathit{elim}{-}U^r_{εγ}" %format elimUgg = "\mathit{elim}{-}U^g_γ" %format elimId = "\mathit{elim}_{==}" %format elim_P = "\mathit{elim}_{==,PM}" %format elim_ML = "\mathit{elim}_{==,ML}" %format elim_K = "\mathit{elim}_{==,K}" %format 0 = "\mathbf{0}" %format 1 = "\mathbf{1}" %format 2 = "\mathbf{2}" %format star = "\star" %format star0 = "\star_0" %format star1 = "\star_1" %format < = "\left\langle" %format > = "\right\rangle" %format << = "<" %format =~= = "\cong" %format Urg = "U^r_γ" %format introrg = "\mathrm{intro}^r_γ" %format Ugg = "U^g_γ" %format introgg = "\mathrm{intro}^g_γ" %format Ureg = "U^r_{εγ}" %format introreg = "\mathrm{intro}^r_{εγ}" %format grArgs = "g{\to}rArgs" %format grArgs_I = "g{\to}rArgs_I" %format rgArgs = "r{\to}gArgs" %format rgArgs_I = "r{\to}gArgs_I" %format rgArgssubst = "rgArgs{-}subst" %format ar = "a_r" %format arg = "a_{rg}" %format stepr = "\mathit{step}_r" %format IdA = "\mathrel{{==}_A}" %endif \usepackage{ucs} \usepackage[utf8x]{inputenc} \usepackage{autofe} \usepackage{color} \newcommand \infer[2] { \frac {\begin{array}{c}\displaystyle #1\end{array}} {\begin{array}{c}\displaystyle #2\end{array}} } % Enables greek letters in math environment \everymath{\SetUnicodeOption{mathletters}} \everydisplay{\SetUnicodeOption{mathletters}} % This makes sure that local glyph overrides below are % chosen. \DeclareUnicodeOption{localDefs} \SetUnicodeOption{localDefs} % For some reason these macros need to be defined. \newcommand \textmu {$μ$} \newcommand \textnu {$ν$} \newcommand \texteta {$η$} \newcommand \textbeta {$β$} \newcommand \textlambda {$λ$} % This character doesn't seem to be defined by ucs.sty. \DeclareUnicodeCharacter{"21A6}{\ensuremath{\mapsto}} \input{macros} \title{Encoding indexed inductive definitions using the intensional identity type} \author{Ulf Norell} \institute{Chalmers University of Technology \\ \email{ulfn@@cs.chalmers.se} } \begin{document} \maketitle \begin{abstract} It is well-known how to represent indexed inductive definitions, or inductive families, using extensional equality. We show that this encoding also works in intensional type theory and that the computation rules associated with an inductive family are preserved. The proof has been formalised in Agda. \end{abstract} \section{Introduction} % Describe the current state of affairs (and sell inductive families) Indexed inductive definitions (IID), or inductive families, are inductively defined families of sets. As such they have a wide range of applications in both mathematics and programming. Examples include the transitive closure of a relation, the typing relation of simply typed $λ$-calculus, and vectors of a fixed length. Indexed inductive definitions have been studied extensively in various theories, such as Martin-Löf type theory~\cite{dybjer:sophia,dybjer:bastadfacs}, Calculus of Inductive Constructions~\cite{paulin:thesis,coquand:bastad}, and Luo's UTT~\cite{luo:typetheory}, and they are supported by tools building on these theories. For instance, ALF~\cite{magnussonnordstrom:alf}, Coq~\cite{mohring:inductivedefsincoq}, LEGO~\cite{luo:lego}, and Epigram~\cite{mcbride:left}. They have even made it into languages such as Haskell~\cite{pj:gadt}. % Representing inductive families using equality is well-known An example of an IID is the predicate |Even| over natural numbers inductively defined by the rules \[\begin{array}{ccc} \infer{}{\Even \, \zero} && \infer{\Even \, n}{\Even \, (\suc \, (\suc \, n))} \end{array}\] We distinguish between generalised IID, such as |Even| above, and restricted IID where the conclusions must all be of the form $P\,\bar x$~\cite{dybjer:indexed-ir}. It is well-known~\cite{feferman94finitary} how to reduce generalised IID to restricted IID using equality. For instance, the |Even| predicate can be represented by the restricted IID \[\begin{array}{ccc} \infer{n = \zero}{\Even \, n} && \infer{\Even \, m \quad n = \suc \, (\suc \, m)}{\Even \, n} \end{array}\] There are several reasons, both practical and theoretical, why restricted IID are simpler to work with than generalised IID. A practical advantage is that the elimination rule for a restricted IID can be presented nicely as pattern matching~\cite{coquand:patternmatching}. From a theoretical standpoint a restricted IID has the property that it can be expressed as a fixed-point of an equation. In the example of |Even|: \[\Even \, n \Leftrightarrow n = \zero \vee \exists m. \, \Even \, m \wedge n = \suc \, (\suc \, m) \] From a set theoretic point of view it is clear that the formulation of the generalised IID as a restricted IID is equivalent to the original formulation, but in a type theoretic setting it is not so obvious. The reason for this is that in type theory we are not only interested in provability but also in the proof terms. In the first formulation of the |Even| predicate we have proof terms |evenZ| and |evenSS m p|, for a number |m| and a proof |p| that |m| is even, corresponding to the two rules. We also have a dependent elimination rule |elim_Even|: \begin{code} elim_Even : (C : (n : Nat) -> Even n -> Set) -> C zero evenZ -> ( (n : Nat)(e : Even n) -> C n e -> C (suc (suc n)) (evenSS n e)) -> (n : Nat)(e : Even n) -> C n e \end{code} Note that the predicate |C| that we are eliminating over, depends not only on a natural number, but also on the actual proof term that proves it is even. The elimination rule is equipped with two computation rules stating that > elim_Even C cz css zero evenZ = cz > elim_Even C cz css (suc (suc m)) (evenSS m p) = > css m p (elim_Even C cz css m p) Now it is not at all clear that the second formulation of |Even| enjoys the same elimination and computation rules, since the proof terms are quite different. Dybjer and Setzer~\cite{dybjer:indexed-ir} show that in extensional type theory generalised IID can be reduced to restricted IID, and the main result of the present paper is to show that this can be done also in intensional type theory. The difference between extensional and intensional type theory is that in intensional type theory one distinguishes between provable equality and definitional equality. The advantage of this is that proof checking becomes decidable, but a disadvantage is that the proof checker can only decide definitional equality, so substituting equals for equals for provable equality is more cumbersome. The main challenge in relating the two formulations of indexed inductive definitions in intensional type theory is proving that the computation rules hold definitionally. % Fill gap The main contribution of this paper is a proof that, in intensional type theory, we can faithfully represent generalised IID in terms of restricted IID and an intensional equality type. The proof has been formally verified by the Agda proof checker~\cite{coquand:stt-lfm99}. The formal proof has been carried out for the fully general case of indexed inductive-recursive definitions~\cite{dybjer:indexed-ir}, but for presentation reasons we restrict ourselves to indexed inductive definitions. Adding a recursive component adds no difficulties to the proof. For systems such as Agda, which only support restricted indexed inductive definitions, our result provides a way to get the power of generalised inductive families without having to extend the meta-theory. The rest of this paper is organised as follows. Section~\ref{sec-lf} introduces the logical framework, Section~\ref{sec-id} gives a brief introduction to the intensional identity type, Section~\ref{sec-IID} gives a formalisation of indexed inductive definitions, Section~\ref{sec-Encoding} contains the proof that generalised IID can be reduced to restricted IID, Section~\ref{sec-formal} comments on the formal proof, and Section~\ref{sec-concl} concludes. \section{The logical framework} \label{sec-lf} We use Martin-Löf's logical framework~\cite{nordstrom:book} extended with sigma types |(x : A) ** B|, |0|, |1|, and |2|. This is the same framework as is used by Dybjer and Setzer and the complete rules can be found in~\cite{dybjer:indexed-ir}. In contrast to Dybjer and Setzer, however, we work entirely in intensional type theory. The type of sets |Set| is closed under dependent sums and products, and if |A : Set| then |A| is a type. Dependent function types are written |(x : A) -> B| and have elements |\ x. a|, where |a : B| provided |x : A|. Application of |f| to |a| is written |f a|. If |x| does not occur free in |B| we write |A -> B| for |(x : A) -> B| and when the result type is itself a function type we write |(x : A)(y : B) -> C| for |(x : A) -> (y : B) -> C|. The elements of a sigma type |(x : A) ** B| are pairs || where |a : A| and $b : B[a/x]$ (|B| with |a| substituted for |x|). We have projections |pi0| and |pi1| with the |beta|-rules |pi0 = a| and |pi1 = b| and the |eta|-rule | = p|. The empty type |0| has no elements and elimination rule |elim0 : 0 -> A|, for any |A : Set|. The element of the singleton type is |star : 1| and if |a : 1| then |a = star| (|eta|-rule). The two element type |2| has elements |star0| and |star1|, and elimination rule $\elimBool : (i : \mathbf{2}) \to A[\star_0] \to A[\star_1] \to A[i]$, where $A[i]$ is a type for |i : 2|. We also have large elimination for |2|: |Elim2 : 2 -> Set -> Set -> Set|. Using the large elimination we can define the disjoint union of two types > A + B = (i : 2) ** Elim2 i A B. \section{The identity type} \label{sec-id} In this paper we show that the logical framework extended with restricted IID and an intensional identity type can express generalised IID. In order to do this we first have to chose the identity type to use. Let us review our choices. We want a type \begin{code} ! IdA ! : A -> A -> Set \end{code} with introduction rule \begin{code} refl : (x : A) -> x == x \end{code} The choice lies in the elimination rule, where we have two principal candidates. The Martin-Löf elimination rule, introduced in 1973~\cite{martin-lof:predicative} is defined as follows. \begin{definition}[Martin-Löf elimination] The Martin-Löf elimination rule (sometimes called $J$) has the type \begin{code} elim_ML : (C : (x, y : A) -> x == y -> Set) -> ((x : A) -> C x x (refl x)) -> (x, y : A)(p : x == y) -> C x y p \end{code} and computation rule > elim_ML C h x x (refl x) = h x \end{definition} A different elimination rule was introduced by Paulin-Mohring~\cite{pfenning-paulin:inductive-coc}: \begin{definition}[Paulin-Mohring elimination] The Paulin-Mohring elimination rule has type \begin{code} elim_P : (x : A)(C : (y : A) -> x == y -> Set) -> C x (refl x) -> (y : A)(p : x == y) -> C y p \end{code} and computation rule > elim_P x C h x (refl x) = h \end{definition} The difference between Martin-Löf elimination and Paulin-Mohring elimination is that in Martin-Löf elimination the predicate |C| abstracts over both |x| and |y|, whereas in Paulin-Mohring elimination the predicate need only abstract over |y|. At first glance, Paulin-Mohring elimination looks stronger than Martin-Löf elimination, and indeed it is easy to define |elim_ML| in terms of |elim_P|. \begin{lemma} Martin-Löf elimination can be defined in terms of Paulin-Mohring elimination. \end{lemma} \begin{proof} > elim_ML C h x y p = elim_P x (\ z q. C x z q) (h x) y p \end{proof} % However, it turns out that Paulin-Mohring elimination is also definable in terms of Martin-Löf elimination~\cite{paulin:mail}. The proof of this is slightly more involved. % \begin{lemma} Paulin-Mohring elimination can be defined in terms of Martin-Löf elimination. \end{lemma} \begin{proof} We first define the substitution rule \begin{code} subst : (C : A -> Set)(x, y : A) x == y -> C x -> C y subst C x y p Cx = elim_ML (\ a b q. C a -> C b) (\ a Ca. Ca) x y p Cx \end{code} Now define |E x = (y : A) ** (x == y)|. We can prove that any element of |E x| is equal to ||. \begin{code} uniqE : (x, y : A)(p : x == y) -> == uniqE = elim_ML (\ x y p. == ) refl \end{code} Finally \begin{code} elim_P x C h y p = subst (\ z. C (pi0 z) (pi1 z)) (uniqE x y p) h \end{code} \end{proof} In an impredicative setting there is a simpler proof due to Streicher~\cite{streicher:habilitation}. Yet another elimination rule is Streicher's axiom K~\cite{HofmannM:gromru}, given by > elim_K : (x : A)(C : x == x -> Set) -> > C refl -> (p : x == x) -> C p which he shows cannot be defined in terms of the previous elimination rules. Seeing as Martin-Löf elimination and Paulin-Mohring elimination are equivalent we choose Paulin-Mohring elimination which is easier to work with. So we extend our logical framework with \begin{code} ! IdA ! : A -> A -> Set refl : (x : A) -> x == x elimId : (x : A)(C : (y : A) -> x == y -> Set) -> C x (refl x) -> (y : A)(p : x == y) -> C y p elimId x C h x (refl x) = h \end{code} \section{Indexed Inductive Definitions} \label{sec-IID} An indexed inductive definition (IID) defines a family of types. We distinguish between generalised IID, which can be seen as an inductively defined family of types, and restricted IID, which can be seen as a family of inductive types. Non-indexed types are a special case of restricted IID, indexed over |1|. For instance, the type of natural numbers can be seen as the restricted IID \begin{code} Nat : 1 -> Set zero : (x : 1) -> Nat x suc : (x : 1) -> Nat x -> Nat x \end{code} In these cases we omit the index and simply write \begin{code} Nat : Set zero : Nat suc : Nat -> Nat \end{code} An example of a restricted IID indexed by a natural number |n| is the type of ordered lists of natural numbers greater than or equal to |n|: \begin{code} OrdList : Nat -> Set nil : (n : Nat) -> OrdList n cons : (n : Nat) -> (m : Nat) -> (m >= n) -> OrdList m -> OrdList n \end{code} Note that the introduction rules (constructors) |nil| and |cons|, constructs elements in |OrdList n| for an arbitrary |n|. Note also that the types at different indices can depend on each other. In this case the inductive argument of the |cons| constructor is |OrdList m| for an arbitrary |m >= n|. In a generalised IID, however, the constructors can target different parts of the inductive family. In the case of lists of a certain length we have \begin{code} Vec : Nat -> Set nil : Vec zero cons : (n : Nat) -> Nat -> Vec n -> Vec (suc n) \end{code} In the rest of this section we present the formalisation of indexed inductive types. We follow the formalisation of indexed induction-recursion of Dybjer and Setzer~\cite{dybjer:indexed-ir} but leave out the recursion to simplify the presentation. \subsection{Codes for IID} \label{sec-IID-Codes} Like Dybjer and Setzer we introduce a common type of codes which will serve both as codes for general IID and restricted IID. \begin{code} OP I E : Set iota : E -> OP I E sigma : (A : Set) -> (A -> OP I E) -> OP I E delta : (A : Set) -> (A -> I) -> OP I E -> OP I E \end{code} Now the codes for general indexed inductive types are defined by |OPg I = OP I I|, and the codes for restricted types are |OPr I = I -> OP I 1|. The intuition is that for general IID the index is computed from the shape of the value, whereas the index of a restricted IID is given beforehand. With these definitions in mind, let us study the type of codes in more detail. We have three constructors: \begin{itemize} \item Base case: |iota e|. This corresponds to an IID with no arguments to the constructor. In the case of a general IID we have to give the index for the constructor. For instance the code for the singleton type of true booleans given by the formation rule |IsTrue : Bool -> Set| and introduction rule |IsTrue true| is |iota true : OPg Bool| \item Non-inductive argument: |sigma A gamma|. In this case the constructor has a non-inductive argument |a : A|. The remaining arguments may depend on |a| and are coded by |gamma a|. A datatype with multiple constructors can be coded by |sigma C gamma| where |C| is a type representing the constructors and |gamma c| is the code for the constructor corresponding to |c|. For instance, the code for the datatype |Bool| with two nullary constructors is \begin{code} \i . sigma 2 (\c. elim2 c (iota star) (iota star)) \end{code} Another example is the type of pairs over |A| and |B| \begin{code} \ i. sigma A (\ a. sigma B (\ b. iota star)) : OPr 1 \end{code} In this case the following arguments do not depend on the value of the non-inductive arguments. \item Inductive argument: |delta A i gamma|. For an inductive argument we need to know the index of the argument. Note that the following arguments cannot depend on the value of the inductive argument. The inductive argument may occur under some assumptions |A|. For example consider the accessible part of a relation |<<| over |A|, |Acc : A -> Set| with introduction rule that for any |x|, if |((y : A) -> y << x -> Acc y)| then |Acc x|. Here the inductive argument |Acc y| occurs under the assumptions |(y : A)| and |y << x|. The code for this type is \begin{code} \ x. delta ((y : A) ** (y << x)) pi0 (iota star) : OPr A \end{code} The index of the inductive argument is |y| which is the first projection of the assumptions. \end{itemize} See Section~\ref{sec-IID-Examples} for more examples. \subsection{From codes to types} \label{sec-IID-Types} Now that we have defined the codes for IID the next step is to describe their semantics, i.e. what the elements of an IID with a given code are. First we define the type of arguments to the constructor parameterised by the type of inductive arguments\footnote{Analogous to when you for simple inductive types define an inductive type as the fixed point of some functor.}. \begin{code} Args_IE : (gamma : OP I E)(U : I -> Set) -> Set Args (iota e) U = 1 Args (sigma A gamma) U = A ** \ a. Args (gamma a) U Args (delta A i gamma) U = ((a : A) -> U (i a)) ** \ d. Args gamma U \end{code} There are no surprises here, in the base case there are no arguments, in the non-inductive case there is one argument |a : A| followed by the rest of the arguments (which may depend on |a|). In the inductive case we have a function from the assumptions |A| to a value of the inductive type at the specified index. For generalised IID we also need to be able to compute the index of a given constructor argument. \begin{code} index_IE : (gamma : OP I E)(U : I -> Set)(a : Args gamma U) -> E index (iota e) U star = e index (sigma A gamma) U = index (gamma x) U a index (delta A i gamma) U <_, a> = index gamma U a \end{code} Note that only the non-inductive arguments are used when computing the index. This is all the machinery needed to introduce the types of generalised and restricted IID. For restricted IID we introduce, given |gamma : OPr I| and |i : I| \begin{code} Urg : I -> Set introrg i : Args (gamma i) Urg -> Urg i \end{code} For generalised IID, given |gamma : OPg I| we want \begin{code} Ugg : I -> Set introgg : (a : Args gamma Ugg) -> Ugg (index gamma Ugg a) \end{code} In Section~\ref{sec-Encoding} we show how to define |Ugg| in terms of |Urg|. As an example take the type of pairs over |A| and |B|: \begin{code} gamma = \ i. sigma A (\ a. sigma B (\ b. iota star)) : OPr 1 Pair A B = Urg : 1 -> Set introrg star : A ** (\ a. B ** (\ b. 1)) -> Pair A B star \end{code} Note that while the index of a restricted IID is determined from the outside, it is still possible to have a different index on the inductive occurrences. An example of this is the accessibility predicate given in Section~\ref{sec-IID-Codes}. This is crucial when interpreting general IID by restricted IID (see Section~\ref{sec-Encoding}). \subsection{Elimination rules} \label{sec-IID-Elimination} To complete the formalisation of IID we have to give the elimination rules. We start by defining the set of assumptions of the inductive occurrences in a given constructor argument. \begin{code} IndArg_IE : (gamma : OP I E)(U : I -> Set) -> Args gamma U -> Set IndArg (iota e) U star = 0 IndArg (sigma A gamma) U < a, b > = IndArg (gamma a) U b IndArg (delta A i gamma) U < g, b > = A + IndArg gamma U b \end{code} Simply put |IndArg gamma U a| is the disjoint union of the assumptions of the inductive occurrences in |a|. Now, given the assumptions of one inductive occurrence we can compute the index of that occurrence. \begin{code} IndIndex_IE : (gamma : OP I E)(U : I -> Set) (a : Args gamma U) -> IndArg gamma U a -> I indIndex (iota e) U star z = elim0 z indIndex (sigma A gamma) U < a, b > c = indIndex (gamma a) U b c indIndex (delta A i gamma) U < g, b > (inl a) = i a indIndex (delta A i gamma) U < g, b > (inr a) = indIndex gamma U b a \end{code} The code |gamma| contains the values of the indices for the inductive occurrences so we just have to find the right inductive occurrence. We can now define a function to extract a particular inductive occurrence from a constructor argument. \begin{code} Ind_IE : (gamma : OP I E)(U : I -> Set) (a : Args gamma U)(v : IndArg gamma U a) -> U (indIndex gamma U a v) ind (iota e) U star z = elim0 z ind (sigma A gamma) U < a, b > c = ind (gamma a) U b c ind (delta A i gamma) U < g, b > (inl a) = g a ind (delta A i gamma) U < g, b > (inr a) = ind gamma U b a \end{code} Again the definition is very simple. Next we define the notion of an induction hypothesis. Given a predicate |C| over elements in a datatype, an induction hypothesis for a constructor argument |a| is a function that proves the predicate for all inductive occurrences in |a|. \begin{code} IndHyp_IE : (gamma : OP I E)(U : I -> Set) -> (C : (i : I) -> U i -> Set)(a : Args gamma U) -> Set IndHyp gamma U C a = (v : IndArg gamma U a) -> C (indIndex gamma U a v) (ind gamma U a v) \end{code} Given a function |g| that proves |C i u| for all |i| and |u| we can construct an induction hypothesis for |a| by applying |g| to all inductive occurrences in |a|. \begin{code} indHyp_IE : (gamma : OP I E)(U : I -> Set) (C : (i : I) -> U i -> Set) (g : (i : I)(u : U i) -> C i u) (a : Args gamma U) -> IndHyp gamma U C a indHyp gamma U C g a = \ v. g (indIndex gamma U a v) (ind gamma U a v) \end{code} We are now ready to introduce the elimination rules. Given |I : Set| and |gamma : OPr I| the elimination rule for the restricted IID |Urg| is given by the following type and computation rule: \begin{code} elimUrg : (C : (i : I) -> Urg i -> Set) -> ((i : I)(a : Args (γ i) Urg) -> IndHyp (γ i) Urg C a -> C i (introrg i a)) -> (i : I)(u : Urg i) -> C i u elimUrg C step i (introrg a) = step i a (indHyp (γ i) Urg C (elimUrg C step) a) \end{code} That is, for any predicate |C| over |Urg|, if given that |C| holds for all inductive occurrences in some arbitrary constructor argument |a| then |C| holds for |introrg a|, then |C| holds for all elements of |Urg|. The computation rule states that eliminating an element built by the introduction rule is the same as first eliminating all inductive occurrences and then applying the induction step. The elimination rule for a general IID is similar. The difference is that the index of a constructor argument is computed from the value of the argument. \begin{code} elimUgg : (C : (i : I) -> Ugg i -> Set) -> ( (a : Args γ Ugg) -> IndHyp γ Ugg C a -> C (index γ Ugg a) (introgg a)) -> (i : I)(u : Ugg i) -> C i u elimUgg C step (index γ Ugg a) (introgg a) = step a (indHyp γ Ugg C (elimUgg C m) a) \end{code} \subsection{Examples} \label{sec-IID-Examples} %format gammaNat = "γ_{\mathit{Nat}}" %format introrgn = "\mathit{intro}^r_{γ_{\mathit{Nat}}}" %format gammaEven = "γ_{\mathit{Even}}" %format gammaId = "γ_{{==}}" As we have seen, datatypes with more than one constructor can be encoded by having the first argument be a representation of the constructor. For instance, the code for natural numbers is > gammaNat : OPr 1 = \i. sigma 2 (\ c. elim2 c (iota star) (delta 1 (\ x. star) (iota star))) Here, the first argument is an element of |2| encoding whether the number is built by |zero| or |suc|. We can recover the familiar introduction rules |zero| and |suc| by \begin{code} zero = introrgn star ! suc n = introrgn star ! > \end{code} Another example is the generalised IID of proofs that a natural numbers are even given introduction rules \begin{code} evenZ : Even zero evenSS : (n : Nat) -> Even n -> Even (suc (suc n)) \end{code} The code for |Even| is \begin{code} gammaEven : OPg Nat = sigma 2 (\ c. elim2 c (iota zero) (sigma Nat (\ n. delta 1 (\ x. n) (iota (suc (suc n)))))) \end{code} Again an argument of type |2| is used to distinguish the two constructors. In the |evenZ| case there are no arguments and the index is |zero|. In the |evenSS| case there is one non-inductive argument |n| of type |Nat| and one inductive argument with no assumptions and index |n|. The index of the result is |suc (suc n)|. The Paulin-Mohring intensional identity type also has a code. Given a set |A| and an |x : A| code for the family |x == y| indexed by |y : A| is \begin{code} gammaId : OPg A = iota x \end{code} That is, there is a single constructor with no arguments, whose index is |x|. This corresponds to the introduction rule > refl : x == x The elimination rule for this type is exactly the Paulin-Mohring elimination rule. \section{Encoding generalised IID as restricted IID} \label{sec-Encoding} In this section we show that generalised IID are expressible in the logical framework extended with restricted IID and the intensional identity type. We do this by defining the formation, introduction, and elimination rules of a generalised IID and subsequently proving that the computation rules hold intensionally. \subsection{Formation rule} We first show how to transform the code for a generalised IID into the code for its encoding as a restricted IID. The basic idea, as we have seen, is to add a proof that the index of the restricted IID is equal to the index computed for the generalised IID. Concretely: \begin{code} eps_I : OPg I -> OPr I eps (iota i) j = sigma (i == j) (\ p. iota star) eps (sigma A gamma) j = sigma A (\ a. eps (gamma a) j) eps (delta H i gamma) j = delta H i (eps gamma j) \end{code} Now a generalised IID for a code |gamma| can be defined as the restricted IID of |eps gamma|. \begin{code} Ugg : I -> Set Ugg i = Ureg i \end{code} For example, the generalised IID of the proofs that a number is even, given by \begin{code} Even : Nat -> Set evenZ : Even zero evenSS : (n : Nat) -> Even n -> Even (suc (suc n)) \end{code} is encoded by the following restricted IID: \begin{code} Even' : Nat -> Set evenZ' : (n : Nat) -> zero == n -> Even' n evenSS' : (n : Nat)(m : Nat) -> Even' m -> suc (suc m) == n -> Even' n \end{code} \subsection{Introduction rule} We need an introduction rule \begin{code} introgg : (a : Args gamma Ugg) -> Ugg (index gamma Ugg a) \end{code} and we have the introduction rule for the restricted IID: \begin{code} introreg i : Args (eps gamma i) Ureg -> Ureg i = Args (eps gamma i) Ugg -> Ugg i \end{code} So, what we need is a function |grArgs| to convert a constructor argument for a generalised IID, |a : Args gamma Ugg|, to a constructor argument for its representation, |Args (eps gamma (index gamma Ugg a)) Ugg|. This function simply adds a reflexivity proof to |a|: \begin{code} grArgs_I : (gamma : OPg I)(U : I -> Set) (a : Args gamma U) -> Args (eps gamma (index gamma U a)) U grArgs (iota e) U a = < refl, star > grArgs (sigma A gamma) U < a, b > = < a, grArgs (gamma a) U b > grArgs (delta H i gamma) U < g, b > = < g, grArgs gamma U b > \end{code} As usual we abstract over the type of inductive occurrences. Now the introduction rule is simply defined by \begin{code} introgg a = introreg (index gamma Ugg a) (grArgs gamma Ugg a) \end{code} In our example: \begin{code} evenZ : Even' zero evenZ = evenZ' refl evenSS : (n : Nat) -> Even' n -> Even' (suc (suc n)) evenSS n e = evenSS' n e refl \end{code} \subsection{Elimination rule} Now we turn our attention towards the elimination rule. \begin{theorem} The elimination rule for a generalised IID is provable for the representation of generalised IID given above. More precisely, we can prove the following rule in the logical framework with restricted IID and the identity type. \begin{code} elimUgg : (C : (i : I) -> Ugg i -> Set) -> ( (a : Args γ Ugg) -> IndHyp γ Ugg C a -> C (index γ Ugg a) (introgg a)) -> (i : I)(u : Ugg i) -> C i u \end{code} \end{theorem} \begin{proof} We can use the elimination for the restricted IID \begin{code} elimUreg : (C : (i : I) -> Ugg i -> Set) -> ( (i : I)(a : Args (eps gamma i) Ugg) -> IndHyp (eps gamma i) Ugg C a -> C i (introreg i a)) -> (i : I)(u : Ugg i) -> C i u \end{code} Now we face the opposite problem from what we encountered when defining the introduction rule. In order to apply the induction step we have to convert a constructor argument to the restricted IID to a generalised argument, and likewise for the induction hypothesis. To convert a restricted constructor argument we simply remove the equality proof. \begin{code} rgArgs_I : (gamma : OPg I)(U : I -> Set) (i : I)(a : Args (eps gamma i) U) -> Args gamma U rgArgs (iota i) U j _ = star rgArgs (sigma A gamma) U j < a, b > = < a, rgArgs (gamma a) U j b > rgArgs (delta H i gamma) U j < g, b > = < g, rgArgs gamma U j b > \end{code} Converting induction hypotheses requires a little more work. This work, however, is pure book-keeping, as we will see. We have an induction hypothesis for the restricted IID. Namely, for |a : Args (eps gamma i) Ugg| we have \begin{code} ih : IndHyp (eps gamma i) Ugg C a = (v : IndArg (eps gamma i) U a -> C (indIndex (eps gamma i) U a v) (ind (eps gamma i) U a v) \end{code} We need, for |a' = rgArgs gamma Ugg i a| \begin{code} ih : IndHyp gamma Ugg C a' = (v : IndArg gamma U a') -> C (indIndex gamma U a' v) (ind gamma U a' v) \end{code} Our intuition is that |eps| does not change the inductive occurrences in any way, and indeed we can prove the following lemma: \begin{lemma} \label{lem-eps-ind} For any closed |gamma|, and |a : Args (eps gamma i) U| and |v : IndArg (eps gamma i) U a| the following equalities hold definitionally. \begin{code} IndArg gamma U (rgArgs gamma U i a) = IndArg (eps gamma i) U a indIndex gamma U (rgArgs gamma U i a) v = indIndex (eps gamma i) U a v ind gamma U (rgArgs gamma U i a) v = ind (eps gamma i) U a v IndHyp gamma U C (rgArgs gamma U i a) = IndHyp (eps gamma i) U C a indHyp gamma U C g (rgArgs gamma U i a) = indHyp (eps gamma i) U C g a \end{code} \end{lemma} %format lem_epsInd = "\ref{lem-eps-ind}" \begin{proof} The first three are proven by induction on |gamma|. The last two follows from the first three. \end{proof} That is, we can use the induction hypothesis we have as it is. Let us now try to define the elimination rule. We are given \begin{code} C : (i : I) -> Ugg i -> Set step : (a : Args gamma Ugg) -> IndHyp gamma Ugg C a -> C (index gamma Ugg a) (introgg a) i : I u : Ugg i \end{code} and we have to prove |C i u|. To apply the restricted elimination rule (|elimUreg|) we need an induction step |stepr| of type \begin{code} (i : I)(a : Args (eps gamma i) Ugg) -> IndHyp (eps gamma i) Ugg C a -> C i (intror i a) \end{code} As we have observed the induction hypothesis already has the right type, so we attempt to define \begin{code} stepr i a ih = step (rgArgs gamma Ugg i a) ih \end{code} The type of |stepr i a ih| is |C (index gamma U ar) (intror (grArgs gamma U ar))|, where |ar = rgArgs gamma Ugg i a|. Here, we would like the conversion of a constructor argument from the restricted representation to a generalised argument and back to be the definitional identity. It is easy to see that this is not the case. For instance, in our |Even| example the argument to the |evenZ'| constructor is a proof |p : zero == zero|. Converting to a generalised argument we throw away the proof, and converting back we add a proof by reflexivity. But |p| and |refl| are not definitionally equal. Fortunately they are provably equal, so we can define the following substitution function: \begin{code} rgArgssubst : (gamma : OPg I)(U : I -> Set) (C : (i : I) -> rArgs (eps gamma) U i -> Set) (i : I)(a : rArgs (eps gamma) U i) -> (C (index gamma U (rgArgs gamma U i a)) (grArgs gamma U (rgArgs gamma U i a)) ) -> C i a rgArgssubst (iota i) U C j < p, star > m = elimId i (\ k q. C k < q, star >) m j p rgArgssubst (delta A gamma) U C j < a, b > m = rgArgssubst (gamma a) U (\ i c. C i < a, c >) j b m rgArgssubst (delta H i gamma) U C j < g, b > m = rgArgssubst gamma U (\ i c. C i < g, c >) j b m \end{code} The interesting case is the |iota|-case where we have to prove |C j | given |C i | and |p : i == j|. This is proven using the elimination rule, |elimId|, for the identity type. Armed with this substitution rule we can define the elimination rule for a generalised IID: \begin{code} elimUgg C step i u = elimUreg C stepr i u where stepr i a ih = rgArgssubst gamma Ugg (\ i a. C i (intror i a)) i a (step (rgArgs gamma Ugg i a) ih) \end{code} \end{proof} In our example the definition of the elimination rule is \begin{code} elim_Even : (C : (n : Nat) -> Even n -> Set) -> C zero evenZ -> ( (n : Nat)(e : Even n) -> C n e -> C (suc (suc n)) (evenSS n e)) -> (n : Nat)(e : Even n) -> C n e elim_Even C cz css n (evenZ' p) = elimId zero (\ m q. C m (evenZ' q)) cz n p elim_Even C cz css n (evenSS' m e p) = elimId (suc (suc m)) (\ z q. C z (evenSS' m e q)) (css m e (elim_Even C cz css m e)) n p \end{code} To improve readability we present the rule using pattern matching and explicit recursion rather than calling |elim_Even'|. The call to |rgArgssubst| is has been reduced to identity proof eliminations. \subsection{Computation rule} So far we have shown that we can represent generalised IID as a restricted IID and that the elimination rule is still valid. The only thing remaining is to show that the computation rule is also valid. That is, that we get the same definitional equalities for our representation as we would if we extended our system with generalised IID. \begin{theorem} For the representation of generalised IID given above, and the encoding of the elimination rule |elimUgg| the following computation rule holds definitionally for closed |gamma|: \begin{code} elimUgg C step (index γ Ugg a) (introgg a) = step a (indHyp γ Ugg C (elimUgg C step) a) \end{code} \end{theorem} \begin{proof} The key insight here is that the computation rule does not talk about arbitrary elements of |Ugg|, but only those that have been constructed using the introduction rule. This means that we do not have to satisfy any definitional equalities for elements where the equality proof is not definitionally equal to |refl|. So, the main step in the proof is to prove that |rgArgssubst| is the definitional identity when the equality proof is |refl|, i.e. when the argument is build using the |grArgs| function. \begin{lemma} \label{lem-rgArgsubst} For all closed |gamma|, and all |U|, |C|, |a : Args gamma U|, and \begin{code} h : C (index gamma U arg) (grArgs gamma U arg) \end{code} where \begin{code} ar = grArgs gamma U a i = index gamma U a arg = rgArgs gamma U i ar \end{code} it holds definitionally that \begin{code} rgArgssubst gamma U C i ar h = h \end{code} \end{lemma} %format lem_rgArgsubst = "\ref{lem-rgArgsubst}" \begin{proof} By induction on |gamma|. In the |iota|-case we have to prove that \begin{code} elimId i C' h i refl = h \end{code} which is exactly the computation rule for the identity type. \end{proof} The final lemma we need before proving the computation rule is that starting with a generalised constructor argument, converting it to a restricted one, and then back is the definitional identity. This amounts to adding a reflexivity proof and then removing it, so it is easy to see that this should be true. \begin{lemma} \label{lem-arg-is-a} For all closed |gamma|, and all |a : Args gamma U| it holds definitionally that > rgArgs gamma U (index gamma U a) (grArgs gamma U a) = a \end{lemma} %format lem_argIsa = "\ref{lem-arg-is-a}" \begin{proof} By induction on |gamma|. \end{proof} Now we are ready to prove the computation rule. Take |a : Args gamma Ugg| and let \begin{code} i = index gamma Ugg a ar = grArgs gamma Ugg a arg = rgArgs gamma Ugg i ar \end{code} we have \begin{code} elimUgg C step (index gamma Ugg a) (introgg a) = elimUgg C step i (introgg a) = {definition of_ elimUgg and introrg} elimUreg C stepr i (introreg i ar) = {computation rule for Ureg} stepr i ar (indHyp (eps gamma i) Ugg C (elimUgg C step) ar) = {definition of_ stepr} rgArgssubst gamma Ugg (\ i a. C i (intror i ar)) i ar (step arg (indHyp (eps gamma i) Ugg C (elimUgg C step) ar)) = {Lemma lem_rgArgsubst} step arg (indHyp (eps gamma i) Ugg C (elimUgg C step) ar) = {Lemma lem_epsInd} step arg (indHyp gamma Ugg C (elimUgg C step) arg) = {Lemma lem_argIsa} step a (indHyp gamma Ugg C (elimUgg C step) a) \end{code} \end{proof} In the example of |Even| the proofs of the computation rules are \begin{code} elim_Even C cz css zero evenZ = elim_Even C cz css zero (evenZ' refl) = elimId zero (\ m q. C m (evenZ' q)) cz zero refl = cz elim_Even C cz css (suc (suc m)) (evenSS m p) = elim_Even C cz css (suc (suc m)) (evenSS' m p refl) = elimId (suc (suc m)) (\ z q. C z (evenSS' m e q)) (css m e (elim_Even C cz css m e)) (suc (suc m)) refl = css m e (elim_Even C cz css m e) \end{code} The important steps are the appeals to the computation rule for the identity type. This concludes the proof that we can faithfully represent generalised IID in the theory of restricted IID and the intensional identity type. \section{Notes on the formal proof} \label{sec-formal} One approach to formalise our result would be to do a deep embedding, formalising the logical framework and the theory of restricted IID in Agda, and prove our theorems for this formalisation. This would be a big undertaking, however, so we chose a more light-weight approach. In Agda we can define the rules for restricted IID directly, that is, we can define restricted IID as a datatype in Agda and get the introduction, elimination, and computation rules for free. Using this definition of restricted IID we can then prove the formation, introduction, and elimination rules for the representation of generalised IID. When we want to prove the computation rule, however, there is a problem. The computation rule talks about definitional equality and in Agda we cannot reason about the internal definitional equality. To solve this problem we axiomatised the definitional equality of the logical framework. That is, for each |A, B : Set| we introduce a constant \begin{code} ! = ! : A -> B -> Set \end{code} and axioms corresponding to the conversion rules of the logical framework. For instance, for all |f|, |g|, |x|, and |y| \begin{code} app : (f = g) -> (x = y) -> (f x = g y) \end{code} In this axiom, we can see why the definitional equality has type |A -> B -> Set|: since |f| and |g| can be dependent functions, |f x| and |g y| can have different types. With this approach one has to be careful with induction. For instance, if one proves by induction on |n| that |n + zero = n|, this only holds definitionally for closed |n|. In our case the only induction is over codes |gamma| and we always assume |gamma| to be closed. The formalisation can be downloaded from the author's webpage~\cite{norell:iird-formal}. \section{Conclusions} \label{sec-concl} We have shown that the theory of generalised indexed inductive definitions can be interpreted in the theory of restricted indexed inductive definitions extended with an intensional identity type. The informal proof presented here has been formalised in Agda using a light-weight approach where Agda is used both for the object language and the meta language. This result gives way of adding generalised IID to theories with only restricted IID, such as Agda, without having to extend the meta-theory. \bibliographystyle{abbrv} \bibliography{../../../../bib/pmgrefs,iird} \end{document} % vim: et