1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
Require Import Coq.Lists.List.
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.
(*
Section _mmatch.
Variable ps : list Type.
Variable RecT : asFunc ps Type.
Fixpoint Fmatch (i : itype ps) (Ret : asFunc ps Type)
(brs : asPi ps (fun App => App _ (cases RecT i (fun x => combine (fun x y => x -> y) _ x Ret))))
{struct i}
: asPi ps (fun App => App _ (itypeD i RecT) -> App _ Ret).
destruct i.
{ simpl in *. revert brs.
unfold combine.
apply asPi_combine.
apply asPiE.
intro. intro.
destruct i.
{ simpl in *.
Abort.
*)
(** Some Examples **)
(** Vectors **)
(*
Definition rfvec T : itype ((nat : Type) :: nil) :=
@Get ((nat : Type) :: @nil Type) nat (MZ _ _)
(fun x =>
match x with
| 0 => Inj _ unit
| S n => Prod (Inj _ T) (Rec (Hcons n Hnil))
end).
Definition rfvec' T : itype ((nat : Type) :: nil) :=
Sum (@Get ((nat : Type) :: @nil Type) nat (MZ _ _)
(fun x => Inj _ (x = 0)))
(@Get ((nat : Type) :: @nil Type) nat (MZ _ _)
(fun x => Sig (fun n : nat => Prod (Inj _ T) (Prod (Rec (Hcons n Hnil)) (Inj _ (x = S n)))))).
Definition rfvec'' T : itype ((nat : Type) :: nil) :=
Sum (Unf (MZ _ _) 0 Unit)
(Sig (fun n : nat =>
(Unf (MZ _ _) (S n) (Prod (Inj _ T) (Rec (Hcons n Hnil)))))).
Eval simpl in fun T => itypeD (rfvec T).
Eval simpl in fun T => itypeD (rfvec' T).
Eval simpl in fun T => itypeD (rfvec'' T).
Eval simpl in fun T Result Rec =>
@cases _ Rec (rfvec T) (fun x => combine (fun x y => x -> y) _ x Result).
Eval simpl in fun T Result Rec =>
@cases _ Rec (rfvec' T) (fun x => combine (fun x y => x -> y) _ x Result).
Eval simpl in fun T Result Rec =>
@cases _ Rec (rfvec'' T) (fun x => combine (fun x y => x -> y) _ x Result).
(** Nats **)
Definition rfnat := Sum (Inj nil unit) (Rec Hnil).
Eval simpl in fun Result Rec =>
@Tmatch _ Rec rfnat (fun x => combine (fun x y => x -> y) _ x Result).
Definition inat :=
Eval simpl in itypeD rfnat.
Definition i0 : inat :=
@existT bool (fun x' => itypeD nil (if x' then Inj nil unit else Rec nil Hnil)
nat) true tt.
Definition iS : nat -> inat :=
@existT bool (fun x' => itypeD nil (if x' then Inj nil unit else Rec nil Hnil)
nat) false.
Definition fold (i : nat) : inat :=
match i with
| 0 => i0
| S n => iS n
end.
Definition unfold (i : inat) : nat :=
match i with
| existT true _ => 0
| existT false x => S x
end.
Theorem fold_unfold : forall x, fold (unfold x) = x.
Proof.
destruct x; simpl.
destruct x; simpl.
{ simpl in *. destruct i. reflexivity. }
{ simpl in *. reflexivity. }
Qed.
Theorem unfold_fold : forall x, unfold (fold x) = x.
Proof.
destruct x; simpl; reflexivity.
Qed.
*)
|