.
.
.
.
.
.
.
).
Proof.
.
Proof.
.
.
.
.
Proof.
.
Proof.
.
Proof.
).
Proof.
).
Proof.
.
Proof.
.
Proof.
.
Proof.
).
Proof.
Effect of an injective renaming of nodes on a CFG.
).
Proof.
).
Proof.
.
Proof.
.
.
.
.
.
').
].
.
.
Proof.
econstructor.
instantiate(1:=
fun b (
i:
nat)=>
MS b).
instantiate(1:=
lt).
constructor.
apply lt_wf.
intros;
invMS;
eapply proper_mu_inject;
eauto.
intros;
invMS;
eapply proper_mu_ge_init_inj;
eauto.
apply ge_match.
{
intros mu fid args args'
score GE_INIT_INJ INJID GARG ARGREL INITCORE.
unfold init_core_local in *.
simpl in *.
unfold init_core in *.
unfold generic_init_core in INITCORE |- *.
erewrite symbols_preserved.
inv_eq.
erewrite funct_ptr_translated;
eauto.
unfold fundef_init in *.
inv_eq.
clear H0.
erewrite wd_args_inject;
eauto.
Esimpl;
eauto.
intros sm0 tm0 INITSM INITTM MEMINITINJ sm tm [
HRELY LRELY MINJ].
exists 0%
nat.
This could be a general purposed lemma...
assert (
args' =
args).
{
generalize ARGREL GARG MEMINITINJ;
clear.
revert args'.
induction args;
intros args'
REL G MEMREL;
inv REL.
auto.
inv G.
f_equal.
inv H1;
auto.
inv MEMREL.
apply inj_inject_id in H.
inv H.
rewrite Ptrofs.add_zero;
auto.
contradiction.
apply IHargs;
auto. }
subst.
splitMS.
constructor.
{
clear;
induction args;
auto. }
{
inv MEMINITINJ;
inv HRELY;
inv LRELY.
eapply inject_implies_extends;
eauto.
intros b0 A.
unfold Mem.valid_block in A;
rewrite EQNEXT, <-
dom_eq_src in A.
eapply Bset.inj_dom in A;
eauto.
destruct A as [
b'
A].
unfold Bset.inj_to_meminj.
rewrite A.
eauto.
inv GE_INIT_INJ.
rewrite mu_shared_src in dom_eq_src.
rewrite mu_shared_tgt in dom_eq_tgt.
rewrite S_EQ in dom_eq_src.
assert (
forall b,
Plt b (
Mem.nextblock sm0) <->
Plt b (
Mem.nextblock tm0)).
{
intro.
rewrite <-
dom_eq_src, <-
dom_eq_tgt.
tauto. }
rewrite EQNEXT,
EQNEXT0.
destruct (
Pos.lt_total (
Mem.nextblock sm0) (
Mem.nextblock tm0))
as [
LT | [
EQ |
LT]];
auto;
(
generalize H3 LT;
clear;
intros;
exfalso;
apply H3 in LT;
eapply Pos.lt_irrefl;
eauto). }
inv MEMINITINJ.
inv HRELY.
unfold Mem.valid_block in *.
intros.
rewrite EQNEXT.
apply dom_eq_src;
auto.
inv MEMINITINJ.
inv LRELY.
unfold Mem.valid_block in *.
intros.
rewrite EQNEXT.
apply dom_eq_tgt;
auto.
inv MEMINITINJ;
econstructor;
eauto.
simpl.
intro.
intros ? ? ? ? ? .
exploit inj_inject_id.
exact H.
intro.
inv H0.
intro A.
inv A.
auto.
apply MemClosures_local.reach_closed_unmapped_closed.
inv LRELY.
auto.
}
{
intros i mu Hfp Lfp Hcore Hm Lcore Lm Hfp'
Hcore'
Hm'
MS STEP.
simpl in STEP.
revert i mu Hfp Lfp Lcore Lm MS.
pose proof STEP as STEP_bk.
induction STEP;
intros;
invMS;
inv MS;
right;
exists 0%
nat.
{
Esimpl.
constructor;
simpl.
econstructor;
eauto.
eapply transf_function_at in H;
eauto.
eresolvfp.
splitMS.
eapply reach_succ;
eauto.
simpl;
auto.
}
{
assert (
Val.lessdef_list (
rs##
args) (
rs'##
args)).
apply regs_lessdef_regs;
auto.
exploit eval_operation_lessdef;
eauto.
intros [
v' [
EVAL'
VLD]].
exploit eval_operation_lessdef_fp;
eauto.
intros [
fp' [
EVALFP'
FPINJ]].
Esimpl.
econstructor;
simpl.
eapply exec_Iop;
eauto.
eapply transf_function_at in H;
eauto.
erewrite <-
EVAL'.
eapply eval_operation_preserved.
exact symbols_preserved.
rewrite <-
EVALFP'.
apply eval_operation_fp_preserved.
exact symbols_preserved.
eresolvfp.
splitMS.
eapply reach_succ;
eauto.
simpl;
auto.
apply set_reg_lessdef;
auto.
}
{
assert (
Val.lessdef_list (
rs##
args) (
rs'##
args)).
apply regs_lessdef_regs;
auto.
exploit eval_addressing_lessdef;
eauto.
intros [
a' [
ADDR'
ALD]].
exploit Mem.loadv_extends;
eauto.
intros [
v' [
LOAD'
VLD]].
assert(
Injections.FPMatch'
mu (
FP.union Hfp (
FMemOpFP.loadv_fp chunk a))
(
FP.union Lfp (
FMemOpFP.loadv_fp chunk a))).
eresolvfp.
Esimpl;
eauto.
constructor.
eapply exec_Iload with (
a :=
a').
eauto.
eapply transf_function_at in H;
eauto.
erewrite <-
ADDR'.
apply eval_addressing_preserved.
exact symbols_preserved.
eauto.
eauto.
assert (
a' =
a)
by (
destruct a;
try discriminate;
inv ALD;
auto).
subst a'.
eresolvfp.
splitMS.
eapply reach_succ;
eauto;
simpl;
auto.
apply set_reg_lessdef;
auto.
}
{
assert (
Val.lessdef_list (
rs##
args) (
rs'##
args)).
apply regs_lessdef_regs;
auto.
exploit eval_addressing_lessdef;
eauto.
intros [
a' [
ADDR'
ALD]].
exploit Mem.storev_extends. 2:
eexact H1.
eauto.
eauto.
apply RLD.
intros [
m'1 [
STORE'
MLD']].
destruct a;
simpl in H1;
try discriminate.
inv ALD.
simpl in STORE'.
Esimpl.
constructor.
eapply transf_function_at in H ;
eauto.
eapply exec_Istore.
apply H.
rewrite <-
ADDR'.
apply eval_addressing_preserved.
exact symbols_preserved.
eauto.
eauto.
eresolvfp.
splitMS.
eapply reach_succ;
eauto.
simpl;
auto.
}
{
eapply transf_function_at in H as ?;
eauto.
exploit find_function_translated;
eauto.
intro FIND'.
Esimpl.
constructor.
eapply exec_Icall;
eauto.
rewrite sig_preserved;
auto.
eresolvfp.
splitMS.
econstructor;
eauto.
eapply reach_succ;
eauto;
simpl;
eauto.
eapply regs_lessdef_regs;
eauto.
}
{
eapply transf_function_at in H as ?;
eauto.
exploit find_function_translated;
eauto.
exploit Mem.free_parallel_extends;
eauto.
intros [
m'1 [
FREE EXT]].
intro FIND'.
Esimpl.
constructor.
eapply exec_Itailcall;
eauto.
rewrite sig_preserved;
auto.
rewrite stacksize_preserved;
auto.
eresolvfp.
rewrite stacksize_preserved.
splitMS.
apply regs_lessdef_regs;
auto.
}
{
eapply transf_function_at in H as ?;
eauto.
exploit (@
eval_builtin_args_lessdef _ sge (
fun r =>
rs#
r) (
fun r =>
rs'#
r));
eauto.
intros (
vargs' &
P &
Q).
exploit (
MemOpFP.eval_builtin_args_fp_lessdef _ sge (
fun r =>
rs#
r) (
fun r =>
rs'#
r));
eauto.
intros EVALFP.
exploit external_call_mem_extends;
eauto.
intros [
v' [
m'1 [
A [
B [
C D]]]]].
pose proof A as A'.
apply helpers.i64ext_effects in A'.
destruct A';
subst.
Esimpl.
constructor.
eapply exec_Ibuiltin;
eauto.
eapply eval_builtin_args_preserved with(
ge1:=
sge);
eauto.
exact symbols_preserved.
eapply MemOpFP.eval_builtin_args_fp_preserved.
apply senv_preserved.
eauto.
eapply external_call_symbols_preserved;
eauto.
apply senv_preserved.
eresolvfp.
splitMS.
eapply reach_succ;
eauto.
simpl;
auto.
eapply set_res_lessdef;
eauto.
auto.
}
{
eapply transf_function_at in H as ?;
eauto.
exploit eval_condition_lessdef_fp;
try eassumption.
apply regs_lessdef_regs;
eauto.
intros [
fp' [
EVALFP FPINJ]].
Esimpl.
econstructor.
eapply exec_Icond;
eauto.
apply eval_condition_lessdef with (
rs##
args)
m;
eauto.
apply regs_lessdef_regs;
eauto.
eresolvfp.
destruct b;
splitMS;
eapply reach_succ;
eauto;
simpl;
auto.
}
{
jumptable*)
eapply transf_function_at in H as ?;
eauto.
Esimpl.
constructor.
eapply exec_Ijumptable.
eauto.
specialize (
RLD arg).
inv RLD;
try eassumption.
rewrite H0 in H4.
inv H4.
rewrite list_nth_z_map,
H1.
simpl.
eauto.
eresolvfp.
splitMS.
eapply reach_succ;
eauto.
simpl;
auto.
eapply list_nth_z_in;
eauto.
}
{
eapply transf_function_at in H as ?;
eauto.
exploit Mem.free_parallel_extends;
eauto.
intros [
m'1 [
FREE EXT]].
Esimpl.
econstructor.
eapply exec_Ireturn;
eauto.
rewrite stacksize_preserved.
eresolvfp.
splitMS.
destruct or;
auto.
apply RLD.
rewrite stacksize_preserved.
eresolvfp.
}
{
simpl.
eapply Mem.alloc_extends in MLD as ?;
eauto.
Hsimpl.
Esimpl.
econstructor.
eapply exec_function_internal.
rewrite stacksize_preserved.
eauto.
rewrite stacksize_preserved.
eauto.
unfold MemOpFP.alloc_fp.
erewrite Mem.mext_next;
eauto.
eresolvfp.
splitMS.
unfold reach.
constructor.
simpl.
apply regs_lessdef_init_regs.
auto.
unfold local_block.
destruct (
plt stk (
Genv.genv_next sge));
unfold Plt,
Ple in *; [|
lia].
exfalso.
apply Mem.alloc_result in H.
subst.
erewrite LDSimDefs.mu_shared_src in SVALID;[|
inv AGMU;
eauto].
specialize (
SVALID (
Mem.nextblock m)
p).
unfold Mem.valid_block,
Plt in SVALID.
lia.
unfold MemOpFP.alloc_fp.
erewrite Mem.mext_next;
eauto.
eresolvfp.
omega.
omega.
}
{
exploit external_call_mem_extends;
eauto.
intros [
res' [
m2' [
A [
B [
C D]]]]].
pose proof A as A'.
apply helpers.i64ext_effects in A';
auto.
destruct A';
subst.
Esimpl.
econstructor.
econstructor;
eauto.
eapply external_call_symbols_preserved;
eauto.
apply senv_preserved.
eresolvfp.
splitMS.
}
{
inv STACKS.
Esimpl.
constructor.
econstructor.
eresolvfp.
splitMS.
eapply set_reg_lessdef;
eauto.
}
}
{
unfold at_external_local;
simpl;
unfold at_external;
simpl.
intros.
invMS.
inv MS;
try discriminate.
destruct f0;
simpl;
try discriminate.
destruct e;
try discriminate.
destruct invert_symbol_from_string eqn:
FINDID;
try discriminate.
erewrite match_genvs_invert_symbol_from_string_preserved;
eauto using genv_match.
destruct peq;
simpl in *;
try discriminate.
destruct peq;
simpl in *;
try discriminate.
inv H0.
exists 0%
nat.
eexists.
split;
eauto.
split.
{
simpl in *.
unfold LDSimDefs.arg_rel.
revert args'
AGMU H2 VLD ;
clear.
should be extracted as a lemma ...
induction argSrc;
intros args'
AGMU GARG LD.
simpl.
inv LD.
auto.
inv LD.
inv GARG.
constructor;
auto.
clear H3 H4 IHargSrc.
inv H1;
auto.
destruct v2;
auto.
simpl in H2.
eapply Bset.inj_dom in H2;
inv AGMU;
eauto.
destruct H2.
exploit proper_mu_inject_incr.
unfold Bset.inj_to_meminj;
rewrite H;
eauto.
intro.
inv H0.
econstructor.
unfold Bset.inj_to_meminj;
rewrite H.
eauto.
rewrite Ptrofs.add_zero;
auto. }
split.
eapply MemClosures_local.unmapped_closed_reach_closed_preserved_by_extends;
inv AGMU;
eauto.
split;
eresolvfp.
split.
eapply extends_reach_closed_implies_inject;
inv AGMU;
eauto.
splitMS.
intros.
inv H;
auto.
inv H3.
destruct f1;
simpl;
auto.
}
{
simpl.
unfold after_external.
intros i mu Hcore Hm Lcore Lm oresSrc Hcore'
oresTgt MS GRES AFTEXT RESREL.
destruct Hcore;
try discriminate.
destruct f;
try discriminate.
destruct e;
try discriminate.
invMS;
inv MS;
try discriminate.
assert (
oresSrc =
oresTgt).
{
destruct oresSrc,
oresTgt;
try contradiction;
auto.
simpl in RESREL.
inv RESREL;
simpl in GRES;
auto;
try contradiction.
inv AGMU.
apply proper_mu_inject_incr in H.
inv H.
rewrite Ptrofs.add_zero.
auto. }
subst.
assert (
Hcore' =
Core_Returnstate stack (
match oresTgt with Some v =>
v |
None =>
Vundef end)).
{
destruct oresTgt, (
sig_res sg);
inv AFTEXT;
auto.
destruct (
val_has_type_func v t);
inv H0.
auto. }
rename H into AFTEXT'.
exists (
Core_Returnstate s' (
match oresTgt with Some v =>
v |
None =>
Vundef end)).
split.
{
destruct oresTgt, (
sig_res sg);
try discriminate;
auto.
destruct val_has_type_func;
try discriminate;
auto. }
intros Hm'
Lm' [
HRELY LRELY INV].
subst.
exists 0%
nat.
splitMS.
inv AGMU;
eapply extends_rely_extends;
eauto.
econstructor;
eauto.
intros ?
S.
apply SVALID in S.
unfold Mem.valid_block in *.
inv HRELY.
rewrite EQNEXT;
auto.
intros ?
T.
apply TVALID in T.
unfold Mem.valid_block in *.
inv LRELY.
rewrite EQNEXT;
auto.
inv LRELY.
eapply MemClosures_local.reach_closed_unmapped_closed;
eauto.
}
{
simpl.
unfold halted.
intros i mu Hfp Lfp Hcore Hm Lcore Lm resSrc MS HALT RC GRES.
destruct Hcore,
stack;
try discriminate.
invMS.
inv HALT.
inv MS.
inv STACKS.
exists resSrc.
Esimpl;
eauto.
f_equal.
inv VLD;
auto.
contradiction.
{
revert VLD GRES AGMU.
clear;
intros.
destruct resSrc;
try constructor.
econstructor.
simpl in GRES.
inv AGMU.
eapply Bset.inj_dom in GRES;
eauto.
destruct GRES as [
b'
INJ].
exploit proper_mu_inject_incr.
unfold Bset.inj_to_meminj;
rewrite INJ;
eauto.
intro A.
inv A.
unfold Bset.inj_to_meminj;
rewrite INJ;
eauto.
rewrite Ptrofs.add_zero;
auto. }
inv AGMU;
eapply MemClosures_local.unmapped_closed_reach_closed_preserved_by_extends;
eauto.
eresolvfp.
inv AGMU;
eapply extends_reach_closed_implies_inject;
eauto.
}
Qed.
.