From b279716c76c387c6c5eec96388c0c35629858b4c Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Wed, 26 Nov 2014 14:46:07 +0100 Subject: Introduce symbol environments (type Senv.t) as a restricted view on global environments (type Genv.t). Use symbol environments instead of global environments for external functions (module Events). --- common/Globalenvs.v | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'common/Globalenvs.v') diff --git a/common/Globalenvs.v b/common/Globalenvs.v index eb98e876..db212685 100644 --- a/common/Globalenvs.v +++ b/common/Globalenvs.v @@ -70,6 +70,51 @@ Qed. Local Unset Elimination Schemes. Local Unset Case Analysis Schemes. +(** * Symbol environments *) + +(** Symbol environments are a restricted view of global environments, + focusing on symbol names and their associated blocks. They do not + contain mappings from blocks to function or variable definitions. *) + +Module Senv. + +Record t: Type := mksenv { + (** Operations *) + find_symbol: ident -> option block; + public_symbol: ident -> bool; + invert_symbol: block -> option ident; + block_is_volatile: block -> bool; + nextblock: block; + (** Properties *) + find_symbol_injective: + forall id1 id2 b, find_symbol id1 = Some b -> find_symbol id2 = Some b -> id1 = id2; + invert_find_symbol: + forall id b, invert_symbol b = Some id -> find_symbol id = Some b; + find_invert_symbol: + forall id b, find_symbol id = Some b -> invert_symbol b = Some id; + public_symbol_exists: + forall id, public_symbol id = true -> exists b, find_symbol id = Some b; + find_symbol_below: + forall id b, find_symbol id = Some b -> Plt b nextblock; + block_is_volatile_below: + forall b, block_is_volatile b = true -> Plt b nextblock +}. + +Definition symbol_address (ge: t) (id: ident) (ofs: int) : val := + match find_symbol ge id with + | Some b => Vptr b ofs + | None => Vundef + end. + +Theorem shift_symbol_address: + forall ge id ofs n, + symbol_address ge id (Int.add ofs n) = Val.add (symbol_address ge id ofs) (Vint n). +Proof. + intros. unfold symbol_address. destruct (find_symbol ge id); auto. +Qed. + +End Senv. + Module Genv. (** * Global environments *) @@ -149,6 +194,15 @@ Definition invert_symbol (ge: t) (b: block) : option ident := Definition find_var_info (ge: t) (b: block) : option (globvar V) := PTree.get b ge.(genv_vars). +(** [block_is_volatile ge b] returns [true] if [b] points to a global variable + of volatile type, [false] otherwise. *) + +Definition block_is_volatile (ge: t) (b: block) : bool := + match find_var_info ge b with + | None => false + | Some gv => gv.(gvar_volatile) + end. + (** ** Constructing the global environment *) Program Definition add_global (ge: t) (idg: ident * globdef F V) : t := @@ -519,6 +573,30 @@ Proof. unfold globalenv; intros. rewrite genv_public_add_globals. auto. Qed. +Theorem block_is_volatile_below: + forall ge b, block_is_volatile ge b = true -> Plt b ge.(genv_next). +Proof. + unfold block_is_volatile; intros. destruct (find_var_info ge b) as [gv|] eqn:FV. + eapply genv_vars_range; eauto. + discriminate. +Qed. + +(** ** Coercing a global environment into a symbol environment *) + +Definition to_senv (ge: t) : Senv.t := + @Senv.mksenv + (find_symbol ge) + (public_symbol ge) + (invert_symbol ge) + (block_is_volatile ge) + ge.(genv_next) + ge.(genv_vars_inj) + (invert_find_symbol ge) + (find_invert_symbol ge) + (public_symbol_exists ge) + ge.(genv_symb_range) + (block_is_volatile_below ge). + (** * Construction of the initial memory state *) Section INITMEM. @@ -1970,6 +2048,19 @@ Proof. auto. Qed. +Theorem block_is_volatile_transf_partial2: + forall (b: block), + block_is_volatile (globalenv p') b = block_is_volatile (globalenv p) b. +Proof. + unfold block_is_volatile; intros. + destruct (find_var_info (globalenv p) b) as [v|] eqn:FV. + exploit find_var_info_transf_partial2; eauto. intros (v' & P & Q). + rewrite P. monadInv Q. auto. + destruct (find_var_info (globalenv p') b) as [v'|] eqn:FV'. + exploit find_var_info_rev_transf_partial2; eauto. intros (v & P & Q). congruence. + auto. +Qed. + Theorem init_mem_transf_partial2: forall m, init_mem p = Some m -> init_mem p' = Some m. Proof. @@ -2048,6 +2139,13 @@ Proof. auto. Qed. +Theorem block_is_volatile_transf_partial: + forall (b: block), + block_is_volatile (globalenv p') b = block_is_volatile (globalenv p) b. +Proof. + exact (@block_is_volatile_transf_partial2 _ _ _ _ _ _ _ _ transf_OK). +Qed. + Theorem init_mem_transf_partial: forall m, init_mem p = Some m -> init_mem p' = Some m. Proof. @@ -2128,6 +2226,13 @@ Proof. exact (@find_var_info_transf_partial _ _ _ _ _ _ transf_OK). Qed. +Theorem block_is_volatile_transf: + forall (b: block), + block_is_volatile (globalenv tp) b = block_is_volatile (globalenv p) b. +Proof. + exact (@block_is_volatile_transf_partial _ _ _ _ _ _ transf_OK). +Qed. + Theorem init_mem_transf: forall m, init_mem p = Some m -> init_mem tp = Some m. Proof. @@ -2137,3 +2242,5 @@ Qed. End TRANSF_PROGRAM. End Genv. + +Coercion Genv.to_senv: Genv.t >-> Senv.t. -- cgit From f00b70b6a17fdfb4e8606df891f6becc8102ef12 Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Fri, 23 Jan 2015 10:05:18 +0100 Subject: Add weaker variants of theorems find_funct_ptr_exists and find_var_exists. Instead of assuming name uniqueness for all definitions in the program, these variants only assume uniqueness for a particular name. Use this approach to weaken the hypotheses for match_program and transf_program_partial_augment. --- common/Globalenvs.v | 192 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 122 insertions(+), 70 deletions(-) (limited to 'common/Globalenvs.v') diff --git a/common/Globalenvs.v b/common/Globalenvs.v index db212685..30f03654 100644 --- a/common/Globalenvs.v +++ b/common/Globalenvs.v @@ -321,20 +321,47 @@ Proof. apply IHgl; auto. Qed. +Lemma add_globals_unique_preserves: + forall id gl ge, + (forall ge id1 g, P ge -> In (id1, g) gl -> id1 <> id -> P (add_global ge (id1, g))) -> + ~In id (map fst gl) -> P ge -> P (add_globals ge gl). +Proof. + induction gl; simpl; intros. + auto. + destruct a. apply IHgl; auto. +Qed. + +Lemma add_globals_unique_ensures: + forall gl1 id g gl2 ge, + (forall ge id1 g1, P ge -> In (id1, g1) gl2 -> id1 <> id -> P (add_global ge (id1, g1))) -> + (forall ge, P (add_global ge (id, g))) -> + ~In id (map fst gl2) -> P (add_globals ge (gl1 ++ (id, g) :: gl2)). +Proof. + intros. rewrite add_globals_app. simpl. apply add_globals_unique_preserves with id; auto. +Qed. + +Remark in_norepet_unique: + forall id g (gl: list (ident * globdef F V)), + In (id, g) gl -> list_norepet (map fst gl) -> + exists gl1 gl2, gl = gl1 ++ (id, g) :: gl2 /\ ~In id (map fst gl2). +Proof. + induction gl as [|[id1 g1] gl]; simpl; intros. + contradiction. + inv H0. destruct H. + inv H. exists nil, gl. auto. + exploit IHgl; eauto. intros (gl1 & gl2 & X & Y). + exists ((id1, g1) :: gl1), gl2; split; auto. rewrite X; auto. +Qed. + Lemma add_globals_norepet_ensures: forall id g gl ge, (forall ge id1 g1, P ge -> In (id1, g1) gl -> id1 <> id -> P (add_global ge (id1, g1))) -> (forall ge, P (add_global ge (id, g))) -> In (id, g) gl -> list_norepet (map fst gl) -> P (add_globals ge gl). Proof. - induction gl; simpl; intros. - contradiction. - inv H2. - destruct H1. subst a. simpl in H5. - apply add_globals_preserves; auto. - intros. apply H. auto. auto. red; intros; subst id0. elim H5. - change id with (fst (id, g0)). apply List.in_map; auto. - apply IHgl; auto. + intros. exploit in_norepet_unique; eauto. intros (gl1 & gl2 & X & Y). + subst gl. apply add_globals_unique_ensures; auto. intros. eapply H; eauto. + apply in_or_app; simpl; auto. Qed. End GLOBALENV_PRINCIPLES. @@ -387,15 +414,14 @@ Proof. intros. unfold find_symbol; simpl. rewrite PTree.gss. econstructor; eauto. Qed. -Theorem find_funct_ptr_exists: - forall p id f, - list_norepet (prog_defs_names p) -> - In (id, Gfun f) (prog_defs p) -> +Theorem find_funct_ptr_exists_2: + forall p gl1 id f gl2, + prog_defs p = gl1 ++ (id, Gfun f) :: gl2 -> ~In id (map fst gl2) -> exists b, find_symbol (globalenv p) id = Some b /\ find_funct_ptr (globalenv p) b = Some f. Proof. - intros; unfold globalenv. eapply add_globals_norepet_ensures; eauto. + intros; unfold globalenv. rewrite H. eapply add_globals_unique_ensures; eauto. (* preserves *) intros. unfold find_symbol, find_funct_ptr in *; simpl. destruct H1 as [b [A B]]. exists b; split. @@ -408,15 +434,26 @@ Proof. exists (genv_next ge); split. apply PTree.gss. apply PTree.gss. Qed. -Theorem find_var_exists: - forall p id v, +Corollary find_funct_ptr_exists: + forall p id f, list_norepet (prog_defs_names p) -> - In (id, Gvar v) (prog_defs p) -> + In (id, Gfun f) (prog_defs p) -> + exists b, + find_symbol (globalenv p) id = Some b + /\ find_funct_ptr (globalenv p) b = Some f. +Proof. + intros. exploit in_norepet_unique; eauto. intros (gl1 & gl2 & X & Y). + eapply find_funct_ptr_exists_2; eauto. +Qed. + +Theorem find_var_exists_2: + forall p gl1 id v gl2, + prog_defs p = gl1 ++ (id, Gvar v) :: gl2 -> ~In id (map fst gl2) -> exists b, find_symbol (globalenv p) id = Some b /\ find_var_info (globalenv p) b = Some v. Proof. - intros; unfold globalenv. eapply add_globals_norepet_ensures; eauto. + intros; unfold globalenv. rewrite H. eapply add_globals_unique_ensures; eauto. (* preserves *) intros. unfold find_symbol, find_var_info in *; simpl. destruct H1 as [b [A B]]. exists b; split. @@ -428,6 +465,18 @@ Proof. exists (genv_next ge); split. apply PTree.gss. apply PTree.gss. Qed. +Corollary find_var_exists: + forall p id v, + list_norepet (prog_defs_names p) -> + In (id, Gvar v) (prog_defs p) -> + exists b, + find_symbol (globalenv p) id = Some b + /\ find_var_info (globalenv p) b = Some v. +Proof. + intros. exploit in_norepet_unique; eauto. intros (gl1 & gl2 & X & Y). + eapply find_var_exists_2; eauto. +Qed. + Lemma find_symbol_inversion : forall p x b, find_symbol (globalenv p) x = Some b -> In x (prog_defs_names p). @@ -1728,9 +1777,10 @@ Proof. destruct progmatch as (P & Q & R). rewrite R. auto. Qed. -Hypothesis new_ids_fresh : - forall s', find_symbol (globalenv p) s' <> None -> - ~In s' (map fst new_globs). +Hypothesis new_ids_fresh: + forall s, In s (prog_defs_names p) -> In s (map fst new_globs) -> False. +Hypothesis new_ids_unique: + list_norepet (map fst new_globs). Lemma store_init_data_list_match: forall idl m b ofs m', @@ -1743,7 +1793,7 @@ Proof. store_init_data (globalenv p') m b ofs a = Some m'). destruct a; simpl; auto. rewrite find_symbol_match. auto. simpl in H. destruct (find_symbol (globalenv p) i) as [b'|] eqn:?; try discriminate. - apply new_ids_fresh. congruence. + red; intros. exploit find_symbol_inversion; eauto. case_eq (store_init_data (globalenv p) m b ofs a); intros. rewrite H1 in H. pose proof (H0 _ H1). rewrite H2. auto. @@ -1780,6 +1830,32 @@ Proof. eapply alloc_globals_match; eauto. Qed. +Theorem find_new_funct_ptr_match: + forall id f, In (id, Gfun f) new_globs -> + exists b, + find_symbol (globalenv p') id = Some b + /\ find_funct_ptr (globalenv p') b = Some f. +Proof. + intros. + destruct progmatch as [[tglob [P Q]] R]. + exploit in_norepet_unique; eauto. intros (gl1 & gl2 & S & T). + rewrite S in Q. rewrite <- app_ass in Q. + eapply find_funct_ptr_exists_2; eauto. +Qed. + +Theorem find_new_var_match: + forall id v, In (id, Gvar v) new_globs -> + exists b, + find_symbol (globalenv p') id = Some b + /\ find_var_info (globalenv p') b = Some v. +Proof. + intros. + destruct progmatch as [[tglob [P Q]] R]. + exploit in_norepet_unique; eauto. intros (gl1 & gl2 & S & T). + rewrite S in Q. rewrite <- app_ass in Q. + eapply find_var_exists_2; eauto. +Qed. + End MATCH_PROGRAMS. Section TRANSF_PROGRAM_AUGMENT. @@ -1797,7 +1873,7 @@ Variable p': program B W. Hypothesis transf_OK: transform_partial_augment_program transf_fun transf_var new_globs new_main p = OK p'. -Remark prog_match: +Let prog_match: match_program (fun fd tfd => transf_fun fd = OK tfd) (fun info tinfo => transf_var info = OK tinfo) @@ -1818,27 +1894,6 @@ Proof. intros [tf [X Y]]. exists tf; auto. Qed. -Theorem find_new_funct_ptr_exists: - list_norepet (List.map fst new_globs) -> - forall id f, In (id, Gfun f) new_globs -> - exists b, find_symbol (globalenv p') id = Some b - /\ find_funct_ptr (globalenv p') b = Some f. -Proof. - intros. destruct prog_match as [[tglob [P Q]] R]. - unfold globalenv. rewrite Q. rewrite add_globals_app. - eapply add_globals_norepet_ensures; eauto. -(* preserves *) - intros. unfold find_symbol, find_funct_ptr in *; simpl. - destruct H1 as [b [X Y]]. exists b; split. - rewrite PTree.gso; auto. - destruct g1 as [f1 | v1]. rewrite PTree.gso. auto. - apply Plt_ne. eapply genv_funs_range; eauto. - auto. -(* ensures *) - intros. unfold find_symbol, find_funct_ptr in *; simpl. - exists (genv_next ge); split. apply PTree.gss. apply PTree.gss. -Qed. - Theorem find_funct_ptr_rev_transf_augment: forall (b: block) (tf: B), find_funct_ptr (globalenv p') b = Some tf -> @@ -1848,7 +1903,7 @@ Theorem find_funct_ptr_rev_transf_augment: In (Gfun tf) (map snd new_globs). Proof. intros. - exploit find_funct_ptr_rev_match; eauto. eexact prog_match; eauto. auto. + exploit find_funct_ptr_rev_match; eauto. Qed. Theorem find_funct_transf_augment: @@ -1883,26 +1938,6 @@ Proof. rewrite H0; simpl. auto. Qed. -Theorem find_new_var_exists: - list_norepet (List.map fst new_globs) -> - forall id gv, In (id, Gvar gv) new_globs -> - exists b, find_symbol (globalenv p') id = Some b - /\ find_var_info (globalenv p') b = Some gv. -Proof. - intros. destruct prog_match as [[tglob [P Q]] R]. - unfold globalenv. rewrite Q. rewrite add_globals_app. - eapply add_globals_norepet_ensures; eauto. -(* preserves *) - intros. unfold find_symbol, find_var_info in *; simpl. - destruct H1 as [b [X Y]]. exists b; split. - rewrite PTree.gso; auto. - destruct g1 as [f1 | v1]. auto. rewrite PTree.gso. auto. - red; intros; subst b. eelim Plt_strict. eapply genv_vars_range; eauto. -(* ensures *) - intros. unfold find_symbol, find_var_info in *; simpl. - exists (genv_next ge); split. apply PTree.gss. apply PTree.gss. -Qed. - Theorem find_var_info_rev_transf_augment: forall (b: block) (v': globvar W), find_var_info (globalenv p') b = Some v' -> @@ -1934,9 +1969,12 @@ Proof. intros. eapply public_symbol_match. eexact prog_match. auto. Qed. +Hypothesis new_ids_fresh: + forall s, In s (prog_defs_names p) -> In s (map fst new_globs) -> False. +Hypothesis new_ids_unique: + list_norepet (map fst new_globs). + Theorem init_mem_transf_augment: - (forall s', find_symbol (globalenv p) s' <> None -> - ~ In s' (map fst new_globs)) -> forall m, init_mem p = Some m -> init_mem p' = alloc_globals (globalenv p') m new_globs. Proof. @@ -1944,18 +1982,32 @@ Proof. Qed. Theorem init_mem_inject_transf_augment: - (forall s', find_symbol (globalenv p) s' <> None -> - ~ In s' (map fst new_globs)) -> forall m, init_mem p = Some m -> forall m', init_mem p' = Some m' -> Mem.inject (Mem.flat_inj (Mem.nextblock m)) m m'. Proof. intros. - pose proof (initmem_inject p H0). - erewrite init_mem_transf_augment in H1; eauto. + pose proof (initmem_inject p H). + erewrite init_mem_transf_augment in H0; eauto. eapply alloc_globals_augment; eauto. apply Ple_refl. Qed. +Theorem find_new_funct_ptr_exists: + forall id f, In (id, Gfun f) new_globs -> + exists b, find_symbol (globalenv p') id = Some b + /\ find_funct_ptr (globalenv p') b = Some f. +Proof. + intros. eapply find_new_funct_ptr_match; eauto. +Qed. + +Theorem find_new_var_exists: + forall id gv, In (id, Gvar gv) new_globs -> + exists b, find_symbol (globalenv p') id = Some b + /\ find_var_info (globalenv p') b = Some gv. +Proof. + intros. eapply find_new_var_match; eauto. +Qed. + End TRANSF_PROGRAM_AUGMENT. Section TRANSF_PROGRAM_PARTIAL2. -- cgit