Library ExtLib.Generic.Data
Require Import Coq.Lists.List.
Require Import ExtLib.Data.Member.
Require Import ExtLib.Data.HList.
Require Import ExtLib.Generic.Func.
Require Import ExtLib.Data.Member.
Require Import ExtLib.Data.HList.
Require Import ExtLib.Generic.Func.
This module gives a representation of inductive types
Set Implicit Arguments.
Set Strict Implicit.
Fixpoint hlist_to_tuple ps (h : hlist (fun x : Type => x) ps) : asTuple ps :=
match h in hlist _ ps return asTuple ps with
| Hnil => tt
| Hcons x h => (x,hlist_to_tuple h)
end.
Inductive itype (ps : list Type) : Type :=
| Inj : Type -> itype ps
| Rec : hlist (fun x => x) ps -> itype ps
| Sum : itype ps -> itype ps -> itype ps
| Prod : itype ps -> itype ps -> itype ps
| Sig : forall T : Type, (T -> itype ps) -> itype ps
| Pi : forall T : Type, (T -> itype ps) -> itype ps
| Get : forall T : Type, member T ps -> (T -> itype ps) -> itype ps
| Unf : forall T : Type, member T ps -> T -> itype ps -> itype ps.
Definition Unit {ps} := @Inj ps unit.
Section denote.
Variable (ps : list Type).
Fixpoint itypeD (i : itype ps) {struct i}
: asFunc ps Type -> asFunc ps Type :=
match i return asFunc ps Type -> asFunc ps Type with
| Get pf f => fun F => @get ps _ _ pf (fun x => itypeD (f x) F)
| Inj _ T => fun _ => const T
| Rec h => fun F => const (applyF F (hlist_to_tuple h))
| @Sig _ t f => fun F =>
@under _ _ (fun App => @sigT t (fun x' => App _ (itypeD (f x') F)))
| @Pi _ t f => fun F =>
@under _ _ (fun App => forall x' : t, App _ (itypeD (f x') F))
| Sum a b => fun F => combine sum ps (itypeD a F) (itypeD b F)
| Prod a b => fun F => combine prod ps (itypeD a F) (itypeD b F)
| @Unf _ T pf v i => fun F =>
@get ps _ _ pf (fun x => combine prod _ (const (x = v : Type)) (replace pf v (itypeD i F)))
end%type.
End denote.
Section _match.
Variable ps : list Type.
Variable RecT : asFunc ps Type.
NOTE: Non-dependent
Fixpoint cases (i : itype ps) (k : asFunc ps Type -> asFunc ps Type)
{struct i} : asFunc ps Type :=
match i with
| Inj _ T => k (const T)
| Sum a b => combine prod ps (cases a k) (cases b k)
| Prod a b =>
cases a (fun A => cases b (fun B =>
under _ _ (fun App => App _ A -> App _ (k B))))
| Rec ps => k (const (applyF RecT (hlist_to_tuple ps)))
| @Get _ T m f => @get _ _ _ m (fun x => cases (f x) k)
| @Sig _ t f => @under _ _ (fun App => forall x' : t, (App _ (cases (f x') k)))
| @Pi _ t f => @under _ _ (fun App => @sigT t (fun x' => App _ (cases (f x') k)))
| @Unf _ T pf v i => replace pf v (cases i k)
end.
End _match.
Fixpoint asPiE ps {struct ps}
: forall (F : _)
(G : forall x : (forall U, asFunc ps U -> U), F x),
asPi ps F :=
match ps as ps
return forall F : (forall U : Type, asFunc ps U -> U) -> Type,
(forall x : forall U : Type, asFunc ps U -> U, F x) -> asPi ps F
with
| nil => fun _ G => G _
| p :: ps => fun _ G => fun x => asPiE _ _ (fun x' => G _)
end.
Fixpoint asPi_combine ps {struct ps}
: forall (F G : _),
asPi ps (fun App => F App -> G App) ->
asPi ps F -> asPi ps G :=
match ps as ps
return forall F G : (forall U : Type, asFunc ps U -> U) -> Type,
asPi ps (fun App : forall U : Type, asFunc ps U -> U => F App -> G App) ->
asPi ps F -> asPi ps G
with
| nil => fun _ _ a b => a b
| p :: ps => fun _ _ a b x => asPi_combine _ _ _ (a x) (b x)
end.
{struct i} : asFunc ps Type :=
match i with
| Inj _ T => k (const T)
| Sum a b => combine prod ps (cases a k) (cases b k)
| Prod a b =>
cases a (fun A => cases b (fun B =>
under _ _ (fun App => App _ A -> App _ (k B))))
| Rec ps => k (const (applyF RecT (hlist_to_tuple ps)))
| @Get _ T m f => @get _ _ _ m (fun x => cases (f x) k)
| @Sig _ t f => @under _ _ (fun App => forall x' : t, (App _ (cases (f x') k)))
| @Pi _ t f => @under _ _ (fun App => @sigT t (fun x' => App _ (cases (f x') k)))
| @Unf _ T pf v i => replace pf v (cases i k)
end.
End _match.
Fixpoint asPiE ps {struct ps}
: forall (F : _)
(G : forall x : (forall U, asFunc ps U -> U), F x),
asPi ps F :=
match ps as ps
return forall F : (forall U : Type, asFunc ps U -> U) -> Type,
(forall x : forall U : Type, asFunc ps U -> U, F x) -> asPi ps F
with
| nil => fun _ G => G _
| p :: ps => fun _ G => fun x => asPiE _ _ (fun x' => G _)
end.
Fixpoint asPi_combine ps {struct ps}
: forall (F G : _),
asPi ps (fun App => F App -> G App) ->
asPi ps F -> asPi ps G :=
match ps as ps
return forall F G : (forall U : Type, asFunc ps U -> U) -> Type,
asPi ps (fun App : forall U : Type, asFunc ps U -> U => F App -> G App) ->
asPi ps F -> asPi ps G
with
| nil => fun _ _ a b => a b
| p :: ps => fun _ _ a b x => asPi_combine _ _ _ (a x) (b x)
end.
Some Examples Vectors