.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
).
).
).
.
).
.
'.
'.
'.
).
'.
Opaque switch_scope.
induction blk using block_ind2;
intros *
Hsubin Hsubnin Hsubat Hnsub Hnsubl Hsub Hsubl Hincl Hnd1 Hnd2 Hat Hdomub Hdomlb Hsc Hdomub1 Hbck Hnl3 LD Hnd3 Hgood Hwt Hwc Hsem Hmmap;
inv LD;
inv Hnl3;
inv Hnd3;
inv Hgood;
inv Hwt;
inv Hwc;
inv Hsem;
simpl in *;
repeat inv_bind.
-
constructor.
eapply subclock_equation_sem with (
H:=
Hi);
eauto.
-
econstructor;
eauto.
+
eapply subclock_exp_sem with (
H:=
Hi);
eauto.
+
eapply Hnsub;
eauto.
apply Env.Props.P.F.not_find_in_iff.
intros contra.
eapply Hsubnin;
eauto.
+
eapply Hnsubl;
eauto.
apply Env.Props.P.F.not_find_in_iff.
intros contra.
eapply Hsubnin;
eauto.
-
econstructor;
eauto.
1:{
eapply subclock_exp_sem with (
H:=
Hi);
eauto using change_last,
sem_var_refines. }
intros k.
eapply switch_blocks_sem'
with (Γ
ty:=Γ
ty) (
Hi:=
mask_hist k r Hi)
in H0;
eauto.
1-4:(
intros *
Hfind Hv;
eapply sem_var_mask_inv in Hv as (?&
Hv&
Heq);
rewrite Heq;
eapply sem_var_mask;
eauto).
+
apply dom_ub_map;
auto.
+
apply dom_lb_map;
auto.
+
eapply sc_vars_mask in Hsc;
eauto.
+
apply dom_ub_map;
auto.
+
eapply sem_clock_mask;
eauto.
-
destruct (
partition _ _)
eqn:
Hpart.
apply partition_Partition in Hpart.
repeat inv_bind.
destruct x.
repeat inv_bind.
rename x into subs.
assert (
sem_clock (
var_history Hi)
bs ck (
abstract_clock sc))
as Hsemck.
{
take (
sem_exp_ck _ _ _ _ _)
and eapply sc_exp in it;
eauto.
rewrite H14 in it;
simpl in *.
now inv it. }
repeat rewrite subclock_exp_typeof,
H8 in *;
simpl in *.
repeat rewrite subclock_exp_clockof,
H14 in *;
simpl in *.
assert (
sem_clock (
var_history Hi')
bs' (
subclock_clock bck sub ck) (
abstract_clock sc))
as Hsemck'.
{
eapply subclock_clock_sem. 3,4:
eauto. 1,2:
intros *;
rewrite 2
sem_var_history;
eauto using sem_var_refines. }
assert (
incl (
l ++
filter (
fun '(
_,
ann) =>
ann.(
clo) ==
b ck)
l0) Γ
ck)
as Hincl1.
{
apply Partition_Permutation in Hpart.
rewrite Hpart.
apply incl_app; [
solve_incl_app|
apply incl_appr,
incl_filter',
incl_refl]. }
assert (
NoDupMembers (
l ++
filter (
fun '(
_,
ann) =>
ann.(
clo) ==
b ck)
l0))
as Hnd'.
{
apply Partition_Permutation in Hpart.
rewrite Hpart in Hnd2.
apply NoDupMembers_app;
eauto using NoDupMembers_app_l,
NoDupMembers_app_r,
NoDupMembers_filter.
intros ?
Hinm1 Hinm2.
eapply NoDupMembers_app_InMembers in Hnd2;
eauto.
eapply Hnd2,
filter_InMembers';
eauto. }
assert (
Forall (
fun '(
x,
_) =>
forall vs,
sem_var Hi (
Var x)
vs ->
abstract_clock vs ≡
abstract_clock sc)
(
filter (
fun '(
_,
ann) =>
ann.(
clo) ==
b ck)
l0 ++
l))
as Hsc'.
{
eapply Forall_forall;
intros (?&?)
Hin *
Hv.
rewrite Permutation_app_comm in Hincl1.
eapply Hsc in Hv. 2:
apply Hincl1 in Hin;
eauto with senv.
assert (
clo a =
ck);
subst. 2:
eapply sem_clock_det;
eauto.
apply in_app_iff in Hin as [
Hin|
Hin].
-
apply filter_In in Hin as (?&
Hin').
rewrite equiv_decb_equiv in Hin';
inv Hin';
auto.
-
assert (
Is_defined_in (
Var i0) (
Bswitch ec branches))
as Hdef.
{
eapply vars_defined_Is_defined_in.
eapply Partition_Forall1,
Forall_forall in Hpart;
eauto;
simpl in *.
apply PSF.mem_2;
auto. }
inv Hdef.
simpl_Exists.
simpl_Forall.
repeat inv_branch.
simpl_Exists.
simpl_Forall.
take (
Syn.Is_defined_in _ _)
and eapply wc_block_Is_defined_in in it;
eauto.
eapply InMembers_In in it as (?&
Hin').
take (
forall x ck,
HasClock _ _ _ ->
_)
and edestruct it as (
Hck&
_);
eauto with senv.
inv Hck.
eapply NoDupMembers_det with (
t:=
a)
in H1;
eauto.
congruence.
eapply Hincl1;
auto using in_or_app.
}
assert (
Forall (
fun '(
x,
_) =>
forall vs,
sem_var Hi (
Last x)
vs ->
abstract_clock vs ≡
abstract_clock sc)
(
filter (
fun '(
_,
ann) =>
isSome (
causl_last ann)) (
filter (
fun '(
_,
ann) =>
ann.(
clo) ==
b ck)
l0 ++
l)))
as Hscl'.
{
eapply Forall_forall;
intros (?&?)
Hin *
Hv.
simpl_In.
rewrite Permutation_app_comm in Hincl1.
eapply Hsc in Hv.
2:{
apply Hincl1 in Hin0;
eauto with senv. }
2:{
apply Partition_Permutation in Hpart.
rewrite Hpart.
econstructor.
rewrite in_app_iff in *.
destruct Hin0;
simpl_In;
eauto.
destruct a,
causl_last0;
simpl in *;
congruence. }
assert (
clo a =
ck);
subst. 2:
eapply sem_clock_det;
eauto.
apply in_app_iff in Hin0 as [
Hin|
Hin].
-
apply filter_In in Hin as (?&
Hin').
rewrite equiv_decb_equiv in Hin';
inv Hin';
auto.
-
assert (
Is_defined_in (
Var i0) (
Bswitch ec branches))
as Hdef.
{
eapply vars_defined_Is_defined_in.
eapply Partition_Forall1,
Forall_forall in Hpart;
eauto;
simpl in *.
apply PSF.mem_2;
auto. }
inv Hdef.
simpl_Exists.
simpl_Forall.
repeat inv_branch.
simpl_Exists.
simpl_Forall.
take (
Syn.Is_defined_in _ _)
and eapply wc_block_Is_defined_in in it;
eauto.
eapply InMembers_In in it as (?&
Hin').
take (
forall x ck,
HasClock _ _ _ ->
_)
and edestruct it as (
Hck&
_);
eauto with senv.
inv Hck.
eapply NoDupMembers_det with (
t:=
a)
in H1;
eauto.
congruence.
eapply Hincl1;
auto using in_or_app.
}
assert (
forall x,
InMembers x (
l ++
filter (
fun '(
_,
ann) =>
ann.(
clo) ==
b ck)
l0) ->
Forall (
fun '(
_,
sub,
_,
_,
_,
_) =>
Env.In x sub)
subs)
as Hinsubs.
{
intros ?
Hinm.
eapply mmap_values,
Forall2_ignore1 in H6;
eauto.
eapply Forall_impl; [|
eapply H6];
intros (((?&?)&?)&?) ((?&?)&?&?&?&?);
repeat inv_bind.
apply Env.In_from_list,
fst_InMembers.
erewrite map_map,
map_ext,
map_app, ?
new_idents_old, <-
map_app;
eauto. 2:
intros ((?&?)&(?&?));
auto.
now rewrite <-
fst_InMembers,
Permutation_app_comm. }
assert (
sem_exp_ck G2 Hi'
bs' (
subclock_exp bck sub subl ec) [
sc])
as Hsem.
{
eapply subclock_exp_sem with (
H:=
Hi);
eauto using change_last,
sem_var_refines. }
assert (
Hcond:=
H0).
eapply cond_eq_sem in H0 as (
Hi1&
Hv1&
Hsem1&
Href1&
Hdom1&
Hdoml1&
Hsc1);
eauto.
assert (
dom_ub (
Hi' +
Hi1) (Γ
ty ++
st_senv x1))
as Hdomub1'.
{
split;
intros ?
Hin;
apply FEnv.union_In in Hin as [
Hin|
Hin];
try apply Hdomub1 in Hin.
-
eapply IsVar_incl; [|
eauto].
eapply incl_appr',
incl_map,
st_follows_incl;
eauto using cond_eq_st_follows.
-
eapply Hdom1,
cond_eq_incl in Hin; [|
eauto].
apply IsVar_app,
or_intror,
IsVar_fst.
unfold st_senv,
senv_of_tyck.
solve_In.
-
eapply IsLast_incl; [|
eauto].
eapply incl_appr',
incl_map,
st_follows_incl;
eauto using cond_eq_st_follows.
-
eapply Hdoml1 in Hin as [].
}
assert (
Hni:=
H6).
eapply new_idents_sem with (
bs':=
bs')
in H6 as (
Hi2&
Href2&
Hdom2&
Hdoml2&
Hv2&
Hl2&
Hsc2);
eauto with fresh.
2:{
eapply Sem.sem_clock_refines;
eauto using var_history_refines. }
2:
take (
wt_streams [
_] [
_])
and inv it;
auto.
constructor.
eapply Sscope with (
Hi':=
Hi1 +
Hi2);
eauto. 3:
rewrite ?
Forall_app;
repeat split.
split.
+
intros.
rewrite FEnv.union_In,
Hdom1,
Hdom2,
IsVar_senv_of_decls,
InMembers_app.
apply or_iff_compat_r.
erewrite fst_InMembers,
map_map,
map_ext.
reflexivity.
intros;
destruct_conjs;
auto.
+
intros.
rewrite FEnv.union_In,
senv_of_decls_app,
IsLast_app.
split; [
intros [
In|
In]|
intros [
In|
In]]. 3,4:
clear -
In;
inv In;
simpl_In;
congruence.
1,2:
exfalso.
eapply Hdoml1;
eauto.
eapply Hdoml2;
eauto.
+
simpl_app.
apply sc_vars_app.
*
intros *
Hinm1 Hinm2.
rewrite fst_InMembers in Hinm1,
Hinm2.
specialize (
st_valid_NoDup x2)
as Hvalid'.
apply new_idents_st_ids'
in Hni.
apply cond_eq_st_ids in Hcond.
rewrite Hni,
Hcond in Hvalid'.
simpl_app.
simpl_In.
eapply NoDup_app_r,
NoDup_app_In in Hvalid'. 2:
solve_In.
eapply Hvalid'.
solve_In.
auto.
*
eapply sc_vars_refines.
1:{
rewrite FEnv.union_assoc;
eauto using EqStrel_Reflexive. }
3:{
erewrite map_map,
map_ext;
eauto.
intros (?&?&?);
auto. }
--
intros *
Hin1 Hin2.
erewrite IsVar_fst, 2
map_map,
map_ext, <-
fst_InMembers in Hin1.
2:
intros;
destruct_conjs;
auto.
apply fst_InMembers,
Hdom1 in Hin1.
apply FEnv.union_In;
auto.
--
intros *
L.
clear -
L.
inv L.
simpl_In.
congruence.
*
clear -
Hsc2.
eapply sc_vars_morph. 4:
eauto. 3:
reflexivity.
2:
symmetry;
apply FEnv.union_assoc;
auto using EqStrel_Reflexive.
erewrite 2
flat_map_concat_map,
concat_map,
map_map,
map_ext;
eauto.
intros;
destruct_conjs;
auto.
erewrite map_map,
map_ext;
eauto.
intros;
destruct_conjs;
auto.
+
simpl_Forall.
assert (
Is_defined_in (
Var i0) (
Bswitch ec branches))
as Hdef.
{
eapply vars_defined_Is_defined_in.
eapply Partition_Forall1,
Forall_forall in Hpart;
eauto;
simpl in *.
apply PSF.mem_2;
auto. }
assert (
exists vs,
sem_var Hi (
Var i0)
vs)
as (
vs&
Hi0).
{
eapply sem_block_defined in Hdef;
eauto.
-
inv Hdef.
esplit;
econstructor;
eauto.
reflexivity.
-
econstructor;
eauto.
take (
typeof ec =
_)
and now rewrite it. }
inv Hdef.
simpl_Exists.
simpl_Forall.
repeat inv_branch.
simpl_Exists.
simpl_Forall.
take (
Is_defined_in _ _)
and eapply wc_block_Is_defined_in,
InMembers_In in it as (?&
Hin1);
eauto.
assert (
HasClock Γ'
i0 x5.(
clo))
as Hck by eauto with senv.
eapply H16 in Hck as (
Hin'&?);
subst.
inv Hin'.
eapply sem_block_ck_morph; [
symmetry;
eapply FEnv.union_assoc,
EqStrel_Reflexive| | |];
simpl;
try reflexivity.
eapply merge_defs_sem with (
Hi:=
Hi);
eauto using Sem.sem_var_refines.
*
rewrite <-
H10.
replace (
map fst (
map _ subs))
with (
map fst branches).
reflexivity.
clear -
Hni.
apply mmap_values in Hni.
induction Hni as [|(?&?) (((?&?)&?)&?)];
simpl;
auto.
destruct H as (?&?&?);
repeat inv_bind.
f_equal;
auto.
*
take (
wt_streams [
_] [
_])
and inv it;
auto.
*
eapply sem_clock_det in Hsemck;
eauto.
destruct Hsc as (
Hsc&
_).
eapply Hsc;
eauto with senv.
*
simpl_Forall.
eapply Hv2;
eauto.
assert (
Env.In i0 t0)
as Henvin.
{
eapply Forall_forall in Hinsubs;
eauto. 2:
eapply InMembers_app;
left;
eauto using In_InMembers.
simpl in *;
auto. }
inv Henvin.
unfold rename_var,
Env.MapsTo in *.
rewrite H24 in *;
auto.
+
eapply CS.mmap2_values'
in H20.
assert (
st_follows x1 x2)
as Hfollows2.
{
eapply mmap_st_follows;
eauto.
simpl_Forall;
destruct_conjs;
repeat inv_bind.
repeat (
etransitivity;
eauto using new_idents_st_follows). }
assert (
Hf:=
Hni).
eapply mmap_values,
Forall3_ignore3'
with (
zs:=
x3)
in Hf.
2:{
eapply Forall3_length in H20 as (?&?);
congruence. }
2:
eapply mmap_length in Hni;
eauto.
2:{
intros;
destruct_conjs.
take (
branch _)
and destruct it.
repeat inv_bind.
eapply mmap_st_follows;
eauto.
simpl_Forall;
eauto using switch_block_st_follows. }
eapply Forall3_Forall3 in Hf; [|
eapply H20].
clear H20.
eapply Forall_concat,
Forall_forall;
intros ?
Hin1.
eapply Forall3_ignore12,
Forall_forall in Hf as ((?&?)&?&
Hin2&
Hin3&(?&?&
Hfollows&?)&?&?&?);
eauto;
repeat inv_bind.
simpl_Forall.
repeat inv_branch.
repeat inv_bind.
take (
In _ (
_ ++
_))
and rewrite ?
in_app_iff in it.
destruct it as [|[
Hin|
Hin]];
simpl_Forall.
*{
eapply sem_block_ck_morph; [
symmetry;
eapply FEnv.union_assoc,
EqStrel_Reflexive| | |];
simpl;
try reflexivity.
assert (
Forall (
wc_block G1 (
map (
fun '(
x,
ann0) => (
x,
ann_with_clock ann0 Cbase)) (
l ++
filter (
fun '(
_,
ann0) =>
clo ann0 ==
b ck)
l0)))
blks)
as Hwc'.
{
simpl_Forall.
eapply wc_block_incl; [| |
eauto].
+
intros *
Hin.
apply H16 in Hin as (
Hin&?);
subst.
inv Hin;
econstructor;
solve_In.
2:{
apply Partition_Permutation in Hpart.
rewrite Hpart in H25.
rewrite in_app_iff in *.
destruct H25;
eauto;
right;
solve_In.
apply equiv_decb_refl. }
simpl;
eauto.
auto.
+
intros *
Hin.
assert (
HasClock Γ
ck x16 ck)
as Ck.
{
inv Hin.
edestruct H16;
eauto with senv. }
eapply H18 in Hin.
inv Hin.
inv Ck.
eapply NoDupMembers_det in H25;
eauto;
subst.
apply Partition_Permutation in Hpart.
rewrite Hpart,
in_app_iff in H30.
rewrite map_app,
IsLast_app.
destruct H30 as [
Hin|
Hin]; [
left|
right];
econstructor;
solve_In.
2:
apply equiv_decb_refl.
1,2:
destruct e0;
simpl in *;
auto.
}
eapply switch_blocks_sem'
with (
ls:=
map (
fun _ => [])
blks) (Γ
ty:=Γ
ty) (
bs:=
fwhenb e bs sc)
(
Hi:=
restrict (
fwhen_hist e Hi sc) (
map (
fun '(
x,
ann0) => (
x,
ann_with_clock ann0 Cbase)) (
l ++
filter (
fun '(
_,
ann) =>
ann.(
clo) ==
b ck)
l0)))
in H0.
simpl_Forall;
eauto.
all:
eauto.
-
intros ?
Hin.
rewrite ?
Env.In_from_list, ?
fst_InMembers in Hin.
rewrite fst_InMembers.
destruct Hin.
+
erewrite map_map,
map_ext,
map_app, <-2
new_idents_old, <-
map_app,
Permutation_app_comm;
eauto.
solve_In.
intros;
destruct_conjs;
auto.
+
simpl_In.
eapply new_idents_In_inv in H21 as (?&
In&
_);
eauto.
setoid_rewrite Permutation_app_comm.
solve_In.
-
intros *
_ In.
apply in_concat in In as (?&?&
In).
simpl_In.
inv In.
-
repeat (
take (
new_idents _ _ _ _ _ _ =
_)
and apply new_idents_prefixed in it).
intros * [
Hfind|
Hfind];
apply Env.from_list_find_In in Hfind;
simpl_In.
+
apply in_app_iff in Hin as [|];
simpl_Forall;
eauto.
+
simpl_Forall.
eauto.
-
intros ??
Hfind Hv.
eapply Sem.sem_var_restrict_inv in Hv as (
Hin&
_).
exfalso.
apply Env.Props.P.F.not_find_in_iff in Hfind.
apply Hfind,
Env.In_from_list.
rewrite fst_InMembers.
erewrite vars_of_senv_Var,
IsVar_fst,
map_map,
map_ext,
map_app, <-2
new_idents_old, <-
map_app,
Permutation_app_comm in Hin;
eauto.
erewrite map_map,
map_ext;
eauto. 1,2:
intros;
destruct_conjs;
auto.
-
intros ??
Hfind Hv.
eapply Sem.sem_var_restrict_inv in Hv as (
Hin&
_).
exfalso.
apply Env.Props.P.F.not_find_in_iff in Hfind.
apply Hfind,
Env.In_from_list.
rewrite fst_InMembers.
erewrite vars_of_senv_Last in Hin.
erewrite map_map,
map_ext,
new_idents_old;
eauto.
2:
intros;
destruct_conjs;
auto.
inv Hin.
rewrite Permutation_app_comm.
solve_In.
destruct a;
simpl in *.
destruct causl_last0;
simpl;
auto;
congruence.
-
intros ???
Hfind Hv.
eapply Sem.sem_var_restrict_inv in Hv as (
_&
Hv).
eapply sem_var_fwhen_inv in Hv as (?&
Hv&
Heq).
rewrite Heq;
eauto.
-
intros ???
Hfind Hv.
eapply Sem.sem_var_restrict_inv in Hv as (
_&
Hv).
eapply sem_var_fwhen_inv in Hv as (?&
Hv&
Heq).
rewrite Heq;
eauto.
-
etransitivity; [|
eauto].
erewrite map_map,
map_ext.
apply incl_map;
eauto.
intros (?&?);
auto.
-
clear -
Hnd'.
erewrite fst_NoDupMembers,
map_map,
map_ext, <-
fst_NoDupMembers;
auto.
intros (?&?);
auto.
-
simpl_Forall;
auto.
-
split;
intros ?
In;
eapply dom_ub_map;
eauto.
1,2:
eapply FEnv.restrict_In in In as (?&?);
eauto.
-
split;
intros ?
In;
apply FEnv.restrict_In;
(
split; [
apply FEnv.map_in_iff,
Hdomlb|
try apply vars_of_senv_Var;
try apply vars_of_senv_Last]).
1:
eapply IsVar_incl;
eauto. 3:
eapply IsLast_incl;
eauto.
1,2:
clear -
In;
inv In;
econstructor;
solve_In.
1,2:
clear -
In;
inv In;
eapply in_map_iff in H as ((?&?)&?&?);
inv_equalities;
econstructor;
eauto;
solve_In.
-
split.
+
intros *
Hck Hv.
inv Hck.
simpl_In.
eapply Forall_forall in Hsc'. 2:
rewrite Permutation_app_comm;
eauto.
simpl in *.
apply Sem.sem_var_restrict_inv in Hv as (
_&
Hv).
apply sem_var_fwhen_inv in Hv as (?&
Hv&
Hwhen).
constructor.
rewrite Hwhen,
ac_fwhen,
Hsc';
eauto.
apply fwhenb_both_slower;
eauto using ac_slower,
sc_slower,
ac_aligned.
+
intros *
Hck Hl Hv.
inv Hck.
inv Hl.
simpl_In.
eapply NoDupMembers_det in Hin0;
eauto;
subst.
eapply Forall_forall in Hscl'.
2:{
rewrite Permutation_app_comm.
solve_In.
simpl.
destruct causl_last;
simpl;
auto. }
simpl in *.
apply Sem.sem_var_restrict_inv in Hv as (
_&
Hv).
apply sem_var_fwhen_inv in Hv as (?&
Hv&
Hwhen).
constructor.
rewrite Hwhen,
ac_fwhen,
Hscl';
eauto.
apply fwhenb_both_slower;
eauto using ac_slower,
sc_slower,
ac_aligned.
-
split;
intros ?
Hin;
apply FEnv.union_In in Hin as [
Hin|
Hin].
+
eapply Hdomub1'
in Hin.
eapply IsVar_incl;
eauto.
eapply incl_appr',
incl_map,
st_follows_incl.
etransitivity;
eauto.
+
apply Hdom2 in Hin.
eapply IsVar_app,
or_intror,
IsVar_incl; [
eapply incl_map,
st_follows_incl;
eauto|].
eapply new_idents_st_ids'
in Hni.
erewrite IsVar_fst,
map_map,
map_ext.
setoid_rewrite Hni. 2:
intros;
destruct_conjs;
auto.
apply in_app_iff,
or_intror;
auto.
apply fst_InMembers in Hin.
clear -
Hin.
solve_In.
auto.
+
eapply Hdomub1'
in Hin.
eapply IsLast_incl;
eauto.
eapply incl_appr',
incl_map,
st_follows_incl.
etransitivity;
eauto.
+
exfalso.
eapply Hdoml2;
eauto.
-
eapply sem_clock_Con_when;
eauto using Sem.sem_clock_refines,
var_history_refines.
+
take (
wt_streams [
_] [
_])
and inv it;
auto.
+
eapply sc_slower;
eauto using ac_aligned.
+
eapply sem_var_history,
sem_var_refines;
eauto.
-
simpl_Forall.
auto.
-
simpl_Forall.
eapply sem_block_restrict;
eauto.
+
unfold wc_env.
simpl_Forall.
take (
In _ (
idck _))
and clear -
it.
simpl_In.
constructor.
+
take (
when_hist _ _ _ _)
and apply when_hist_fwhen_hist in it;
eauto using sem_block_refines.
}
*{
simpl_In.
simpl_Forall.
assert (
InMembers i0 (
filter (
fun '(
_,
ann) =>
ann.(
clo) ==
b ck)
l0))
as Hin.
{
eapply new_idents_In_inv in H6 as (?&?&?);
eauto using In_InMembers. }
apply InMembers_In in Hin as (?&
Hin).
assert (
exists vs,
sem_var Hi (
Var i0)
vs)
as (
vs&
Hv).
{
assert (
FEnv.In (
Var i0)
Hi)
as (?&?). 2:
do 2
econstructor;
eauto;
reflexivity.
eapply Hdomlb,
IsVar_incl,
IsVar_app,
or_intror;
eauto.
clear -
Hin.
econstructor.
solve_In. }
eapply Forall_forall in Hsc';
eauto using in_or_app;
simpl in *.
eapply sem_block_ck_morph; [
symmetry;
eapply FEnv.union_assoc,
EqStrel_Reflexive| | |];
simpl;
try reflexivity.
eapply when_free_sem;
eauto using Sem.sem_var_refines.
-
take (
wt_streams [
_] [
_])
and inv it;
auto.
-
eapply Sem.sem_var_refines; [|
eapply rename_var_sem;
eauto].
etransitivity;
eauto.
-
eapply Hv2;
eauto.
apply Env.find_In_from_list.
+
apply in_map_iff;
do 2
esplit;
eauto using in_or_app.
auto.
+
erewrite fst_NoDupMembers,
map_map,
map_ext,
map_app, 2
new_idents_old, <-
map_app, <-
fst_NoDupMembers. 2,3:
eauto.
now rewrite Permutation_app_comm.
intros ((?&?)&(?&?));
auto.
}
*{
simpl_In.
assert (
InMembers i0 (
filter (
fun '(
_,
ann) =>
isSome (
causl_last ann)) (
filter (
fun '(
_,
ann) =>
clo ann ==
b ck)
l0 ++
l)))
as Hin.
{
eapply new_idents_In_inv in H21 as (?&?&?);
eauto using In_InMembers. }
apply InMembers_In in Hin as (?&
Hin).
assert (
exists vs,
sem_var Hi (
Last i0)
vs)
as (
vs&
Hv).
{
assert (
FEnv.In (
Last i0)
Hi)
as (?&?). 2:
do 2
econstructor;
eauto;
reflexivity.
eapply Hdomlb,
IsLast_incl;
eauto.
rewrite Permutation_app_comm.
econstructor;
simpl_In.
eauto.
edestruct causl_last;
simpl in *;
congruence. }
eapply Forall_forall in Hscl';
eauto using in_or_app;
simpl in *.
eapply sem_block_ck_morph; [
symmetry;
eapply FEnv.union_assoc,
EqStrel_Reflexive| | |];
simpl;
try reflexivity.
eapply when_freel_sem;
eauto using Sem.sem_var_refines.
-
take (
wt_streams [
_] [
_])
and inv it;
auto.
-
eapply Hl2;
eauto.
apply Env.find_In_from_list.
+
apply in_map_iff;
do 2
esplit;
eauto using in_or_app.
auto.
+
erewrite fst_NoDupMembers,
map_map,
map_ext,
new_idents_old, <-
fst_NoDupMembers. 2:
eauto.
apply NoDupMembers_filter.
now rewrite Permutation_app_comm.
intros ((?&?)&(?&?));
auto.
}
+
simpl_Forall.
constructor.
eapply sem_equation_refines;
eauto.
rewrite FEnv.union_assoc;
eauto using EqStrel_Reflexive.
-
constructor.
eapply switch_scope_sem with (Γ
ty:=Γ
ty);
eauto.
intros.
simpl in *.
inv_VarsDefined.
eapply switch_blocks_sem'
with (Γ
ty:=Γ
ty0);
eauto.
+
intros *
In1.
rewrite Hperm;
eauto.
Transparent switch_scope.
Qed.
.
).
.
.