Agda-2.3.2.2: examples/outdated-and-incorrect/iird/IIRD.agda
module IIRD where
open import LF
-- A code for an IIRD (captures both general and restricted IIRDs)
-- I - index set
-- D - return type of the recursive component
-- E - generalised return type of the recursive component (including the index)
-- for restricted IIRD E = D i for an external i
-- and for general IIRD E = (i : I) × D i
-- The intuition is that restricted IIRD are parameterised over the index,
-- whereas general IIRD compute their indices.
data OP (I : Set)(D : I -> Set1)(E : Set1) : Set1 where
-- Nullary constructor, contains the result of the recursive component
ι : E -> OP I D E
-- Non-recursive argument A, following arguments may depend on this argument.
-- To code multi-constructor datatypes, the first argument is the name of the
-- constructor and γ does the appropriate case-split on the name.
σ : (A : Set)(γ : A -> OP I D E) -> OP I D E
-- Recursive argument
-- A - assumptions, for instance lim : (Nat -> Ord) -> Ord, where A = Nat
-- i - the index of the inductive occurrence
-- γ - the rest of the arguments, may depend on the result of calling the
-- recursive function on the inductive argument
δ : (A : Set)(i : A -> I)(γ : ((a : A) -> D (i a)) -> OP I D E) -> OP I D E
-- Helper function. The definition is simple, but the type is not.
_«_×_» : {A B : Set}{C : B -> Set}{D : B -> Set1}
(f : (b : B) -> C b -> D b)
(g : A -> B)(h : (a : A) -> C (g a)) ->
(a : A) -> D (g a)
f « g × h » = \a -> f (g a) (h a)
-- The type of constructor arguments. Parameterised over
-- U - the inductive type
-- T - the recursive function
-- This is the F of the simple polynomial type μF
Ku : {I : Set}{D : I -> Set1}{E : Set1} -> OP I D E ->
(U : I -> Set)(T : (i : I) -> U i -> D i) -> Set
Ku (ι e) U T = One
Ku (σ A γ) U T = A × \a -> Ku (γ a) U T
Ku (δ A i γ) U T = ((a : A) -> U (i a)) × \g -> Ku (γ (T « i × g »)) U T
-- The recursive function. As with Ku this is only the top-level structure.
-- To get the real function there is a recursive knot to be tied.
Kt : {I : Set}{D : I -> Set1}{E : Set1}
(γ : OP I D E)(U : I -> Set)(T : (i : I) -> U i -> D i) ->
Ku γ U T -> E
Kt (ι e) U T ★ = e
Kt (σ A γ) U T < a | b > = Kt (γ a) U T b
Kt (δ A i γ) U T < g | b > = Kt (γ (T « i × g »)) U T b
-- The assumptions of a particular inductive occurrence in a value.
KIArg : {I : Set}{D : I -> Set1}{E : Set1}
(γ : OP I D E)(U : I -> Set)(T : (i : I) -> U i -> D i) ->
Ku γ U T -> Set
KIArg (ι e) U T ★ = Zero
KIArg (σ A γ) U T < a | b > = KIArg (γ a) U T b
KIArg (δ A i γ) U T < g | b > = A + KIArg (γ (T « i × g »)) U T b
-- Given the assumptions of an inductive occurence in a value we can compute
-- its index.
KIArg→I : {I : Set}{D : I -> Set1}{E : Set1}
(γ : OP I D E)(U : I -> Set)(T : (i : I) -> U i -> D i) ->
(a : Ku γ U T) -> KIArg γ U T a -> I
KIArg→I (ι e) U T ★ ()
KIArg→I (σ A γ) U T < a | b > c = KIArg→I (γ a) U T b c
KIArg→I (δ A i γ) U T < g | b > (inl a) = i a
KIArg→I (δ A i γ) U T < g | b > (inr a) = KIArg→I (γ (T « i × g »)) U T b a
-- Given the assumptions of an inductive occurrence in a value we can compute
-- its value.
KIArg→U : {I : Set}{D : I -> Set1}{E : Set1}
(γ : OP I D E)(U : I -> Set)(T : (i : I) -> U i -> D i) ->
(a : Ku γ U T)(v : KIArg γ U T a) -> U (KIArg→I γ U T a v)
KIArg→U (ι e) U T ★ ()
KIArg→U (σ A γ) U T < a | b > c = KIArg→U (γ a) U T b c
KIArg→U (δ A i γ) U T < g | b > (inl a) = g a
KIArg→U (δ A i γ) U T < g | b > (inr a) = KIArg→U (γ (T « i × g »)) U T b a
-- The type of induction hypotheses. Basically
-- forall assumptions, the predicate holds for an inductive occurrence with
-- those assumptions
KIH : {I : Set}{D : I -> Set1}{E : Set1}
(γ : OP I D E)(U : I -> Set)(T : (i : I) -> U i -> D i) ->
(F : (i : I) -> U i -> Set1)(a : Ku γ U T) -> Set1
KIH γ U T F a = (v : KIArg γ U T a) -> F (KIArg→I γ U T a v) (KIArg→U γ U T a v)
-- If we can prove a predicate F for any values, we can construct the inductive
-- hypotheses for a given value.
-- Termination note: g will only be applied to values smaller than a
Kmap : {I : Set}{D : I -> Set1}{E : Set1}
(γ : OP I D E)(U : I -> Set)(T : (i : I) -> U i -> D i) ->
(F : (i : I) -> U i -> Set1)
(g : (i : I)(u : U i) -> F i u)
(a : Ku γ U T) -> KIH γ U T F a
Kmap γ U T F g a = \v -> g (KIArg→I γ U T a v) (KIArg→U γ U T a v)
-- Things needed for general IIRD
OPg : (I : Set)(D : I -> Set1) -> Set1
OPg I D = OP I D (I ×' D)
Gu : {I : Set}{D : I -> Set1}(γ : OPg I D)(U : I -> Set)(T : (i : I) -> U i -> D i) -> Set
Gu γ U T = Ku γ U T
Gi : {I : Set}{D : I -> Set1}(γ : OPg I D)(U : I -> Set)(T : (i : I) -> U i -> D i)
(a : Gu γ U T) -> I
Gi γ U T a = π₀' (Kt γ U T a)
Gt : {I : Set}{D : I -> Set1}(γ : OPg I D)(U : I -> Set)(T : (i : I) -> U i -> D i)
(a : Gu γ U T) -> D (Gi γ U T a)
Gt γ U T a = π₁' (Kt γ U T a)
-- Things needed for restricted IIRD
OPr : (I : Set)(D : I -> Set1) -> Set1
OPr I D = (i : I) -> OP I D (D i)
Hu : {I : Set}{D : I -> Set1}
(γ : OPr I D)(U : I -> Set)(T : (i : I) -> U i -> D i)
(i : I) -> Set
Hu γ U T i = Ku (γ i) U T
Ht : {I : Set}{D : I -> Set1}
(γ : OPr I D)(U : I -> Set)(T : (i : I) -> U i -> D i)
(i : I)(a : Hu γ U T i) -> D i
Ht γ U T i a = Kt (γ i) U T a