123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095 |
- \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 |<a, b>| 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, b> = a| and |pi1 <a, b> = b| and the
- |eta|-rule |<pi0 p, pi1 p> = 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 |<x, refl x>|.
- \begin{code}
- uniqE : (x, y : A)(p : x == y) -> <x, refl x> == <y, p>
- uniqE = elim_ML (\ x y p. <x, refl x> == <y, p>) refl
- \end{code}
- Finally
- \begin{code}
- elim_P x C h y p = subst (\ z. C (pi0 z) (pi1 z))
- <x, refl x> <y, p> (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 <x, a> = 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 ! <star0, star>
- suc n = introrgn star ! <star1, < \ x. n, 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 <p, star>|
- given |C i <refl, star>| 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
|