diff options
Diffstat (limited to 'cfrontend/Cminorgenproof.v')
-rw-r--r-- | cfrontend/Cminorgenproof.v | 694 |
1 files changed, 319 insertions, 375 deletions
diff --git a/cfrontend/Cminorgenproof.v b/cfrontend/Cminorgenproof.v index ad31ff19..5bcb8801 100644 --- a/cfrontend/Cminorgenproof.v +++ b/cfrontend/Cminorgenproof.v @@ -2,6 +2,7 @@ Require Import FSets. Require Import Coqlib. +Require Import Errors. Require Import Maps. Require Import AST. Require Import Integers. @@ -11,68 +12,49 @@ Require Import Mem. Require Import Events. Require Import Globalenvs. Require Import Csharpminor. -Require Import Op. Require Import Cminor. -Require Cmconstr. Require Import Cminorgen. -Require Import Cmconstrproof. + +Open Local Scope error_monad_scope. Section TRANSLATION. Variable prog: Csharpminor.program. Variable tprog: program. -Hypothesis TRANSL: transl_program prog = Some tprog. +Hypothesis TRANSL: transl_program prog = OK tprog. Let ge : Csharpminor.genv := Genv.globalenv prog. Let tge: genv := Genv.globalenv tprog. Let gce : compilenv := build_global_compilenv prog. 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_partial2 with (transl_fundef gce) transl_globvar. - exact TRANSL. -Qed. +Proof (Genv.find_symbol_transf_partial2 (transl_fundef gce) transl_globvar _ TRANSL). Lemma function_ptr_translated: 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_fundef gce f = Some tf. -Proof. - intros. - generalize - (Genv.find_funct_ptr_transf_partial2 (transl_fundef gce) transl_globvar TRANSL H). - case (transl_fundef gce f). - intros tf [A B]. exists tf. tauto. - intros [A B]. elim B. reflexivity. -Qed. + Genv.find_funct_ptr tge b = Some tf /\ transl_fundef gce f = OK tf. +Proof (Genv.find_funct_ptr_transf_partial2 (transl_fundef gce) transl_globvar TRANSL). + Lemma functions_translated: forall (v: val) (f: Csharpminor.fundef), Genv.find_funct ge v = Some f -> exists tf, - Genv.find_funct tge v = Some tf /\ transl_fundef gce f = Some tf. -Proof. - intros. - generalize - (Genv.find_funct_transf_partial2 (transl_fundef gce) transl_globvar TRANSL H). - case (transl_fundef gce f). - intros tf [A B]. exists tf. tauto. - intros [A B]. elim B. reflexivity. -Qed. + Genv.find_funct tge v = Some tf /\ transl_fundef gce f = OK tf. +Proof (Genv.find_funct_transf_partial2 (transl_fundef gce) transl_globvar TRANSL). Lemma sig_preserved: forall f tf, - transl_fundef gce f = Some tf -> + transl_fundef gce f = OK 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. + case (zle z Int.max_signed); simpl; try congruence. + intros. monadInv H. monadInv EQ. reflexivity. + intro. inv H. reflexivity. Qed. Definition global_compilenv_match (ce: compilenv) (gv: gvarenv) : Prop := @@ -510,15 +492,12 @@ Lemma load_from_alloc_is_undef: alloc m1 0 (size_chunk chunk) = (m2, b) -> load chunk m2 b 0 = Some Vundef. Proof. - intros. - assert (valid_block m2 b). eapply valid_new_block; eauto. - assert (low_bound m2 b <= 0). - generalize (low_bound_alloc _ _ b _ _ _ H). rewrite zeq_true. omega. - assert (0 + size_chunk chunk <= high_bound m2 b). - generalize (high_bound_alloc _ _ b _ _ _ H). rewrite zeq_true. omega. - elim (load_in_bounds _ _ _ _ H0 H1 H2). intros v LOAD. - assert (v = Vundef). eapply load_alloc_same; eauto. - congruence. + intros. + assert (exists v, load chunk m2 b 0 = Some v). + apply valid_access_load. + eapply valid_access_alloc_same; eauto; omega. + destruct H0 as [v LOAD]. rewrite LOAD. decEq. + eapply load_alloc_same; eauto. Qed. Lemma match_env_alloc_same: @@ -577,14 +556,20 @@ Proof. contradiction. (* other vars *) generalize (me_vars0 id0); intros. - inversion H6; econstructor; eauto. - unfold e2; rewrite PTree.gso; auto. - unfold f2, extend_inject, eq_block; rewrite zeq_false; auto. - generalize (me_bounded0 _ _ _ H8). unfold block in *; omega. - unfold e2; rewrite PTree.gso; eauto. - unfold e2; rewrite PTree.gso; eauto. - unfold e2; rewrite PTree.gso; eauto. - unfold e2; rewrite PTree.gso; eauto. + inversion H6. + eapply match_var_local with (v := v); eauto. + unfold e2; rewrite PTree.gso; eauto. + eapply load_alloc_other; eauto. + unfold f2, extend_inject, eq_block; rewrite zeq_false; auto. + generalize (me_bounded0 _ _ _ H8). unfold block in *; omega. + econstructor; eauto. + unfold e2; rewrite PTree.gso; eauto. + econstructor; eauto. + unfold e2; rewrite PTree.gso; eauto. + econstructor; eauto. + unfold e2; rewrite PTree.gso; eauto. + econstructor; eauto. + unfold e2; rewrite PTree.gso; eauto. (* lo <= hi *) unfold block in *; omega. (* me_bounded *) @@ -629,9 +614,15 @@ Proof. inversion H2. constructor; auto. (* me_vars *) intros. generalize (me_vars0 id); intro. - inversion H5; econstructor; eauto. - unfold f2, extend_inject, eq_block. rewrite zeq_false. auto. - generalize (me_bounded0 _ _ _ H7). unfold block in *; omega. + inversion H5. + eapply match_var_local with (v := v); eauto. + eapply load_alloc_other; eauto. + unfold f2, extend_inject, eq_block. rewrite zeq_false. auto. + generalize (me_bounded0 _ _ _ H7). unfold block in *; omega. + econstructor; eauto. + econstructor; eauto. + econstructor; eauto. + econstructor; eauto. (* me_bounded *) intros until delta. unfold f2, extend_inject, eq_block. case (zeq b0 b); intros. rewrite H5 in H0. omegaContradiction. @@ -726,9 +717,10 @@ Proof. (* me_vars *) intros. generalize (me_vars0 id); intro. inversion H5. (* var_local *) - econstructor; eauto. + eapply match_var_local with (v := v); eauto. + eapply load_alloc_other; eauto. generalize (me_bounded0 _ _ _ H7). intro. - unfold f2, extend_inject. case (eq_block b0 b); intro. + unfold f2, extend_inject. case (zeq b0 b); intro. subst b0. rewrite BEQ in H12. omegaContradiction. auto. (* var_stack_scalar *) @@ -740,12 +732,12 @@ Proof. (* var_global_array *) econstructor; eauto. (* me_bounded *) - intros until delta. unfold f2, extend_inject. case (eq_block b0 b); intro. + intros until delta. unfold f2, extend_inject. case (zeq 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. + intros until delta. unfold f2, extend_inject. case (zeq b0 b); intros. injection H5; clear H5; intros; subst b0 tb0 delta. rewrite BEQ in H6. omegaContradiction. eauto. @@ -804,16 +796,7 @@ Qed. (** * Correctness of Cminor construction functions *) -Hint Resolve eval_negint eval_negfloat eval_absfloat eval_intoffloat - eval_floatofint eval_floatofintu eval_notint eval_notbool - eval_cast8signed eval_cast8unsigned eval_cast16signed - eval_cast16unsigned eval_singleoffloat eval_add eval_add_ptr - eval_add_ptr_2 eval_sub eval_sub_ptr_int eval_sub_ptr_ptr - eval_mul eval_divs eval_mods eval_divu eval_modu - eval_and eval_or eval_xor eval_shl eval_shr eval_shru - eval_addf eval_subf eval_mulf eval_divf - eval_cmp eval_cmp_null_r eval_cmp_null_l eval_cmp_ptr - eval_cmpu eval_cmpf: evalexpr. +Hint Resolve eval_Econst eval_Eunop eval_Ebinop eval_Eload: evalexpr. Remark val_inject_val_of_bool: forall f b, val_inject f (Val.of_bool b) (Val.of_bool b). @@ -821,151 +804,146 @@ Proof. intros; destruct b; unfold Val.of_bool, Vtrue, Vfalse; constructor. Qed. +Remark val_inject_bool_of_val: + forall f v b tv, + val_inject f v tv -> Val.bool_of_val v b -> Val.bool_of_val tv b. +Proof. + intros. inv H; inv H0; constructor; auto. +Qed. + +Remark val_inject_eval_compare_null: + forall f c i v, + eval_compare_null c i = Some v -> + val_inject f v v. +Proof. + unfold eval_compare_null; intros. + destruct (Int.eq i Int.zero). + destruct c; inv H; unfold Vfalse, Vtrue; constructor. + discriminate. +Qed. + Ltac TrivialOp := match goal with - | [ |- exists x, _ /\ val_inject _ (Vint ?x) _ ] => + | [ |- exists y, _ /\ val_inject _ (Vint ?x) _ ] => exists (Vint x); split; [eauto with evalexpr | constructor] - | [ |- exists x, _ /\ val_inject _ (Vfloat ?x) _ ] => + | [ |- exists y, _ /\ val_inject _ (Vfloat ?x) _ ] => exists (Vfloat x); split; [eauto with evalexpr | constructor] - | [ |- exists x, _ /\ val_inject _ (Val.of_bool ?x) _ ] => + | [ |- exists y, _ /\ val_inject _ (Val.of_bool ?x) _ ] => exists (Val.of_bool x); split; [eauto with evalexpr | apply val_inject_val_of_bool] + | [ |- exists y, Some ?x = Some y /\ val_inject _ _ _ ] => + exists x; split; [auto | econstructor; eauto] | _ => idtac end. -Remark eval_compare_null_inv: - forall c i v, - Csharpminor.eval_compare_null c i = Some v -> - i = Int.zero /\ (c = Ceq /\ v = Vfalse \/ c = Cne /\ v = Vtrue). +(** Correctness of [transl_constant]. *) + +Lemma transl_constant_correct: + forall f sp cst v, + Csharpminor.eval_constant cst = Some v -> + exists tv, + eval_constant tge sp (transl_constant cst) = Some tv + /\ val_inject f v tv. Proof. - intros until v. unfold Csharpminor.eval_compare_null. - predSpec Int.eq Int.eq_spec i Int.zero. - case c; intro EQ; simplify_eq EQ; intro; subst v; tauto. - congruence. + destruct cst; simpl; intros; inv H; TrivialOp. Qed. -(** Correctness of [make_op]. The generated Cminor code evaluates - to a value that matches the result value of the Csharpminor operation, - provided arguments match pairwise ([val_list_inject f] hypothesis). *) +(** Compatibility of [eval_unop] with respect to [val_inject]. *) -Lemma make_op_correct: - forall al a op vl m2 v sp le te tm1 t 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 te tm1 al t tm2 tvl -> - val_list_inject f vl tvl -> - mem_inject f m2 tm2 -> +Lemma eval_unop_compat: + forall f op v1 tv1 v, + eval_unop op v1 = Some v -> + val_inject f v1 tv1 -> exists tv, - eval_expr tge (Vptr sp Int.zero) le te tm1 a t tm2 tv + eval_unop op tv1 = Some tv /\ val_inject f v tv. Proof. - intros. - destruct al as [ | a1 al]; - [idtac | destruct al as [ | a2 al]; - [idtac | destruct al as [ | a3 al]]]; - simpl in H; try discriminate. - (* Constant operators *) - inversion H1. subst sp0 le0 e m tm1 tvl. - inversion H2. subst vl. - destruct op; simplify_eq H; intro; subst a; - simpl in H0; injection H0; intro; subst v. - (* intconst *) - TrivialOp. econstructor. constructor. reflexivity. - (* floatconst *) - TrivialOp. econstructor. constructor. reflexivity. - (* Unary operators *) - 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. - replace (Int.eq i Int.zero) with (negb (negb (Int.eq i Int.zero))). - eapply eval_notbool. eauto. - generalize (Int.eq_spec i Int.zero). destruct (Int.eq i Int.zero); intro; simpl. - rewrite H1; constructor. constructor; auto. - apply negb_elim. - unfold Vfalse; TrivialOp. change (Vint Int.zero) with (Val.of_bool (negb true)). - eapply eval_notbool. eauto. constructor. - change (Vfloat (Float.singleoffloat f0)) with (Val.singleoffloat (Vfloat f0)). eauto with evalexpr. - (* Binary operations *) - 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 H8; subst v0; subst v1; - TrivialOp. - (* add int ptr *) - exists (Vptr b2 (Int.add ofs2 i)); split. - eauto with evalexpr. apply val_inject_ptr with x. auto. - subst ofs2. repeat rewrite Int.add_assoc. decEq. apply Int.add_commut. - (* add ptr int *) - exists (Vptr b2 (Int.add ofs2 i0)); split. - eauto with evalexpr. apply val_inject_ptr with x. auto. - subst ofs2. repeat rewrite Int.add_assoc. decEq. apply Int.add_commut. - (* sub ptr int *) - exists (Vptr b2 (Int.sub ofs2 i0)); split. - eauto with evalexpr. apply val_inject_ptr with x. auto. - subst ofs2. apply Int.sub_add_l. - (* 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 ofs3 ofs2)); split. - eauto with evalexpr. - subst ofs2 ofs3. replace x0 with x. rewrite Int.sub_shifted. constructor. - congruence. - (* divs *) - generalize (Int.eq_spec i0 Int.zero); destruct (Int.eq i0 Int.zero); intro; - simplify_eq H0; intro; subst v. TrivialOp. - (* divu *) - generalize (Int.eq_spec i0 Int.zero); destruct (Int.eq i0 Int.zero); intro; - simplify_eq H0; intro; subst v. TrivialOp. - (* mods *) - generalize (Int.eq_spec i0 Int.zero); destruct (Int.eq i0 Int.zero); intro; - simplify_eq H0; intro; subst v. TrivialOp. - (* modu *) - generalize (Int.eq_spec i0 Int.zero); destruct (Int.eq i0 Int.zero); intro; - simplify_eq H0; intro; subst v. TrivialOp. - (* shl *) - caseEq (Int.ltu i0 (Int.repr 32)); intro EQ; rewrite EQ in H0; - simplify_eq H0; intro; subst v. TrivialOp. - (* shr *) - caseEq (Int.ltu i0 (Int.repr 32)); intro EQ; rewrite EQ in H0; - simplify_eq H0; intro; subst v. TrivialOp. - (* shru *) - caseEq (Int.ltu i0 (Int.repr 32)); intro EQ; rewrite EQ in H0; - simplify_eq H0; intro; subst v. TrivialOp. - (* cmp int ptr *) - elim (eval_compare_null_inv _ _ _ H0); intros; subst i1 i. - exists v; split. eauto with evalexpr. - 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 H12; intros [A B]; subst v; unfold Vtrue, Vfalse; constructor. + destruct op; simpl; intros. + inv H; inv H0; simpl; TrivialOp. + inv H; inv H0; simpl; TrivialOp. + inv H; inv H0; simpl; TrivialOp. + inv H; inv H0; simpl; TrivialOp. + inv H0; inv H. TrivialOp. + inv H0; inv H. TrivialOp. unfold Vfalse; TrivialOp. + inv H0; inv H; TrivialOp. + inv H0; inv H; TrivialOp. + inv H0; inv H; TrivialOp. + inv H; inv H0; simpl; TrivialOp. + inv H0; inv H; TrivialOp. + inv H0; inv H; TrivialOp. + inv H0; inv H; TrivialOp. +Qed. + +(** Compatibility of [eval_binop] with respect to [val_inject]. *) + +Lemma eval_binop_compat: + forall f op v1 tv1 v2 tv2 v m tm, + eval_binop op v1 v2 m = Some v -> + val_inject f v1 tv1 -> + val_inject f v2 tv2 -> + mem_inject f m tm -> + exists tv, + eval_binop op tv1 tv2 tm = Some tv + /\ val_inject f v tv. +Proof. + destruct op; simpl; intros. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + repeat rewrite Int.add_assoc. decEq. apply Int.add_commut. + repeat rewrite Int.add_assoc. decEq. apply Int.add_commut. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + apply Int.sub_add_l. + destruct (eq_block b1 b0); inv H4. + assert (b3 = b2) by congruence. subst b3. + unfold eq_block; rewrite zeq_true. TrivialOp. + replace x0 with x by congruence. decEq. decEq. + apply Int.sub_shifted. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + destruct (Int.eq i0 Int.zero); inv H1. TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + destruct (Int.eq i0 Int.zero); inv H1. TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + destruct (Int.eq i0 Int.zero); inv H1. TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + destruct (Int.eq i0 Int.zero); inv H1. TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + destruct (Int.ltu i0 (Int.repr 32)); inv H1. TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + destruct (Int.ltu i0 (Int.repr 32)); inv H1. TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + destruct (Int.ltu i0 (Int.repr 32)); inv H1. TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. + exists v; split; auto. eapply val_inject_eval_compare_null; eauto. + exists v; split; auto. eapply val_inject_eval_compare_null; eauto. (* 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. - destruct (eq_block b b0); simplify_eq H0; intro; subst v b0. - assert (b4 = b2); [congruence|subst b4]. - assert (x0 = x); [congruence|subst x0]. + caseEq (valid_pointer m b1 (Int.signed ofs1) && valid_pointer m b0 (Int.signed ofs0)); + intro EQ; rewrite EQ in H4; try discriminate. + destruct (eq_block b1 b0); inv H4. + assert (b3 = b2) by congruence. subst b3. + assert (x0 = x) by congruence. subst x0. elim (andb_prop _ _ EQ); intros. - 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. + exists (Val.of_bool (Int.cmp c ofs1 ofs0)); split. + exploit (Mem.valid_pointer_inject f m tm b0 ofs0); eauto. + intro VP; rewrite VP; clear VP. + exploit (Mem.valid_pointer_inject f m tm b0 ofs1); eauto. + intro VP; rewrite VP; clear VP. + unfold eq_block; rewrite zeq_true; simpl. + decEq. decEq. rewrite Int.translate_cmp. auto. eapply valid_pointer_inject_no_overflow; eauto. eapply valid_pointer_inject_no_overflow; eauto. + apply val_inject_val_of_bool. + (* *) + inv H0; try discriminate; inv H1; inv H; TrivialOp. + inv H0; try discriminate; inv H1; inv H; TrivialOp. Qed. (** Correctness of [make_cast]. Note that the resulting Cminor value is @@ -980,35 +958,28 @@ Lemma make_cast_correct: te tm1 (make_cast chunk a) t tm2 tv' /\ val_inject f (Val.load_result chunk v) tv'. Proof. - intros. destruct chunk. + intros. destruct chunk; simpl make_cast. exists (Val.cast8signed tv). - split. apply eval_cast8signed; auto. - inversion H0; simpl; constructor. + split. eauto with evalexpr. inversion H0; simpl; constructor. exists (Val.cast8unsigned tv). - split. apply eval_cast8unsigned; auto. - inversion H0; simpl; constructor. + split. eauto with evalexpr. inversion H0; simpl; constructor. exists (Val.cast16signed tv). - split. apply eval_cast16signed; auto. - inversion H0; simpl; constructor. + split. eauto with evalexpr. inversion H0; simpl; constructor. exists (Val.cast16unsigned tv). - split. apply eval_cast16unsigned; auto. - inversion H0; simpl; constructor. + split. eauto with evalexpr. inversion H0; simpl; constructor. - exists tv. - split. simpl; auto. - inversion H0; simpl; econstructor; eauto. + exists tv. + split. auto. inversion H0; simpl; econstructor; eauto. exists (Val.singleoffloat tv). - split. apply eval_singleoffloat; auto. - inversion H0; simpl; constructor. + split. eauto with evalexpr. inversion H0; simpl; constructor. - exists tv. - split. simpl; auto. - inversion H0; simpl; constructor. + exists tv. + split. auto. inversion H0; simpl; econstructor; eauto. Qed. Lemma make_stackaddr_correct: @@ -1018,7 +989,7 @@ Lemma make_stackaddr_correct: E0 tm (Vptr sp (Int.repr ofs)). Proof. intros; unfold make_stackaddr. - eapply eval_Eop. econstructor. simpl. decEq. decEq. + econstructor. simpl. decEq. decEq. rewrite Int.add_commut. apply Int.add_zero. Qed. @@ -1030,22 +1001,10 @@ Lemma make_globaladdr_correct: E0 tm (Vptr b Int.zero). Proof. intros; unfold make_globaladdr. - eapply eval_Eop. econstructor. simpl. rewrite H. auto. + econstructor. simpl. rewrite H. auto. Qed. -(** Correctness of [make_load] and [make_store]. *) - -Lemma make_load_correct: - forall sp le te tm1 a t tm2 va chunk v, - eval_expr tge (Vptr sp Int.zero) le te tm1 a t tm2 va -> - Mem.loadv chunk tm2 va = Some v -> - eval_expr tge (Vptr sp Int.zero) le - te tm1 (make_load chunk a) - t tm2 v. -Proof. - intros; unfold make_load. - eapply eval_load; eauto. -Qed. +(** Correctness of [make_store]. *) Lemma store_arg_content_inject: forall f sp le te tm1 a t tm2 v va chunk, @@ -1053,25 +1012,23 @@ Lemma store_arg_content_inject: val_inject f v va -> exists vb, eval_expr tge (Vptr sp Int.zero) le te tm1 (store_arg chunk a) t tm2 vb - /\ val_content_inject f (mem_chunk chunk) v vb. + /\ val_content_inject f chunk v vb. Proof. intros. assert (exists vb, eval_expr tge (Vptr sp Int.zero) le te tm1 a t tm2 vb - /\ val_content_inject f (mem_chunk chunk) v vb). + /\ val_content_inject f 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. + destruct a; simpl store_arg; trivial; + destruct u; trivial; + destruct chunk; trivial; + inv H; simpl in H12; inv H12; + econstructor; (split; [eauto|idtac]); + destruct v1; simpl in H0; inv H0; try (constructor; constructor). + apply val_content_inject_8. auto. apply Int.cast8_unsigned_idem. + apply val_content_inject_8; auto. apply Int.cast8_unsigned_signed. + apply val_content_inject_16; auto. apply Int.cast16_unsigned_idem. + apply val_content_inject_16; auto. apply Int.cast16_unsigned_signed. apply val_content_inject_32. apply Float.singleoffloat_idem. Qed. @@ -1098,13 +1055,11 @@ Proof. intros [tv [EVAL VCINJ]]. exploit storev_mapped_inject_1; eauto. intros [tm4 [STORE MEMINJ]]. - exploit eval_store. eexact H. eexact EVAL. eauto. - intro EVALSTORE. exists tm4. - split. apply exec_Sexpr with tv. auto. + split. apply exec_Sexpr with tv. eapply eval_Estore; eauto. split. auto. unfold storev in STORE; destruct tvaddr; try discriminate. - exploit store_inv; eauto. simpl. tauto. + eapply nextblock_store; eauto. Qed. (** Correctness of the variable accessors [var_get], [var_set] @@ -1112,7 +1067,7 @@ Qed. Lemma var_get_correct: forall cenv id a f e te sp lo hi m cs tm b chunk v le, - var_get cenv id = Some a -> + var_get cenv id = OK a -> match_callstack f (mkframe cenv e te sp lo hi :: cs) m.(nextblock) tm.(nextblock) m -> mem_inject f m tm -> eval_var_ref prog e id b chunk -> @@ -1138,7 +1093,7 @@ Proof. unfold loadv. eexact H3. intros [tv [LOAD INJ]]. exists tv; split. - eapply make_load_correct; eauto. eapply make_stackaddr_correct; eauto. + econstructor; eauto. eapply make_stackaddr_correct; eauto. auto. (* var_global_scalar *) inversion H2; [congruence|subst]. @@ -1151,14 +1106,14 @@ Proof. generalize (loadv_inject _ _ _ _ _ _ _ H1 H12 H13). intros [tv [LOAD INJ]]. exists tv; split. - eapply make_load_correct; eauto. eapply make_globaladdr_correct; eauto. + econstructor; eauto. eapply make_globaladdr_correct; eauto. auto. Qed. Lemma var_addr_correct: forall cenv id a f e te sp lo hi m cs tm b le, match_callstack f (mkframe cenv e te sp lo hi :: cs) m.(nextblock) tm.(nextblock) m -> - var_addr cenv id = Some a -> + var_addr cenv id = OK a -> eval_var_addr prog e id b -> exists tv, eval_expr tge (Vptr sp Int.zero) le te tm a E0 tm tv /\ @@ -1196,7 +1151,7 @@ Qed. Lemma var_set_correct: forall cenv id rhs a f e te sp lo hi m2 cs tm2 tm1 tv b chunk v m3 t, - var_set cenv id rhs = Some a -> + var_set cenv id rhs = OK a -> match_callstack f (mkframe cenv e te sp lo hi :: cs) m2.(nextblock) tm2.(nextblock) m2 -> eval_expr tge (Vptr sp Int.zero) nil te tm1 rhs t tm2 tv -> val_inject f v tv -> @@ -1210,7 +1165,7 @@ Lemma var_set_correct: Proof. unfold var_set; intros. assert (NEXTBLOCK: nextblock m3 = nextblock m2). - exploit store_inv; eauto. simpl; tauto. + eapply nextblock_store; eauto. inversion H0. subst. assert (match_var f id e m2 te sp cenv!!id). inversion H19; auto. inversion H6; subst; rewrite <- H7 in H; inversion H; subst; clear H. @@ -1337,7 +1292,7 @@ Proof. 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). + rewrite (high_bound_alloc _ _ _ _ _ H b). case (zeq b b1); intros. inversion H3. unfold sizeof; rewrite LV. omega. generalize (BOUND _ _ H3). omega. @@ -1350,7 +1305,7 @@ Proof. 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). + rewrite (high_bound_alloc _ _ _ _ _ H b). case (zeq b b1); intros. discriminate. eapply BOUND; eauto. intros [f' [INCR2 [MINJ2 MATCH2]]]. @@ -1373,7 +1328,7 @@ Proof. 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). + rewrite (high_bound_alloc _ _ _ _ _ H b). case (zeq b b1); intros. inversion H6. unfold sizeof; rewrite LV. omega. generalize (BOUND _ _ H6). omega. @@ -1439,10 +1394,9 @@ Proof. intros. assert (SP: sp = nextblock tm). injection H2; auto. unfold build_compilenv in H. - eapply match_callstack_alloc_variables_rec with (sz' := sz); eauto. - eapply valid_new_block; eauto. - rewrite (low_bound_alloc _ _ sp _ _ _ H2). apply zeq_true. - rewrite (high_bound_alloc _ _ sp _ _ _ H2). apply zeq_true. + eapply match_callstack_alloc_variables_rec with (sz' := sz); eauto with mem. + eapply low_bound_alloc_same; eauto. + eapply high_bound_alloc_same; eauto. (* match_callstack *) constructor. omega. change (valid_block tm' sp). eapply valid_new_block; eauto. constructor. @@ -1460,15 +1414,15 @@ Proof. (* me_inj *) intros until lv2. unfold Csharpminor.empty_env; rewrite PTree.gempty; congruence. (* me_inv *) - intros. exploit mi_mappedblocks; eauto. intros [A B]. + intros. exploit mi_mappedblocks; eauto. intro A. elim (fresh_block_alloc _ _ _ _ _ H2 A). (* me_incr *) - intros. exploit mi_mappedblocks; eauto. intros [A B]. + intros. exploit mi_mappedblocks; eauto. intro A. rewrite SP; auto. rewrite SP; auto. eapply alloc_right_inject; eauto. omega. - intros. exploit mi_mappedblocks; eauto. intros [A B]. + intros. exploit mi_mappedblocks; eauto. unfold valid_block; intro. unfold block in SP; omegaContradiction. (* defined *) intros. unfold te. apply set_locals_params_defined. @@ -1569,7 +1523,7 @@ Proof. inversion H18. inversion NOREPET. subst hd tl. assert (NEXT: nextblock m1 = nextblock m). - exploit store_inv; eauto. simpl; tauto. + eapply nextblock_store; eauto. generalize (me_vars0 id). intro. inversion H2; subst. (* cenv!!id = Var_local chunk *) assert (b0 = b). congruence. subst b0. @@ -1724,43 +1678,6 @@ Qed. (** * Semantic preservation for the translation *) -(** These tactics simplify hypotheses of the form [f ... = Some x]. *) - -Ltac monadSimpl1 := - match goal with - | [ |- (bind _ _ ?F ?G = Some ?X) -> _ ] => - unfold bind at 1; - generalize (refl_equal F); - pattern F at -1 in |- *; - case F; - [ (let EQ := fresh "EQ" in - (intro; intro EQ; - try monadSimpl1)) - | intros; discriminate ] - | [ |- (None = Some _) -> _ ] => - intro; discriminate - | [ |- (Some _ = Some _) -> _ ] => - let h := fresh "H" in - (intro h; injection h; intro; clear h) - end. - -Ltac monadSimpl := - match goal with - | [ |- (bind _ _ ?F ?G = Some ?X) -> _ ] => monadSimpl1 - | [ |- (None = Some _) -> _ ] => monadSimpl1 - | [ |- (Some _ = Some _) -> _ ] => monadSimpl1 - | [ |- (?F _ _ _ _ _ _ _ = Some _) -> _ ] => simpl F; monadSimpl1 - | [ |- (?F _ _ _ _ _ _ = Some _) -> _ ] => simpl F; monadSimpl1 - | [ |- (?F _ _ _ _ _ = Some _) -> _ ] => simpl F; monadSimpl1 - | [ |- (?F _ _ _ _ = Some _) -> _ ] => simpl F; monadSimpl1 - | [ |- (?F _ _ _ = Some _) -> _ ] => simpl F; monadSimpl1 - | [ |- (?F _ _ = Some _) -> _ ] => simpl F; monadSimpl1 - | [ |- (?F _ = Some _) -> _ ] => simpl F; monadSimpl1 - end. - -Ltac monadInv H := - generalize H; monadSimpl. - (** The proof of semantic preservation uses simulation diagrams of the following form: << @@ -1790,7 +1707,7 @@ Ltac monadInv H := Definition eval_expr_prop (le: Csharpminor.letenv) (e: Csharpminor.env) (m1: mem) (a: Csharpminor.expr) (t: trace) (m2: mem) (v: val) : Prop := forall cenv ta f1 tle te tm1 sp lo hi cs - (TR: transl_expr cenv a = Some ta) + (TR: transl_expr cenv a = OK ta) (LINJ: val_list_inject f1 le tle) (MINJ: mem_inject f1 m1 tm1) (MATCH: match_callstack f1 @@ -1808,7 +1725,7 @@ Definition eval_expr_prop Definition eval_exprlist_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 te tm1 sp lo hi cs - (TR: transl_exprlist cenv al = Some tal) + (TR: transl_exprlist cenv al = OK tal) (LINJ: val_list_inject f1 le tle) (MINJ: mem_inject f1 m1 tm1) (MATCH: match_callstack f1 @@ -1826,7 +1743,7 @@ Definition eval_exprlist_prop Definition eval_funcall_prop (m1: mem) (fn: Csharpminor.fundef) (args: list val) (t: trace) (m2: mem) (res: val) : Prop := forall tfn f1 tm1 cs targs - (TR: transl_fundef gce fn = Some tfn) + (TR: transl_fundef gce fn = OK tfn) (MINJ: mem_inject f1 m1 tm1) (MATCH: match_callstack f1 cs m1.(nextblock) tm1.(nextblock) m1) (ARGSINJ: val_list_inject f1 args targs), @@ -1852,7 +1769,7 @@ Inductive outcome_inject (f: meminj) : Csharpminor.outcome -> outcome -> Prop := Definition exec_stmt_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) + (TR: transl_stmt cenv s = OK ts) (MINJ: mem_inject f1 m1 tm1) (MATCH: match_callstack f1 (mkframe cenv e te1 sp lo hi :: cs) @@ -1897,21 +1814,61 @@ Proof. exists f1; 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) - (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) t m1 v. -Proof. - intros; red; intros. monadInv TR; intro EQ0. +Lemma transl_expr_Econst_correct: + forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem) + (cst : Csharpminor.constant) (v : val), + Csharpminor.eval_constant cst = Some v -> + eval_expr_prop le e m (Csharpminor.Econst cst) E0 m v. +Proof. + intros; red; intros; monadInv TR. + exploit transl_constant_correct; eauto. + intros [tv [EVAL VINJ]]. + exists f1; exists tm1; exists tv. intuition eauto. + constructor; eauto. +Qed. + +Lemma transl_expr_Eunop_correct: + forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem) + (op : unary_operation) (a : Csharpminor.expr) (t : trace) + (m1 : mem) (v1 v : val), + Csharpminor.eval_expr prog le e m a t m1 v1 -> + eval_expr_prop le e m a t m1 v1 -> + Csharpminor.eval_unop op v1 = Some v -> + eval_expr_prop le e m (Csharpminor.Eunop op a) t m1 v. +Proof. + intros; red; intros. monadInv TR. exploit H0; eauto. intros [f2 [tm2 [tvl [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]]. - exploit make_op_correct; eauto. - intros [tv [EVAL2 VINJ2]]. - exists f2; exists tm2; exists tv. intuition. + exploit eval_unop_compat; eauto. intros [tv [EVAL VINJ]]. + exists f2; exists tm2; exists tv; intuition. + econstructor; eauto. +Qed. + +Lemma transl_expr_Ebinop_correct: + forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem) + (op : binary_operation) (a1 a2 : Csharpminor.expr) (t1 : trace) + (m1 : mem) (v1 : val) (t2 : trace) (m2 : mem) (v2 : val) + (t : trace) (v : val), + Csharpminor.eval_expr prog le e m a1 t1 m1 v1 -> + eval_expr_prop le e m a1 t1 m1 v1 -> + Csharpminor.eval_expr prog le e m1 a2 t2 m2 v2 -> + eval_expr_prop le e m1 a2 t2 m2 v2 -> + Csharpminor.eval_binop op v1 v2 m2 = Some v -> + t = t1 ** t2 -> + eval_expr_prop le e m (Csharpminor.Ebinop op a1 a2) t m2 v. +Proof. + intros; red; intros. monadInv TR. + exploit H0; eauto. + intros [f2 [tm2 [tvl [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]]. + exploit H2. + eauto. eapply val_list_inject_incr; eauto. eauto. eauto. + intros [f3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]]. + exploit eval_binop_compat. + eauto. eapply val_inject_incr; eauto. eauto. eauto. + intros [tv [EVAL VINJ]]. + exists f3; exists tm3; exists tv; intuition. + econstructor; eauto. + eapply inject_incr_trans; eauto. Qed. Lemma transl_expr_Eload_correct: @@ -1931,7 +1888,7 @@ Proof. intros [tv [TLOAD VINJ]]. exists f2; exists tm2; exists tv. intuition. - subst ta. eapply make_load_correct; eauto. + econstructor; eauto. Qed. Lemma transl_expr_Ecall_correct: @@ -1951,7 +1908,7 @@ Lemma transl_expr_Ecall_correct: 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. + intros;red;intros. monadInv TR. exploit H0; eauto. intros [f2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]]. exploit H2. @@ -1960,18 +1917,18 @@ Proof. 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. + generalize (Genv.find_funct_ptr_negative H3). intro. assert (match_globalenvs f2). eapply match_callstack_match_globalenvs; eauto. - generalize (mg_functions _ H9 _ H8). intro. + generalize (mg_functions _ H7 _ H4). intro. rewrite VF in VINJ1. inversion VINJ1. subst vf. decEq. congruence. - subst ofs2. replace x with 0. reflexivity. congruence. + subst ofs2. replace x1 with 0. reflexivity. congruence. subst tv1. elim (functions_translated _ _ H3). intros tf [FIND TRF]. exploit H6; eauto. intros [f4 [tm4 [tres [EVAL3 [VINJ3 [MINJ3 [INCR3 MATCH3]]]]]]]. exists f4; exists tm4; exists tres. intuition. eapply eval_Ecall; eauto. - rewrite <- H4. apply sig_preserved; auto. + apply sig_preserved; auto. apply inject_incr_trans with f2; auto. apply inject_incr_trans with f3; auto. Qed. @@ -1996,8 +1953,8 @@ Proof. intros [f3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]]. exists f3; exists tm3; exists tv2. intuition. - rewrite <- H6. subst t; eapply eval_conditionalexpr_true; eauto. - inversion VINJ1; subst v1 tv1; simpl in H1; simpl; contradiction || auto. + eapply eval_Econdition with (b1 := true); eauto. + eapply val_inject_bool_of_val; eauto. apply Val.bool_of_true_val; eauto. eapply inject_incr_trans; eauto. Qed. @@ -2021,8 +1978,8 @@ Proof. intros [f3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]]. exists f3; exists tm3; exists tv2. intuition. - rewrite <- H6. subst t; eapply eval_conditionalexpr_false; eauto. - inversion VINJ1; subst v1 tv1; simpl in H1; simpl; contradiction || auto. + eapply eval_Econdition with (b1 := false); eauto. + eapply val_inject_bool_of_val; eauto. apply Val.bool_of_false_val; eauto. eapply inject_incr_trans; eauto. Qed. @@ -2047,7 +2004,7 @@ Proof. intros [f3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]]. exists f3; exists tm3; exists tv2. intuition. - subst ta; eapply eval_Elet; eauto. + eapply eval_Elet; eauto. eapply inject_incr_trans; eauto. Qed. @@ -2072,7 +2029,7 @@ Proof. exploit val_list_inject_nth; eauto. intros [tv [A B]]. exists f1; exists tm1; exists tv. intuition. - subst ta. eapply eval_Eletvar; auto. + eapply eval_Eletvar; auto. Qed. Lemma transl_expr_Ealloc_correct: @@ -2095,7 +2052,7 @@ Proof. intros [MINJ3 INCR3]. exists (extend_inject b (Some (tb, 0)) f2); exists tm3; exists (Vptr tb Int.zero). - split. subst ta; econstructor; eauto. + split. econstructor; eauto. split. econstructor. unfold extend_inject, eq_block. rewrite zeq_true. reflexivity. reflexivity. split. assumption. @@ -2109,7 +2066,7 @@ Lemma transl_exprlist_Enil_correct: Proof. intros; red; intros. monadInv TR. exists f1; exists tm1; exists (@nil val). - intuition. subst tal; constructor. + intuition. constructor. Qed. Lemma transl_exprlist_Econs_correct: @@ -2131,7 +2088,7 @@ Proof. eauto. eapply val_list_inject_incr; eauto. eauto. eauto. intros [f3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ3 [INCR3 MATCH3]]]]]]]. exists f3; exists tm3; exists (tv1 :: tv2). - intuition. subst tal; econstructor; eauto. + intuition. econstructor; eauto. constructor. eapply val_inject_incr; eauto. auto. eapply inject_incr_trans; eauto. Qed. @@ -2149,15 +2106,11 @@ Lemma transl_funcall_internal_correct: eval_funcall_prop m (Internal f) vargs t (free_list m3 lb) vres. Proof. intros; red. intros tfn f1 tm; intros. - 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. + monadInv TR. generalize EQ. + unfold transl_function. 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. + destruct (zle stacksize Int.max_signed); try congruence. + intro TR. monadInv TR. caseEq (alloc tm 0 stacksize). intros tm1 sp ALLOC. exploit function_entry_ok; eauto. intros [f2 [te2 [tm2 [STOREPARAM [MINJ2 [INCR12 [MATCH2 BLOCKS]]]]]]]. @@ -2177,9 +2130,11 @@ Proof. exists v2; split. auto. subst vres; auto. contradiction. destruct H5 as [tvres [TOUT VINJRES]]. + assert (outcome_free_mem tout tm3 sp = Mem.free tm3 sp). + inversion OUTINJ; auto. exists f3; exists (Mem.free tm3 sp); exists tvres. (* execution *) - split. rewrite <- H6; econstructor; simpl; eauto. + split. rewrite <- H5. econstructor; simpl; eauto. apply exec_Sseq_continue with E0 te2 tm2 t. exact STOREPARAM. eexact EXECBODY. @@ -2195,7 +2150,7 @@ Proof. (* match_callstack *) assert (forall bl mm, nextblock (free_list mm bl) = nextblock mm). induction bl; intros. reflexivity. simpl. auto. - unfold free; simpl nextblock. rewrite H5. + unfold free; simpl nextblock. rewrite H6. eapply match_callstack_freelist; eauto. intros. elim (BLOCKS b); intros B1 B2. generalize (B2 H7). omega. Qed. @@ -2206,8 +2161,7 @@ Lemma transl_funcall_external_correct: 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. + intros; red; intros. monadInv TR. exploit event_match_inject; eauto. intros [A B]. exists f1; exists tm1; exists vres; intuition. constructor; auto. @@ -2219,7 +2173,7 @@ Lemma transl_stmt_Sskip_correct: Proof. intros; red; intros. monadInv TR. exists f1; exists te1; exists tm1; exists Out_normal. - intuition. subst ts; constructor. constructor. + intuition. constructor. constructor. Qed. Lemma transl_stmt_Sexpr_correct: @@ -2233,7 +2187,7 @@ Proof. exploit H0; eauto. intros [f2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]. exists f2; exists te1; exists tm2; exists Out_normal. - intuition. subst ts. econstructor; eauto. + intuition. econstructor; eauto. constructor. Qed. @@ -2247,7 +2201,7 @@ Lemma transl_stmt_Sassign_correct: 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. + intros; red; intros. monadInv TR. exploit H0; eauto. intros [f2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR12 MATCH1]]]]]]]. exploit var_set_correct; eauto. @@ -2282,15 +2236,15 @@ Proof. eapply val_inject_incr; eauto. eauto. intros [tm4 [EVAL [MINJ4 NEXTBLOCK]]]. exists f3; exists te1; exists tm4; exists Out_normal. - rewrite <- H6. subst t3. intuition. + 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. + eapply match_callstack_mapped; eauto. congruence. + symmetry. eapply nextblock_store; eauto. Qed. Lemma transl_stmt_Sseq_continue_correct: @@ -2309,7 +2263,7 @@ Proof. 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. + intuition. eapply exec_Sseq_continue; eauto. inversion OINJ1. subst tout1. auto. eapply inject_incr_trans; eauto. Qed. @@ -2326,7 +2280,7 @@ Proof. 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. + intuition. eapply exec_Sseq_stop; eauto. inversion OINJ1; subst out tout1; congruence. Qed. @@ -2350,8 +2304,8 @@ Proof. intros [f3 [te3 [tm3 [tout [EVAL2 [OINJ [MINJ3 [INCR3 MATCH3]]]]]]]]. exists f3; exists te3; exists tm3; exists tout. intuition. - subst ts t. eapply exec_ifthenelse_true; eauto. - inversion VINJ1; subst v1 tv1; simpl in H1; simpl; contradiction || auto. + eapply exec_Sifthenelse with (b1 := true); eauto. + eapply val_inject_bool_of_val; eauto. apply Val.bool_of_true_val; auto. eapply inject_incr_trans; eauto. Qed. @@ -2375,8 +2329,8 @@ Proof. intros [f3 [te3 [tm3 [tout [EVAL2 [OINJ [MINJ3 [INCR3 MATCH3]]]]]]]]. exists f3; exists te3; exists tm3; exists tout. intuition. - subst ts t. eapply exec_ifthenelse_false; eauto. - inversion VINJ1; subst v1 tv1; simpl in H1; simpl; contradiction || auto. + eapply exec_Sifthenelse with (b1 := false); eauto. + eapply val_inject_bool_of_val; eauto. apply Val.bool_of_false_val; auto. eapply inject_incr_trans; eauto. Qed. @@ -2391,14 +2345,14 @@ Lemma transl_stmt_Sloop_loop_correct: t = t1 ** t2 -> exec_stmt_prop e m (Csharpminor.Sloop sl) t m2 out. Proof. - intros; red; intros. monadInv TR. + intros; red; intros. generalize TR; intro TR'; monadInv TR'. 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. + eapply exec_Sloop_loop; eauto. inversion OINJ1; subst tout1; eauto. eapply inject_incr_trans; eauto. Qed. @@ -2415,7 +2369,7 @@ Proof. 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. + intuition. eapply exec_Sloop_stop; eauto. inversion OINJ1; subst out tout1; congruence. Qed. @@ -2431,7 +2385,7 @@ Proof. 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. + intuition. eapply exec_Sblock; eauto. inversion OINJ1; subst out tout1; simpl. constructor. destruct n; constructor. @@ -2445,7 +2399,7 @@ Lemma transl_stmt_Sexit_correct: Proof. intros; red; intros. monadInv TR. exists f1; exists te1; exists tm1; exists (Out_exit n). - intuition. subst ts; constructor. constructor. + intuition. constructor. constructor. Qed. Lemma transl_stmt_Sswitch_correct: @@ -2462,7 +2416,7 @@ Proof. intros [f2 [tm2 [tv1 [EVAL [VINJ1 [MINJ2 [INCR MATCH2]]]]]]]. exists f2; exists te1; exists tm2; exists (Out_exit (switch_target n default cases)). intuition. - subst ts. constructor. inversion VINJ1. subst tv1. assumption. + constructor. inversion VINJ1. subst tv1. assumption. constructor. Qed. @@ -2473,7 +2427,7 @@ Lemma transl_stmt_Sreturn_none_correct: Proof. intros; red; intros. monadInv TR. exists f1; exists te1; exists tm1; exists (Out_return None). - intuition. subst ts; constructor. constructor. + intuition. constructor. constructor. Qed. Lemma transl_stmt_Sreturn_some_correct: @@ -2488,7 +2442,7 @@ Proof. exploit H0; eauto. intros [f2 [tm2 [tv1 [EVAL [VINJ1 [MINJ2 [INCR MATCH2]]]]]]]. exists f2; exists te1; exists tm2; exists (Out_return (Some tv1)). - intuition. subst ts; econstructor; eauto. constructor; auto. + intuition. econstructor; eauto. constructor; auto. Qed. (** We conclude by an induction over the structure of the Csharpminor @@ -2499,7 +2453,7 @@ Lemma transl_function_correct: Csharpminor.eval_funcall prog m1 f vargs t m2 vres -> eval_funcall_prop m1 f vargs t m2 vres. Proof - (eval_funcall_ind4 prog + (Csharpminor.eval_funcall_ind4 prog eval_expr_prop eval_exprlist_prop eval_funcall_prop @@ -2507,7 +2461,9 @@ Proof transl_expr_Evar_correct transl_expr_Eaddrof_correct - transl_expr_Eop_correct + transl_expr_Econst_correct + transl_expr_Eunop_correct + transl_expr_Ebinop_correct transl_expr_Eload_correct transl_expr_Ecall_correct transl_expr_Econdition_true_correct @@ -2545,11 +2501,9 @@ Lemma match_globalenvs_init: match_globalenvs f. Proof. intros. constructor. - (* globalvars *) - (* symbols *) intros. split. unfold f. rewrite zlt_true. auto. unfold m. - eapply Genv.find_symbol_inv; eauto. + eapply Genv.find_symbol_not_fresh; eauto. rewrite <- H. apply symbols_preserved. intros. unfold f. rewrite zlt_true. auto. generalize (nextblock_pos m). omega. @@ -2566,20 +2520,10 @@ Proof. intros t n [b [fn [m [FINDS [FINDF [SIG EVAL]]]]]]. elim (function_ptr_translated _ _ FINDF). intros tfn [TFIND TR]. set (m0 := Genv.init_mem prog) in *. - set (f := fun b => if zlt b m0.(nextblock) then Some(b, 0) else None). + set (f := meminj_init m0). assert (MINJ0: mem_inject f m0 m0). - unfold f; constructor; intros. - apply zlt_false; auto. - destruct (zlt b0 (nextblock m0)); try discriminate. - inversion H; subst b' delta. - split. auto. - constructor. compute. split; congruence. left; auto. - intros; omega. - generalize (Genv.initmem_block_init 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. + unfold f; apply init_inject. + unfold m0; apply Genv.initmem_inject_neutral. assert (MATCH0: match_callstack f nil m0.(nextblock) m0.(nextblock) m0). constructor. unfold f; apply match_globalenvs_init. fold ge in EVAL. |