Require Import List.
Require Import Arith.
Require Import Freevar.
Require Import Misc.
Require Import Psatz.
Require Import Star.
Require Import Coq.Logic.Eqdep_dec.
Require Import FEnv.
Require Import STerm.
Require Import Pretty.
Require Import Inductive.
Strong call-by-name pretty-big-step semantics, with environments.
Inductive clo :=
|
clo_var :
freevar ->
clo
|
clo_term :
list freevar ->
term ->
list clo ->
clo.
Fixpoint clo_fv c :=
match c with
|
clo_var x =>
x ::
nil
|
clo_term xs t l =>
concat (
map clo_fv l)
end.
Inductive clo_closed :
clo ->
Prop :=
|
cc_var :
forall x,
clo_closed (
clo_var x)
|
cc_term :
forall xs t l,
closed_at t (
length l) -> (
forall c,
c \
in l ->
clo_closed c /\
clo_fv c \
subseteq xs) ->
clo_closed (
clo_term xs t l).
Fixpoint clo_ind2 (
P :
clo ->
Prop) (
Hvar :
forall x,
P (
clo_var x)) (
Hterm :
forall xs t l,
Forall P l ->
P (
clo_term xs t l)) (
c :
clo) :
P c :=
match c with
|
clo_var x =>
Hvar x
|
clo_term xs t l =>
Hterm xs t l ((
fix H (
l :
_) :
Forall P l :=
match l with
|
nil => @
Forall_nil _ _
|
cons c l => @
Forall_cons _ _ c l (
clo_ind2 P Hvar Hterm c) (
H l)
end)
l)
end.
Inductive nfvalx :=
|
nxvar :
freevar ->
nfvalx
|
nxapp :
nfvalx ->
nfvalx_or_lam ->
nfvalx
|
nxswitch :
nfvalx ->
list (
list freevar *
nfvalx_or_lam) ->
nfvalx
with nfvalx_or_lam :=
|
nxval :
nfvalx ->
nfvalx_or_lam
|
nxlam :
freevar ->
nfvalx_or_lam ->
nfvalx_or_lam
|
nxconstr :
nat ->
list nfvalx_or_lam ->
nfvalx_or_lam.
Inductive valE :
deep_flag ->
Type :=
|
valE_nf :
forall {
df},
nfvalx ->
valE df
|
valEs_abs :
term ->
list clo ->
valE shallow
|
valEs_constr :
nat ->
list clo ->
valE shallow
|
valEd_abs :
term ->
list clo ->
nfvalx_or_lam ->
valE deep
|
valEd_constr :
nat ->
list clo ->
nfvalx_or_lam ->
valE deep.
Inductive extE :
deep_flag ->
Type :=
|
extE_term :
forall df,
list clo ->
term ->
extE df
|
extE_clo :
forall df,
clo ->
extE df
|
extE_app :
forall df,
list clo ->
out (
valE shallow) ->
term ->
extE df
|
extE_appnf :
forall df,
list clo ->
nfvalx ->
out (
valE deep) ->
extE df
|
extE_switch :
forall df,
list clo ->
out (
valE shallow) ->
list (
nat *
term) ->
extE df
|
extE_switchnf1 :
forall df,
list clo ->
nfvalx ->
list (
list freevar *
nfvalx_or_lam) ->
list (
nat *
term) ->
extE df
|
extE_switchnf2 :
forall df,
list clo ->
nfvalx ->
list (
list freevar *
nfvalx_or_lam) ->
list freevar ->
out (
valE deep) ->
list (
nat *
term) ->
extE df
|
extEd_abs :
list clo ->
freevar ->
term ->
out (
valE deep) ->
extE deep
|
extEd_constr1 :
nat ->
list clo ->
list nfvalx_or_lam ->
list clo ->
extE deep
|
extEd_constr2 :
nat ->
list clo ->
list nfvalx_or_lam ->
out (
valE deep) ->
list clo ->
extE deep.
Arguments extE_term {
df}
_ _.
Arguments extE_clo {
df}
_.
Arguments extE_app {
df}
_ _ _.
Arguments extE_appnf {
df}
_ _ _.
Arguments extE_switch {
df}
_ _ _.
Arguments extE_switchnf1 {
df}
_ _ _ _.
Arguments extE_switchnf2 {
df}
_ _ _ _ _ _.
Fixpoint nfvalx_fv v :=
match v with
|
nxvar x =>
x ::
nil
|
nxapp v1 v2 =>
nfvalx_fv v1 ++
nfvalx_or_lam_fv v2
|
nxswitch t m =>
nfvalx_fv t ++
concat (
map (
fun pt2 =>
list_diff (
nfvalx_or_lam_fv (
snd pt2)) (
fst pt2))
m)
end
with nfvalx_or_lam_fv v :=
match v with
|
nxval v =>
nfvalx_fv v
|
nxlam x v =>
list_remove x (
nfvalx_or_lam_fv v)
|
nxconstr tag l =>
concat (
map nfvalx_or_lam_fv l)
end.
Definition cl_closed xs l := (
forall c,
c \
in l ->
clo_closed c /\
clo_fv c \
subseteq xs).
Definition valE_closed {
df}
xs (
v :
valE df) :=
match v with
|
valEs_abs t l =>
closed_at t (
S (
length l)) /\
cl_closed xs l
|
valE_nf v =>
nfvalx_fv v \
subseteq xs
|
valEd_abs t l v =>
closed_at t (
S (
length l)) /\
cl_closed xs l /\
nfvalx_or_lam_fv v \
subseteq xs
|
valEs_constr tag l =>
cl_closed xs l
|
valEd_constr tag l v =>
cl_closed xs l /\
nfvalx_or_lam_fv v \
subseteq xs
end.
Lemma cl_closed_mono :
forall xs1 l,
cl_closed xs1 l ->
forall xs2,
xs1 \
subseteq xs2 ->
cl_closed xs2 l.
Proof.
intros xs1 l H xs2 Hinc c Hc; split; [apply H; assumption|].
etransitivity; [|eassumption]. apply H; assumption.
Qed.
Lemma valE_closed_mono :
forall df (
v :
valE df)
xs1,
valE_closed xs1 v ->
forall xs2,
xs1 \
subseteq xs2 ->
valE_closed xs2 v.
Proof.
intros df v xs1 H xs2 Hinc; destruct v; simpl in *.
- etransitivity; eassumption.
- destruct H; split; [|eapply cl_closed_mono]; eassumption.
- eapply cl_closed_mono; eassumption.
- destruct H as (? & ? & ?); splits 3; [|eapply cl_closed_mono|etransitivity]; eassumption.
- destruct H as (H & H2). split; [|etransitivity; eassumption].
eapply cl_closed_mono; eassumption.
Qed.
Definition outE_closed {
df}
xs (
o :
out (
valE df)) :=
match o with
|
out_div =>
True
|
out_ret v =>
valE_closed xs v
end.
Lemma outE_closed_mono :
forall df (
o :
out (
valE df))
xs1,
outE_closed xs1 o ->
forall xs2,
xs1 \
subseteq xs2 ->
outE_closed xs2 o.
Proof.
intros df o xs1 H xs2 Hinc; destruct o; simpl in *; [|tauto].
eapply valE_closed_mono; eassumption.
Qed.
Inductive extE_closed_at :
forall {
df},
extE df ->
list freevar ->
Prop :=
|
extE_term_closed :
forall df env t xs,
cl_closed xs env ->
closed_at t (
length env) ->
extE_closed_at (@
extE_term df env t)
xs
|
extE_clo_closed :
forall df c xs,
clo_closed c ->
clo_fv c \
subseteq xs ->
extE_closed_at (@
extE_clo df c)
xs
|
extE_app_closed :
forall df env o t xs,
cl_closed xs env ->
closed_at t (
length env) ->
outE_closed xs o ->
extE_closed_at (@
extE_app df env o t)
xs
|
extE_appnf_closed :
forall df env v o xs,
cl_closed xs env ->
nfvalx_fv v \
subseteq xs ->
outE_closed xs o ->
extE_closed_at (@
extE_appnf df env v o)
xs
|
extE_switch_closed :
forall df env o m xs,
cl_closed xs env ->
(
forall p t2, (
p,
t2) \
in m ->
closed_at t2 (
p +
length env)) ->
outE_closed xs o ->
extE_closed_at (@
extE_switch df env o m)
xs
|
extE_switchnf1_closed :
forall df env v m1 m2 xs,
cl_closed xs env ->
nfvalx_fv v \
subseteq xs ->
(
forall xs2 v2, (
xs2,
v2) \
in m1 ->
nfvalx_or_lam_fv v2 \
subseteq xs2 ++
xs) ->
(
forall p t2, (
p,
t2) \
in m2 ->
closed_at t2 (
p +
length env)) ->
extE_closed_at (@
extE_switchnf1 df env v m1 m2)
xs
|
extE_switchnf_closed :
forall df env v m1 xs2 o m2 xs,
cl_closed xs env ->
nfvalx_fv v \
subseteq xs ->
(
forall xs2 v2, (
xs2,
v2) \
in m1 ->
nfvalx_or_lam_fv v2 \
subseteq xs2 ++
xs) ->
(
forall p t2, (
p,
t2) \
in m2 ->
closed_at t2 (
p +
length env)) ->
outE_closed (
xs2 ++
xs)
o ->
extE_closed_at (@
extE_switchnf2 df env v m1 xs2 o m2)
xs
|
extEd_abs_closed :
forall env o t x xs,
cl_closed xs env ->
closed_at t (
S (
length env)) ->
outE_closed (
x ::
xs)
o ->
extE_closed_at (
extEd_abs env x t o)
xs
|
extEd_constr1_closed :
forall tag l l1 l2 xs,
cl_closed xs l ->
(
forall v,
v \
in l1 ->
nfvalx_or_lam_fv v \
subseteq xs) ->
cl_closed xs l2 ->
extE_closed_at (
extEd_constr1 tag l l1 l2)
xs
|
extEd_constr2_closed :
forall tag l l1 o l2 xs,
cl_closed xs l ->
(
forall v,
v \
in l1 ->
nfvalx_or_lam_fv v \
subseteq xs) ->
outE_closed xs o ->
cl_closed xs l2 ->
extE_closed_at (
extEd_constr2 tag l l1 o l2)
xs.
Definition dummyvar :=
proj1_sig (
fresh nil).
Definition dummy_nfvalx :=
nxvar dummyvar.
Definition dummy_nfvalx_or_lam :=
nxval dummy_nfvalx.
Definition getvalEd_nf (
v :
valE deep) :
nfvalx_or_lam :=
match v return nfvalx_or_lam with
|
valE_nf v =>
nxval v
|
valEd_abs t l v =>
v
|
valEd_constr tag l v =>
v
|
valEs_abs _ _ =>
dummy_nfvalx_or_lam
|
valEs_constr _ _ =>
dummy_nfvalx_or_lam
end.
Definition get_abortE {
df t} (
e :
extE df) :
option (
out t) :=
match e with
|
extE_term _ _ =>
None
|
extE_clo _ =>
None
|
extE_app _ o _ =>
get_out_abort o
|
extE_appnf _ _ o =>
get_out_abort o
|
extE_switch _ o _ =>
get_out_abort o
|
extE_switchnf1 _ _ _ _ =>
None
|
extE_switchnf2 _ _ _ _ o _ =>
get_out_abort o
|
extEd_abs _ _ _ o =>
get_out_abort o
|
extEd_constr1 _ _ _ _ =>
None
|
extEd_constr2 _ _ _ o _ =>
get_out_abort o
end.
Inductive redE_ (
rec :
forall df,
list freevar ->
list freevar ->
list freevar ->
extE df ->
out (
valE df) ->
Prop) :
forall df,
list freevar ->
list freevar ->
list freevar ->
extE df ->
out (
valE df) ->
Prop :=
|
redE_clo_term :
forall df xs xs2 dom fvs t env o,
xs2 \
subseteq dom ->
rec df xs2 dom (
list_inter xs2 fvs) (
extE_term env t)
o ->
redE_ rec df xs dom fvs (
extE_clo (
clo_term xs2 t env))
o
|
redE_clo_var :
forall df xs dom fvs x,
redE_ rec df xs dom fvs (
extE_clo (
clo_var x)) (
out_ret (
valE_nf (
nxvar x)))
|
redE_var :
forall df xs dom fvs env n c o,
nth_error env n =
Some c ->
rec df xs dom fvs (
extE_clo c)
o ->
redE_ rec df xs dom fvs (
extE_term env (
var n))
o
|
redE_abs_shallow :
forall t xs dom fvs env,
redE_ rec shallow xs dom fvs (
extE_term env (
abs t)) (
out_ret (
valEs_abs t env))
|
redE_abs_deep :
forall t x xs dom fvs env o1 o2,
x \
notin xs ->
x \
in dom ->
rec deep (
x ::
xs)
dom (
x ::
fvs) (
extE_term (
clo_var x ::
env)
t)
o1 ->
rec deep xs dom fvs (
extEd_abs env x t o1)
o2 ->
redE_ rec deep xs dom fvs (
extE_term env (
abs t))
o2
|
redE_abs1 :
forall x t xs dom fvs env v,
redE_ rec deep xs dom fvs (
extEd_abs env x t (
out_ret v)) (
out_ret (
valEd_abs t env (
nxlam x (
getvalEd_nf v))))
|
redE_app :
forall df xs dom fvs env t1 o1 t2 o2,
rec shallow xs dom fvs (
extE_term env t1)
o1 ->
rec df xs dom fvs (
extE_app env o1 t2)
o2 ->
redE_ rec df xs dom fvs (
extE_term env (
app t1 t2))
o2
|
redE_app1_nf :
forall df xs dom fvs env v o1 t2 o2,
rec deep xs dom fvs (
extE_term env t2)
o1 ->
rec df xs dom fvs (
extE_appnf env v o1)
o2 ->
redE_ rec df xs dom fvs (
extE_app env (
out_ret (
valE_nf v))
t2)
o2
|
redE_app1_abs :
forall df xs xs2 dom fvs env env2 t1 t2 o,
xs \
subseteq xs2 ->
xs2 \
subseteq dom ->
rec df xs dom fvs (
extE_term (
match env_get_maybe_var env t2 with Some c =>
c |
_ =>
clo_term xs2 t2 env end ::
env2)
t1)
o ->
redE_ rec df xs dom fvs (
extE_app env (
out_ret (
valEs_abs t1 env2))
t2)
o
|
redE_appnf :
forall df xs dom fvs env v1 v2,
redE_ rec df xs dom fvs (
extE_appnf env v1 (
out_ret v2)) (
out_ret (
valE_nf (
nxapp v1 (
getvalEd_nf v2))))
|
redE_constr_shallow :
forall xs dom fvs env tag l lc,
Forall2 (
fun t c =>
match env_get_maybe_var env t with Some c1 =>
c =
c1 |
None =>
exists xs2,
xs \
subseteq xs2 /\
xs2 \
subseteq dom /\
c =
clo_term xs2 t env end)
l lc ->
redE_ rec shallow xs dom fvs (
extE_term env (
constr tag l)) (
out_ret (
valEs_constr tag lc))
|
redE_constr_deep :
forall xs dom fvs env tag l lc o,
Forall2 (
fun t c =>
match env_get_maybe_var env t with Some c1 =>
c =
c1 |
None =>
exists xs2,
xs \
subseteq xs2 /\
xs2 \
subseteq dom /\
c =
clo_term xs2 t env end)
l lc ->
rec deep xs dom fvs (
extEd_constr1 tag lc nil lc)
o ->
redE_ rec deep xs dom fvs (
extE_term env (
constr tag l))
o
|
redE_constr1_done :
forall xs dom fvs tag l l1,
redE_ rec deep xs dom fvs (
extEd_constr1 tag l l1 nil) (
out_ret (
valEd_constr tag l (
nxconstr tag l1)))
|
redE_constr1_step :
forall xs dom fvs tag l l1 l2 c o1 o2,
rec deep xs dom fvs (
extE_clo c)
o1 ->
rec deep xs dom fvs (
extEd_constr2 tag l l1 o1 l2)
o2 ->
redE_ rec deep xs dom fvs (
extEd_constr1 tag l l1 (
c ::
l2))
o2
|
redE_constr2 :
forall xs dom fvs tag l l1 l2 v o,
rec deep xs dom fvs (
extEd_constr1 tag l (
l1 ++
getvalEd_nf v ::
nil)
l2)
o ->
redE_ rec deep xs dom fvs (
extEd_constr2 tag l l1 (
out_ret v)
l2)
o
|
redE_switch :
forall df xs dom fvs env t o1 m o2,
rec shallow xs dom fvs (
extE_term env t)
o1 ->
rec df xs dom fvs (
extE_switch env o1 m)
o2 ->
redE_ rec df xs dom fvs (
extE_term env (
switch t m))
o2
|
redE_switch1_constr :
forall df xs dom fvs env tag l m t o,
nth_error m tag =
Some (
length l,
t) ->
rec df xs dom fvs (
extE_term (
l ++
env)
t)
o ->
redE_ rec df xs dom fvs (
extE_switch env (
out_ret (
valEs_constr tag l))
m)
o
|
redE_switch1_nf :
forall df xs dom fvs env v m o,
rec df xs dom fvs (
extE_switchnf1 env v nil m)
o ->
redE_ rec df xs dom fvs (
extE_switch env (
out_ret (
valE_nf v))
m)
o
|
redE_switchnf1_done :
forall df xs dom fvs env v m,
redE_ rec df xs dom fvs (
extE_switchnf1 env v m nil) (
out_ret (
valE_nf (
nxswitch v m)))
|
redE_switchnf1_step :
forall df xs ys dom fvs env v m1 m2 p t o1 o2,
distinct xs p ys ->
ys \
subseteq dom ->
rec deep (
ys ++
xs)
dom (
ys ++
fvs) (
extE_term (
map clo_var ys ++
env)
t)
o1 ->
rec df xs dom fvs (
extE_switchnf2 env v m1 ys o1 m2)
o2 ->
redE_ rec df xs dom fvs (
extE_switchnf1 env v m1 ((
p,
t) ::
m2))
o2
|
redE_switchnf2 :
forall df xs dom fvs env m1 m2 v1 v2 ys o,
rec df xs dom fvs (
extE_switchnf1 env v1 (
m1 ++ (
ys,
getvalEd_nf v2) ::
nil)
m2)
o ->
redE_ rec df xs dom fvs (
extE_switchnf2 env v1 m1 ys (
out_ret v2)
m2)
o
|
redE_abort :
forall df xs dom fvs e o,
get_abortE e =
Some o ->
redE_ rec df xs dom fvs e o.
Inductive redE :
forall df,
list freevar ->
list freevar ->
list freevar ->
extE df ->
out (
valE df) ->
Prop :=
|
mkredE :
forall df xs dom fvs e o,
redE_ redE df xs dom fvs e o ->
redE df xs dom fvs e o.
CoInductive coredE :
forall df,
list freevar ->
list freevar ->
list freevar ->
extE df ->
out (
valE df) ->
Prop :=
|
mkcoredE :
forall df xs dom fvs e o,
redE_ coredE df xs dom fvs e o ->
coredE df xs dom fvs e o.
Lemma redE_is_ind6 :
is_ind6 redE_ redE.
Proof.
prove_ind6. Defined.
Lemma for stronger induction principles.
Lemma valE_nf_closed :
forall df v xs,
nfvalx_fv v \
subseteq xs ->
valE_closed xs (@
valE_nf df v).
Proof.
intros [|]; simpl; tauto.
Qed.
Lemma destruct_valE :
forall df (
v :
valE df),
{
v2 |
existT valE df v =
existT valE df (
valE_nf v2) } +
{
t & {
env |
existT valE df v =
existT valE shallow (
valEs_abs t env) } } +
{
t & {
env & {
v2 |
existT valE df v =
existT valE deep (
valEd_abs t env v2) } } } +
{
tag & {
l |
existT valE df v =
existT valE shallow (
valEs_constr tag l) } } +
{
tag & {
l & {
v2 |
existT valE df v =
existT valE deep (
valEd_constr tag l v2) } } }.
Proof.
intros df v. destruct v.
- left; left; left; left. exists n. reflexivity.
- left; left; left; right. exists t. exists l. reflexivity.
- left; right. exists n. exists l. reflexivity.
- left; left; right. exists t. exists l. exists n. reflexivity.
- right. exists n. exists l. exists n0. reflexivity.
Qed.
Lemma destruct_valE_deep :
forall (
v :
valE deep),
{
v2 |
v =
valE_nf v2 } +
{
t & {
env & {
v2 |
v =
valEd_abs t env v2 } } } +
{
tag & {
l & {
v2 |
v =
valEd_constr tag l v2 } } }.
Proof.
intros v. assert (H := destruct_valE deep v).
destruct H as [[[[(v2 & Heq) | (t & env & Heq)] | (t & env & v2 & Heq)] | (tag & l & Heq)] | (tag & l & v2 & Heq)].
- unexistT. left; left. exists v2. assumption.
- apply projT1_eq in Heq; simpl in Heq; congruence.
- unexistT. left; right. exists t. exists env. exists v2. assumption.
- apply projT1_eq in Heq; simpl in Heq; congruence.
- unexistT. right. exists tag. exists l. exists v2. assumption.
Qed.
Lemma redE_coredE :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
coredE df xs dom fvs e o.
Proof.
refine (preserved6_rec _ _ redE_is_ind6 _ _).
intros df xs dom e o H. constructor.
eapply (is_positive6 _ _ redE_is_ind6); [|eassumption].
simpl. intros; tauto.
Qed.
Lemma redE_xsdom_mono :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
forall xs2 dom2 fvs2,
xs2 \
subseteq xs ->
dom \
subseteq dom2 ->
redE df xs2 dom2 fvs2 e o.
Proof.
refine (preserved6_rec _ _ redE_is_ind6 _ _).
intros df xs dom fvs e o H; inversion H; unexistT; subst; unexistT; subst; intros xs3 dom2 fvs2 Hxs3 Hdom2; constructor.
- eapply redE_clo_term; [etransitivity; eassumption|]. eapply H7; [reflexivity|assumption].
- eapply redE_clo_var.
- eapply redE_var; [eassumption|]. eapply H7; eassumption.
- eapply redE_abs_shallow.
- eapply redE_abs_deep; [rewrite Hxs3; eassumption|rewrite <- Hdom2; eassumption|eapply H10; [|assumption]|eapply H11; assumption].
intros y [<- | Hy]; [left; reflexivity|right; apply Hxs3; assumption].
- eapply redE_abs1.
- eapply redE_app; [eapply H6|eapply H7]; assumption.
- eapply redE_app1_nf; [eapply H6|eapply H7]; assumption.
- eapply redE_app1_abs; [| |eapply H8; assumption]; etransitivity; eassumption.
- eapply redE_appnf.
- eapply redE_constr_shallow. eapply Forall2_impl; [|eassumption].
intros t c Htc. simpl in *. destruct env_get_maybe_var; [assumption|].
destruct Htc as (xs2 & H1 & H2 & H3); exists xs2; splits 3; try assumption; etransitivity; eassumption.
- eapply redE_constr_deep; [|eapply H9; eassumption]. eapply Forall2_impl; [|eassumption].
intros t c Htc. simpl in *. destruct env_get_maybe_var; [assumption|].
destruct Htc as (xs2 & H1 & H2 & H3); exists xs2; splits 3; try assumption; etransitivity; eassumption.
- eapply redE_constr1_done.
- eapply redE_constr1_step; [eapply H7|eapply H9]; eassumption.
- eapply redE_constr2. eapply H5; eassumption.
- eapply redE_switch; [eapply H6|eapply H7]; eassumption.
- eapply redE_switch1_constr; [eassumption|].
eapply H7; eassumption.
- eapply redE_switch1_nf. eapply H6; eassumption.
- eapply redE_switchnf1_done.
- eapply redE_switchnf1_step; [| |eapply H8|eapply H9].
+ eapply distinct_incl; eassumption.
+ etransitivity; eassumption.
+ rewrite Hxs3. reflexivity.
+ eassumption.
+ eassumption.
+ eassumption.
- eapply redE_switchnf2. eapply H6; eassumption.
- eapply redE_abort. eassumption.
Qed.
Lemma redE_xs_mono :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
forall xs2,
xs2 \
subseteq xs ->
redE df xs2 dom fvs e o.
Proof.
intros; eapply redE_xsdom_mono; try eassumption. reflexivity.
Qed.
Lemma redE_dom_mono :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
forall dom2,
dom \
subseteq dom2 ->
redE df xs dom2 fvs e o.
Proof.
intros; eapply redE_xsdom_mono; try eassumption. reflexivity.
Qed.
Lemma redE_fvs_any :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
forall fvs2,
redE df xs dom fvs2 e o.
Proof.
intros; eapply redE_xsdom_mono; try eassumption; reflexivity.
Qed.
Lemma out_abort_div :
forall df t (
e :
extE df) (
o :
out t),
get_abortE e =
Some o ->
o =
out_div.
Proof.
intros; destruct e; simpl in *; try congruence; autoinjSome; eapply get_out_abort_div; eassumption.
Qed.
Lemma valE_closed_fv :
forall xs v,
valE_closed xs v ->
nfvalx_or_lam_fv (
getvalEd_nf v) \
subseteq xs.
Proof.
intros xs v Hv.
destruct (destruct_valE_deep v) as [[(v2 & ->) | (t2 & env2 & v2 & ->)] | (tag & l & v2 & ->)]; simpl in *; tauto.
Qed.
Lemma closed_preserved_down_H :
forall Q df xs dom fvs e o,
redE_ (
fun df xs dom fvs e o =>
Q df xs dom fvs e o /\ (
fvs \
subseteq xs ->
extE_closed_at e fvs ->
outE_closed fvs o))
df xs dom fvs e o ->
fvs \
subseteq xs /\
extE_closed_at e fvs ->
redE_ (
fun df xs dom fvs e o =>
Q df xs dom fvs e o /\
fvs \
subseteq xs /\
extE_closed_at e fvs)
df xs dom fvs e o /\
outE_closed fvs o.
Proof.
intros Q df xs dom fvs e o H [Hfvs He].
Local Ltac use_rec H1 H2 :=
destruct H1 as [H1 H2];
match type of H2 with
| ?A -> ?B -> ?C =>
let Hfvs := fresh "Hfvs" in
let Hclosed := fresh "Hclosed" in
enough (Hclosed : B); [enough (Hfvs : A); [specialize (H2 Hfvs Hclosed); try solve [split; [econstructor; try splits 3; eassumption|assumption]]|
try assumption]|try assumption]
end.
inversion H; unexistT; subst; unexistT; subst; match goal with [ _ : context[get_abortE] |- _ ] => idtac | _ => inversion He; subst end.
- inversion H1; subst.
use_rec H7 Ho.
+ split; [|eapply outE_closed_mono; [apply Ho|apply list_inter_subl2]].
constructor; [assumption|]. splits 3; assumption.
+ apply list_inter_subl1.
+ constructor; [|assumption].
intros c Hc; split; [apply H8; assumption|].
simpl in H3. rewrite concat_incl, Forall_map, Forall_forall in H3.
rewrite list_inter_subr; split; [apply H8; assumption|apply H3; assumption].
- split; [constructor|]. assumption.
- use_rec H7 Ho.
constructor; eapply H3, nth_error_In; eassumption.
- split; [constructor|]. simpl.
split; [|assumption].
inversion H6; assumption.
- inversion H7; subst.
use_rec H10 Ho1.
+ use_rec H11 Ho.
constructor; assumption.
+ rewrite Hfvs; reflexivity.
+ inversion He; subst. constructor.
* intros c [<- | Hc]; split; [constructor|simpl; prove_list_inc|apply H5; assumption|].
etransitivity; [apply H5; assumption|]. prove_list_inc.
* assumption.
- split; [constructor|]. simpl.
splits 3; try assumption.
simpl in *. apply valE_closed_fv in H9.
intros y Hy. rewrite list_remove_correct in Hy.
destruct (H9 y ltac:(tauto)); tauto.
- inversion H5; subst.
use_rec H6 Ho1; [|constructor; assumption].
use_rec H7 Ho.
constructor; assumption.
- use_rec H6 Ho1; [|constructor; assumption].
use_rec H7 Ho.
constructor; assumption.
- use_rec H8 Ho.
constructor; simpl in *; [|tauto].
intros c [<- | Hc].
+ destruct env_get_maybe_var as [c|] eqn:Hc; [eapply H5, env_get_maybe_var_in; eassumption|].
split; simpl.
* constructor; [assumption|]. eapply cl_closed_mono; [eassumption|]. etransitivity; eassumption.
* rewrite concat_incl, Forall_map, Forall_forall.
intros; apply H5; assumption.
+ simpl in *. apply H10. assumption.
- split; [constructor|]. simpl. rewrite list_inc_app_left.
split; [assumption|apply valE_closed_fv; assumption].
- split; [constructor; assumption|]. simpl.
intros c Hc. destruct (Forall2_In_right _ _ _ _ _ _ H5 Hc) as (t & Ht1 & Htc).
destruct env_get_maybe_var eqn:Hc1.
+ subst. apply H4. eapply env_get_maybe_var_in; eassumption.
+ destruct Htc as (xs2 & Hxs2a & Hxs2b & ->).
split; simpl.
* constructor; [inversion H8; subst; apply H6; assumption|].
eapply cl_closed_mono; [eassumption|]. etransitivity; eassumption.
* rewrite concat_incl, Forall_map, Forall_forall.
intros; apply H4; assumption.
- use_rec H9 Ho.
enough (cl_closed fvs lc) by (constructor; [|intros _ []|]; assumption).
intros c Hc. destruct (Forall2_In_right _ _ _ _ _ _ H7 Hc) as (t & Ht1 & Htc).
destruct env_get_maybe_var eqn:Hc1.
+ subst. apply H4. eapply env_get_maybe_var_in; eassumption.
+ destruct Htc as (xs2 & Hxs2a & Hxs2b & ->).
split; simpl.
* constructor; [inversion H8; subst; apply H5; assumption|].
eapply cl_closed_mono; [eassumption|]. etransitivity; eassumption.
* rewrite concat_incl, Forall_map, Forall_forall.
intros; apply H4; assumption.
- split; [constructor|]. simpl.
split; [assumption|]. rewrite concat_incl, Forall_map, Forall_forall. assumption.
- use_rec H7 Ho1; [|constructor; apply H11; simpl; tauto].
use_rec H9 Ho.
constructor; try tauto. intros c2 Hc2; apply H11; simpl in *; tauto.
- use_rec H5 Ho.
constructor; try assumption.
intros v2 Hv2. rewrite in_app_iff in Hv2; simpl in Hv2.
destruct Hv2 as [Hv2 | [<- | []]]; [apply H10; assumption|].
apply valE_closed_fv, H11.
- inversion H5; subst.
use_rec H6 Ho1; [|constructor; assumption].
use_rec H7 Ho. constructor; assumption.
- use_rec H7 Ho.
constructor.
+ intros c Hc; rewrite in_app_iff in Hc; destruct Hc as [Hc | Hc].
* apply H9. assumption.
* apply H4. assumption.
+ rewrite app_length.
eapply H8, nth_error_In; eassumption.
- use_rec H6 Ho.
constructor; try assumption.
intros xs2 v2 [].
- split; [constructor|]. simpl.
rewrite list_inc_app_left. split; [assumption|].
rewrite concat_incl, Forall_map, Forall_forall. intros [xs2 v2] Hxsv2. simpl.
apply H8 in Hxsv2. rewrite Hxsv2. intros y Hy. rewrite list_diff_In_iff, in_app_iff in Hy. tauto.
- use_rec H8 Ho1.
+ use_rec H9 Ho.
constructor; try tauto. intros; apply H13; simpl; tauto.
+ rewrite Hfvs. reflexivity.
+ constructor.
* intros c Hc; rewrite in_app_iff, in_map_iff in Hc; destruct Hc as [(y & <- & Hy) | Hc].
-- simpl. split; [constructor; assumption|]. intros z [<- | []]. rewrite in_app_iff; tauto.
-- eapply cl_closed_mono; try eassumption. prove_list_inc.
* erewrite app_length, map_length, distinct_length; [|eassumption].
apply H13; simpl; tauto.
- use_rec H6 Ho.
constructor; try tauto.
intros xs2 v Hxsv2; rewrite in_app_iff in Hxsv2; destruct Hxsv2 as [Hxsv2 | [[=<- <-] | []]].
+ apply H11. assumption.
+ apply valE_closed_fv, H13.
- split.
+ constructor; assumption.
+ destruct e; simpl in *; try congruence;
match goal with [ _ : get_out_abort ?o = _ |- _ ] => destruct o; simpl in *; autoinjSome; try congruence end;
constructor.
Qed.
Lemma redE_closed :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
fvs \
subseteq xs ->
extE_closed_at e fvs ->
outE_closed fvs o.
Proof.
refine (preserved6_rec _ _ redE_is_ind6 _ _).
intros df xs dom fvs e o H1 H2 H3.
eapply closed_preserved_down_H; [eassumption|]. split; assumption.
Qed.
Lemma closed_preserved_down :
preserved_down6 redE_ redE (
fun df xs dom fvs e o =>
fvs \
subseteq xs /\
extE_closed_at e fvs).
Proof.
intros df xs dom fvs e o Q H Hxse.
eapply (is_positive6 _ _ redE_is_ind6); [|apply closed_preserved_down_H with (Q := fun df xs dom fvs e o => redE df xs dom fvs e o /\ Q df xs dom fvs e o)].
- intros; simpl in *; tauto.
- eapply (is_positive6 _ _ redE_is_ind6); [|eassumption].
intros; simpl in *; split; [assumption|]. eapply redE_closed; apply H0.
- assumption.
Qed.
Transfer lemmas.
Definition extE_shallow_to_deep (
e :
extE shallow) :
extE deep :=
match e return extE deep with
|
extE_term env t =>
extE_term env t
|
extE_clo c =>
extE_clo c
|
extE_app env o1 t2 =>
extE_app env o1 t2
|
extE_appnf env v1 o2 =>
extE_appnf env v1 o2
|
extE_switch env o m =>
extE_switch env o m
|
extE_switchnf1 env v m1 m2 =>
extE_switchnf1 env v m1 m2
|
extE_switchnf2 env v m1 xs o m2 =>
extE_switchnf2 env v m1 xs o m2
|
extEd_abs env x t o =>
extEd_abs env x t o
|
extEd_constr1 tag l l1 l2 =>
extEd_constr1 tag l l1 l2
|
extEd_constr2 tag l l1 o l2 =>
extEd_constr2 tag l l1 o l2
end.
Definition extE_deep_to_shallow (
e :
extE deep) :
option (
extE shallow) :=
match e return option (
extE shallow)
with
|
extE_term env t =>
Some (
extE_term env t)
|
extE_clo c =>
Some (
extE_clo c)
|
extE_app env o1 t2 =>
Some (
extE_app env o1 t2)
|
extE_appnf env v1 o2 =>
Some (
extE_appnf env v1 o2)
|
extE_switch env o m =>
Some (
extE_switch env o m)
|
extE_switchnf1 env v m1 m2 =>
Some (
extE_switchnf1 env v m1 m2)
|
extE_switchnf2 env v m1 xs o m2 =>
Some (
extE_switchnf2 env v m1 xs o m2)
|
extEd_abs env x t o =>
None
|
extEd_constr1 tag l l1 l2 =>
None
|
extEd_constr2 tag l l1 o l2 =>
None
end.
Lemma redE_shallow_deep_val_aux :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
forall (
p :
df =
shallow)
v, (
match p in _ =
df return out (
valE df)
with eq_refl =>
o end) =
out_ret (
valE_nf v) ->
redE deep xs dom fvs (
extE_shallow_to_deep (
match p in _ =
df return extE df with eq_refl =>
e end)) (
out_ret (
valE_nf v)).
Proof.
refine (preserved6_rec _ _ redE_is_ind6 _ _).
intros df xs dom fvs e o H p v Hv.
inversion H; unexistT; subst; unexistT; subst; try discriminate;
repeat (match goal with [ H : _ /\ (forall (p : _ = shallow), _) |- _ ] => let Hred := fresh "Hred" in let Hrec := fresh "Hrec" in destruct H as [Hred Hrec]; specialize (Hrec eq_refl); simpl in Hrec end).
- constructor. econstructor; [assumption|]. apply Hrec. reflexivity.
- injection H6 as H6; subst. constructor; constructor.
- constructor; econstructor; [eassumption|]. apply Hrec. reflexivity.
- constructor; econstructor; [apply Hred0 | apply Hrec]. reflexivity.
- constructor; econstructor; [apply H6 | apply Hrec]. reflexivity.
- constructor; econstructor; [eassumption|eassumption|].
apply Hrec. reflexivity.
- injection H6 as H6; subst. constructor; econstructor.
- constructor; econstructor; [apply Hred0 | apply Hrec]. reflexivity.
- constructor; econstructor; [eassumption|]. apply Hrec. reflexivity.
- constructor; econstructor. apply Hrec. reflexivity.
- injection H6 as H6; subst. constructor; econstructor.
- constructor; econstructor; try eassumption; [apply H8 | apply Hrec]. reflexivity.
- constructor; econstructor. apply Hrec. reflexivity.
- apply out_abort_div in H6. congruence.
Qed.
Lemma redE_shallow_deep_val :
forall xs dom fvs e v,
redE shallow xs dom fvs e (
out_ret (
valE_nf v)) ->
redE deep xs dom fvs (
extE_shallow_to_deep e) (
out_ret (
valE_nf v)).
Proof.
intros xs dom fvs e v H.
exact (redE_shallow_deep_val_aux shallow xs dom fvs e _ H eq_refl v eq_refl).
Qed.
Lemma redE_shallow_deep_abs_aux :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
forall (
p :
df =
shallow)
t env, (
match p in _ =
df return out (
valE df)
with eq_refl =>
o end) =
out_ret (
valEs_abs t env) ->
forall o2 dom2,
xs \
subseteq dom ->
dom \
subseteq dom2 ->
redE deep dom dom2 fvs (
extE_term env (
abs t))
o2 ->
redE deep xs dom2 fvs (
extE_shallow_to_deep (
match p in _ =
df return extE df with eq_refl =>
e end))
o2.
Proof.
refine (preserved6_rec _ _ redE_is_ind6 _ _).
intros df xs dom fvs e o H p t env Htenv o2 dom2 Hxs Hdom Hred2.
inversion H; unexistT; subst; unexistT; subst; try discriminate;
repeat (match goal with [ H : _ /\ (forall (p : _ = shallow), _) |- _ ] => let Hred := fresh "Hred" in let Hrec := fresh "Hrec" in destruct H as [Hred Hrec]; specialize (Hrec eq_refl); simpl in Hrec end); simpl in *.
- constructor; econstructor; [etransitivity; eassumption|].
eapply Hrec; try reflexivity; try eassumption.
eapply redE_fvs_any; eassumption.
- constructor; econstructor; [eassumption|].
eapply Hrec; try reflexivity; try eassumption.
- injection H8 as; subst. eapply redE_xs_mono; eassumption.
- constructor; econstructor; [eapply redE_dom_mono; [apply Hred0|assumption] | eapply Hrec; try reflexivity; eassumption].
- constructor; econstructor; [eapply redE_dom_mono; [apply H6|assumption]|eapply Hrec; try reflexivity; eassumption].
- constructor; econstructor; [| |eapply Hrec]; try eassumption; [etransitivity; eassumption|reflexivity].
- constructor; econstructor; [eapply redE_dom_mono; [apply Hred0|assumption] | eapply Hrec; try reflexivity; eassumption].
- constructor; econstructor; [eassumption|].
eapply Hrec; try reflexivity; eassumption.
- constructor; econstructor. eapply Hrec; try reflexivity; eassumption.
- constructor; econstructor; [eassumption|etransitivity; eassumption|eapply redE_dom_mono; [apply H8|assumption]|].
eapply Hrec; try reflexivity; eassumption.
- constructor; econstructor. eapply Hrec; try reflexivity; eassumption.
- apply out_abort_div in H6. congruence.
Qed.
Lemma redE_shallow_deep_abs :
forall xs dom fvs e t env,
redE shallow xs dom fvs e (
out_ret (
valEs_abs t env)) ->
forall o dom2,
xs \
subseteq dom ->
dom \
subseteq dom2 ->
redE deep dom dom2 fvs (
extE_term env (
abs t))
o ->
redE deep xs dom2 fvs (
extE_shallow_to_deep e)
o.
Proof.
intros xs dom fvs e t env H.
exact (redE_shallow_deep_abs_aux shallow xs dom fvs e _ H eq_refl t env eq_refl).
Qed.
Lemma redE_deep_constr_aux :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
forall (
p :
df =
deep)
tag l v,
(
let e :=
match p in _ =
df return extE df with eq_refl =>
e end in (
exists l1 l2,
e =
extEd_constr1 tag l l1 l2) \/ (
exists l1 o l2,
e =
extEd_constr2 tag l l1 o l2)) ->
o =
out_ret v ->
exists v2,
match p in _ =
df return valE df with eq_refl =>
v end =
valEd_constr tag l v2.
Proof.
refine (preserved6_rec _ _ redE_is_ind6 _ _).
intros df xs dom fvs e o H p tag l v [(l1 & l2 & He) | (l1 & o2 & l2 & He)] Hv;
inversion H; unexistT; subst; unexistT; subst; try discriminate;
repeat (match goal with [ H : _ /\ (forall (p : _ = deep), _) |- _ ] => let Hred := fresh "Hred" in let Hrec := fresh "Hrec" in destruct H as [Hred Hrec]; specialize (Hrec eq_refl); simpl in Hrec end); simpl in *.
- injection H8 as; injection H6 as; subst. eexists; reflexivity.
- eapply Hrec; [|reflexivity].
injection H1 as; subst; right; repeat eexists; reflexivity.
- eapply Hrec; [|reflexivity].
injection H6 as; subst; left; repeat eexists; reflexivity.
- apply get_out_abort_div in H6. congruence.
Qed.
Lemma redE_deep_constr1 :
forall xs dom fvs tag l l1 l2 v,
redE deep xs dom fvs (
extEd_constr1 tag l l1 l2) (
out_ret v) ->
exists v2,
v =
valEd_constr tag l v2.
Proof.
intros xs dom fvs tag l l1 l2 v H.
eapply redE_deep_constr_aux with (p := eq_refl); [eassumption| |reflexivity].
simpl. left. repeat eexists; reflexivity.
Qed.
Lemma redE_deep_constr2 :
forall xs dom fvs tag l l1 o l2 v,
redE deep xs dom fvs (
extEd_constr2 tag l l1 o l2) (
out_ret v) ->
exists v2,
v =
valEd_constr tag l v2.
Proof.
intros xs dom fvs tag l l1 o l2 v H.
eapply redE_deep_constr_aux with (p := eq_refl); [eassumption| |reflexivity].
simpl. right. repeat eexists; reflexivity.
Qed.
Lemma redE_shallow_deep_constr_aux :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
forall (
p :
df =
shallow)
tag l, (
match p in _ =
df return out (
valE df)
with eq_refl =>
o end) =
out_ret (
valEs_constr tag l) ->
forall o2 dom2,
xs \
subseteq dom ->
dom \
subseteq dom2 ->
redE deep dom dom2 fvs (
extEd_constr1 tag l nil l)
o2 ->
redE deep xs dom2 fvs (
extE_shallow_to_deep (
match p in _ =
df return extE df with eq_refl =>
e end))
o2.
Proof.
refine (preserved6_rec _ _ redE_is_ind6 _ _).
intros df xs dom fvs e o H p tag l Htagl o2 dom2 Hxs Hdom Hred2.
inversion H; unexistT; subst; unexistT; subst; try discriminate;
repeat (match goal with [ H : _ /\ (forall (p : _ = shallow), _) |- _ ] => let Hred := fresh "Hred" in let Hrec := fresh "Hrec" in destruct H as [Hred Hrec]; specialize (Hrec eq_refl); simpl in Hrec end); simpl in *.
- constructor; econstructor; [etransitivity; eassumption|].
eapply Hrec; try reflexivity; try eassumption.
eapply redE_fvs_any; eassumption.
- constructor; econstructor; [eassumption|].
eapply Hrec; try reflexivity; try eassumption.
- constructor; econstructor; [eapply redE_dom_mono; [apply Hred0|assumption] | eapply Hrec; try reflexivity; eassumption].
- constructor; econstructor; [eapply redE_dom_mono; [apply H6|assumption]|eapply Hrec; try reflexivity; eassumption].
- constructor; econstructor; [| |eapply Hrec]; try eassumption; [etransitivity; eassumption|reflexivity].
- injection H8 as; subst. constructor; econstructor; [|eapply redE_xs_mono; eassumption].
eapply Forall2_impl; [|eassumption]. simpl.
intros t c Htc. destruct env_get_maybe_var; [assumption|].
destruct Htc as (xs2 & Hxs2a & Hxs2b & Hc); exists xs2; splits 3; try assumption.
etransitivity; eassumption.
- constructor; econstructor; [eapply redE_dom_mono; [apply Hred0|assumption] | eapply Hrec; try reflexivity; eassumption].
- constructor; econstructor; [eassumption|].
eapply Hrec; try reflexivity; eassumption.
- constructor; econstructor. eapply Hrec; try reflexivity; eassumption.
- constructor; econstructor; [eassumption|etransitivity; eassumption|eapply redE_dom_mono; [apply H8|assumption]|].
eapply Hrec; try reflexivity; eassumption.
- constructor; econstructor. eapply Hrec; try reflexivity; eassumption.
- apply out_abort_div in H6. congruence.
Qed.
Lemma redE_shallow_deep_constr :
forall xs dom fvs e tag l,
redE shallow xs dom fvs e (
out_ret (
valEs_constr tag l)) ->
forall o dom2,
xs \
subseteq dom ->
dom \
subseteq dom2 ->
redE deep dom dom2 fvs (
extEd_constr1 tag l nil l)
o ->
redE deep xs dom2 fvs (
extE_shallow_to_deep e)
o.
Proof.
intros xs dom fvs e tag l H.
exact (redE_shallow_deep_constr_aux shallow xs dom fvs e _ H eq_refl tag l eq_refl).
Qed.
Lemma redE_deep_shallow_abs_aux :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
forall (
p :
df =
deep)
t env v, (
match p in _ =
df return out (
valE df)
with eq_refl =>
o end) =
out_ret (
valEd_abs t env v) ->
forall e2,
extE_deep_to_shallow (
match p in _ =
df return extE df with eq_refl =>
e end) =
Some e2 ->
redE shallow xs dom fvs e2 (
out_ret (
valEs_abs t env)).
Proof.
refine (preserved6_rec _ _ redE_is_ind6 _ _).
intros df xs dom fvs e o H p t env v Htenv e2 He2.
inversion H; unexistT; subst; unexistT; subst; try discriminate; simpl in *; autoinjSome;
repeat (match goal with [ H : _ /\ (forall (p : _ = deep), _) |- _ ] => let Hred := fresh "Hred" in let Hrec := fresh "Hrec" in destruct H as [Hred Hrec]; specialize (Hrec eq_refl); simpl in Hrec end); simpl in *.
- constructor; econstructor; [eassumption|].
eapply Hrec; reflexivity.
- constructor; econstructor; [eassumption|].
eapply Hrec; reflexivity.
- enough (Heq : t = t0 /\ env = env0) by (destruct Heq; subst; constructor; econstructor).
inversion Hred; unexistT; subst.
inversion H11; unexistT; subst; [tauto|apply out_abort_div in H12; congruence].
- constructor; econstructor; [apply H6 | eapply Hrec]; reflexivity.
- constructor; econstructor; [apply Hred0 | eapply Hrec]; reflexivity.
- constructor; econstructor; try eassumption.
eapply Hrec; reflexivity.
- apply redE_deep_constr1 in Hred as [v2 Hred]. congruence.
- constructor; econstructor; [apply H6 | eapply Hrec]; reflexivity.
- constructor; econstructor; [eassumption|].
eapply Hrec; reflexivity.
- constructor; econstructor. eapply Hrec; reflexivity.
- constructor; econstructor; try eassumption.
eapply Hrec; reflexivity.
- constructor; econstructor. eapply Hrec; reflexivity.
- apply out_abort_div in H6. congruence.
Qed.
Lemma redE_deep_shallow_abs :
forall xs dom fvs e t env v,
redE deep xs dom fvs e (
out_ret (
valEd_abs t env v)) ->
forall e2,
extE_deep_to_shallow e =
Some e2 ->
redE shallow xs dom fvs e2 (
out_ret (
valEs_abs t env)).
Proof.
intros xs dom fvs e t env v H e2 He2.
exact (redE_deep_shallow_abs_aux deep xs dom fvs e _ H eq_refl t env v eq_refl e2 He2).
Qed.
Lemma redE_deep_shallow_constr_aux :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
forall (
p :
df =
deep)
tag l v, (
match p in _ =
df return out (
valE df)
with eq_refl =>
o end) =
out_ret (
valEd_constr tag l v) ->
forall e2,
extE_deep_to_shallow (
match p in _ =
df return extE df with eq_refl =>
e end) =
Some e2 ->
redE shallow xs dom fvs e2 (
out_ret (
valEs_constr tag l)).
Proof.
refine (preserved6_rec _ _ redE_is_ind6 _ _).
intros df xs dom fvs e o H p tag l v Htagl e2 He2.
inversion H; unexistT; subst; unexistT; subst; try discriminate; simpl in *; autoinjSome;
repeat (match goal with [ H : _ /\ (forall (p : _ = deep), _) |- _ ] => let Hred := fresh "Hred" in let Hrec := fresh "Hrec" in destruct H as [Hred Hrec]; specialize (Hrec eq_refl); simpl in Hrec end); simpl in *.
- constructor; econstructor; [eassumption|].
eapply Hrec; reflexivity.
- constructor; econstructor; [eassumption|].
eapply Hrec; reflexivity.
- inversion Hred; unexistT; subst. inversion H11; unexistT; subst.
apply out_abort_div in H12; congruence.
- constructor; econstructor; [apply H6 | eapply Hrec]; reflexivity.
- constructor; econstructor; [apply Hred0 | eapply Hrec]; reflexivity.
- constructor; econstructor; try eassumption.
eapply Hrec; reflexivity.
- apply redE_deep_constr1 in Hred as [v2 Hred]. injection Hred as; subst.
constructor; econstructor; assumption.
- constructor; econstructor; [apply H6 | eapply Hrec]; reflexivity.
- constructor; econstructor; [eassumption|].
eapply Hrec; reflexivity.
- constructor; econstructor. eapply Hrec; reflexivity.
- constructor; econstructor; try eassumption.
eapply Hrec; reflexivity.
- constructor; econstructor. eapply Hrec; reflexivity.
- apply out_abort_div in H6. congruence.
Qed.
Lemma redE_deep_shallow_constr :
forall xs dom fvs e tag l v,
redE deep xs dom fvs e (
out_ret (
valEd_constr tag l v)) ->
forall e2,
extE_deep_to_shallow e =
Some e2 ->
redE shallow xs dom fvs e2 (
out_ret (
valEs_constr tag l)).
Proof.
intros xs dom fvs e tag l v H e2 He2.
exact (redE_deep_shallow_constr_aux deep xs dom fvs e _ H eq_refl tag l v eq_refl e2 He2).
Qed.
Lemma redE_deep_shallow_val_aux :
forall df xs dom fvs e o,
redE df xs dom fvs e o ->
forall (
p :
df =
deep)
v, (
match p in _ =
df return out (
valE df)
with eq_refl =>
o end) =
out_ret (
valE_nf v) ->
forall e2,
extE_deep_to_shallow (
match p in _ =
df return extE df with eq_refl =>
e end) =
Some e2 ->
redE shallow xs dom fvs e2 (
out_ret (
valE_nf v)).
Proof.
refine (preserved6_rec _ _ redE_is_ind6 _ _).
intros df xs dom fvs e o H p v Hv e2 He2.
inversion H; unexistT; subst; unexistT; subst; try discriminate; simpl in *; autoinjSome;
repeat (match goal with [ H : _ /\ (forall (p : _ = deep), _) |- _ ] => let Hred := fresh "Hred" in let Hrec := fresh "Hrec" in destruct H as [Hred Hrec]; specialize (Hrec eq_refl); simpl in Hrec end); simpl in *.
- constructor; econstructor; [eassumption|].
eapply Hrec; reflexivity.
- injection H6 as; subst. constructor; econstructor.
- constructor; econstructor; [eassumption|].
eapply Hrec; reflexivity.
- inversion Hred; unexistT; subst. inversion H11; unexistT; subst.
apply out_abort_div in H12; congruence.
- constructor; econstructor; [apply H6 | eapply Hrec]; reflexivity.
- constructor; econstructor; [apply Hred0 | eapply Hrec]; reflexivity.
- constructor; econstructor; try eassumption.
eapply Hrec; reflexivity.
- injection H6 as; subst. constructor; econstructor.
- apply redE_deep_constr1 in Hred as [v2 Hred]. congruence.
- constructor; econstructor; [apply H6 | eapply Hrec]; reflexivity.
- constructor; econstructor; [eassumption|].
eapply Hrec; reflexivity.
- constructor; econstructor. eapply Hrec; reflexivity.
- injection H6 as; subst. constructor; econstructor.
- constructor; econstructor; try eassumption.
eapply Hrec; reflexivity.
- constructor; econstructor. eapply Hrec; reflexivity.
- apply out_abort_div in H6. congruence.
Qed.
Lemma redE_deep_shallow_val :
forall xs dom fvs e v,
redE deep xs dom fvs e (
out_ret (
valE_nf v)) ->
forall e2,
extE_deep_to_shallow e =
Some e2 ->
redE shallow xs dom fvs e2 (
out_ret (
valE_nf v)).
Proof.
intros xs dom fvs e v H e2 He2.
exact (redE_deep_shallow_val_aux deep xs dom fvs e _ H eq_refl v eq_refl e2 He2).
Qed.