aboutsummaryrefslogtreecommitdiffstats
path: root/backend/Cminorgenproof.v
diff options
context:
space:
mode:
Diffstat (limited to 'backend/Cminorgenproof.v')
-rw-r--r--backend/Cminorgenproof.v1209
1 files changed, 645 insertions, 564 deletions
diff --git a/backend/Cminorgenproof.v b/backend/Cminorgenproof.v
index 7b3bc9bb..7820095a 100644
--- a/backend/Cminorgenproof.v
+++ b/backend/Cminorgenproof.v
@@ -8,6 +8,7 @@ Require Import Integers.
Require Import Floats.
Require Import Values.
Require Import Mem.
+Require Import Events.
Require Import Globalenvs.
Require Import Csharpminor.
Require Import Op.
@@ -29,38 +30,51 @@ Lemma symbols_preserved:
forall (s: ident), Genv.find_symbol tge s = Genv.find_symbol ge s.
Proof.
intro. unfold ge, tge.
- apply Genv.find_symbol_transf_partial with (transl_function gce).
+ apply Genv.find_symbol_transf_partial with (transl_fundef gce).
exact TRANSL.
Qed.
Lemma function_ptr_translated:
- forall (b: block) (f: Csharpminor.function),
+ forall (b: block) (f: Csharpminor.fundef),
Genv.find_funct_ptr ge b = Some f ->
exists tf,
- Genv.find_funct_ptr tge b = Some tf /\ transl_function gce f = Some tf.
+ Genv.find_funct_ptr tge b = Some tf /\ transl_fundef gce f = Some tf.
Proof.
intros.
generalize
- (Genv.find_funct_ptr_transf_partial (transl_function gce) TRANSL H).
- case (transl_function gce f).
+ (Genv.find_funct_ptr_transf_partial (transl_fundef gce) TRANSL H).
+ case (transl_fundef gce f).
intros tf [A B]. exists tf. tauto.
intros [A B]. elim B. reflexivity.
Qed.
Lemma functions_translated:
- forall (v: val) (f: Csharpminor.function),
+ forall (v: val) (f: Csharpminor.fundef),
Genv.find_funct ge v = Some f ->
exists tf,
- Genv.find_funct tge v = Some tf /\ transl_function gce f = Some tf.
+ Genv.find_funct tge v = Some tf /\ transl_fundef gce f = Some tf.
Proof.
intros.
generalize
- (Genv.find_funct_transf_partial (transl_function gce) TRANSL H).
- case (transl_function gce f).
+ (Genv.find_funct_transf_partial (transl_fundef gce) TRANSL H).
+ case (transl_fundef gce f).
intros tf [A B]. exists tf. tauto.
intros [A B]. elim B. reflexivity.
Qed.
+Lemma sig_preserved:
+ forall f tf,
+ transl_fundef gce f = Some tf ->
+ Cminor.funsig tf = Csharpminor.funsig f.
+Proof.
+ intros until tf; destruct f; simpl.
+ unfold transl_function. destruct (build_compilenv gce f).
+ case (zle z Int.max_signed); try congruence.
+ intro. case (transl_stmt c (Csharpminor.fn_body f)); simpl; try congruence.
+ intros. inversion H. reflexivity.
+ intro. inversion H; reflexivity.
+Qed.
+
Definition global_compilenv_match (ce: compilenv) (gv: gvarenv) : Prop :=
forall id,
match ce!!id with
@@ -72,9 +86,9 @@ Definition global_compilenv_match (ce: compilenv) (gv: gvarenv) : Prop :=
Lemma global_compilenv_charact:
global_compilenv_match gce (global_var_env prog).
Proof.
- set (mkgve := fun gv vars =>
+ set (mkgve := fun gv (vars: list (ident * var_kind * list init_data)) =>
List.fold_left
- (fun gv (id_vi: ident * var_kind) => PTree.set (fst id_vi) (snd id_vi) gv)
+ (fun gve x => match x with (id, k, init) => PTree.set id k gve end)
vars gv).
assert (forall vars gv ce,
global_compilenv_match ce gv ->
@@ -83,7 +97,7 @@ Proof.
induction vars; simpl; intros.
auto.
apply IHvars. intro id1. unfold assign_global_variable.
- destruct a as [id2 lv2]. destruct lv2; simpl; rewrite PMap.gsspec; rewrite PTree.gsspec.
+ destruct a as [[id2 lv2] init2]. destruct lv2; simpl; rewrite PMap.gsspec; rewrite PTree.gsspec.
case (peq id1 id2); intro. auto. apply H.
case (peq id1 id2); intro. auto. apply H.
@@ -283,6 +297,7 @@ Qed.
must be normalized with respect to the memory chunk of the variable,
in the following sense. *)
+(*
Definition val_normalized (chunk: memory_chunk) (v: val) : Prop :=
exists v0, v = Val.load_result chunk v0.
@@ -305,34 +320,31 @@ Lemma load_result_normalized:
Proof.
intros chunk v [v0 EQ]. rewrite EQ. apply load_result_idem.
Qed.
-
+*)
Lemma match_env_store_local:
forall f cenv e m1 m2 te sp lo hi id b chunk v tv,
e!id = Some(b, Vscalar chunk) ->
- val_inject f v tv ->
- val_normalized chunk tv ->
+ val_inject f (Val.load_result chunk v) tv ->
store chunk m1 b 0 v = Some m2 ->
match_env f cenv e m1 te sp lo hi ->
match_env f cenv e m2 (PTree.set id tv te) sp lo hi.
Proof.
- intros. inversion H3. constructor; auto.
+ intros. inversion H2. constructor; auto.
intros. generalize (me_vars0 id0); intro.
- inversion H4; subst.
+ inversion H3; subst.
(* var_local *)
case (peq id id0); intro.
(* the stored variable *)
subst id0.
- change Csharpminor.var_kind with var_kind in H5.
- rewrite H in H6. injection H6; clear H6; intros; subst b0 chunk0.
+ change Csharpminor.var_kind with var_kind in H4.
+ rewrite H in H5. injection H5; clear H5; intros; subst b0 chunk0.
econstructor. eauto.
eapply load_store_same; eauto. auto.
rewrite PTree.gss. reflexivity.
- replace tv with (Val.load_result chunk tv).
- apply Mem.load_result_inject. constructor; auto.
- apply load_result_normalized; auto.
+ auto.
(* a different variable *)
econstructor; eauto.
- rewrite <- H7. eapply load_store_other; eauto.
+ rewrite <- H6. eapply load_store_other; eauto.
rewrite PTree.gso; auto.
(* var_stack_scalar *)
econstructor; eauto.
@@ -375,16 +387,15 @@ Qed.
Lemma match_callstack_store_local:
forall f cenv e te sp lo hi cs bound tbound m1 m2 id b chunk v tv,
e!id = Some(b, Vscalar chunk) ->
- val_inject f v tv ->
- val_normalized chunk tv ->
+ val_inject f (Val.load_result chunk v) tv ->
store chunk m1 b 0 v = Some m2 ->
match_callstack f (mkframe cenv e te sp lo hi :: cs) bound tbound m1 ->
match_callstack f (mkframe cenv e (PTree.set id tv te) sp lo hi :: cs) bound tbound m2.
Proof.
- intros. inversion H3. constructor; auto.
+ intros. inversion H2. constructor; auto.
eapply match_env_store_local; eauto.
eapply match_callstack_store_above; eauto.
- inversion H17.
+ inversion H16.
generalize (me_bounded0 _ _ _ H). omega.
Qed.
@@ -409,20 +420,19 @@ Qed.
Lemma match_callstack_store_local_unchanged:
forall f cenv e te sp lo hi cs bound tbound m1 m2 id b chunk v tv,
e!id = Some(b, Vscalar chunk) ->
- val_inject f v tv ->
- val_normalized chunk tv ->
+ val_inject f (Val.load_result chunk v) tv ->
store chunk m1 b 0 v = Some m2 ->
te!id = Some tv ->
match_callstack f (mkframe cenv e te sp lo hi :: cs) bound tbound m1 ->
match_callstack f (mkframe cenv e te sp lo hi :: cs) bound tbound m2.
Proof.
- intros. inversion H4. constructor; auto.
+ intros. inversion H3. constructor; auto.
apply match_env_extensional with (PTree.set id tv te).
eapply match_env_store_local; eauto.
intros. rewrite PTree.gsspec.
case (peq id0 id); intros. congruence. auto.
eapply match_callstack_store_above; eauto.
- inversion H18.
+ inversion H17.
generalize (me_bounded0 _ _ _ H). omega.
Qed.
@@ -698,6 +708,90 @@ Proof.
injection H; intros. rewrite <- H2; simpl. omega.
Qed.
+Lemma match_env_alloc:
+ forall m1 l h m2 b tm1 tm2 tb f1 ce e te sp lo hi,
+ alloc m1 l h = (m2, b) ->
+ alloc tm1 l h = (tm2, tb) ->
+ match_env f1 ce e m1 te sp lo hi ->
+ hi <= m1.(nextblock) ->
+ sp < tm1.(nextblock) ->
+ let f2 := extend_inject b (Some(tb, 0)) f1 in
+ inject_incr f1 f2 ->
+ match_env f2 ce e m2 te sp lo hi.
+Proof.
+ intros.
+ assert (BEQ: b = m1.(nextblock)). injection H; auto.
+ assert (TBEQ: tb = tm1.(nextblock)). injection H0; auto.
+ inversion H1. constructor; auto.
+ (* me_vars *)
+ intros. generalize (me_vars0 id); intro. inversion H5.
+ (* var_local *)
+ econstructor; eauto.
+ generalize (me_bounded0 _ _ _ H7). intro.
+ unfold f2, extend_inject. case (eq_block b0 b); intro.
+ subst b0. rewrite BEQ in H12. omegaContradiction.
+ auto.
+ (* var_stack_scalar *)
+ econstructor; eauto.
+ (* var_stack_array *)
+ econstructor; eauto.
+ (* var_global_scalar *)
+ econstructor; eauto.
+ (* var_global_array *)
+ econstructor; eauto.
+ (* me_bounded *)
+ intros until delta. unfold f2, extend_inject. case (eq_block b0 b); intro.
+ intro. injection H5; clear H5; intros.
+ rewrite H6 in TBEQ. rewrite TBEQ in H3. omegaContradiction.
+ eauto.
+ (* me_inj *)
+ intros until delta. unfold f2, extend_inject. case (eq_block b0 b); intros.
+ injection H5; clear H5; intros; subst b0 tb0 delta.
+ rewrite BEQ in H6. omegaContradiction.
+ eauto.
+Qed.
+
+Lemma match_callstack_alloc_rec:
+ forall f1 cs bound tbound m1,
+ match_callstack f1 cs bound tbound m1 ->
+ forall l h m2 b tm1 tm2 tb,
+ alloc m1 l h = (m2, b) ->
+ alloc tm1 l h = (tm2, tb) ->
+ bound <= m1.(nextblock) ->
+ tbound <= tm1.(nextblock) ->
+ let f2 := extend_inject b (Some(tb, 0)) f1 in
+ inject_incr f1 f2 ->
+ match_callstack f2 cs bound tbound m2.
+Proof.
+ induction 1; intros.
+ constructor.
+ inversion H. constructor.
+ intros. elim (mg_symbols0 _ _ H5); intros.
+ split; auto. elim (H4 b0); intros; congruence.
+ intros. generalize (mg_functions0 _ H5). elim (H4 b0); congruence.
+ constructor. auto. auto.
+ unfold f2. eapply match_env_alloc; eauto. omega. omega.
+ unfold f2; eapply IHmatch_callstack; eauto.
+ inversion H1; omega.
+ omega.
+Qed.
+
+Lemma match_callstack_alloc:
+ forall f1 cs m1 tm1 l h m2 b tm2 tb,
+ match_callstack f1 cs m1.(nextblock) tm1.(nextblock) m1 ->
+ alloc m1 l h = (m2, b) ->
+ alloc tm1 l h = (tm2, tb) ->
+ let f2 := extend_inject b (Some(tb, 0)) f1 in
+ inject_incr f1 f2 ->
+ match_callstack f2 cs m2.(nextblock) tm2.(nextblock) m2.
+Proof.
+ intros. unfold f2 in *.
+ apply match_callstack_incr_bound with m1.(nextblock) tm1.(nextblock).
+ eapply match_callstack_alloc_rec; eauto. omega. omega.
+ injection H0; intros; subst m2; simpl; omega.
+ injection H1; intros; subst tm2; simpl; omega.
+Qed.
+
(** [match_callstack] implies [match_globalenvs]. *)
Lemma match_callstack_match_globalenvs:
@@ -757,14 +851,14 @@ Qed.
provided arguments match pairwise ([val_list_inject f] hypothesis). *)
Lemma make_op_correct:
- forall al a op vl m2 v sp le te1 tm1 te2 tm2 tvl f,
+ forall al a op vl m2 v sp le te1 tm1 t te2 tm2 tvl f,
make_op op al = Some a ->
Csharpminor.eval_operation op vl m2 = Some v ->
- eval_exprlist tge (Vptr sp Int.zero) le te1 tm1 al te2 tm2 tvl ->
+ eval_exprlist tge (Vptr sp Int.zero) le te1 tm1 al t te2 tm2 tvl ->
val_list_inject f vl tvl ->
mem_inject f m2 tm2 ->
exists tv,
- eval_expr tge (Vptr sp Int.zero) le te1 tm1 a te2 tm2 tv
+ eval_expr tge (Vptr sp Int.zero) le te1 tm1 a t te2 tm2 tv
/\ val_inject f v tv.
Proof.
intros.
@@ -782,23 +876,27 @@ Proof.
(* floatconst *)
TrivialOp. econstructor. constructor. reflexivity.
(* Unary operators *)
- inversion H1. subst sp0 le0 e m a0 bl e2 m0 tvl.
- inversion H14. subst sp0 le0 e m e1 m1 vl0.
- inversion H2. subst vl v' vl'. inversion H8. subst vl0.
+ inversion H1; clear H1; subst.
+ inversion H11; clear H11; subst.
+ rewrite E0_right.
+ inversion H2; clear H2; subst. inversion H8; clear H8; subst.
destruct op; simplify_eq H; intro; subst a;
simpl in H0; destruct v1; simplify_eq H0; intro; subst v;
inversion H7; subst v0;
TrivialOp.
+ change (Vint (Int.cast8unsigned i)) with (Val.cast8unsigned (Vint i)). eauto with evalexpr.
+ change (Vint (Int.cast8signed i)) with (Val.cast8signed (Vint i)). eauto with evalexpr.
+ change (Vint (Int.cast16unsigned i)) with (Val.cast16unsigned (Vint i)). eauto with evalexpr.
+ change (Vint (Int.cast16signed i)) with (Val.cast16signed (Vint i)). eauto with evalexpr.
+ change (Vfloat (Float.singleoffloat f0)) with (Val.singleoffloat (Vfloat f0)). eauto with evalexpr.
(* Binary operations *)
- inversion H1. subst sp0 le0 e m a0 bl e2 m0 tvl.
- inversion H14. subst sp0 le0 e m a0 bl e2 m3 vl0.
- inversion H16. subst sp0 le0 e m e0 m0 vl1.
- inversion H2. subst vl v' vl'.
- inversion H8. subst vl0 v' vl'.
- inversion H12. subst vl.
+ inversion H1; clear H1; subst. inversion H11; clear H11; subst.
+ inversion H12; clear H12; subst. rewrite E0_right.
+ inversion H2; clear H2; subst. inversion H9; clear H9; subst.
+ inversion H10; clear H10; subst.
destruct op; simplify_eq H; intro; subst a;
simpl in H0; destruct v2; destruct v3; simplify_eq H0; intro; try subst v;
- inversion H7; inversion H9; subst v0; subst v1;
+ inversion H7; inversion H8; subst v0; subst v1;
TrivialOp.
(* add int ptr *)
exists (Vptr b2 (Int.add ofs2 i)); split.
@@ -815,7 +913,8 @@ Proof.
(* sub ptr ptr *)
destruct (eq_block b b0); simplify_eq H0; intro; subst v; subst b0.
assert (b4 = b2). congruence. subst b4.
- exists (Vint (Int.sub ofs2 ofs3)); split. eauto with evalexpr.
+ exists (Vint (Int.sub ofs3 ofs2)); split.
+ eauto with evalexpr.
subst ofs2 ofs3. replace x0 with x. rewrite Int.sub_shifted. constructor.
congruence.
(* divs *)
@@ -842,11 +941,11 @@ Proof.
(* cmp int ptr *)
elim (eval_compare_null_inv _ _ _ H0); intros; subst i1 i.
exists v; split. eauto with evalexpr.
- elim H18; intros [A B]; subst v; unfold Vtrue, Vfalse; constructor.
+ elim H12; intros [A B]; subst v; unfold Vtrue, Vfalse; constructor.
(* cmp ptr int *)
elim (eval_compare_null_inv _ _ _ H0); intros; subst i1 i0.
exists v; split. eauto with evalexpr.
- elim H18; intros [A B]; subst v; unfold Vtrue, Vfalse; constructor.
+ elim H12; intros [A B]; subst v; unfold Vtrue, Vfalse; constructor.
(* cmp ptr ptr *)
caseEq (valid_pointer m2 b (Int.signed i) && valid_pointer m2 b0 (Int.signed i0));
intro EQ; rewrite EQ in H0; try discriminate.
@@ -854,7 +953,7 @@ Proof.
assert (b4 = b2); [congruence|subst b4].
assert (x0 = x); [congruence|subst x0].
elim (andb_prop _ _ EQ); intros.
- exists (Val.of_bool (Int.cmp c ofs2 ofs3)); split.
+ exists (Val.of_bool (Int.cmp c ofs3 ofs2)); split.
eauto with evalexpr.
subst ofs2 ofs3. rewrite Int.translate_cmp.
apply val_inject_val_of_bool.
@@ -866,55 +965,51 @@ Qed.
normalized according to the given memory chunk. *)
Lemma make_cast_correct:
- forall f sp le te1 tm1 a te2 tm2 v chunk v' tv,
- eval_expr tge (Vptr sp Int.zero) le te1 tm1 a te2 tm2 tv ->
- cast chunk v = Some v' ->
+ forall f sp le te1 tm1 a t te2 tm2 v chunk tv,
+ eval_expr tge (Vptr sp Int.zero) le te1 tm1 a t te2 tm2 tv ->
val_inject f v tv ->
exists tv',
eval_expr tge (Vptr sp Int.zero) le
te1 tm1 (make_cast chunk a)
- te2 tm2 tv'
- /\ val_inject f v' tv'
- /\ val_normalized chunk tv'.
+ t te2 tm2 tv'
+ /\ val_inject f (Val.load_result chunk v) tv'.
Proof.
- intros. destruct chunk; destruct v; simplify_eq H0; intro; subst v'; simpl;
- inversion H1; subst tv.
+ intros. destruct chunk.
- exists (Vint (Int.cast8signed i)).
+ exists (Val.cast8signed tv).
split. apply eval_cast8signed; auto.
- split. constructor. exists (Vint i); reflexivity.
+ inversion H0; simpl; constructor.
- exists (Vint (Int.cast8unsigned i)).
+ exists (Val.cast8unsigned tv).
split. apply eval_cast8unsigned; auto.
- split. constructor. exists (Vint i); reflexivity.
+ inversion H0; simpl; constructor.
- exists (Vint (Int.cast16signed i)).
+ exists (Val.cast16signed tv).
split. apply eval_cast16signed; auto.
- split. constructor. exists (Vint i); reflexivity.
+ inversion H0; simpl; constructor.
- exists (Vint (Int.cast16unsigned i)).
+ exists (Val.cast16unsigned tv).
split. apply eval_cast16unsigned; auto.
- split. constructor. exists (Vint i); reflexivity.
-
- exists (Vint i).
- split. auto. split. auto. exists (Vint i); reflexivity.
+ inversion H0; simpl; constructor.
- exists (Vptr b2 ofs2).
- split. auto. split. auto. exists (Vptr b2 ofs2); reflexivity.
+ exists tv.
+ split. simpl; auto.
+ inversion H0; simpl; econstructor; eauto.
- exists (Vfloat (Float.singleoffloat f0)).
+ exists (Val.singleoffloat tv).
split. apply eval_singleoffloat; auto.
- split. constructor. exists (Vfloat f0); reflexivity.
+ inversion H0; simpl; constructor.
- exists (Vfloat f0).
- split. auto. split. auto. exists (Vfloat f0); reflexivity.
+ exists tv.
+ split. simpl; auto.
+ inversion H0; simpl; constructor.
Qed.
Lemma make_stackaddr_correct:
forall sp le te tm ofs,
eval_expr tge (Vptr sp Int.zero) le
te tm (make_stackaddr ofs)
- te tm (Vptr sp (Int.repr ofs)).
+ E0 te tm (Vptr sp (Int.repr ofs)).
Proof.
intros; unfold make_stackaddr.
eapply eval_Eop. econstructor. simpl. decEq. decEq.
@@ -926,7 +1021,7 @@ Lemma make_globaladdr_correct:
Genv.find_symbol tge id = Some b ->
eval_expr tge (Vptr sp Int.zero) le
te tm (make_globaladdr id)
- te tm (Vptr b Int.zero).
+ E0 te tm (Vptr b Int.zero).
Proof.
intros; unfold make_globaladdr.
eapply eval_Eop. econstructor. simpl. rewrite H. auto.
@@ -935,67 +1030,75 @@ Qed.
(** Correctness of [make_load] and [make_store]. *)
Lemma make_load_correct:
- forall sp le te1 tm1 a te2 tm2 va chunk v,
- eval_expr tge (Vptr sp Int.zero) le te1 tm1 a te2 tm2 va ->
+ forall sp le te1 tm1 a t te2 tm2 va chunk v,
+ eval_expr tge (Vptr sp Int.zero) le te1 tm1 a t te2 tm2 va ->
Mem.loadv chunk tm2 va = Some v ->
eval_expr tge (Vptr sp Int.zero) le
te1 tm1 (make_load chunk a)
- te2 tm2 v.
+ t te2 tm2 v.
Proof.
intros; unfold make_load.
eapply eval_load; eauto.
Qed.
-Lemma val_content_inject_cast:
- forall f chunk v1 v2 tv1,
- cast chunk v1 = Some v2 ->
- val_inject f v1 tv1 ->
- val_content_inject f (mem_chunk chunk) v2 tv1.
+Lemma store_arg_content_inject:
+ forall f sp le te1 tm1 a t te2 tm2 v va chunk,
+ eval_expr tge (Vptr sp Int.zero) le te1 tm1 a t te2 tm2 va ->
+ val_inject f v va ->
+ exists vb,
+ eval_expr tge (Vptr sp Int.zero) le te1 tm1 (store_arg chunk a) t te2 tm2 vb
+ /\ val_content_inject f (mem_chunk chunk) v vb.
Proof.
- intros. destruct chunk; destruct v1; simplify_eq H; intro; subst v2;
- inversion H0; simpl.
- apply val_content_inject_8. apply Int.cast8_unsigned_signed.
- apply val_content_inject_8. apply Int.cast8_unsigned_idem.
- apply val_content_inject_16. apply Int.cast16_unsigned_signed.
- apply val_content_inject_16. apply Int.cast16_unsigned_idem.
- constructor; constructor.
- constructor; econstructor; eauto.
- apply val_content_inject_32. apply Float.singleoffloat_idem.
- constructor; constructor.
+ intros.
+ assert (exists vb,
+ eval_expr tge (Vptr sp Int.zero) le te1 tm1 a t te2 tm2 vb
+ /\ val_content_inject f (mem_chunk chunk) v vb).
+ exists va; split. assumption. constructor. assumption.
+ inversion H; clear H; subst; simpl; trivial.
+ inversion H2; clear H2; subst; trivial.
+ inversion H4; clear H4; subst; trivial.
+ rewrite E0_right. rewrite E0_right in H1.
+ destruct op; trivial; destruct chunk; trivial;
+ exists v0; (split; [auto|
+ simpl in H3; inversion H3; clear H3; subst va;
+ destruct v0; simpl in H0; inversion H0; subst; try (constructor; constructor)]).
+ apply val_content_inject_8. apply Int.cast8_unsigned_signed.
+ apply val_content_inject_8. apply Int.cast8_unsigned_idem.
+ apply val_content_inject_16. apply Int.cast16_unsigned_signed.
+ apply val_content_inject_16. apply Int.cast16_unsigned_idem.
+ apply val_content_inject_32. apply Float.singleoffloat_idem.
Qed.
Lemma make_store_correct:
- forall f sp le te1 tm1 addr te2 tm2 tvaddr rhs te3 tm3 tvrhs
- chunk vrhs v m3 vaddr m4,
- eval_expr tge (Vptr sp Int.zero) le
- te1 tm1 addr te2 tm2 tvaddr ->
- eval_expr tge (Vptr sp Int.zero) le
- te2 tm2 rhs te3 tm3 tvrhs ->
- cast chunk vrhs = Some v ->
- Mem.storev chunk m3 vaddr v = Some m4 ->
+ forall f sp te1 tm1 addr te2 tm2 tvaddr rhs te3 tm3 tvrhs
+ chunk vrhs m3 vaddr m4 t1 t2,
+ eval_expr tge (Vptr sp Int.zero) nil
+ te1 tm1 addr t1 te2 tm2 tvaddr ->
+ eval_expr tge (Vptr sp Int.zero) nil
+ te2 tm2 rhs t2 te3 tm3 tvrhs ->
+ Mem.storev chunk m3 vaddr vrhs = Some m4 ->
mem_inject f m3 tm3 ->
val_inject f vaddr tvaddr ->
val_inject f vrhs tvrhs ->
- exists tm4, exists tv,
- eval_expr tge (Vptr sp Int.zero) le
+ exists tm4,
+ exec_stmt tge (Vptr sp Int.zero)
te1 tm1 (make_store chunk addr rhs)
- te3 tm4 tv
+ (t1**t2) te3 tm4 Out_normal
/\ mem_inject f m4 tm4
- /\ val_inject f v tv
/\ nextblock tm4 = nextblock tm3.
Proof.
intros. unfold make_store.
- assert (val_content_inject f (mem_chunk chunk) v tvrhs).
- eapply val_content_inject_cast; eauto.
- elim (storev_mapped_inject_1 _ _ _ _ _ _ _ _ _ H3 H2 H4 H6).
- intros tm4 [STORE MEMINJ].
- generalize (eval_store _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ H H0 STORE).
+ exploit store_arg_content_inject. eexact H0. eauto.
+ intros [tv [EVAL VCINJ]].
+ exploit storev_mapped_inject_1; eauto.
+ intros [tm4 [STORE MEMINJ]].
+ exploit eval_store. eexact H. eexact EVAL. eauto.
intro EVALSTORE.
- elim (make_cast_correct _ _ _ _ _ _ _ _ _ _ _ _ EVALSTORE H1 H5).
- intros tv [EVALCAST [VALINJ VALNORM]].
- exists tm4; exists tv. intuition.
+ exists tm4.
+ split. apply exec_Sexpr with tv. auto.
+ split. auto.
unfold storev in STORE; destruct tvaddr; try discriminate.
- generalize (store_inv _ _ _ _ _ _ STORE). simpl. tauto.
+ exploit store_inv; eauto. simpl. tauto.
Qed.
(** Correctness of the variable accessors [var_get], [var_set]
@@ -1009,7 +1112,7 @@ Lemma var_get_correct:
eval_var_ref prog e id b chunk ->
load chunk m b 0 = Some v ->
exists tv,
- eval_expr tge (Vptr sp Int.zero) le te tm a te tm tv /\
+ eval_expr tge (Vptr sp Int.zero) le te tm a E0 te tm tv /\
val_inject f v tv.
Proof.
unfold var_get; intros.
@@ -1025,8 +1128,8 @@ Proof.
inversion H2; [subst|congruence].
assert (b0 = b). congruence. subst b0.
assert (chunk0 = chunk). congruence. subst chunk0.
- assert (loadv chunk m (Vptr b Int.zero) = Some v). assumption.
- generalize (loadv_inject _ _ _ _ _ _ _ H1 H9 H7).
+ exploit loadv_inject; eauto.
+ unfold loadv. eexact H3.
intros [tv [LOAD INJ]].
exists tv; split.
eapply make_load_correct; eauto. eapply make_stackaddr_correct; eauto.
@@ -1052,7 +1155,7 @@ Lemma var_addr_correct:
var_addr cenv id = Some a ->
eval_var_addr prog e id b ->
exists tv,
- eval_expr tge (Vptr sp Int.zero) le te tm a te tm tv /\
+ eval_expr tge (Vptr sp Int.zero) le te tm a E0 te tm tv /\
val_inject f (Vptr b Int.zero) tv.
Proof.
unfold var_addr; intros.
@@ -1086,65 +1189,61 @@ Proof.
Qed.
Lemma var_set_correct:
- forall cenv id rhs a f e te2 sp lo hi m2 cs tm2 le te1 tm1 vrhs b chunk v1 v2 m3,
+ forall cenv id rhs a f e te2 sp lo hi m2 cs tm2 te1 tm1 tv b chunk v m3 t,
var_set cenv id rhs = Some a ->
match_callstack f (mkframe cenv e te2 sp lo hi :: cs) m2.(nextblock) tm2.(nextblock) m2 ->
- eval_expr tge (Vptr sp Int.zero) le te1 tm1 rhs te2 tm2 vrhs ->
- val_inject f v1 vrhs ->
+ eval_expr tge (Vptr sp Int.zero) nil te1 tm1 rhs t te2 tm2 tv ->
+ val_inject f v tv ->
mem_inject f m2 tm2 ->
eval_var_ref prog e id b chunk ->
- cast chunk v1 = Some v2 ->
- store chunk m2 b 0 v2 = Some m3 ->
- exists te3, exists tm3, exists tv,
- eval_expr tge (Vptr sp Int.zero) le te1 tm1 a te3 tm3 tv /\
- val_inject f v2 tv /\
+ store chunk m2 b 0 v = Some m3 ->
+ exists te3, exists tm3,
+ exec_stmt tge (Vptr sp Int.zero) te1 tm1 a t te3 tm3 Out_normal /\
mem_inject f m3 tm3 /\
match_callstack f (mkframe cenv e te3 sp lo hi :: cs) m3.(nextblock) tm3.(nextblock) m3.
Proof.
unfold var_set; intros.
assert (NEXTBLOCK: nextblock m3 = nextblock m2).
- generalize (store_inv _ _ _ _ _ _ H6). simpl. tauto.
+ exploit store_inv; eauto. simpl; tauto.
inversion H0. subst f0 cenv0 e0 te sp0 lo0 hi0 cs0 bound tbound m.
- assert (match_var f id e m2 te2 sp cenv!!id). inversion H20; auto.
- inversion H7; subst; rewrite <- H8 in H; inversion H; subst; clear H.
+ assert (match_var f id e m2 te2 sp cenv!!id). inversion H19; auto.
+ inversion H6; subst; rewrite <- H7 in H; inversion H; subst; clear H.
(* var_local *)
inversion H4; [subst|congruence].
assert (b0 = b). congruence. subst b0.
assert (chunk0 = chunk). congruence. subst chunk0.
- elim (make_cast_correct _ _ _ _ _ _ _ _ _ _ _ _ H1 H5 H2).
- intros tv [EVAL [INJ NORM]].
- exists (PTree.set id tv te2); exists tm2; exists tv.
- split. eapply eval_Eassign. auto.
- split. auto.
+ exploit make_cast_correct; eauto.
+ intros [tv' [EVAL INJ]].
+ exists (PTree.set id tv' te2); exists tm2.
+ split. eapply exec_Sexpr. eapply eval_Eassign. eauto.
split. eapply store_unmapped_inject; eauto.
rewrite NEXTBLOCK. eapply match_callstack_store_local; eauto.
(* var_stack_scalar *)
inversion H4; [subst|congruence].
assert (b0 = b). congruence. subst b0.
assert (chunk0 = chunk). congruence. subst chunk0.
- assert (storev chunk m2 (Vptr b Int.zero) v2 = Some m3). assumption.
- generalize (make_stackaddr_correct sp le te1 tm1 ofs). intro EVALSTACKADDR.
- generalize (make_store_correct _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
- EVALSTACKADDR H1 H5 H11 H3 H10 H2).
- intros [tm3 [tv [EVAL [MEMINJ [VALINJ TNEXTBLOCK]]]]].
- exists te2; exists tm3; exists tv.
- split. auto. split. auto. split. auto.
+ assert (storev chunk m2 (Vptr b Int.zero) v = Some m3). assumption.
+ exploit make_store_correct.
+ eapply make_stackaddr_correct.
+ eauto. eauto. eauto. eauto. eauto.
+ rewrite E0_left. intros [tm3 [EVAL [MEMINJ TNEXTBLOCK]]].
+ exists te2; exists tm3.
+ split. auto. split. auto.
rewrite NEXTBLOCK; rewrite TNEXTBLOCK.
eapply match_callstack_mapped; eauto.
- inversion H10; congruence.
+ inversion H9; congruence.
(* var_global_scalar *)
inversion H4; [congruence|subst].
assert (chunk0 = chunk). congruence. subst chunk0.
- assert (storev chunk m2 (Vptr b Int.zero) v2 = Some m3). assumption.
+ assert (storev chunk m2 (Vptr b Int.zero) v = Some m3). assumption.
assert (match_globalenvs f). eapply match_callstack_match_globalenvs; eauto.
- inversion H14. destruct (mg_symbols0 _ _ H11) as [A B].
- assert (val_inject f (Vptr b Int.zero) (Vptr b Int.zero)). econstructor; eauto.
- generalize (make_globaladdr_correct sp le te1 tm1 id b B). intro EVALGLOBALADDR.
- generalize (make_store_correct _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
- EVALGLOBALADDR H1 H5 H13 H3 H15 H2).
- intros [tm3 [tv [EVAL [MEMINJ [VALINJ TNEXTBLOCK]]]]].
- exists te2; exists tm3; exists tv.
- split. auto. split. auto. split. auto.
+ inversion H13. destruct (mg_symbols0 _ _ H10) as [A B].
+ exploit make_store_correct.
+ eapply make_globaladdr_correct; eauto.
+ eauto. eauto. eauto. eauto. eauto.
+ rewrite E0_left. intros [tm3 [EVAL [MEMINJ TNEXTBLOCK]]].
+ exists te2; exists tm3.
+ split. auto. split. auto.
rewrite NEXTBLOCK; rewrite TNEXTBLOCK.
eapply match_callstack_mapped; eauto. congruence.
Qed.
@@ -1228,36 +1327,26 @@ Proof.
omega. omega. omega. omega. unfold sizeof; rewrite LV. omega.
intros. left. generalize (BOUND _ _ H5). omega.
elim H3; intros MINJ1 INCR1; clear H3.
- assert (MATCH1: match_callstack f1
- (mkframe cenv1 (PTree.set id (b1, lv) e) te sp lo (nextblock m1) :: cs)
- (nextblock m1) (nextblock tm) m1).
- unfold f1; rewrite <- H2; eapply match_callstack_alloc_left; eauto.
- assert (SZ1POS: 0 <= sz1). rewrite <- H1. omega.
- assert (BOUND1: forall b delta, f1 b = Some(sp, delta) ->
- high_bound m1 b + delta <= sz1).
+ exploit IHalloc_variables; eauto.
+ unfold f1; rewrite <- H2; eapply match_callstack_alloc_left; eauto.
+ rewrite <- H1. omega.
intros until delta; unfold f1, extend_inject, eq_block.
rewrite (high_bound_alloc _ _ b _ _ _ H).
case (zeq b b1); intros.
inversion H3. unfold sizeof; rewrite LV. omega.
generalize (BOUND _ _ H3). omega.
- generalize (IHalloc_variables _ _ _ ASVS MATCH1 MINJ1 SZ1POS BOUND1 DEFINED1).
intros [f' [INCR2 [MINJ2 MATCH2]]].
exists f'; intuition. eapply inject_incr_trans; eauto.
(* 1.2 info = Var_local chunk *)
intro EQ; injection EQ; intros; clear EQ. subst sz1.
- generalize (alloc_unmapped_inject _ _ _ _ _ _ _ MINJ H).
+ exploit alloc_unmapped_inject; eauto.
set (f1 := extend_inject b1 None f). intros [MINJ1 INCR1].
- assert (MATCH1: match_callstack f1
- (mkframe cenv1 (PTree.set id (b1, lv) e) te sp lo (nextblock m1) :: cs)
- (nextblock m1) (nextblock tm) m1).
- unfold f1; rewrite <- H2; eapply match_callstack_alloc_left; eauto.
- assert (BOUND1: forall b delta, f1 b = Some(sp, delta) ->
- high_bound m1 b + delta <= sz).
+ exploit IHalloc_variables; eauto.
+ unfold f1; rewrite <- H2; eapply match_callstack_alloc_left; eauto.
intros until delta; unfold f1, extend_inject, eq_block.
rewrite (high_bound_alloc _ _ b _ _ _ H).
case (zeq b b1); intros. discriminate.
eapply BOUND; eauto.
- generalize (IHalloc_variables _ _ _ ASVS MATCH1 MINJ1 SZPOS BOUND1 DEFINED1).
intros [f' [INCR2 [MINJ2 MATCH2]]].
exists f'; intuition. eapply inject_incr_trans; eauto.
(* 2. lv = LVarray dim, info = Var_stack_array *)
@@ -1273,20 +1362,15 @@ Proof.
unfold f1; eapply alloc_mapped_inject; eauto.
omega. omega. omega. omega. unfold sizeof; rewrite LV. omega.
intros. left. generalize (BOUND _ _ H8). omega.
- elim H6; intros MINJ1 INCR1; clear H6.
- assert (MATCH1: match_callstack f1
- (mkframe cenv1 (PTree.set id (b1, lv) e) te sp lo (nextblock m1) :: cs)
- (nextblock m1) (nextblock tm) m1).
+ destruct H6 as [MINJ1 INCR1].
+ exploit IHalloc_variables; eauto.
unfold f1; rewrite <- H2; eapply match_callstack_alloc_left; eauto.
- assert (SZ1POS: 0 <= sz1). rewrite <- H1. omega.
- assert (BOUND1: forall b delta, f1 b = Some(sp, delta) ->
- high_bound m1 b + delta <= sz1).
- intros until delta; unfold f1, extend_inject, eq_block.
- rewrite (high_bound_alloc _ _ b _ _ _ H).
- case (zeq b b1); intros.
- inversion H6. unfold sizeof; rewrite LV. omega.
- generalize (BOUND _ _ H6). omega.
- generalize (IHalloc_variables _ _ _ ASVS MATCH1 MINJ1 SZ1POS BOUND1 DEFINED1).
+ rewrite <- H1. omega.
+ intros until delta; unfold f1, extend_inject, eq_block.
+ rewrite (high_bound_alloc _ _ b _ _ _ H).
+ case (zeq b b1); intros.
+ inversion H6. unfold sizeof; rewrite LV. omega.
+ generalize (BOUND _ _ H6). omega.
intros [f' [INCR2 [MINJ2 MATCH2]]].
exists f'; intuition. eapply inject_incr_trans; eauto.
Qed.
@@ -1370,15 +1454,15 @@ Proof.
(* me_inj *)
intros until lv2. unfold Csharpminor.empty_env; rewrite PTree.gempty; congruence.
(* me_inv *)
- intros. elim (mi_mappedblocks _ _ _ H4 _ _ _ H5); intros.
- elim (fresh_block_alloc _ _ _ _ _ H2 H6).
+ intros. exploit mi_mappedblocks; eauto. intros [A B].
+ elim (fresh_block_alloc _ _ _ _ _ H2 A).
(* me_incr *)
- intros. elim (mi_mappedblocks _ _ _ H4 _ _ _ H5); intros.
+ intros. exploit mi_mappedblocks; eauto. intros [A B].
rewrite SP; auto.
rewrite SP; auto.
eapply alloc_right_inject; eauto.
omega.
- intros. elim (mi_mappedblocks _ _ _ H4 _ _ _ H5); intros.
+ intros. exploit mi_mappedblocks; eauto. intros [A B].
unfold block in SP; omegaContradiction.
(* defined *)
intros. unfold te. apply set_locals_params_defined.
@@ -1421,7 +1505,7 @@ Proof.
unfold block; rewrite H2; omega.
elim H4; intro. left; congruence. right; auto.
elim H3; intro. subst b b1.
- generalize (alloc_variables_nextblock_incr _ _ _ _ _ _ H0).
+ generalize (alloc_variables_nextblock_incr _ _ _ _ _ _ H0).
rewrite H2. omega.
generalize (B H4). rewrite H2. omega.
Qed.
@@ -1465,7 +1549,7 @@ Lemma store_parameters_correct:
exists te2, exists tm2,
exec_stmt tge (Vptr sp Int.zero)
te1 tm1 (store_parameters cenv params)
- te2 tm2 Out_normal
+ E0 te2 tm2 Out_normal
/\ mem_inject f m2 tm2
/\ match_callstack f (mkframe cenv e te2 sp lo hi :: cs) m2.(nextblock) tm2.(nextblock) m2.
Proof.
@@ -1476,59 +1560,54 @@ Proof.
intros until tm1. intros VVM NOREPET MINJ MATCH. simpl.
inversion VVM. subst f0 id0 chunk0 vars v vals te.
inversion MATCH. subst f0 cenv0 e0 te sp0 lo0 hi0 cs0 bound tbound m0.
- inversion H19.
+ inversion H18.
inversion NOREPET. subst hd tl.
assert (NEXT: nextblock m1 = nextblock m).
- generalize (store_inv _ _ _ _ _ _ H1). simpl; tauto.
- generalize (me_vars0 id). intro. inversion H3; subst.
+ exploit store_inv; eauto. simpl; tauto.
+ generalize (me_vars0 id). intro. inversion H2; subst.
(* cenv!!id = Var_local chunk *)
assert (b0 = b). congruence. subst b0.
assert (chunk0 = chunk). congruence. subst chunk0.
assert (v' = tv). congruence. subst v'.
- assert (eval_expr tge (Vptr sp Int.zero) nil te1 tm1 (Evar id) te1 tm1 tv).
- constructor. auto.
- generalize (make_cast_correct _ _ _ _ _ _ _ _ _ _ _ _
- H15 H0 H11).
- intros [tv' [EVAL1 [VINJ1 VNORM]]].
+ exploit make_cast_correct.
+ apply eval_Evar with (id := id). eauto.
+ eexact H10.
+ intros [tv' [EVAL1 VINJ1]].
set (te2 := PTree.set id tv' te1).
assert (VVM2: vars_vals_match f params vl te2).
apply vars_vals_match_extensional with te1; auto.
intros. unfold te2; apply PTree.gso. red; intro; subst id0.
- elim H5. change id with (fst (id, lv)). apply List.in_map; auto.
- generalize (store_unmapped_inject _ _ _ _ _ _ _ _ MINJ H1 H9); intro MINJ2.
- generalize (match_callstack_store_local _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
- H VINJ1 VNORM H1 MATCH);
+ elim H4. change id with (fst (id, lv)). apply List.in_map; auto.
+ exploit store_unmapped_inject; eauto. intro MINJ2.
+ exploit match_callstack_store_local; eauto.
fold te2; rewrite <- NEXT; intro MATCH2.
- destruct (IHbind_parameters _ _ _ _ _ _ _ _ VVM2 H6 MINJ2 MATCH2)
- as [te3 [tm3 [EXEC3 [MINJ3 MATCH3]]]].
+ exploit IHbind_parameters; eauto.
+ intros [te3 [tm3 [EXEC3 [MINJ3 MATCH3]]]].
exists te3; exists tm3.
(* execution *)
- split. apply exec_Sseq_continue with te2 tm1.
- econstructor. unfold te2. constructor. assumption.
- assumption.
+ split. apply exec_Sseq_continue with E0 te2 tm1 E0.
+ econstructor. unfold te2. constructor. eassumption.
+ assumption. traceEq.
(* meminj & match_callstack *)
tauto.
(* cenv!!id = Var_stack_scalar *)
assert (b0 = b). congruence. subst b0.
assert (chunk0 = chunk). congruence. subst chunk0.
- pose (EVAL1 := make_stackaddr_correct sp nil te1 tm1 ofs).
- assert (EVAL2: eval_expr tge (Vptr sp Int.zero) nil te1 tm1 (Evar id) te1 tm1 tv).
- constructor. auto.
- destruct (make_store_correct _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
- (Vptr b Int.zero) _
- EVAL1 EVAL2 H0 H1 MINJ H8 H11)
- as [tm2 [tv' [EVAL3 [MINJ2 [VINJ NEXT1]]]]].
- assert (f b <> None). inversion H8. congruence.
- generalize (match_callstack_mapped _ _ _ _ _ MATCH _ _ _ _ _ H9 H1).
+ exploit make_store_correct.
+ eapply make_stackaddr_correct.
+ apply eval_Evar with (id := id).
+ eauto. 2:eauto. 2:eauto. unfold storev; eexact H0. eauto.
+ intros [tm2 [EVAL3 [MINJ2 NEXT1]]].
+ exploit match_callstack_mapped.
+ eexact MATCH. 2:eauto. inversion H7. congruence.
rewrite <- NEXT; rewrite <- NEXT1; intro MATCH2.
- destruct (IHbind_parameters _ _ _ _ _ _ _ _
- H12 H6 MINJ2 MATCH2) as [te3 [tm3 [EVAL4 [MINJ3 MATCH3]]]].
+ exploit IHbind_parameters; eauto.
+ intros [te3 [tm3 [EVAL4 [MINJ3 MATCH3]]]].
exists te3; exists tm3.
(* execution *)
- split. apply exec_Sseq_continue with te1 tm2.
- econstructor. eauto.
- assumption.
+ split. apply exec_Sseq_continue with (E0**E0) te1 tm2 E0.
+ auto. assumption. traceEq.
(* meminj & match_callstack *)
tauto.
@@ -1589,44 +1668,6 @@ Proof.
induction 1; simpl; eauto.
Qed.
-(****
-Lemma build_compilenv_domain:
- forall f id chunk,
- In (id, chunk) f.(Csharpminor.fn_params) ->
- (fst (build_compilenv gce f))!id <> None.
-Proof.
- assert (forall atk id lv cenv_sz id0,
- let cenv_sz' := assign_variable atk (id, lv) cenv_sz in
- (fst cenv_sz')!id <> None
- /\ ((fst cenv_sz)!id0 <> None -> (fst cenv_sz')!id0 <> None)).
- intros. unfold cenv_sz'. destruct cenv_sz as [cenv sz].
- unfold assign_variable. destruct lv.
- case (Identset.mem id atk); simpl. split. rewrite PTree.gss. congruence.
- rewrite PTree.gsspec. case (peq id0 id); intros. congruence. auto.
- split. rewrite PTree.gss. congruence.
- rewrite PTree.gsspec. case (peq id0 id); intros. congruence. auto.
- simpl. split. rewrite PTree.gss. congruence.
- rewrite PTree.gsspec. case (peq id0 id); intros. congruence. auto.
-
- assert (forall atk id_lv_list cenv_sz id lv,
- In (id, lv) id_lv_list \/ (fst cenv_sz)!id <> None ->
- (fst (assign_variables atk id_lv_list cenv_sz))!id <> None).
- induction id_lv_list; simpl; intros.
- tauto.
- apply IHid_lv_list with lv.
- destruct a as [id0 lv0].
- generalize (H atk id0 lv0 cenv_sz id).
- simpl. intro. intuition. injection H0; intros; subst id0 lv0. intuition.
-
- intros. unfold build_compilenv. apply H0 with (Vscalar chunk).
- left. unfold fn_variables. apply List.in_or_app. left.
- set (g := fun (id_chunk : ident * memory_chunk) => (fst id_chunk, Vscalar (snd id_chunk))).
- change positive with ident.
- change (id, Vscalar chunk) with (g (id, chunk)).
- apply List.in_map. auto.
-Qed.
-****)
-
(** The final result in this section: the behaviour of function entry
in the generated Cminor code (allocate stack data block and store
parameters whose address is taken) simulates what happens at function
@@ -1649,7 +1690,7 @@ Lemma function_entry_ok:
exists f2, exists te2, exists tm2,
exec_stmt tge (Vptr sp Int.zero)
te tm1 (store_parameters cenv fn.(Csharpminor.fn_params))
- te2 tm2 Out_normal
+ E0 te2 tm2 Out_normal
/\ mem_inject f2 m2 tm2
/\ inject_incr f f2
/\ match_callstack f2
@@ -1658,24 +1699,21 @@ Lemma function_entry_ok:
/\ (forall b, m.(nextblock) <= b < m1.(nextblock) <-> In b lb).
Proof.
intros.
- generalize (bind_parameters_length _ _ _ _ _ H0); intro LEN1.
- destruct (match_callstack_alloc_variables _ _ _ _ _ _ _ _ _ _ _ _ tvargs
- H2 H3 H H4 H1 H6)
- as [f1 [INCR1 [MINJ1 MATCH1]]].
- fold te in MATCH1.
- assert (VLI: val_list_inject f1 vargs tvargs).
- eapply val_list_inject_incr; eauto.
- generalize (vars_vals_match_holds _ _ _ _ LEN1 VLI _
- (list_norepet_append_commut _ _ H7)).
- fold te. intro VVM.
- assert (NOREPET: list_norepet (List.map (@fst ident memory_chunk) fn.(Csharpminor.fn_params))).
- unfold fn_params_names in H7.
- eapply list_norepet_append_left; eauto.
- destruct (store_parameters_correct _ _ _ _ _ H0 _ _ _ _ _ _ _ _
- VVM NOREPET MINJ1 MATCH1)
- as [te2 [tm2 [EXEC [MINJ2 MATCH2]]]].
+ exploit bind_parameters_length; eauto. intro LEN1.
+ exploit match_callstack_alloc_variables; eauto.
+ intros [f1 [INCR1 [MINJ1 MATCH1]]].
+ exploit vars_vals_match_holds.
+ eauto. apply val_list_inject_incr with f. eauto. eauto.
+ apply list_norepet_append_commut.
+ unfold fn_vars_names in H7. eexact H7.
+ intro VVM.
+ exploit store_parameters_correct.
+ eauto. eauto.
+ unfold fn_params_names in H7. eapply list_norepet_append_left; eauto.
+ eexact MINJ1. eauto.
+ intros [te2 [tm2 [EXEC [MINJ2 MATCH2]]]].
exists f1; exists te2; exists tm2.
- split. auto. split. auto. split. auto. split. auto.
+ split; auto. split; auto. split; auto. split; auto.
intros; eapply alloc_variables_list_block; eauto.
Qed.
@@ -1745,7 +1783,7 @@ Ltac monadInv H :=
hypotheses in the proof of simulation. *)
Definition eval_expr_prop
- (le: Csharpminor.letenv) (e: Csharpminor.env) (m1: mem) (a: Csharpminor.expr) (m2: mem) (v: val) : Prop :=
+ (le: Csharpminor.letenv) (e: Csharpminor.env) (m1: mem) (a: Csharpminor.expr) (t: trace) (m2: mem) (v: val) : Prop :=
forall cenv ta f1 tle te1 tm1 sp lo hi cs
(TR: transl_expr cenv a = Some ta)
(LINJ: val_list_inject f1 le tle)
@@ -1754,7 +1792,7 @@ Definition eval_expr_prop
(mkframe cenv e te1 sp lo hi :: cs)
m1.(nextblock) tm1.(nextblock) m1),
exists f2, exists te2, exists tm2, exists tv,
- eval_expr tge (Vptr sp Int.zero) tle te1 tm1 ta te2 tm2 tv
+ eval_expr tge (Vptr sp Int.zero) tle te1 tm1 ta t te2 tm2 tv
/\ val_inject f2 v tv
/\ mem_inject f2 m2 tm2
/\ inject_incr f1 f2
@@ -1763,7 +1801,7 @@ Definition eval_expr_prop
m2.(nextblock) tm2.(nextblock) m2.
Definition eval_exprlist_prop
- (le: Csharpminor.letenv) (e: Csharpminor.env) (m1: mem) (al: Csharpminor.exprlist) (m2: mem) (vl: list val) : Prop :=
+ (le: Csharpminor.letenv) (e: Csharpminor.env) (m1: mem) (al: Csharpminor.exprlist) (t: trace) (m2: mem) (vl: list val) : Prop :=
forall cenv tal f1 tle te1 tm1 sp lo hi cs
(TR: transl_exprlist cenv al = Some tal)
(LINJ: val_list_inject f1 le tle)
@@ -1772,7 +1810,7 @@ Definition eval_exprlist_prop
(mkframe cenv e te1 sp lo hi :: cs)
m1.(nextblock) tm1.(nextblock) m1),
exists f2, exists te2, exists tm2, exists tvl,
- eval_exprlist tge (Vptr sp Int.zero) tle te1 tm1 tal te2 tm2 tvl
+ eval_exprlist tge (Vptr sp Int.zero) tle te1 tm1 tal t te2 tm2 tvl
/\ val_list_inject f2 vl tvl
/\ mem_inject f2 m2 tm2
/\ inject_incr f1 f2
@@ -1781,14 +1819,14 @@ Definition eval_exprlist_prop
m2.(nextblock) tm2.(nextblock) m2.
Definition eval_funcall_prop
- (m1: mem) (fn: Csharpminor.function) (args: list val) (m2: mem) (res: val) : Prop :=
+ (m1: mem) (fn: Csharpminor.fundef) (args: list val) (t: trace) (m2: mem) (res: val) : Prop :=
forall tfn f1 tm1 cs targs
- (TR: transl_function gce fn = Some tfn)
+ (TR: transl_fundef gce fn = Some tfn)
(MINJ: mem_inject f1 m1 tm1)
(MATCH: match_callstack f1 cs m1.(nextblock) tm1.(nextblock) m1)
(ARGSINJ: val_list_inject f1 args targs),
exists f2, exists tm2, exists tres,
- eval_funcall tge tm1 tfn targs tm2 tres
+ eval_funcall tge tm1 tfn targs t tm2 tres
/\ val_inject f2 res tres
/\ mem_inject f2 m2 tm2
/\ inject_incr f1 f2
@@ -1807,7 +1845,7 @@ Inductive outcome_inject (f: meminj) : Csharpminor.outcome -> outcome -> Prop :=
outcome_inject f (Csharpminor.Out_return (Some v1)) (Out_return (Some v2)).
Definition exec_stmt_prop
- (e: Csharpminor.env) (m1: mem) (s: Csharpminor.stmt) (m2: mem) (out: Csharpminor.outcome): Prop :=
+ (e: Csharpminor.env) (m1: mem) (s: Csharpminor.stmt) (t: trace) (m2: mem) (out: Csharpminor.outcome): Prop :=
forall cenv ts f1 te1 tm1 sp lo hi cs
(TR: transl_stmt cenv s = Some ts)
(MINJ: mem_inject f1 m1 tm1)
@@ -1815,7 +1853,7 @@ Definition exec_stmt_prop
(mkframe cenv e te1 sp lo hi :: cs)
m1.(nextblock) tm1.(nextblock) m1),
exists f2, exists te2, exists tm2, exists tout,
- exec_stmt tge (Vptr sp Int.zero) te1 tm1 ts te2 tm2 tout
+ exec_stmt tge (Vptr sp Int.zero) te1 tm1 ts t te2 tm2 tout
/\ outcome_inject f2 out tout
/\ mem_inject f2 m2 tm2
/\ inject_incr f1 f2
@@ -1823,14 +1861,6 @@ Definition exec_stmt_prop
(mkframe cenv e te2 sp lo hi :: cs)
m2.(nextblock) tm2.(nextblock) m2.
-(*
-Check (eval_funcall_ind4 prog
- eval_expr_prop
- eval_exprlist_prop
- eval_funcall_prop
- exec_stmt_prop).
-*)
-
(** There are as many cases in the inductive proof as there are evaluation
rules in the Csharpminor semantics. We treat each case as a separate
lemma. *)
@@ -1841,33 +1871,12 @@ Lemma transl_expr_Evar_correct:
(b : block) (chunk : memory_chunk) (v : val),
eval_var_ref prog e id b chunk ->
load chunk m b 0 = Some v ->
- eval_expr_prop le e m (Csharpminor.Evar id) m v.
+ eval_expr_prop le e m (Csharpminor.Evar id) E0 m v.
Proof.
intros; red; intros. unfold transl_expr in TR.
- generalize (var_get_correct _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tle
- TR MATCH MINJ H H0).
+ exploit var_get_correct; eauto.
intros [tv [EVAL VINJ]].
- exists f1; exists te1; exists tm1; exists tv; intuition.
-Qed.
-
-Lemma transl_expr_Eassign_correct:
- forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
- (id : positive) (a : Csharpminor.expr) (m1 : mem) (b : block)
- (chunk : memory_chunk) (v1 v2 : val) (m2 : mem),
- Csharpminor.eval_expr prog le e m a m1 v1 ->
- eval_expr_prop le e m a m1 v1 ->
- eval_var_ref prog e id b chunk ->
- cast chunk v1 = Some v2 ->
- store chunk m1 b 0 v2 = Some m2 ->
- eval_expr_prop le e m (Csharpminor.Eassign id a) m2 v2.
-Proof.
- intros; red; intros. monadInv TR; intro EQ0.
- generalize (H0 _ _ _ _ _ _ _ _ _ _ EQ LINJ MINJ MATCH).
- intros [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR12 MATCH1]]]]]]]].
- generalize (var_set_correct _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
- EQ0 MATCH1 EVAL1 VINJ1 MINJ1 H1 H2 H3).
- intros [te3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 MATCH2]]]]]].
- exists f2; exists te3; exists tm3; exists tv2. tauto.
+ exists f1; exists te1; exists tm1; exists tv; intuition eauto.
Qed.
Lemma transl_expr_Eaddrof_correct:
@@ -1875,199 +1884,162 @@ Lemma transl_expr_Eaddrof_correct:
(e : Csharpminor.env) (m : mem) (id : positive)
(b : block),
eval_var_addr prog e id b ->
- eval_expr_prop le e m (Eaddrof id) m (Vptr b Int.zero).
+ eval_expr_prop le e m (Eaddrof id) E0 m (Vptr b Int.zero).
Proof.
intros; red; intros. simpl in TR.
- generalize (var_addr_correct _ _ _ _ _ _ _ _ _ _ _ _ _ tle
- MATCH TR H).
+ exploit var_addr_correct; eauto.
intros [tv [EVAL VINJ]].
- exists f1; exists te1; exists tm1; exists tv. intuition.
+ exists f1; exists te1; exists tm1; exists tv. intuition eauto.
Qed.
Lemma transl_expr_Eop_correct:
forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
- (op : Csharpminor.operation) (al : Csharpminor.exprlist) (m1 : mem)
- (vl : list val) (v : val),
- Csharpminor.eval_exprlist prog le e m al m1 vl ->
- eval_exprlist_prop le e m al m1 vl ->
+ (op : Csharpminor.operation) (al : Csharpminor.exprlist)
+ (t: trace) (m1 : mem) (vl : list val) (v : val),
+ Csharpminor.eval_exprlist prog le e m al t m1 vl ->
+ eval_exprlist_prop le e m al t m1 vl ->
Csharpminor.eval_operation op vl m1 = Some v ->
- eval_expr_prop le e m (Csharpminor.Eop op al) m1 v.
+ eval_expr_prop le e m (Csharpminor.Eop op al) t m1 v.
Proof.
intros; red; intros. monadInv TR; intro EQ0.
- generalize (H0 _ _ _ _ _ _ _ _ _ _ EQ LINJ MINJ MATCH).
+ exploit H0; eauto.
intros [f2 [te2 [tm2 [tvl [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]]].
- generalize (make_op_correct _ _ _ _ _ _ _ _ _ _ _ _ _ _
- EQ0 H1 EVAL1 VINJ1 MINJ1).
+ exploit make_op_correct; eauto.
intros [tv [EVAL2 VINJ2]].
exists f2; exists te2; exists tm2; exists tv. intuition.
Qed.
Lemma transl_expr_Eload_correct:
forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
- (chunk : memory_chunk) (a : Csharpminor.expr) (m1 : mem)
+ (chunk : memory_chunk) (a : Csharpminor.expr) (t: trace) (m1 : mem)
(v1 v : val),
- Csharpminor.eval_expr prog le e m a m1 v1 ->
- eval_expr_prop le e m a m1 v1 ->
+ Csharpminor.eval_expr prog le e m a t m1 v1 ->
+ eval_expr_prop le e m a t m1 v1 ->
loadv chunk m1 v1 = Some v ->
- eval_expr_prop le e m (Csharpminor.Eload chunk a) m1 v.
+ eval_expr_prop le e m (Csharpminor.Eload chunk a) t m1 v.
Proof.
intros; red; intros.
monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ _ EQ LINJ MINJ MATCH)
- as [f2 [te2 [tm2 [tv1 [EVAL [VINJ1 [MINJ2 [INCR MATCH2]]]]]]]].
- destruct (loadv_inject _ _ _ _ _ _ _ MINJ2 H1 VINJ1)
- as [tv [TLOAD VINJ]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL [VINJ1 [MINJ2 [INCR MATCH2]]]]]]]].
+ exploit loadv_inject; eauto.
+ intros [tv [TLOAD VINJ]].
exists f2; exists te2; exists tm2; exists tv.
intuition.
subst ta. eapply make_load_correct; eauto.
Qed.
-Lemma transl_expr_Estore_correct:
- forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
- (chunk : memory_chunk) (a b : Csharpminor.expr) (m1 : mem)
- (v1 : val) (m2 : mem) (v2 : val) (m3 : mem) (v3 : val),
- Csharpminor.eval_expr prog le e m a m1 v1 ->
- eval_expr_prop le e m a m1 v1 ->
- Csharpminor.eval_expr prog le e m1 b m2 v2 ->
- eval_expr_prop le e m1 b m2 v2 ->
- cast chunk v2 = Some v3 ->
- storev chunk m2 v1 v3 = Some m3 ->
- eval_expr_prop le e m (Csharpminor.Estore chunk a b) m3 v3.
-Proof.
- intros; red; intros. monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ _ EQ LINJ MINJ MATCH)
- as [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
- assert (LINJ2: val_list_inject f2 le tle). eapply val_list_inject_incr; eauto.
- destruct (H2 _ _ _ _ _ _ _ _ _ _ EQ0 LINJ2 MINJ2 MATCH2)
- as [f3 [te3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ3 [INCR3 MATCH3]]]]]]]].
- assert (VINJ1': val_inject f3 v1 tv1). eapply val_inject_incr; eauto.
- destruct (make_store_correct _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
- EVAL1 EVAL2 H3 H4 MINJ3 VINJ1' VINJ2)
- as [tm4 [tv [EVAL [MINJ4 [VINJ4 NEXTBLOCK]]]]].
- exists f3; exists te3; exists tm4; exists tv.
- rewrite <- H6. intuition.
- eapply inject_incr_trans; eauto.
- assert (val_inject f3 v1 tv1). eapply val_inject_incr; eauto.
- unfold storev in H4; destruct v1; try discriminate.
- inversion H5.
- rewrite NEXTBLOCK. replace (nextblock m3) with (nextblock m2).
- eapply match_callstack_mapped; eauto. congruence.
- generalize (store_inv _ _ _ _ _ _ H4). simpl; symmetry; tauto.
-Qed.
-
-Lemma sig_transl_function:
- forall f tf, transl_function gce f = Some tf -> tf.(fn_sig) = f.(Csharpminor.fn_sig).
-Proof.
- intros f tf. unfold transl_function.
- destruct (build_compilenv gce f).
- case (zle z Int.max_signed); intros.
- monadInv H. subst tf; reflexivity.
- congruence.
-Qed.
-
Lemma transl_expr_Ecall_correct:
forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
(sig : signature) (a : Csharpminor.expr) (bl : Csharpminor.exprlist)
- (m1 m2 m3 : mem) (vf : val) (vargs : list val) (vres : val)
- (f : Csharpminor.function),
- Csharpminor.eval_expr prog le e m a m1 vf ->
- eval_expr_prop le e m a m1 vf ->
- Csharpminor.eval_exprlist prog le e m1 bl m2 vargs ->
- eval_exprlist_prop le e m1 bl m2 vargs ->
+ (t1: trace) (m1: mem) (t2: trace) (m2: mem) (t3: trace) (m3: mem)
+ (vf : val) (vargs : list val) (vres : val)
+ (f : Csharpminor.fundef) (t: trace),
+ Csharpminor.eval_expr prog le e m a t1 m1 vf ->
+ eval_expr_prop le e m a t1 m1 vf ->
+ Csharpminor.eval_exprlist prog le e m1 bl t2 m2 vargs ->
+ eval_exprlist_prop le e m1 bl t2 m2 vargs ->
Genv.find_funct ge vf = Some f ->
- Csharpminor.fn_sig f = sig ->
- Csharpminor.eval_funcall prog m2 f vargs m3 vres ->
- eval_funcall_prop m2 f vargs m3 vres ->
- eval_expr_prop le e m (Csharpminor.Ecall sig a bl) m3 vres.
+ Csharpminor.funsig f = sig ->
+ Csharpminor.eval_funcall prog m2 f vargs t3 m3 vres ->
+ eval_funcall_prop m2 f vargs t3 m3 vres ->
+ t = t1 ** t2 ** t3 ->
+ eval_expr_prop le e m (Csharpminor.Ecall sig a bl) t m3 vres.
Proof.
intros;red;intros. monadInv TR. subst ta.
- generalize (H0 _ _ _ _ _ _ _ _ _ _ EQ LINJ MINJ MATCH).
+ exploit H0; eauto.
intros [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]]].
- assert (LINJ1: val_list_inject f2 le tle). eapply val_list_inject_incr; eauto.
- generalize (H2 _ _ _ _ _ _ _ _ _ _ EQ0 LINJ1 MINJ1 MATCH1).
+ exploit H2.
+ eauto. eapply val_list_inject_incr; eauto. eauto. eauto.
intros [f3 [te3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]]].
assert (tv1 = vf).
elim (Genv.find_funct_inv H3). intros bf VF. rewrite VF in H3.
rewrite Genv.find_funct_find_funct_ptr in H3.
generalize (Genv.find_funct_ptr_inv H3). intro.
assert (match_globalenvs f2). eapply match_callstack_match_globalenvs; eauto.
- generalize (mg_functions _ H8 _ H7). intro.
+ generalize (mg_functions _ H9 _ H8). intro.
rewrite VF in VINJ1. inversion VINJ1. subst vf.
decEq. congruence.
subst ofs2. replace x with 0. reflexivity. congruence.
subst tv1. elim (functions_translated _ _ H3). intros tf [FIND TRF].
- generalize (H6 _ _ _ _ _ TRF MINJ2 MATCH2 VINJ2).
+ exploit H6; eauto.
intros [f4 [tm4 [tres [EVAL3 [VINJ3 [MINJ3 [INCR3 MATCH3]]]]]]].
exists f4; exists te3; exists tm4; exists tres. intuition.
- eapply eval_Ecall; eauto. rewrite <- H4. apply sig_transl_function; auto.
+ eapply eval_Ecall; eauto.
+ rewrite <- H4. apply sig_preserved; auto.
apply inject_incr_trans with f2; auto.
apply inject_incr_trans with f3; auto.
Qed.
Lemma transl_expr_Econdition_true_correct:
forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
- (a b c : Csharpminor.expr) (m1 : mem) (v1 : val) (m2 : mem)
- (v2 : val),
- Csharpminor.eval_expr prog le e m a m1 v1 ->
- eval_expr_prop le e m a m1 v1 ->
+ (a b c : Csharpminor.expr) (t1: trace) (m1 : mem) (v1 : val)
+ (t2: trace) (m2 : mem) (v2 : val) (t: trace),
+ Csharpminor.eval_expr prog le e m a t1 m1 v1 ->
+ eval_expr_prop le e m a t1 m1 v1 ->
Val.is_true v1 ->
- Csharpminor.eval_expr prog le e m1 b m2 v2 ->
- eval_expr_prop le e m1 b m2 v2 ->
- eval_expr_prop le e m (Csharpminor.Econdition a b c) m2 v2.
+ Csharpminor.eval_expr prog le e m1 b t2 m2 v2 ->
+ eval_expr_prop le e m1 b t2 m2 v2 ->
+ t = t1 ** t2 ->
+ eval_expr_prop le e m (Csharpminor.Econdition a b c) t m2 v2.
Proof.
intros; red; intros. monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ _ EQ LINJ MINJ MATCH)
- as [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]]].
- assert (LINJ1: val_list_inject f2 le tle). eapply val_list_inject_incr; eauto.
- destruct (H3 _ _ _ _ _ _ _ _ _ _ EQ0 LINJ1 MINJ1 MATCH1)
- as [f3 [te3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]]].
+ exploit H3.
+ eauto. eapply val_list_inject_incr; eauto. eauto. eauto.
+ intros [f3 [te3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]]].
exists f3; exists te3; exists tm3; exists tv2.
intuition.
- rewrite <- H5. eapply eval_conditionalexpr_true; eauto.
+ rewrite <- H6. subst t; eapply eval_conditionalexpr_true; eauto.
inversion VINJ1; subst v1 tv1; simpl in H1; simpl; contradiction || auto.
eapply inject_incr_trans; eauto.
Qed.
Lemma transl_expr_Econdition_false_correct:
forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
- (a b c : Csharpminor.expr) (m1 : mem) (v1 : val) (m2 : mem)
- (v2 : val),
- Csharpminor.eval_expr prog le e m a m1 v1 ->
- eval_expr_prop le e m a m1 v1 ->
+ (a b c : Csharpminor.expr) (t1: trace) (m1 : mem) (v1 : val)
+ (t2: trace) (m2 : mem) (v2 : val) (t: trace),
+ Csharpminor.eval_expr prog le e m a t1 m1 v1 ->
+ eval_expr_prop le e m a t1 m1 v1 ->
Val.is_false v1 ->
- Csharpminor.eval_expr prog le e m1 c m2 v2 ->
- eval_expr_prop le e m1 c m2 v2 ->
- eval_expr_prop le e m (Csharpminor.Econdition a b c) m2 v2.
+ Csharpminor.eval_expr prog le e m1 c t2 m2 v2 ->
+ eval_expr_prop le e m1 c t2 m2 v2 ->
+ t = t1 ** t2 ->
+ eval_expr_prop le e m (Csharpminor.Econdition a b c) t m2 v2.
Proof.
intros; red; intros. monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ _ EQ LINJ MINJ MATCH)
- as [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]]].
- assert (LINJ1: val_list_inject f2 le tle). eapply val_list_inject_incr; eauto.
- destruct (H3 _ _ _ _ _ _ _ _ _ _ EQ1 LINJ1 MINJ1 MATCH1)
- as [f3 [te3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]]].
+ exploit H3.
+ eauto. eapply val_list_inject_incr; eauto. eauto. eauto.
+ intros [f3 [te3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]]].
exists f3; exists te3; exists tm3; exists tv2.
intuition.
- rewrite <- H5. eapply eval_conditionalexpr_false; eauto.
+ rewrite <- H6. subst t; eapply eval_conditionalexpr_false; eauto.
inversion VINJ1; subst v1 tv1; simpl in H1; simpl; contradiction || auto.
eapply inject_incr_trans; eauto.
Qed.
Lemma transl_expr_Elet_correct:
forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
- (a b : Csharpminor.expr) (m1 : mem) (v1 : val) (m2 : mem) (v2 : val),
- Csharpminor.eval_expr prog le e m a m1 v1 ->
- eval_expr_prop le e m a m1 v1 ->
- Csharpminor.eval_expr prog (v1 :: le) e m1 b m2 v2 ->
- eval_expr_prop (v1 :: le) e m1 b m2 v2 ->
- eval_expr_prop le e m (Csharpminor.Elet a b) m2 v2.
+ (a b : Csharpminor.expr) (t1: trace) (m1 : mem) (v1 : val)
+ (t2: trace) (m2 : mem) (v2 : val) (t: trace),
+ Csharpminor.eval_expr prog le e m a t1 m1 v1 ->
+ eval_expr_prop le e m a t1 m1 v1 ->
+ Csharpminor.eval_expr prog (v1 :: le) e m1 b t2 m2 v2 ->
+ eval_expr_prop (v1 :: le) e m1 b t2 m2 v2 ->
+ t = t1 ** t2 ->
+ eval_expr_prop le e m (Csharpminor.Elet a b) t m2 v2.
Proof.
intros; red; intros. monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ _ EQ LINJ MINJ MATCH)
- as [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]]].
- assert (LINJ1: val_list_inject f2 (v1 :: le) (tv1 :: tle)).
- constructor. auto. eapply val_list_inject_incr; eauto.
- destruct (H2 _ _ _ _ _ _ _ _ _ _ EQ0 LINJ1 MINJ1 MATCH1)
- as [f3 [te3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]]].
+ exploit H2.
+ eauto.
+ constructor. eauto. eapply val_list_inject_incr; eauto.
+ eauto. eauto.
+ intros [f3 [te3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]]].
exists f3; exists te3; exists tm3; exists tv2.
intuition.
subst ta; eapply eval_Elet; eauto.
@@ -2089,19 +2061,46 @@ Lemma transl_expr_Eletvar_correct:
forall (le : list val) (e : Csharpminor.env) (m : mem) (n : nat)
(v : val),
nth_error le n = Some v ->
- eval_expr_prop le e m (Csharpminor.Eletvar n) m v.
+ eval_expr_prop le e m (Csharpminor.Eletvar n) E0 m v.
Proof.
intros; red; intros. monadInv TR.
- destruct (val_list_inject_nth _ _ _ LINJ _ _ H)
- as [tv [A B]].
+ exploit val_list_inject_nth; eauto. intros [tv [A B]].
exists f1; exists te1; exists tm1; exists tv.
intuition.
subst ta. eapply eval_Eletvar; auto.
Qed.
+Lemma transl_expr_Ealloc_correct:
+ forall (le: list val) (e: Csharpminor.env) (m1: mem) (a: Csharpminor.expr)
+ (t: trace) (m2: mem) (n: int) (m3: mem) (b: block),
+ Csharpminor.eval_expr prog le e m1 a t m2 (Vint n) ->
+ eval_expr_prop le e m1 a t m2 (Vint n) ->
+ Mem.alloc m2 0 (Int.signed n) = (m3, b) ->
+ eval_expr_prop le e m1 (Csharpminor.Ealloc a) t m3 (Vptr b Int.zero).
+Proof.
+ intros; red; intros. monadInv TR.
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ inversion VINJ1. subst tv1 i.
+ caseEq (alloc tm2 0 (Int.signed n)). intros tm3 tb TALLOC.
+ assert (LB: Int.min_signed <= 0). compute. congruence.
+ assert (HB: Int.signed n <= Int.max_signed).
+ generalize (Int.signed_range n); omega.
+ exploit alloc_parallel_inject; eauto.
+ intros [MINJ3 INCR3].
+ exists (extend_inject b (Some (tb, 0)) f2);
+ exists te2; exists tm3; exists (Vptr tb Int.zero).
+ split. subst ta; econstructor; eauto.
+ split. econstructor. unfold extend_inject, eq_block. rewrite zeq_true. reflexivity.
+ reflexivity.
+ split. assumption.
+ split. eapply inject_incr_trans; eauto.
+ eapply match_callstack_alloc; eauto.
+Qed.
+
Lemma transl_exprlist_Enil_correct:
forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem),
- eval_exprlist_prop le e m Csharpminor.Enil m nil.
+ eval_exprlist_prop le e m Csharpminor.Enil E0 m nil.
Proof.
intros; red; intros. monadInv TR.
exists f1; exists te1; exists tm1; exists (@nil val).
@@ -2110,50 +2109,55 @@ Qed.
Lemma transl_exprlist_Econs_correct:
forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
- (a : Csharpminor.expr) (bl : Csharpminor.exprlist) (m1 : mem)
- (v : val) (m2 : mem) (vl : list val),
- Csharpminor.eval_expr prog le e m a m1 v ->
- eval_expr_prop le e m a m1 v ->
- Csharpminor.eval_exprlist prog le e m1 bl m2 vl ->
- eval_exprlist_prop le e m1 bl m2 vl ->
- eval_exprlist_prop le e m (Csharpminor.Econs a bl) m2 (v :: vl).
+ (a : Csharpminor.expr) (bl : Csharpminor.exprlist)
+ (t1: trace) (m1 : mem) (v : val)
+ (t2: trace) (m2 : mem) (vl : list val) (t: trace),
+ Csharpminor.eval_expr prog le e m a t1 m1 v ->
+ eval_expr_prop le e m a t1 m1 v ->
+ Csharpminor.eval_exprlist prog le e m1 bl t2 m2 vl ->
+ eval_exprlist_prop le e m1 bl t2 m2 vl ->
+ t = t1 ** t2 ->
+ eval_exprlist_prop le e m (Csharpminor.Econs a bl) t m2 (v :: vl).
Proof.
intros; red; intros. monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ _ EQ LINJ MINJ MATCH)
- as [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
- assert (LINJ2: val_list_inject f2 le tle). eapply val_list_inject_incr; eauto.
- destruct (H2 _ _ _ _ _ _ _ _ _ _ EQ0 LINJ2 MINJ2 MATCH2)
- as [f3 [te3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ3 [INCR3 MATCH3]]]]]]]].
- assert (VINJ1': val_inject f3 v tv1). eapply val_inject_incr; eauto.
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H2.
+ eauto. eapply val_list_inject_incr; eauto. eauto. eauto.
+ intros [f3 [te3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ3 [INCR3 MATCH3]]]]]]]].
exists f3; exists te3; exists tm3; exists (tv1 :: tv2).
intuition. subst tal; econstructor; eauto.
+ constructor. eapply val_inject_incr; eauto. auto.
eapply inject_incr_trans; eauto.
Qed.
-Lemma transl_funcall_correct:
+Lemma transl_funcall_internal_correct:
forall (m : mem) (f : Csharpminor.function) (vargs : list val)
- (e : Csharpminor.env) (m1 : mem) (lb : list block) (m2 m3 : mem)
- (out : Csharpminor.outcome) (vres : val),
+ (e : Csharpminor.env) (m1 : mem) (lb : list block) (m2: mem)
+ (t: trace) (m3 : mem) (out : Csharpminor.outcome) (vres : val),
list_norepet (fn_params_names f ++ fn_vars_names f) ->
alloc_variables empty_env m (fn_variables f) e m1 lb ->
bind_parameters e m1 (Csharpminor.fn_params f) vargs m2 ->
- Csharpminor.exec_stmt prog e m2 (Csharpminor.fn_body f) m3 out ->
- exec_stmt_prop e m2 (Csharpminor.fn_body f) m3 out ->
+ Csharpminor.exec_stmt prog e m2 (Csharpminor.fn_body f) t m3 out ->
+ exec_stmt_prop e m2 (Csharpminor.fn_body f) t m3 out ->
Csharpminor.outcome_result_value out (sig_res (Csharpminor.fn_sig f)) vres ->
- eval_funcall_prop m f vargs (free_list m3 lb) vres.
+ eval_funcall_prop m (Internal f) vargs t (free_list m3 lb) vres.
Proof.
intros; red. intros tfn f1 tm; intros.
- unfold transl_function in TR.
+ generalize TR; clear TR.
+ unfold transl_fundef, transf_partial_fundef.
+ caseEq (transl_function gce f); try congruence.
+ intros tf TR EQ. inversion EQ; clear EQ; subst tfn.
+ unfold transl_function in TR.
caseEq (build_compilenv gce f); intros cenv stacksize CENV.
rewrite CENV in TR.
destruct (zle stacksize Int.max_signed); try discriminate.
monadInv TR. clear TR.
caseEq (alloc tm 0 stacksize). intros tm1 sp ALLOC.
- destruct (function_entry_ok _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
- H0 H1 MATCH CENV z ALLOC ARGSINJ MINJ H)
- as [f2 [te2 [tm2 [STOREPARAM [MINJ2 [INCR12 [MATCH2 BLOCKS]]]]]]].
- destruct (H3 _ _ _ _ _ _ _ _ _ EQ MINJ2 MATCH2)
- as [f3 [te3 [tm3 [tout [EXECBODY [OUTINJ [MINJ3 [INCR23 MATCH3]]]]]]]].
+ exploit function_entry_ok; eauto.
+ intros [f2 [te2 [tm2 [STOREPARAM [MINJ2 [INCR12 [MATCH2 BLOCKS]]]]]]].
+ red in H3; exploit H3; eauto.
+ intros [f3 [te3 [tm3 [tout [EXECBODY [OUTINJ [MINJ3 [INCR23 MATCH3]]]]]]]].
assert (exists tvres,
outcome_result_value tout f.(Csharpminor.fn_sig).(sig_res) tvres /\
val_inject f3 vres tvres).
@@ -2167,13 +2171,14 @@ Proof.
destruct (sig_res (Csharpminor.fn_sig f)); intro.
exists v2; split. auto. subst vres; auto.
contradiction.
- elim H5; clear H5; intros tvres [TOUT VINJRES].
+ destruct H5 as [tvres [TOUT VINJRES]].
exists f3; exists (Mem.free tm3 sp); exists tvres.
(* execution *)
split. rewrite <- H6; econstructor; simpl; eauto.
- apply exec_Sseq_continue with te2 tm2.
+ apply exec_Sseq_continue with E0 te2 tm2 t.
exact STOREPARAM.
eexact EXECBODY.
+ traceEq.
(* val_inject *)
split. assumption.
(* mem_inject *)
@@ -2190,9 +2195,22 @@ Proof.
intros. elim (BLOCKS b); intros B1 B2. generalize (B2 H7). omega.
Qed.
+Lemma transl_funcall_external_correct:
+ forall (m : mem) (ef : external_function) (vargs : list val)
+ (t : trace) (vres : val),
+ event_match ef vargs t vres ->
+ eval_funcall_prop m (External ef) vargs t m vres.
+Proof.
+ intros; red; intros.
+ simpl in TR. inversion TR; clear TR; subst tfn.
+ exploit event_match_inject; eauto. intros [A B].
+ exists f1; exists tm1; exists vres; intuition.
+ constructor; auto.
+Qed.
+
Lemma transl_stmt_Sskip_correct:
forall (e : Csharpminor.env) (m : mem),
- exec_stmt_prop e m Csharpminor.Sskip m Csharpminor.Out_normal.
+ exec_stmt_prop e m Csharpminor.Sskip E0 m Csharpminor.Out_normal.
Proof.
intros; red; intros. monadInv TR.
exists f1; exists te1; exists tm1; exists Out_normal.
@@ -2201,33 +2219,90 @@ Qed.
Lemma transl_stmt_Sexpr_correct:
forall (e : Csharpminor.env) (m : mem) (a : Csharpminor.expr)
- (m1 : mem) (v : val),
- Csharpminor.eval_expr prog nil e m a m1 v ->
- eval_expr_prop nil e m a m1 v ->
- exec_stmt_prop e m (Csharpminor.Sexpr a) m1 Csharpminor.Out_normal.
+ (t: trace) (m1 : mem) (v : val),
+ Csharpminor.eval_expr prog nil e m a t m1 v ->
+ eval_expr_prop nil e m a t m1 v ->
+ exec_stmt_prop e m (Csharpminor.Sexpr a) t m1 Csharpminor.Out_normal.
Proof.
intros; red; intros. monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ _ EQ (val_nil_inject f1) MINJ MATCH)
- as [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
exists f2; exists te2; exists tm2; exists Out_normal.
intuition. subst ts. econstructor; eauto.
constructor.
Qed.
+Lemma transl_stmt_Sassign_correct:
+ forall (e : Csharpminor.env) (m : mem)
+ (id : ident) (a : Csharpminor.expr) (t: trace) (m1 : mem) (b : block)
+ (chunk : memory_chunk) (v : val) (m2 : mem),
+ Csharpminor.eval_expr prog nil e m a t m1 v ->
+ eval_expr_prop nil e m a t m1 v ->
+ eval_var_ref prog e id b chunk ->
+ store chunk m1 b 0 v = Some m2 ->
+ exec_stmt_prop e m (Csharpminor.Sassign id a) t m2 Csharpminor.Out_normal.
+Proof.
+ intros; red; intros. monadInv TR; intro EQ0.
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR12 MATCH1]]]]]]]].
+ exploit var_set_correct; eauto.
+ intros [te3 [tm3 [EVAL2 [MINJ2 MATCH2]]]].
+ exists f2; exists te3; exists tm3; exists Out_normal.
+ intuition. constructor.
+Qed.
+
+Lemma transl_stmt_Sstore_correct:
+ forall (e : Csharpminor.env) (m : mem)
+ (chunk : memory_chunk) (a b : Csharpminor.expr) (t1: trace) (m1 : mem)
+ (v1 : val) (t2: trace) (m2 : mem) (v2 : val)
+ (t3: trace) (m3 : mem),
+ Csharpminor.eval_expr prog nil e m a t1 m1 v1 ->
+ eval_expr_prop nil e m a t1 m1 v1 ->
+ Csharpminor.eval_expr prog nil e m1 b t2 m2 v2 ->
+ eval_expr_prop nil e m1 b t2 m2 v2 ->
+ storev chunk m2 v1 v2 = Some m3 ->
+ t3 = t1 ** t2 ->
+ exec_stmt_prop e m (Csharpminor.Sstore chunk a b) t3 m3 Csharpminor.Out_normal.
+Proof.
+ intros; red; intros. monadInv TR.
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H2.
+ eauto.
+ eapply val_list_inject_incr; eauto.
+ eauto. eauto.
+ intros [f3 [te3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ3 [INCR3 MATCH3]]]]]]]].
+ exploit make_store_correct.
+ eexact EVAL1. eexact EVAL2. eauto. eauto.
+ eapply val_inject_incr; eauto. eauto.
+ intros [tm4 [EVAL [MINJ4 NEXTBLOCK]]].
+ exists f3; exists te3; exists tm4; exists Out_normal.
+ rewrite <- H6. subst t3. intuition.
+ constructor.
+ eapply inject_incr_trans; eauto.
+ assert (val_inject f3 v1 tv1). eapply val_inject_incr; eauto.
+ unfold storev in H3; destruct v1; try discriminate.
+ inversion H4.
+ rewrite NEXTBLOCK. replace (nextblock m3) with (nextblock m2).
+ eapply match_callstack_mapped; eauto. congruence.
+ exploit store_inv; eauto. simpl; symmetry; tauto.
+Qed.
+
Lemma transl_stmt_Sseq_continue_correct:
forall (e : Csharpminor.env) (m : mem) (s1 s2 : Csharpminor.stmt)
- (m1 m2 : mem) (out : Csharpminor.outcome),
- Csharpminor.exec_stmt prog e m s1 m1 Csharpminor.Out_normal ->
- exec_stmt_prop e m s1 m1 Csharpminor.Out_normal ->
- Csharpminor.exec_stmt prog e m1 s2 m2 out ->
- exec_stmt_prop e m1 s2 m2 out ->
- exec_stmt_prop e m (Csharpminor.Sseq s1 s2) m2 out.
+ (t1 t2: trace) (m1 m2 : mem) (t: trace) (out : Csharpminor.outcome),
+ Csharpminor.exec_stmt prog e m s1 t1 m1 Csharpminor.Out_normal ->
+ exec_stmt_prop e m s1 t1 m1 Csharpminor.Out_normal ->
+ Csharpminor.exec_stmt prog e m1 s2 t2 m2 out ->
+ exec_stmt_prop e m1 s2 t2 m2 out ->
+ t = t1 ** t2 ->
+ exec_stmt_prop e m (Csharpminor.Sseq s1 s2) t m2 out.
Proof.
intros; red; intros; monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ EQ MINJ MATCH)
- as [f2 [te2 [tm2 [tout1 [EXEC1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
- destruct (H2 _ _ _ _ _ _ _ _ _ EQ0 MINJ2 MATCH2)
- as [f3 [te3 [tm3 [tout2 [EXEC2 [OINJ2 [MINJ3 [INCR3 MATCH3]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tout1 [EXEC1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H2; eauto.
+ intros [f3 [te3 [tm3 [tout2 [EXEC2 [OINJ2 [MINJ3 [INCR3 MATCH3]]]]]]]].
exists f3; exists te3; exists tm3; exists tout2.
intuition. subst ts; eapply exec_Sseq_continue; eauto.
inversion OINJ1. subst tout1. auto.
@@ -2236,15 +2311,15 @@ Qed.
Lemma transl_stmt_Sseq_stop_correct:
forall (e : Csharpminor.env) (m : mem) (s1 s2 : Csharpminor.stmt)
- (m1 : mem) (out : Csharpminor.outcome),
- Csharpminor.exec_stmt prog e m s1 m1 out ->
- exec_stmt_prop e m s1 m1 out ->
+ (t1: trace) (m1 : mem) (out : Csharpminor.outcome),
+ Csharpminor.exec_stmt prog e m s1 t1 m1 out ->
+ exec_stmt_prop e m s1 t1 m1 out ->
out <> Csharpminor.Out_normal ->
- exec_stmt_prop e m (Csharpminor.Sseq s1 s2) m1 out.
+ exec_stmt_prop e m (Csharpminor.Sseq s1 s2) t1 m1 out.
Proof.
intros; red; intros; monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ EQ MINJ MATCH)
- as [f2 [te2 [tm2 [tout1 [EXEC1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tout1 [EXEC1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
exists f2; exists te2; exists tm2; exists tout1.
intuition. subst ts; eapply exec_Sseq_stop; eauto.
inversion OINJ1; subst out tout1; congruence.
@@ -2252,64 +2327,70 @@ Qed.
Lemma transl_stmt_Sifthenelse_true_correct:
forall (e : Csharpminor.env) (m : mem) (a : Csharpminor.expr)
- (sl1 sl2 : Csharpminor.stmt) (m1 : mem) (v1 : val) (m2 : mem)
- (out : Csharpminor.outcome),
- Csharpminor.eval_expr prog nil e m a m1 v1 ->
- eval_expr_prop nil e m a m1 v1 ->
+ (sl1 sl2 : Csharpminor.stmt)
+ (t1: trace) (m1 : mem) (v1 : val) (t2: trace) (m2 : mem)
+ (out : Csharpminor.outcome) (t: trace),
+ Csharpminor.eval_expr prog nil e m a t1 m1 v1 ->
+ eval_expr_prop nil e m a t1 m1 v1 ->
Val.is_true v1 ->
- Csharpminor.exec_stmt prog e m1 sl1 m2 out ->
- exec_stmt_prop e m1 sl1 m2 out ->
- exec_stmt_prop e m (Csharpminor.Sifthenelse a sl1 sl2) m2 out.
+ Csharpminor.exec_stmt prog e m1 sl1 t2 m2 out ->
+ exec_stmt_prop e m1 sl1 t2 m2 out ->
+ t = t1 ** t2 ->
+ exec_stmt_prop e m (Csharpminor.Sifthenelse a sl1 sl2) t m2 out.
Proof.
intros; red; intros. monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ _ EQ (val_nil_inject f1) MINJ MATCH)
- as [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
- destruct (H3 _ _ _ _ _ _ _ _ _ EQ0 MINJ2 MATCH2)
- as [f3 [te3 [tm3 [tout [EVAL2 [OINJ [MINJ3 [INCR3 MATCH3]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H3; eauto.
+ intros [f3 [te3 [tm3 [tout [EVAL2 [OINJ [MINJ3 [INCR3 MATCH3]]]]]]]].
exists f3; exists te3; exists tm3; exists tout.
intuition.
- subst ts. eapply exec_ifthenelse_true; eauto.
+ subst ts t. eapply exec_ifthenelse_true; eauto.
inversion VINJ1; subst v1 tv1; simpl in H1; simpl; contradiction || auto.
eapply inject_incr_trans; eauto.
Qed.
Lemma transl_stmt_Sifthenelse_false_correct:
forall (e : Csharpminor.env) (m : mem) (a : Csharpminor.expr)
- (sl1 sl2 : Csharpminor.stmt) (m1 : mem) (v1 : val) (m2 : mem)
- (out : Csharpminor.outcome),
- Csharpminor.eval_expr prog nil e m a m1 v1 ->
- eval_expr_prop nil e m a m1 v1 ->
+ (sl1 sl2 : Csharpminor.stmt)
+ (t1: trace) (m1 : mem) (v1 : val) (t2: trace) (m2 : mem)
+ (out : Csharpminor.outcome) (t: trace),
+ Csharpminor.eval_expr prog nil e m a t1 m1 v1 ->
+ eval_expr_prop nil e m a t1 m1 v1 ->
Val.is_false v1 ->
- Csharpminor.exec_stmt prog e m1 sl2 m2 out ->
- exec_stmt_prop e m1 sl2 m2 out ->
- exec_stmt_prop e m (Csharpminor.Sifthenelse a sl1 sl2) m2 out.
+ Csharpminor.exec_stmt prog e m1 sl2 t2 m2 out ->
+ exec_stmt_prop e m1 sl2 t2 m2 out ->
+ t = t1 ** t2 ->
+ exec_stmt_prop e m (Csharpminor.Sifthenelse a sl1 sl2) t m2 out.
Proof.
intros; red; intros. monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ _ EQ (val_nil_inject f1) MINJ MATCH)
- as [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
- destruct (H3 _ _ _ _ _ _ _ _ _ EQ1 MINJ2 MATCH2)
- as [f3 [te3 [tm3 [tout [EVAL2 [OINJ [MINJ3 [INCR3 MATCH3]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H3; eauto.
+ intros [f3 [te3 [tm3 [tout [EVAL2 [OINJ [MINJ3 [INCR3 MATCH3]]]]]]]].
exists f3; exists te3; exists tm3; exists tout.
intuition.
- subst ts. eapply exec_ifthenelse_false; eauto.
+ subst ts t. eapply exec_ifthenelse_false; eauto.
inversion VINJ1; subst v1 tv1; simpl in H1; simpl; contradiction || auto.
eapply inject_incr_trans; eauto.
Qed.
Lemma transl_stmt_Sloop_loop_correct:
forall (e : Csharpminor.env) (m : mem) (sl : Csharpminor.stmt)
- (m1 m2 : mem) (out : Csharpminor.outcome),
- Csharpminor.exec_stmt prog e m sl m1 Csharpminor.Out_normal ->
- exec_stmt_prop e m sl m1 Csharpminor.Out_normal ->
- Csharpminor.exec_stmt prog e m1 (Csharpminor.Sloop sl) m2 out ->
- exec_stmt_prop e m1 (Csharpminor.Sloop sl) m2 out ->
- exec_stmt_prop e m (Csharpminor.Sloop sl) m2 out.
+ (t1: trace) (m1: mem) (t2: trace) (m2 : mem)
+ (out : Csharpminor.outcome) (t: trace),
+ Csharpminor.exec_stmt prog e m sl t1 m1 Csharpminor.Out_normal ->
+ exec_stmt_prop e m sl t1 m1 Csharpminor.Out_normal ->
+ Csharpminor.exec_stmt prog e m1 (Csharpminor.Sloop sl) t2 m2 out ->
+ exec_stmt_prop e m1 (Csharpminor.Sloop sl) t2 m2 out ->
+ t = t1 ** t2 ->
+ exec_stmt_prop e m (Csharpminor.Sloop sl) t m2 out.
Proof.
intros; red; intros. monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ EQ MINJ MATCH)
- as [f2 [te2 [tm2 [tout1 [EVAL1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
- destruct (H2 _ _ _ _ _ _ _ _ _ TR MINJ2 MATCH2)
- as [f3 [te3 [tm3 [tout2 [EVAL2 [OINJ2 [MINJ3 [INCR3 MATCH3]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tout1 [EVAL1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H2; eauto.
+ intros [f3 [te3 [tm3 [tout2 [EVAL2 [OINJ2 [MINJ3 [INCR3 MATCH3]]]]]]]].
exists f3; exists te3; exists tm3; exists tout2.
intuition.
subst ts. eapply exec_Sloop_loop; eauto.
@@ -2317,18 +2398,17 @@ Proof.
eapply inject_incr_trans; eauto.
Qed.
-
Lemma transl_stmt_Sloop_exit_correct:
forall (e : Csharpminor.env) (m : mem) (sl : Csharpminor.stmt)
- (m1 : mem) (out : Csharpminor.outcome),
- Csharpminor.exec_stmt prog e m sl m1 out ->
- exec_stmt_prop e m sl m1 out ->
+ (t1: trace) (m1 : mem) (out : Csharpminor.outcome),
+ Csharpminor.exec_stmt prog e m sl t1 m1 out ->
+ exec_stmt_prop e m sl t1 m1 out ->
out <> Csharpminor.Out_normal ->
- exec_stmt_prop e m (Csharpminor.Sloop sl) m1 out.
+ exec_stmt_prop e m (Csharpminor.Sloop sl) t1 m1 out.
Proof.
intros; red; intros. monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ EQ MINJ MATCH)
- as [f2 [te2 [tm2 [tout1 [EVAL1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tout1 [EVAL1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
exists f2; exists te2; exists tm2; exists tout1.
intuition. subst ts; eapply exec_Sloop_stop; eauto.
inversion OINJ1; subst out tout1; congruence.
@@ -2336,15 +2416,15 @@ Qed.
Lemma transl_stmt_Sblock_correct:
forall (e : Csharpminor.env) (m : mem) (sl : Csharpminor.stmt)
- (m1 : mem) (out : Csharpminor.outcome),
- Csharpminor.exec_stmt prog e m sl m1 out ->
- exec_stmt_prop e m sl m1 out ->
- exec_stmt_prop e m (Csharpminor.Sblock sl) m1
+ (t1: trace) (m1 : mem) (out : Csharpminor.outcome),
+ Csharpminor.exec_stmt prog e m sl t1 m1 out ->
+ exec_stmt_prop e m sl t1 m1 out ->
+ exec_stmt_prop e m (Csharpminor.Sblock sl) t1 m1
(Csharpminor.outcome_block out).
Proof.
intros; red; intros. monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ EQ MINJ MATCH)
- as [f2 [te2 [tm2 [tout1 [EVAL1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tout1 [EVAL1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
exists f2; exists te2; exists tm2; exists (outcome_block tout1).
intuition. subst ts; eapply exec_Sblock; eauto.
inversion OINJ1; subst out tout1; simpl.
@@ -2356,7 +2436,7 @@ Qed.
Lemma transl_stmt_Sexit_correct:
forall (e : Csharpminor.env) (m : mem) (n : nat),
- exec_stmt_prop e m (Csharpminor.Sexit n) m (Csharpminor.Out_exit n).
+ exec_stmt_prop e m (Csharpminor.Sexit n) E0 m (Csharpminor.Out_exit n).
Proof.
intros; red; intros. monadInv TR.
exists f1; exists te1; exists tm1; exists (Out_exit n).
@@ -2366,15 +2446,15 @@ Qed.
Lemma transl_stmt_Sswitch_correct:
forall (e : Csharpminor.env) (m : mem)
(a : Csharpminor.expr) (cases : list (int * nat)) (default : nat)
- (m1 : mem) (n : int),
- Csharpminor.eval_expr prog nil e m a m1 (Vint n) ->
- eval_expr_prop nil e m a m1 (Vint n) ->
- exec_stmt_prop e m (Csharpminor.Sswitch a cases default) m1
+ (t1 : trace) (m1 : mem) (n : int),
+ Csharpminor.eval_expr prog nil e m a t1 m1 (Vint n) ->
+ eval_expr_prop nil e m a t1 m1 (Vint n) ->
+ exec_stmt_prop e m (Csharpminor.Sswitch a cases default) t1 m1
(Csharpminor.Out_exit (Csharpminor.switch_target n default cases)).
Proof.
intros; red; intros. monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ _ EQ (val_nil_inject f1) MINJ MATCH)
- as [f2 [te2 [tm2 [tv1 [EVAL [VINJ1 [MINJ2 [INCR MATCH2]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL [VINJ1 [MINJ2 [INCR MATCH2]]]]]]]].
exists f2; exists te2; exists tm2;
exists (Out_exit (switch_target n default cases)). intuition.
subst ts. constructor. inversion VINJ1. subst tv1. assumption.
@@ -2383,7 +2463,7 @@ Qed.
Lemma transl_stmt_Sreturn_none_correct:
forall (e : Csharpminor.env) (m : mem),
- exec_stmt_prop e m (Csharpminor.Sreturn None) m
+ exec_stmt_prop e m (Csharpminor.Sreturn None) E0 m
(Csharpminor.Out_return None).
Proof.
intros; red; intros. monadInv TR.
@@ -2393,15 +2473,15 @@ Qed.
Lemma transl_stmt_Sreturn_some_correct:
forall (e : Csharpminor.env) (m : mem) (a : Csharpminor.expr)
- (m1 : mem) (v : val),
- Csharpminor.eval_expr prog nil e m a m1 v ->
- eval_expr_prop nil e m a m1 v ->
- exec_stmt_prop e m (Csharpminor.Sreturn (Some a)) m1
+ (t1: trace) (m1 : mem) (v : val),
+ Csharpminor.eval_expr prog nil e m a t1 m1 v ->
+ eval_expr_prop nil e m a t1 m1 v ->
+ exec_stmt_prop e m (Csharpminor.Sreturn (Some a)) t1 m1
(Csharpminor.Out_return (Some v)).
Proof.
intros; red; intros; monadInv TR.
- destruct (H0 _ _ _ _ _ _ _ _ _ _ EQ (val_nil_inject f1) MINJ MATCH)
- as [f2 [te2 [tm2 [tv1 [EVAL [VINJ1 [MINJ2 [INCR MATCH2]]]]]]]].
+ exploit H0; eauto.
+ intros [f2 [te2 [tm2 [tv1 [EVAL [VINJ1 [MINJ2 [INCR MATCH2]]]]]]]].
exists f2; exists te2; exists tm2; exists (Out_return (Some tv1)).
intuition. subst ts; econstructor; eauto. constructor; auto.
Qed.
@@ -2410,9 +2490,9 @@ Qed.
evaluation derivation, using the lemmas above for each case. *)
Lemma transl_function_correct:
- forall m1 f vargs m2 vres,
- Csharpminor.eval_funcall prog m1 f vargs m2 vres ->
- eval_funcall_prop m1 f vargs m2 vres.
+ forall m1 f vargs t m2 vres,
+ Csharpminor.eval_funcall prog m1 f vargs t m2 vres ->
+ eval_funcall_prop m1 f vargs t m2 vres.
Proof
(eval_funcall_ind4 prog
eval_expr_prop
@@ -2421,21 +2501,23 @@ Proof
exec_stmt_prop
transl_expr_Evar_correct
- transl_expr_Eassign_correct
transl_expr_Eaddrof_correct
transl_expr_Eop_correct
transl_expr_Eload_correct
- transl_expr_Estore_correct
transl_expr_Ecall_correct
transl_expr_Econdition_true_correct
transl_expr_Econdition_false_correct
transl_expr_Elet_correct
transl_expr_Eletvar_correct
+ transl_expr_Ealloc_correct
transl_exprlist_Enil_correct
transl_exprlist_Econs_correct
- transl_funcall_correct
+ transl_funcall_internal_correct
+ transl_funcall_external_correct
transl_stmt_Sskip_correct
transl_stmt_Sexpr_correct
+ transl_stmt_Sassign_correct
+ transl_stmt_Sstore_correct
transl_stmt_Sseq_continue_correct
transl_stmt_Sseq_stop_correct
transl_stmt_Sifthenelse_true_correct
@@ -2472,11 +2554,11 @@ Qed.
follows. *)
Theorem transl_program_correct:
- forall n,
- Csharpminor.exec_program prog (Vint n) ->
- exec_program tprog (Vint n).
+ forall t n,
+ Csharpminor.exec_program prog t (Vint n) ->
+ exec_program tprog t (Vint n).
Proof.
- intros n [b [fn [m [FINDS [FINDF [SIG EVAL]]]]]].
+ intros t n [b [fn [m [FINDS [FINDF [SIG EVAL]]]]]].
elim (function_ptr_translated _ _ FINDF). intros tfn [TFIND TR].
set (m0 := Genv.init_mem (program_of_program prog)) in *.
set (f := fun b => if zlt b m0.(nextblock) then Some(b, 0) else None).
@@ -2488,26 +2570,25 @@ Proof.
split. auto.
constructor. compute. split; congruence. left; auto.
intros; omega.
- generalize (Genv.initmem_undef (program_of_program prog) b0). fold m0. intros [lo [hi EQ]].
- rewrite EQ. simpl. constructor.
+ generalize (Genv.initmem_block_init (program_of_program prog) b0). fold m0. intros [idata EQ].
+ rewrite EQ. simpl. apply Mem.contents_init_data_inject.
destruct (zlt b1 (nextblock m0)); try discriminate.
destruct (zlt b2 (nextblock m0)); try discriminate.
left; congruence.
assert (MATCH0: match_callstack f nil m0.(nextblock) m0.(nextblock) m0).
constructor. unfold f; apply match_globalenvs_init.
fold ge in EVAL.
- destruct (transl_function_correct _ _ _ _ _ EVAL
- _ _ _ _ _ TR MINJ0 MATCH0 (val_nil_inject f))
- as [f1 [tm1 [tres [TEVAL [VINJ [MINJ1 [INCR MATCH1]]]]]]].
+ exploit transl_function_correct; eauto.
+ intros [f1 [tm1 [tres [TEVAL [VINJ [MINJ1 [INCR MATCH1]]]]]]].
exists b; exists tfn; exists tm1.
split. fold tge. rewrite <- FINDS.
replace (prog_main prog) with (AST.prog_main tprog). fold ge. apply symbols_preserved.
transitivity (AST.prog_main (program_of_program prog)).
- apply transform_partial_program_main with (transl_function gce). assumption.
+ apply transform_partial_program_main with (transl_fundef gce). assumption.
reflexivity.
split. assumption.
- split. rewrite <- SIG. apply sig_transl_function; auto.
- rewrite (Genv.init_mem_transf_partial (transl_function gce) _ TRANSL).
+ split. rewrite <- SIG. apply sig_preserved; auto.
+ rewrite (Genv.init_mem_transf_partial (transl_fundef gce) _ TRANSL).
inversion VINJ; subst tres. assumption.
Qed.