Combined code flattening and allocation explicitation |
Require
Import
Arith Bool Eqdep List TheoryList.
Require
Import
LambdaTamer.ListUtil.
Require
Import
LambdaTamer.LambdaTamer.
Require
Import
LambdaTamer.Tactics.
Require
Import
CTPC.Continuation.
Require
Import
CTPC.CC.
Require
Import
CTPC.AllocMonad.
Require
Import
CTPC.Trace.
Require
Import
CTPC.Alloc.
Set Implicit
Arguments.
Generic syntactic functions and their soundness proofs |
Definition
insert t G (lin : alinear (t :: G) tt) t' : alinear (t :: t' :: G) tt :=
Alinear.lift' (t :: nil) G lin t'.
Lemma
insert_sound : forall G t t' (lin : alinear (t :: G) tt)
(s : Subst atyDenote G)
(x : atyDenote t') (x0 : atyDenote t),
alinearDenote (insert lin t') (SCons t x0 (SCons t' x s)) =
alinearDenote lin (SCons t x0 s).
Implicit
Arguments insert [t G].
Hint
Resolve AlinearDenote.lift_sound insert_sound.
Auxiliary syntactic types |
Inductive
aprimopB : list aty -> aty -> Set :=
| AFinal : forall G t,
aprimop G t
-> aprimopB G t
| ABindB : forall G t' t,
aprimop G t'
-> aprimopB (t' :: G) t
-> aprimopB G t.
Fixpoint
aprimopBDenote (G : list aty) (t : aty) (opB : aprimopB G t) {struct opB}
: Subst atyDenote G -> aprimopTy t :=
match opB in (aprimopB G t) return (Subst atyDenote G -> aprimopTy t) with
| AFinal _ _ op => aprimopDenote op
| ABindB _ _ _ op opB' => fun s =>
v <- aprimopDenote op s;
aprimopBDenote opB' (SCons _ v s)
end.
Fixpoint
splice (G : list aty) (t : aty) (opB : aprimopB G t) {struct opB}
: alinear (t :: G) tt -> alinear G tt :=
match opB in (aprimopB G t) return (alinear (t :: G) tt -> alinear G tt) with
| AFinal _ _ op => ABind op
| ABindB _ _ _ op opB' => fun lin => ABind op (splice opB' (insert lin _))
end.
Theorem
splice_sound : forall (G : list aty) (t : aty) (opB : aprimopB G t)
(lin : alinear (t :: G) tt) s st P,
allocSpec st
(v <- aprimopBDenote opB s;
alinearDenote lin (SCons _ v s)) P
-> allocSpec st (alinearDenote (splice opB lin) s) P.
A nested-type-friendly induction principle for ctys |
Section
Induction.
Variable
P : cty -> Prop.
Variable
P' : ctys -> Prop.
Hypothesis
P_Nat : P CNat.
Hypothesis
P_Cont : forall ts, P' ts -> P (CCont ts).
Hypothesis
P_Prod : forall ts, P' ts -> P (CProd ts).
Hypothesis
P_Code : forall ctx ts, P' ctx -> P' ts -> P (CCode ctx ts).
Hypothesis
P'_nil : P' nil.
Hypothesis
P'_cons : forall t ts, P t -> P' ts -> P' (t :: ts).
Fixpoint
cty_ind' (t : cty) : P t :=
match t return (P t) with
| CNat => P_Nat
| CCont ts =>
P_Cont ((fix ctys_ind' (ts : ctys) : P' ts :=
match ts return (P' ts) with
| nil => P'_nil
| t :: ts' => P'_cons (cty_ind' t) (ctys_ind' ts')
end) ts)
| CProd ts =>
P_Prod ((fix ctys_ind' (ts : ctys) : P' ts :=
match ts return (P' ts) with
| nil => P'_nil
| t :: ts' => P'_cons (cty_ind' t) (ctys_ind' ts')
end) ts)
| CCode ctx ts =>
P_Code ((fix ctys_ind' (ts : ctys) : P' ts :=
match ts return (P' ts) with
| nil => P'_nil
| t :: ts' => P'_cons (cty_ind' t) (ctys_ind' ts')
end) ctx)
((fix ctys_ind' (ts : ctys) : P' ts :=
match ts return (P' ts) with
| nil => P'_nil
| t :: ts' => P'_cons (cty_ind' t) (ctys_ind' ts')
end) ts)
end.
End
Induction.
Type translation |
Fixpoint
allocTy (t : cty) : aty :=
match t with
| CNat => ANat
| CCont _ => ARef
| CProd _ => ARef
| CCode _ args =>
ACode (ARef :: (fix allocTys (ts : ctys) : atys :=
match ts with
| nil => nil
| t :: ts' => allocTy t :: allocTys ts'
end) args)
end.
Fixpoint
allocTys (ts : ctys) : atys :=
match ts with
| nil => nil
| t :: ts' => allocTy t :: allocTys ts'
end.
Term translation |
Fixpoint
isLarges' (ts : ctys) : bool :=
match ts with
| nil => true
| t :: s => negb (isSmall' t) && isLarges' s
end.
Definition
isLarges ts := isLarges' ts = true.
Theorem
negb_true_intro : forall b,
b = false
-> negb b = true.
Theorem
negb_prop : forall b,
negb b = true
-> b = false.
Ltac
bool_simpl :=
repeat (match goal with
| [ H : _ |- _ ] =>
(generalize (andb_prop _ _ H)
|| generalize (orb_prop _ _ H)
|| generalize (negb_prop _ H));
clear H; intro H
end
|| apply andb_true_intro
|| apply orb_true_intro
|| apply negb_true_intro).
Ltac
simplify := repeat progress (simpl in *; intuition; bool_simpl).
Definition
allocVar' : forall (G fns : list cty) (t : cty) (x : Var (G ++ fns) t),
isLarges fns -> isSmall t -> Var G t.
Definition
allocVar : forall (G : list cty) (t : cty) (x : Var G t),
forall G' fns, G = G' ++ fns
-> isLarges fns -> isSmall t -> Var G' t.
Definition
allocArgs (G : list cty) (ts : ctys) (args : cargs G ts)
: isSmalls ts
-> forall G' fns, G = G' ++ fns -> isLarges fns
-> aargs (map allocTy G') (allocTys ts).
Fixpoint
allocProj (G : list cty) (pt : cprojTy) (p : cproj G pt) {struct p}
: nat :=
match p with
| CPFst _ _ _ => O
| CPSnd _ _ _ _ p' => S (allocProj p')
end.
Lemma
isSmall'_obvious : forall t : smallCty,
isSmall' (proj1_sig t) = true.
Hint
Resolve isSmall'_obvious.
Lemma
isSmall_obvious : forall t : smallCty,
isSmall (proj1_sig t).
Hint
Resolve isSmall_obvious.
Lemma
isSmalls_obvious : forall ctx : smallCtys,
isSmalls (proj1_sig ctx).
Hint
Resolve isSmalls_obvious.
Lemma
isSmalls_nil : isSmalls nil.
Hint
Resolve isSmalls_nil.
Hint
Unfold isSmall.
Section
allocCode.
Variable
allocCode : forall (G : list cty) (t : cty) (x : Var G t), nat.
Definition
allocPrimop (G : list cty) (t : cty) (op : cprimop G t)
: forall G' fns, G = G' ++ fns
-> isLarges fns
-> aprimopB (map allocTy G') (allocTy t).
Definition
allocLinear (G : list cty) (t : unit) (lin : clinear G t)
: forall G' fns, G = G' ++ fns
-> isLarges fns
-> alinear (map allocTy G') tt.
End
allocCode.
Fixpoint
allocCode (G : list cty) (t : cty) (x : Var G t) {struct x} : nat :=
match x with
| First G _ => length G
| Next _ _ _ x' => allocCode x'
end.
Definition
allocFunc (G : list cty) (ts : ctys) (f : cfunc G ts)
: forall G' fns, G = G' ++ fns
-> isLarges fns
-> afunc (map allocTy G') (allocTys ts).
Definition
getLarge (t : cty) (Ht : ~isSmall t) : ctys.
Definition
allocFuncTys (ts : ctys)
: isLarges ts -> list atys.
Definition
allocFuncs (G : list cty) (ts : ctys) (fs : cfuncs G ts)
: isLarges G
-> forall (Hts : isLarges ts),
listI (afunc nil) (allocFuncTys Hts).
Lemma
cfuncs_larges : forall (G : list cty) (ts : ctys) (fs : cfuncs G ts),
isLarges ts.
Definition
allocProg (G : list cty) (p : cprog G tt) : aprog (map allocTy G) :=
Build_aprog
(allocFuncTys (cfuncs_larges (cDefs p)))
(allocFuncs (cDefs p) (refl_equal _) (cfuncs_larges (cDefs p)))
(allocLinear (fun _ _ x => length (cFns p) - S (allocCode x)) (cBody p) G (refl_equal _) (cfuncs_larges (cDefs p))).
Logical relations |
Section
Traces.
Variable
Gpr : list cty.
Variable
pr : cprog Gpr tt.
Fixpoint
val_lr (st : mem adom) (t : cty) {struct t} : ctyDenote t -> atyDenote (allocTy t) -> Prop :=
match t return (ctyDenote t -> atyDenote (allocTy t) -> Prop) with
| CNat => fun n1 n2 => n1 = n2
| CProd ts => fun recd base =>
match nth_error st base with
| error => False
| value fds =>
(fix vals_lr (st : mem adom) (ts : ctys) {struct ts} : ctysDenote ts -> list adom -> Prop :=
match ts return (ctysDenote ts -> list adom -> Prop) with
| nil => fun _ fds =>
match fds with
| nil => True
| _ => False
end
| t :: ts' => fun recd fds =>
match fds with
| nil => False
| (tg, v2) :: fds' => tg = tagof (allocTy t) /\ val_lr st t (fst recd) v2 /\ vals_lr st ts' (snd recd) fds'
end
end) st ts recd fds
end
| CCode ctx args => fun f1 f2 =>
forall st' env1 args1 env2 args2,
match nth_error (st ++ st') env2 with
| error => False
| value fds =>
(fix vals_lr (st : mem adom) (ts : ctys) {struct ts} : ctysDenote ts -> list adom -> Prop :=
match ts return (ctysDenote ts -> list adom -> Prop) with
| nil => fun _ fds =>
match fds with
| nil => True
| _ => False
end
| t :: ts' => fun recd fds =>
match fds with
| nil => False
| (tg, v2) :: fds' => tg = tagof (allocTy t) /\ val_lr st t (fst recd) v2 /\ vals_lr st ts' (snd recd) fds'
end
end) (st ++ st') ctx env1 fds
/\ (fix vals_lr (st : mem adom) (ts : ctys) {struct ts} : ctysDenote ts -> list adom -> Prop :=
match ts return (ctysDenote ts -> list adom -> Prop) with
| nil => fun args1 args2 =>
match args2 with
| nil => True
| _ => False
end
| t :: ts' => fun args1 args2 =>
match args2 with
| nil => False
| (tg, arg2) :: args2' => tg = tagof (allocTy t) /\ val_lr st t (fst args1) arg2 /\ vals_lr st ts' (snd args1) args2'
end
end) (st ++ st') args args1 args2
end
-> runTrace (amakeTrace (allocProg pr) (st ++ st') f2 (ARef :: map allocTy args) ((Traced, env2) :: args2))
(f1 (env1, args1))
| CCont args => fun f1 closure =>
match nth_error st closure with
| value ((Untraced, f2) :: (Traced, env2) :: nil) =>
forall st' args1 args2,
(fix vals_lr (st : mem adom) (ts : ctys) {struct ts} : ctysDenote ts -> list adom -> Prop :=
match ts return (ctysDenote ts -> list adom -> Prop) with
| nil => fun args1 args2 =>
match args2 with
| nil => True
| _ => False
end
| t :: ts' => fun args1 args2 =>
match args2 with
| nil => False
| (tg, arg2) :: args2' => tg = tagof (allocTy t) /\ val_lr st t (fst args1) arg2 /\ vals_lr st ts' (snd args1) args2'
end
end) (st ++ st') args args1 args2
-> runTrace (amakeTrace (allocProg pr) (st ++ st') f2 (ARef :: map allocTy args) ((Traced, env2) :: args2))
(f1 args1)
| _ => False
end
end.
Fixpoint
vals_lr (st : mem adom) (ts : ctys) {struct ts} : ctysDenote ts -> list adom -> Prop :=
match ts return (ctysDenote ts -> list adom -> Prop) with
| nil => fun args1 args2 =>
match args2 with
| nil => True
| _ => False
end
| t :: ts' => fun args1 args2 =>
match args2 with
| nil => False
| (tg, arg2) :: args2' => tg = tagof (allocTy t) /\ val_lr st t (fst args1) arg2 /\ vals_lr st ts' (snd args1) args2'
end
end.
Hint
Constructors Subst_lr.
Definition
Subst_lr st := Subst_lr allocTy (val_lr st).
Hint
Unfold Subst_lr.
The soundness proofs |
Theorem
allocVar'_sound : forall (G fns : list cty) (t : cty) (x : Var (G ++ fns) t)
(Hfns : isLarges fns) (Ht : isSmall t) (s1 : Subst ctyDenote G) s1',
VarDenote (allocVar' _ x Hfns Ht) s1
= VarDenote x (appSubst s1 s1').
Theorem
allocVar_sound : forall (G : list cty) (t : cty) (x : Var G t)
G' fns (Heq : G = G' ++ fns)
(Hfns : isLarges fns) (Ht : isSmall t) (s1 : Subst ctyDenote G') s1',
VarDenote (allocVar x _ Heq Hfns Ht) s1
= VarDenote x (eq_rect _ (Subst ctyDenote) (appSubst s1 s1') _ (sym_eq Heq)).
Theorem
allocProj_sound : forall (G : list cty) (pt : cprojTy) (p : cproj G pt) st s fs1 fs2,
vals_lr st _ fs1 fs2
-> match nth_error fs2 (allocProj p) with
| error => False
| value (tg, v2) => tg = tagof (allocTy (ctChosen pt)) /\ val_lr st _ (cprojDenote p s fs1) v2
end.
Hint
Rewrite nth_error_grab nth_error_grab' nth_error_grab_last : Allocify.
Ltac
my_var_adder :=
repeat match goal with
| [ H : Subst_lr _ _ _ |- context[allocVar ?X ?G' ?Heq ?Hfns ?Ht] ] =>
match goal with
| [ H' : val_lr _ _ (VarDenote (allocVar X G' Heq Hfns Ht) _) _ |- _ ] => fail 1
| _ => generalize (Subst_lr_Var (allocVar X G' Heq Hfns Ht) H); intro
end
end.
Ltac
caseEq e := generalize (refl_equal e); pattern e at -1; case e.
Ltac
elim_match :=
match goal with
| [ H : match ?E with Some _ => _ | None => False end |- _ ] =>
let v := fresh "v" with Hv := fresh "Hv" in
(caseEq E; [intros v Hv; rewrite Hv in H
| intro Hv; rewrite Hv in H; tauto])
| [ H : match ?E with _ :: _ => _ | nil => False end |- _ ] =>
let hd := fresh "hd" with tl := fresh "tl" with Hls := fresh "Hls" in
(caseEq E; [intro Hls; rewrite Hls in H; tauto
| intros hd tl Hls; rewrite Hls in H])
| [ H : match ?E with _ :: _ => False | nil => _ end |- _ ] =>
let hd := fresh "hd" with tl := fresh "tl" with Hls := fresh "Hls" in
(caseEq E; [intro Hls; rewrite Hls in H
| intros hd tl Hls; rewrite Hls in H; tauto])
| [ H : AllS _ (_ :: _) |- _ ] => inversion H; clear H; subst
| [ H : context[match ?E with (_, _) => _ end] |- _ ] =>
destruct E; simpl in *
| [ H : context[match ?E with Traced => _ | Untraced => _ end] |- _ ] =>
destruct E; simpl in *
end.
Hint
Rewrite app_ass : Allocify.
Ltac
my_rewriter :=
repeat match goal with
| [ H : context[allocVar ?V _ ?PF ?Hfns ?Ht], s1 : Subst _ _, s1' : Subst _ _ |- _ ] =>
rewrite (allocVar_sound V PF Hfns Ht s1 s1') in H
| [ H : nth_error _ _ = Some ?x |- _ ] => rewrite (nth_error_monotone (x:= x)); trivial
| [ H : _ |- _ ] => rewrite app_ass in H
end;
autorewrite with Allocify.
Ltac
my_simpl := repeat progress (unfold withCont_bind, checkTag in *; fold vals_lr in *;
repeat elim_match;
try match goal with
| [ c : cproj _ _ , s1 : Subst _ _, s1' : Subst _ _, H0 : _ |- _ ] =>
generalize (allocProj_sound c _ (appSubst s1 s1') _ _ H0); clear H0
end;
allocM_solver;
try apply splice_sound).
Ltac
my_inster T k :=
match T with
| mem _ => fail 1
| list (list adom) => fail 1
| list cty => fail 1
| _ => default_inster T k
end.
Ltac
my_lr_tac := lr_tac my_var_adder my_inster ltac:(my_simpl; my_rewriter).
Theorem
val_lr_monotone : forall t st v1 v2,
val_lr st t v1 v2
-> forall st', val_lr (st ++ st') t v1 v2.
Hint
Resolve val_lr_monotone.
Theorem
vals_lr_monotone : forall ts st vs1 vs2,
vals_lr st ts vs1 vs2
-> forall st', vals_lr (st ++ st') ts vs1 vs2.
Hint
Resolve vals_lr_monotone.
Theorem
Subst_lr_monotone : forall st G (s1 : Subst ctyDenote G) s2,
Subst_lr st s1 s2
-> forall st', Subst_lr (st ++ st') s1 s2.
Hint
Resolve Subst_lr_monotone.
Theorem
allocVar_sound_lr : forall G' fns t st s1 s1' s2,
Subst_lr st s1 s2
-> forall (v : Var (G' ++ fns) t) Heq Hfns Ht,
val_lr st t (VarDenote v (appSubst s1 s1'))
(VarDenote
(VarConvert allocTy
(allocVar v G' (fns:= fns) Heq Hfns Ht))
s2).
Hint
Resolve allocVar_sound_lr.
Theorem
allocArgs_sound : forall G ts (args : cargs G ts)
(Hts : isSmalls ts)
G' fns (Heq : G = G' ++ fns)
(Hfns : isLarges fns)
s1 s1' s2 st, Subst_lr st s1 s2
-> vals_lr st ts
(cargsDenote args (eq_rect _ (Subst ctyDenote) (appSubst s1 s1') _ (sym_eq Heq)))
(aargsDenote (allocArgs args Hts _ Heq Hfns) s2).
Hint
Resolve allocArgs_sound.
Section
allocCode_soundness.
Variable
allocCode : forall (G : list cty) (t : cty) (x : Var G t), nat.
Variable
fns : list cty.
Variable
s1' : Subst ctyDenote fns.
Definition
allocCode_soundness := forall st (ctx : smallCtys) args G'
(s1 : Subst ctyDenote G')
(v : Var (G' ++ fns) (CCode (proj1_sig ctx) args))
env1 (args1 : ctysDenote args) env2 (args2 : list adom),
isSmalls G'
-> val_lr st (CProd (proj1_sig ctx)) env1 env2
-> vals_lr st args args1 args2
-> runTrace
(amakeTrace (allocProg pr) st (S (allocCode v)) (ARef :: allocTys args) ((Traced, env2) :: args2))
(VarDenote v (appSubst s1 s1') (env1, args1)).
End
allocCode_soundness.
Section
allocCode.
Definition
primop_lr G fns t (op1 : cprimop (G ++ fns) t) (op2 : aprimop (map allocTy G) (allocTy t)) :=
forall st s1 s1' s2, Subst_lr st s1 s2
-> allocSpec st (aprimopDenote op2 s2)
(fun st' v2 =>
val_lr st' t (cprimopDenote op1 (appSubst s1 s1')) v2).
Variable
allocCode : forall (G : list cty) (t : cty) (x : Var G t), nat.
Variable
fns : list cty.
Variable
s1' : Subst ctyDenote fns.
Hypothesis
allocCode_sound : forall st (ctx : smallCtys) args G'
(s1 : Subst ctyDenote G')
(v : Var (G' ++ fns) (CCode (proj1_sig ctx) args))
env1 (args1 : ctysDenote args) env2 (args2 : list adom),
isSmalls G'
-> val_lr st (CProd (proj1_sig ctx)) env1 env2
-> vals_lr st args args1 args2
-> runTrace
(amakeTrace (allocProg pr) st (S (allocCode v)) (ARef :: allocTys args) ((Traced, env2) :: args2))
(VarDenote v (appSubst s1 s1') (env1, args1)).
Lemma
mem_nil_end : forall (st : mem adom),
st = st ++ nil.
Hint
Resolve mem_nil_end.
Theorem
allocPrimop_sound : forall (G : list cty) (t : cty) (op : cprimop G t)
G' (Heq : G = G' ++ fns)
(Hfns : isLarges fns) st s1 s2,
isSmalls G'
-> Subst_lr st s1 s2
-> allocSpec st
(aprimopBDenote (allocPrimop allocCode op _ Heq Hfns) s2)
(fun st' v2 => val_lr st' t
(cprimopDenote op (eq_rect _ (Subst ctyDenote) (appSubst s1 s1') _ (sym_eq Heq))) v2
/\ exists st'', st' = st ++ st'').
Hint
Extern 1 (allocSpec _ (aprimopBDenote (allocPrimop _ ?op ?G' ?Heq ?Hfns) _) _) =>
match goal with
| [ H0 : isSmalls _, H : Subst_lr _ _ _ |- _ ] =>
apply (allocPrimop_sound op Heq Hfns H0 H)
end.
Hint
Rewrite AargsDenote.lift_sound : Allocify.
Lemma
Subst_lr_fold : forall st G (s1 : Subst ctyDenote G) s2,
Subst_lr st s1 s2
-> Binding.Subst_lr allocTy (val_lr st) s1 s2.
Hint
Resolve Subst_lr_fold.
Theorem
allocLinear_sound : forall (G : list cty) (t : unit) (lin : clinear G t)
G' (Heq : G = G' ++ fns)
(Hfns : isLarges fns) st s1 s2,
isSmalls G'
-> Subst_lr st s1 s2
-> allocSpec st
(alinearDenote (allocLinear allocCode lin _ Heq Hfns) s2)
(fun st' v2 =>
runTrace
(amakeTrace (allocProg pr) st' (fst (fst v2)) (snd (fst v2)) (snd v2))
(clinearDenote lin (eq_rect _ (Subst ctyDenote) (appSubst s1 s1') _ (sym_eq Heq)))).
End
allocCode.
Section
allocFunc_sound.
Variable
fns : list cty.
Variable
s1' : Subst ctyDenote fns.
Hypothesis
allocCode_sound : forall st (ctx : smallCtys) args G'
(s1 : Subst ctyDenote G')
(v : Var (G' ++ fns) (CCode (proj1_sig ctx) args))
env1 (args1 : ctysDenote args) env2 (args2 : list adom),
isSmalls G'
-> val_lr st (CProd (proj1_sig ctx)) env1 env2
-> vals_lr st args args1 args2
-> runTrace
(amakeTrace (allocProg pr) st (S (allocCode v)) (ARef :: allocTys args) ((Traced, env2) :: args2))
(VarDenote v (appSubst s1 s1') (env1, args1)).
Fixpoint
args_lr (st : mem adom) (ts : ctys) {struct ts} : ctysDenote ts -> aformalsDenote (map allocTy ts) -> Prop :=
match ts return (ctysDenote ts -> aformalsDenote (map allocTy ts) -> Prop) with
| nil => fun args1 args2 => True
| t :: ts' => fun args1 args2 =>
val_lr st t (fst args1) (fst args2) /\ args_lr st ts' (snd args1) (snd args2)
end.
Definition
func_lr (G : list cty) (ts : ctys) (f : cfunc (G ++ fns) ts) (af : afunc (map allocTy G) (map allocTy ts)) :=
forall args1 args2 st s1 s2,
Subst_lr st s1 s2
-> args_lr st _ args1 args2
-> allocSpec st
(afuncDenote af s2 args2)
(fun st' v2 =>
runTrace
(amakeTrace (allocProg pr) st' (fst (fst v2)) (snd (fst v2)) (snd v2))
(cfuncDenote f (appSubst s1 s1') args1)).
Theorem
allocFunc_sound : forall (G : list cty) (ts : ctys) (f : cfunc G ts)
G' (Heq : G = G' ++ fns)
(Hfns : isLarges fns),
isSmalls G'
-> func_lr _ (eq_rec _ (fun G => cfunc G ts) f _ Heq) (allocFunc f _ Heq Hfns).
End
allocFunc_sound.
Fixpoint
funcs_lr (G : list cty) (ts : ctys) (fs : cfuncs G ts) {struct fs}
: forall (Hts : isLarges ts), listI (afunc nil) (allocFuncTys Hts) -> Prop :=
match fs in (cfuncs G ts) return (forall (Hts : isLarges ts), listI (afunc nil) (allocFuncTys Hts) -> Prop) with
| CFNil _ => fun _ _ => True
| CFCons _ _ _ _ f fs' => fun Hts afs =>
(forall s1', allocCode_soundness allocCode s1' -> func_lr s1' nil f (headI afs))
/\ funcs_lr fs' _ (tailI afs)
end.
Theorem
allocFuncs_sound : forall (G : list cty) (ts : ctys) (fs : cfuncs G ts)
(HG : isLarges G) (Hts : isLarges ts),
funcs_lr fs _ (allocFuncs fs HG Hts).
Definition
prog_lr (G : list cty) (p1 : cprog G tt) (p2 : aprog (map allocTy G)) :=
forall st s1 s2, Subst_lr st s1 s2
-> runTrace (aprogDenote p2 s2 st) (cprogDenote p1 s1).
Fixpoint
nthFuncs (G : list cty) (ts : ctys) (fs : cfuncs G ts) (n : nat) {struct fs}
: option (sigS (fun G => sigS (cfunc G))) :=
match fs in (cfuncs G ts) return (option (sigS (fun G => sigS (cfunc G)))) with
| CFNil _ => None
| CFCons _ _ _ _ f fs' =>
match n with
| O => Some (existS (fun G => sigS (cfunc G)) _ (existS _ _ f))
| S n' => nthFuncs fs' n'
end
end.
Theorem
nthFuncs_larges : forall G ts (fs : cfuncs G ts) pc G' ts' f,
isLarges G
-> nthFuncs fs pc = Some (existS (fun G => sigS (cfunc G)) G' (existS _ ts' f))
-> isLarges G'.
Lemma
allocCode_bound : forall G t (v : Var G t),
allocCode v < length G.
Lemma
allocCode_nth : forall G fns (defs : cfuncs G fns) n,
n < length fns
-> exists sg,
nthFuncs defs n = Some sg.
Lemma
allocCode_nth_ts' : forall G fns (defs : cfuncs G fns)
ctx args (v : Var fns (CCode ctx args)),
exists pos, exists f,
nthFuncs defs (length fns - S (allocCode v))
= Some (existS (fun G => sigS (cfunc G)) (revAppN fns pos G)
(existS _ (CProd ctx :: args) f)).
Lemma
allocCode_nth_ts : forall G fns (defs : cfuncs G fns)
ctx args G' (v : Var (G' ++ fns) (CCode ctx args)),
isSmalls G'
-> exists pos, exists f,
nthFuncs defs (length fns - S (allocCode v))
= Some (existS (fun G => sigS (cfunc G)) (revAppN fns pos G)
(existS _ (CProd ctx :: args) f)).
Theorem
internal_nthI : forall G ts (fs : cfuncs G ts) pc G' ts' f
(HG : isLarges G)
(Hnth : nthFuncs fs pc = Some (existS (fun G => sigS (cfunc G)) G' (existS _ ts' f))),
nthI (allocFuncs fs HG (cfuncs_larges fs)) pc
= Some (existS (afunc nil) (allocTys ts')
(allocFunc f nil (refl_equal _) (nthFuncs_larges fs pc HG Hnth))).
Lemma
length_allocTys : forall ts,
length (allocTys ts) = length ts.
Lemma
length_args : forall st args (args1 : ctysDenote args) args2,
vals_lr st args args1 args2
-> length args = length args2.
Theorem
args_lr_vals_lr : forall st args
(args1 : ctysDenote args) (args2 : list adom) Hlen,
vals_lr st args args1 args2
-> args_lr st args args1
(makeActuals (allocTys args) args2 Hlen).
Hint
Resolve args_lr_vals_lr.
Lemma
nthFuncs_contra : forall G ts (defs : cfuncs G ts) pos sG,
nthFuncs defs pos = Some sG
-> length (projS1 sG) >= length G.
Theorem
allocCode_body_var' : forall G fns (defs : cfuncs G fns)
(ctx : smallCtys) args
(s : Subst ctyDenote G)
(v : Var fns (CCode (proj1_sig ctx) args))
pos (f : cfunc (revAppN fns pos G) (CProd (proj1_sig ctx) :: args)),
nthFuncs defs (length fns - S (allocCode v)) =
Some
(existS (fun G : list cty => sigS (cfunc G))
_ (existS _ (CProd (proj1_sig ctx) :: args) f))
-> VarDenote v (ctysSubst (cfuncsDenote defs s))
= cfuncDenote f
(revAppN_Subst
(ctysSubst (cfuncsDenote defs s)) pos
s).
Theorem
allocCode_body_var : forall G fns (defs : cfuncs G fns)
(ctx : smallCtys) args
(G' : list cty)
(s : Subst ctyDenote G)
(s1 : Subst ctyDenote G')
(v : Var (G' ++ fns) (CCode (proj1_sig ctx) args))
pos (f : cfunc (revAppN fns pos G) (CProd (proj1_sig ctx) :: args)),
isSmalls G'
-> nthFuncs defs (length fns - S (allocCode v)) =
Some
(existS (fun G : list cty => sigS (cfunc G))
(revAppN fns pos G)
(existS (cfunc (revAppN fns pos G))
(CProd (proj1_sig ctx) :: args) f))
-> VarDenote v
(appSubst s1
(ctysSubst (cfuncsDenote defs s)))
= cfuncDenote f
(revAppN_Subst
(ctysSubst (cfuncsDenote defs s)) pos
s).
Lemma
Var_app_split : forall ts ts' t
(v : Var (ts ++ ts') t),
allocCode v < length ts'
\/ exists v' : Var ts t,
allocCode v = length ts' + allocCode v'.
Lemma
Var_revAppN_split : forall pos ts t' t
(v : Var (revAppN ts pos (t' :: nil)) t),
(allocCode v = 0 /\ t' = t)
\/ exists v' : Var (revAppN ts pos nil) t,
allocCode v = S (allocCode v').
Lemma
allocCode_nth_revAppN' : forall G fns (defs : cfuncs G fns) pos
ctx args (v : Var (revAppN fns pos nil) (CCode ctx args)),
exists pos', exists f,
pos' < pos
/\ nthFuncs defs (allocCode v)
= Some (existS (fun G => sigS (cfunc G)) (revAppN fns pos' G)
(existS _ (CProd ctx :: args) f)).
Lemma
allocCode_nth_revAppN : forall G fns (defs : cfuncs G fns) pos
ctx args G' (v : Var (G' ++ revAppN fns pos nil) (CCode ctx args)),
isSmalls G'
-> exists pos', exists f,
pos' < pos
/\ nthFuncs defs (allocCode v)
= Some (existS (fun G => sigS (cfunc G)) (revAppN fns pos' G)
(existS _ (CProd ctx :: args) f)).
Lemma
allocCode_zero' : forall fns t
(v : Var (fns ++ t :: nil) t) x s,
allocCode v = 0
-> VarDenote v (appSubst s (SCons t x (SNil ctyDenote))) = x.
Lemma
allocCode_zero : forall fns pos t
(v : Var (revAppN fns pos (t :: nil)) t) x s,
allocCode v = 0
-> VarDenote v (revAppN_Subst s pos (SCons t x (SNil ctyDenote))) = x.
Lemma
allocCode_push' : forall G' s t t'
(v' : Var (G' ++ nil) t') (v : Var (G' ++ t :: nil) t') x,
allocCode v = S (allocCode v') ->
VarDenote v' (appSubst s (SNil ctyDenote)) =
VarDenote v (appSubst s (SCons t x (SNil ctyDenote))).
Lemma
allocCode_push : forall pos ts t t'
(v : Var (revAppN ts pos (t :: nil)) t')
(v' : Var (revAppN ts pos nil) t') x s,
allocCode v = S (allocCode v')
-> VarDenote v'
(revAppN_Subst s pos (SNil ctyDenote))
= VarDenote v (revAppN_Subst s pos
(SCons t x (SNil ctyDenote))).
Lemma
allocProg_funcs_var' : forall G fns (defs : cfuncs G fns)
pos' pos (ctx : smallCtys) args
(v : Var (revAppN fns (pos' + pos) nil) (CCode (proj1_sig ctx) args))
(f : cfunc (revAppN fns pos' G) (CProd (proj1_sig ctx) :: args)) s,
nthFuncs defs (allocCode v) =
Some
(existS (fun G : list cty => sigS (cfunc G))
(revAppN fns pos' G)
(existS (cfunc (revAppN fns pos' G))
(CProd (proj1_sig ctx) :: args) f))
-> cfuncDenote f
(revAppN_Subst
(ctysSubst (cfuncsDenote defs s))
pos' s) =
VarDenote v
(revAppN_Subst
(ctysSubst (cfuncsDenote defs s))
(pos' + pos) (SNil _)).
Lemma
allocProg_funcs_var : forall G fns (defs : cfuncs G fns)
pos' pos (ctx : smallCtys) args
(v : Var (revAppN fns pos nil) (CCode (proj1_sig ctx) args))
(f : cfunc (revAppN fns pos' G) (CProd (proj1_sig ctx) :: args)) s,
pos' < pos
-> nthFuncs defs (allocCode v) =
Some
(existS (fun G : list cty => sigS (cfunc G))
(revAppN fns pos' G)
(existS (cfunc (revAppN fns pos' G))
(CProd (proj1_sig ctx) :: args) f))
-> cfuncDenote f
(revAppN_Subst
(ctysSubst (cfuncsDenote defs s))
pos' s) =
VarDenote v
(revAppN_Subst
(ctysSubst (cfuncsDenote defs s))
pos (SNil _)).
Lemma
allocProg_funcs_soundness :
forall (posBound pos : nat), pos <= posBound
-> forall (st : mem adom) (ctx : smallCtys)
(args : list cty) G' (s1 : Subst ctyDenote G')
(v : Var (G' ++ revAppN (cFns pr) pos nil) (CCode (proj1_sig ctx) args))
(env1 : ctyDenote (CProd (proj1_sig ctx))) (args1 : ctysDenote args)
(env2 : atyDenote (allocTy (CProd (proj1_sig ctx))))
(args2 : list adom),
isSmalls G'
-> val_lr st (CProd (proj1_sig ctx)) env1 env2
-> vals_lr st args args1 args2
-> runTrace (amakeTrace (allocProg pr) st (S (allocCode v))
(ARef :: allocTys args) ((Traced, env2) :: args2))
(VarDenote v
(appSubst s1
(revAppN_Subst
(ctysSubst
(cfuncsDenote (cDefs pr) (SNil ctyDenote))) pos
(SNil ctyDenote))) (env1, args1)).
Theorem
allocProg_body_sound :
allocCode_soundness
(fun (G : list cty) (H : cty) (x : Var G H) =>
length (cFns pr) - S (allocCode x))
(ctysSubst (cfuncsDenote (cDefs pr) (SNil ctyDenote))).
Hypothesis
Gpr_smalls : isSmalls Gpr.
Theorem
allocProg_sound : prog_lr pr (allocProg pr).
End
Traces.