(* * Copyright 2014, NICTA * * This software may be distributed and modified according to the terms of * the BSD 2-Clause license. Note that NO WARRANTY is provided. * See "LICENSE_BSD2.txt" for details. * * @TAG(NICTA_BSD) *) theory SimplRewrite imports "CTranslationNICTA" "SplitRule" begin primrec add_statefn :: "('s \ 's) \ ('s, 'x, 'e) com \ ('s, 'x, 'e) com" where "add_statefn f (Call x) = Call x" | "add_statefn f (Seq c d) = Seq (add_statefn f c) (add_statefn f d)" | "add_statefn f (Catch c d) = Catch (add_statefn f c) (add_statefn f d)" | "add_statefn f Throw = Throw" | "add_statefn f (Guard F S c) = Guard F {s. f s \ S} (add_statefn f c)" | "add_statefn f (DynCom c_fn) = DynCom (\s. add_statefn f (c_fn (f s)))" | "add_statefn f (While S c) = While {s. f s \ S} (add_statefn f c)" | "add_statefn f (Cond S c c') = Cond {s. f s \ S} (add_statefn f c) (add_statefn f c')" | "add_statefn f (Spec R) = Spec {(a, b). (f a, f b) \ R}" | "add_statefn f (Basic g) = Basic (\s. inv f (g (f s)))" | "add_statefn f Skip = Skip" lemma add_statefn_id1: "add_statefn id x = x" by (induct x, simp_all add: inv_id[unfolded id_def]) lemma add_statefn_id[simp]: "add_statefn id = id" by (rule ext, simp add: add_statefn_id1) lemma add_statefn_comp: "\ inv (g o f) = inv f o inv g \ \ add_statefn f (add_statefn g x) = add_statefn (g o f) x" by (induct x, simp_all add: o_def) definition "add_statefn_xstate f xs \ case xs of Normal s \ Normal (f s) | Abrupt s \ Abrupt (f s) | _ \ xs" lemmas add_statefn_xstate_simps[simp] = add_statefn_xstate_def[split_simps xstate.split] lemma isAbr_add_statefn_xstate[simp]: "isAbr (add_statefn_xstate f xs) = isAbr xs" by (cases xs, simp_all) lemma add_statefn_xstate_comp: "add_statefn_xstate f (add_statefn_xstate g xs) = add_statefn_xstate (f o g) xs" by (cases xs, simp_all) lemma add_statefn_xstate_id[simp]: "add_statefn_xstate id = id" by (simp add: add_statefn_xstate_def fun_eq_iff split: xstate.split) lemma add_statefn_exec1: assumes bij: "bij f" shows "\ \ \c, xs\ \ t \ (option_map (add_statefn (inv f)) o \) \ \add_statefn (inv f) c, add_statefn_xstate f xs\ \ add_statefn_xstate f t" proof (induct rule: exec.induct) case Basic show ?case apply simp apply (rule_tac P="exec G c xs" for G c xs in subst[rotated], rule exec.Basic) apply (simp add: inv_inv_eq bij inv_f_f bij_is_inj) done qed (auto intro: exec.intros simp: inv_f_f[OF bij_is_inj, OF bij] surj_f_inv_f[OF bij_is_surj, OF bij]) lemma add_statefn_exec: assumes bij: "bij f" shows "\ \ \add_statefn f c, xs\ \ t = (option_map (add_statefn (inv f)) o \) \ \c, add_statefn_xstate f xs\ \ add_statefn_xstate f t" apply (rule iffI) apply (drule add_statefn_exec1[OF bij]) apply (simp add: add_statefn_comp surj_iff[THEN iffD1] bij_is_surj[OF bij] inv_inv_eq bij) apply (drule add_statefn_exec1[OF bij_imp_bij_inv, OF bij]) apply (simp add: inv_inv_eq bij add_statefn_xstate_comp bij_is_inj[OF bij]) apply (simp add: o_def option.map_comp add_statefn_comp surj_iff[THEN iffD1] bij_is_surj[OF bij]) apply (simp add: add_statefn_comp inj_iff[THEN iffD1] bij_is_inj[OF bij] inv_inv_eq bij) apply (simp add: map_option_case) done definition exec_simulates :: "'s set \ 's set \ ('s, 'x, 'e) com \ ('s, 'x, 'e) com \ bool" where "exec_simulates S T a b = (\s \ S. \\ t. \ \ \a, Normal s\ \ t \ \ \ \b, Normal s\ \ t \ (\ft. \ \ \b, Normal s\ \ Fault ft) \ (\t' \ - T. \ \ \b, Normal s\ \ Normal t'))" lemma exec_simulates_refl: "exec_simulates S T c c" by (simp add: exec_simulates_def) lemma exec_simulatesD: "\ \ \ \a, Normal s\ \ t; exec_simulates S T a b; s \ S \ \ \ \ \b, Normal s\ \ t \ (\ft. \ \ \b, Normal s\ \ Fault ft) \ (\t' \ - T. \ \ \b, Normal s\ \ Normal t')" unfolding exec_simulates_def by auto definition spec_simulates :: "('x \ ('s, 'x, 'e) com) \ ('x \ ('s, 'x, 'e) com) \ bool" where "spec_simulates G G' = (\x. (G x = None) = (G' x = None) \ (\b b'. G x = Some b \ G' x = Some b' \ exec_simulates UNIV UNIV b b'))" lemma spec_simulates_to_exec_simulates: "\ G \ \a, xs\ \ t; spec_simulates G G' \ \ G' \ \a, xs\ \ t \ (\ft. G' \ \a, xs\ \ Fault ft)" proof (induct rule: exec.induct) case (Call p bdy s t) show ?case using Call apply clarsimp apply (frule_tac x=p in spec_simulates_def[THEN iffD1, rule_format]) apply (clarsimp simp: exec_simulates_def) apply (rule exec.Call, simp) apply (blast intro: exec.intros) done next case (CallUndefined p) show ?case using CallUndefined apply clarsimp apply (frule_tac x=p in spec_simulates_def[THEN iffD1, rule_format]) apply (fastforce intro: exec.CallUndefined) done qed (auto intro: exec.intros, (force intro: exec.intros)+) theorem spec_simulates_refinement: "\ spec_simulates G G'; exec_simulates P Q a b; G' \ P b Q, A \ \ G \ P a Q, A" apply (drule hoare_sound) apply (rule hoare_complete) apply (clarsimp simp: HoarePartialDef.cvalid_def HoarePartialDef.valid_def) apply (rule ccontr) apply (drule(1) exec_simulatesD, simp) apply ((auto | drule(1) spec_simulates_to_exec_simulates)+) done definition exec_statefn_simulates :: "('s \ 's) \ 's set \ 's set \ ('s, 'x, 'e) com \ ('s, 'x, 'e) com \ bool" where "exec_statefn_simulates f S T a b = (\s \ S. \\ t. \ \ \a, Normal s\ \ t \ (option_map (add_statefn (inv f)) o \) \ \b, Normal (f s)\ \ add_statefn_xstate f t \ (\ft. (option_map (add_statefn (inv f)) o \) \ \b, Normal (f s)\ \ Fault ft) \ (\t' \ - T. (option_map (add_statefn (inv f)) o \) \ \b, Normal (f s)\ \ Normal (f t')))" lemma exec_statefn_simulatesD: "\ \ \ \a, Normal s\ \ t; exec_statefn_simulates f S T a b; s \ S \ \ (option_map (add_statefn (inv f)) o \) \ \b, Normal (f s)\ \ add_statefn_xstate f t \ (\ft. (option_map (add_statefn (inv f)) o \) \ \b, Normal (f s)\ \ Fault ft) \ (\t' \ - T. (option_map (add_statefn (inv f)) o \) \ \b, Normal (f s)\ \ Normal (f t'))" unfolding exec_statefn_simulates_def by auto lemmas exec_statefn_simulatesI = exec_statefn_simulates_def[THEN iffD2, rule_format] lemma exec_statefn_simulates_refl: "exec_statefn_simulates id S T c c" by (simp add: exec_statefn_simulates_def map_option.id) lemma exec_statefn_simulates_via_statefn: "bij f \ exec_statefn_simulates f S T a b = exec_simulates S T a (add_statefn f b)" apply (simp add: exec_statefn_simulates_def exec_simulates_def) apply (simp add: add_statefn_exec bij_imp_bij_inv) done definition "spec_statefn_simulates f G G' = (\x. (G x = None) = (G' x = None) \ (\b b'. G x = Some b \ G' x = Some b' \ exec_statefn_simulates f UNIV UNIV b b'))" lemma spec_statefn_simulates_via_statefn: "bij f \ spec_statefn_simulates f G G' = spec_simulates G (option_map (add_statefn f) o G')" apply (simp add: spec_statefn_simulates_def spec_simulates_def) apply (rule arg_cong[where f=All, OF ext]) apply (rule HOL.conj_cong[OF refl]) apply (safe, simp_all add: exec_statefn_simulates_via_statefn) done theorem spec_statefn_simulates_refinement: "\ spec_statefn_simulates f G G'; exec_statefn_simulates f {s. f s \ P} {s. f s \ Q} a b; G' \ P b Q, A; bij f \ \ G \ {s. f s \ P} a {s. f s \ Q}, {s. f s \ A}" apply (simp add: spec_statefn_simulates_via_statefn exec_statefn_simulates_via_statefn) apply (erule spec_simulates_refinement) apply (simp add: Compl_Collect) apply (drule hoare_sound) apply (rule hoare_complete) apply (clarsimp simp: HoarePartialDef.cvalid_def HoarePartialDef.valid_def add_statefn_exec) apply (simp add: o_def option.map_comp) apply (simp add: add_statefn_comp surj_iff[THEN iffD1, OF bij_is_surj] inv_inv_eq) apply (simp add: map_option_case) apply (case_tac t, auto) done primrec com_initial_guards :: "('s, 'x, 'e) com \ 's set" where "com_initial_guards (a ;; b) = com_initial_guards a" | "com_initial_guards (Guard F G c) = G \ com_initial_guards c" | "com_initial_guards Skip = UNIV" | "com_initial_guards Throw = UNIV" | "com_initial_guards (Basic f) = UNIV" | "com_initial_guards (Spec r) = UNIV" | "com_initial_guards (Cond S a b) = UNIV" | "com_initial_guards (While S c) = UNIV" | "com_initial_guards (Call f) = UNIV" | "com_initial_guards (DynCom fn) = UNIV" | "com_initial_guards (Catch a b) = UNIV" lemma com_initial_guards_extra_simps[simp]: "com_initial_guards (whileAnno S I V c) = UNIV" "com_initial_guards (creturn exn_upd rv_upd rv) = UNIV" "com_initial_guards (creturn_void exn_upd) = UNIV" "com_initial_guards (call init f ret save) = UNIV" "com_initial_guards (cbreak exn_upd) = UNIV" "com_initial_guards (ccatchbrk exn) = UNIV" by (simp_all add: whileAnno_def creturn_def creturn_void_def call_def block_def cbreak_def ccatchbrk_def) lemmas com_initial_guards_all_simps = com_initial_guards.simps com_initial_guards_extra_simps primrec com_final_guards :: "'s set \ ('s, 'x, 'e) com \ 's set" where "com_final_guards S (a ;; b) = com_final_guards UNIV b" | "com_final_guards S (Guard F G c) = com_final_guards (S \ G) c" | "com_final_guards S Skip = S" | "com_final_guards S Throw = UNIV" | "com_final_guards S (Basic f) = UNIV" | "com_final_guards S (Spec r) = UNIV" | "com_final_guards S (Cond C a b) = UNIV" | "com_final_guards S (While C c) = UNIV" | "com_final_guards S (Call f) = UNIV" | "com_final_guards S (DynCom fn) = UNIV" | "com_final_guards S (Catch a b) = UNIV" lemma com_final_guards_extra_simps[simp]: "com_final_guards S (whileAnno C I V c) = UNIV" "com_final_guards S (creturn exn_upd rv_upd rv) = UNIV" "com_final_guards S (creturn_void exn_upd) = UNIV" "com_final_guards S (call init f ret save) = UNIV" "com_final_guards S (cbreak exn_upd) = UNIV" "com_final_guards S (ccatchbrk exn) = UNIV" by (simp_all add: whileAnno_def creturn_def creturn_void_def call_def block_def cbreak_def ccatchbrk_def) lemmas com_final_guards_all_simps = com_final_guards.simps com_final_guards_extra_simps lemma exec_not_in_initial_guards: "\ s \ com_initial_guards c \ \ \ft. \ \ \c, Normal s\ \ Fault ft" apply (induct c, simp_all) apply clarsimp apply (blast intro: exec.Seq exec.FaultProp) apply (blast intro: exec.GuardFault exec.Guard) done lemma exec_in_final_guards_induct: "\ \ \ \c, x\ \ y \ \ \s t S. x = Normal s \ y = Normal t \ s \ S \ t \ com_final_guards S c" apply (induct rule: exec.induct, simp_all) apply (case_tac s', simp_all) apply (auto elim: exec_Normal_elim_cases) done lemma exec_in_final_guards: "\ \ \ \c, Normal s\ \ Normal t \ \ t \ com_final_guards UNIV c" by (drule exec_in_final_guards_induct, simp) lemma exec_statefn_simulates_Seq: "\ exec_statefn_simulates f S {s. f s \ com_initial_guards d} a b; exec_statefn_simulates f UNIV T c d \ \ exec_statefn_simulates f S T (a ;; c) (b ;; d)" apply (rule exec_statefn_simulatesI) apply (erule exec.cases, simp_all) apply clarsimp apply (drule(2) exec_statefn_simulatesD) apply (elim disjE exE) apply (case_tac s', simp_all)[1] apply (drule(1) exec_statefn_simulatesD, simp) apply (auto intro: exec.Seq)[1] apply ((force elim: exec.Seq exec.cases notE)+)[4] apply clarsimp apply (rule ccontr, frule_tac \="map_option (add_statefn (inv f)) \ \" in exec_not_in_initial_guards, clarsimp) apply (blast intro: exec.Seq) done lemma exec_statefn_simulates_Cond: "\ \s. s \ S \ (s \ C) = (f s \ C'); exec_statefn_simulates f (S \ C) T a b; exec_statefn_simulates f (S \ - C) T c d \ \ exec_statefn_simulates f S T (Cond C a c) (Cond C' b d)" apply atomize apply (rule exec_statefn_simulatesI) apply (erule exec.cases, simp_all) apply clarsimp apply (drule spec, drule(1) mp, simp) apply (drule(1) exec_statefn_simulatesD, simp) apply (auto intro: exec.CondTrue)[1] apply clarsimp apply (drule spec, drule(1) mp, simp) apply (drule(1) exec_statefn_simulatesD, simp) apply (auto intro: exec.CondFalse)[1] done lemma exec_While_not_in_state_lemma: "\ \t'\- T. \ \ \ \While C' b,Normal s\ \ Normal (f t'); \ft. \ \ \ \While C' b,Normal s\ \ Fault ft \ \ (s \ com_initial_guards b \ s \ f ` (- T))" apply (rule ccontr, clarsimp) apply (drule_tac \=\ in exec_not_in_initial_guards) apply (blast intro: exec.WhileTrue exec.WhileFalse) done lemma exec_statefn_simulates_While_lemma: assumes sim: "exec_statefn_simulates f C {s. f s \ S \ (f s \ com_initial_guards b \ f s \ f ` (- T))} a b" assumes eq: "\s. \ f s \ S; f s \ com_initial_guards b \ f s \ f ` (- T) \ \ s \ C = (f s \ C')" assumes subs: "com_final_guards UNIV b \ S" shows "\ \ \ \bdy, xs\ \ t \ \ \s. bdy = While C a \ xs = Normal s \ f s \ S \ (option_map (add_statefn (inv f)) o \) \ \While C' b, Normal (f s)\ \ add_statefn_xstate f t \ (\ft. (option_map (add_statefn (inv f)) o \) \ \While C' b,Normal (f s)\ \ Fault ft) \ (\t' \ - T. (option_map (add_statefn (inv f)) o \) \ \While C' b,Normal (f s)\ \ Normal (f t'))" apply (induct rule: exec.induct, simp_all) apply clarsimp apply (rule ccontr) apply (frule exec_While_not_in_state_lemma, simp) apply (drule(1) eq[rotated]) apply (drule(1) exec_statefn_simulatesD[OF _ sim]) apply (simp add: o_def) apply (elim disjE exE) apply (case_tac s', simp_all) apply (blast intro: exec.WhileTrue exec_in_final_guards[THEN subsetD[OF subs]])[1] apply (erule exec.cases, simp_all)[1] apply (blast intro: exec.WhileTrue)[1] apply (erule exec.cases, simp_all)[1] apply (blast intro: exec.WhileTrue) apply (erule exec.cases, simp_all)[1] apply (blast intro: exec.WhileTrue)[1] apply (case_tac s', simp_all) apply (blast intro: exec.WhileTrue) apply (erule exec.cases, simp_all)[1] apply (blast intro: exec.WhileTrue) apply (erule exec.cases, simp_all) apply (blast intro: exec.WhileTrue) apply (erule exec.cases, simp_all)[1] apply (blast intro: exec.WhileTrue) apply (clarsimp simp: Bex_def exec_in_final_guards[THEN subsetD[OF subs]]) apply (drule_tac \="map_option (add_statefn (inv f)) \ \" in exec_not_in_initial_guards) apply (clarsimp simp: o_def) apply (blast intro: exec.WhileTrue exec.WhileFalse) apply clarsimp apply (rule ccontr, frule exec_While_not_in_state_lemma, simp) apply (cut_tac s=s in eq) apply (auto intro: exec.WhileFalse) done lemma exec_statefn_simulates_While: assumes bij: "bij f" shows "\ \s. \ s \ S \ f s \ com_final_guards UNIV b; f s \ com_initial_guards b \ s \ T \ \ s \ C = (f s \ C'); exec_statefn_simulates f C {s. (s \ S \ f s \ com_final_guards UNIV b) \ (f s \ com_initial_guards b \ s \ T)} a b \ \ exec_statefn_simulates f S T (While C a) (While C' b)" apply (rule exec_statefn_simulatesI) apply (rule_tac S="f ` S \ com_final_guards UNIV b" in exec_statefn_simulates_While_lemma[rule_format]) apply (auto simp add: inj_image_mem_iff[OF bij_is_inj, OF bij]) done lemma exec_statefn_simulates_Catch: "\ exec_statefn_simulates f S UNIV a b; exec_statefn_simulates f UNIV T c d \ \ exec_statefn_simulates f S T (Catch a c) (Catch b d)" apply (rule exec_statefn_simulatesI) apply (erule exec.cases, simp_all) apply clarsimp apply (drule(2) exec_statefn_simulatesD) apply (elim disjE exE) apply (drule(1) exec_statefn_simulatesD, simp) apply (auto intro: exec.intros)[1] apply (fastforce intro: exec.intros) apply (fastforce intro: exec.intros) apply (drule(2) exec_statefn_simulatesD) apply (fastforce intro: exec.intros) done lemma exec_statefn_simulates_Guard_rhs: "exec_statefn_simulates f (S \ {s. f s \ G}) T a b \ exec_statefn_simulates f S T a (Guard E G b)" apply (rule exec_statefn_simulatesI) apply (case_tac "f s \ G") apply (drule(1) exec_statefn_simulatesD, simp) apply (auto intro: exec.intros) done lemma exec_statefn_simulates_Guard_lhs: "\ S \ G; exec_statefn_simulates f S T a b \ \ exec_statefn_simulates f S T (Guard E G a) b" apply (rule exec_statefn_simulatesI) apply (erule exec.cases, simp_all) apply (drule(1) exec_statefn_simulatesD, simp) apply (auto intro: exec.intros) done lemmas exec_statefn_simulates_whileAnno = exec_statefn_simulates_While[folded whileAnno_def[where I=I and V=V]] for I V lemma exec_statefn_simulates_Basic: "\ \s. \ s \ S; g (fn s) \ fn ` (- T) \ \ fn (f s) = g (fn s) \ \ exec_statefn_simulates fn S T (Basic f) (Basic g)" apply atomize apply (rule exec_statefn_simulatesI) apply (erule exec.cases, simp_all, clarsimp) apply (drule spec, drule(1) mp) apply (drule mp) apply clarsimp apply (metis exec.Basic Compl_iff) apply clarsimp apply (blast intro: exec.Basic) done lemma exec_statefn_simulates_Call: "bij f \ exec_statefn_simulates f S T (Call c) (Call c)" apply (rule exec_statefn_simulatesI) apply (intro disjI1) apply (erule exec.cases, simp_all) apply (rule exec.intros, simp) apply (simp add: add_statefn_exec bij_imp_bij_inv option.map_comp o_def inv_inv_eq) apply (simp add: add_statefn_comp inj_iff[THEN iffD1, OF bij_is_inj] inv_inv_eq bij_imp_bij_inv map_option_case inv_f_f[OF bij_is_inj] add_statefn_xstate_comp) apply (fastforce intro: exec.intros) done lemma exec_statefn_simulates_DynCom: "\ \s. s \ S \ exec_statefn_simulates f S T (g s) (h (f s)) \ \ exec_statefn_simulates f S T (DynCom g) (DynCom h)" apply atomize apply (clarsimp simp add: exec_statefn_simulates_def) apply (erule exec.cases, simp_all) apply (fastforce intro: exec.intros) done lemma exec_statefn_simulates_Skip_Throw: "exec_statefn_simulates f S T Skip Skip" "exec_statefn_simulates f S T Throw Throw" apply (simp_all add: exec_statefn_simulates_def) apply (fastforce elim: exec.cases intro: exec.intros)+ done lemma exec_statefn_simulates_call: "\ bij f; \s. s \ S \ f (init1 s) = init2 (f s); \s t. f (ret1 s t) = ret2 (f s) (f t); \s t. exec_statefn_simulates f UNIV T (save1 s t) (save2 (f s) (f t)) \ \ exec_statefn_simulates f S T (call init1 c ret1 save1) (call init2 c ret2 save2)" apply (simp add: call_def block_def) apply (intro exec_statefn_simulates_Seq exec_statefn_simulates_Catch exec_statefn_simulates_DynCom exec_statefn_simulates_Basic exec_statefn_simulates_Call exec_statefn_simulates_Skip_Throw) apply simp+ done lemma exec_statefn_simulates_creturn_void: "\ \inn s. s \ S \ f (exn_upd inn s) = exn_upd' inn (f s) \ \ exec_statefn_simulates f S T (creturn_void exn_upd) (creturn_void exn_upd')" apply (simp add: creturn_void_def) apply (intro exec_statefn_simulates_Seq exec_statefn_simulates_Basic exec_statefn_simulates_Skip_Throw | simp)+ done lemma exec_statefn_simulates_creturn: "\ \inn s. f (exn_upd inn s) = exn_upd' inn (f s); \inn s. s \ S \ f (rv_upd inn s) = rv_upd' inn (f s); \inn s. s \ S \ rv s = rv' (f s) \ \ exec_statefn_simulates f S T (creturn exn_upd rv_upd rv) (creturn exn_upd' rv_upd' rv')" apply (simp add: creturn_def) apply (intro exec_statefn_simulates_Seq exec_statefn_simulates_Basic exec_statefn_simulates_Skip_Throw | simp)+ done lemma exec_statefn_simulates_cbreak: "\ \inn s. s \ S \ f (exn_upd inn s) = exn_upd' inn (f s) \ \ exec_statefn_simulates f S T (cbreak exn_upd) (cbreak exn_upd')" apply (simp add: cbreak_def) apply (intro exec_statefn_simulates_Seq exec_statefn_simulates_Basic exec_statefn_simulates_Skip_Throw | simp)+ done lemma exec_statefn_simulates_ccatchbrk: "\ \s. s \ S \ exn' (f s) = exn s \ \ exec_statefn_simulates f S T (ccatchbrk exn) (ccatchbrk exn')" apply (simp add: ccatchbrk_def) apply (intro exec_statefn_simulates_Cond exec_statefn_simulates_Skip_Throw | simp)+ done lemma exec_statefn_simulates_Spec: "\ bij f; \s. \ s \ S; \t. (f s, f t) \ R' \ t \ T \ \ \t. ((s, t) \ R) = ((f s, f t) \ R') \ \ exec_statefn_simulates f S T (Spec R) (Spec R')" apply (rule exec_statefn_simulatesI) apply (erule exec_Normal_elim_cases, simp_all) apply (blast intro: exec.Spec) apply (case_tac "\t. (f s, f t) \ R' \ t \ T") apply clarsimp apply (subgoal_tac "\t. (f s, f (inv f t)) \ R'") apply (simp add: surj_f_inv_f bij_is_surj) apply (blast intro: exec.SpecStuck) apply clarsimp apply (blast intro: exec.Spec) done lemmas exec_statefn_simulates_comI = exec_statefn_simulates_refl exec_statefn_simulates_Seq exec_statefn_simulates_Cond exec_statefn_simulates_While exec_statefn_simulates_whileAnno exec_statefn_simulates_Catch exec_statefn_simulates_Guard_rhs exec_statefn_simulates_Guard_lhs exec_statefn_simulates_Call exec_statefn_simulates_call exec_statefn_simulates_Skip_Throw exec_statefn_simulates_Basic exec_statefn_simulates_creturn exec_statefn_simulates_creturn_void exec_statefn_simulates_cbreak exec_statefn_simulates_ccatchbrk exec_statefn_simulates_Spec lemma exec_statefn_simulates_additional_Guards: "exec_statefn_simulates f S T a (b ;; Guard F (G \ G') c) \ exec_statefn_simulates f S T a (b ;; Guard F G (Guard F' G' c))" apply (rule exec_statefn_simulatesI) apply (drule(2) exec_statefn_simulatesD) apply (elim disjE exE) apply (erule exec_Normal_elim_cases) apply (case_tac s', auto elim!: exec_Normal_elim_cases, (blast intro: exec.Seq exec.Guard exec.GuardFault)+)[1] apply (erule exec_Normal_elim_cases) apply (case_tac s', auto elim!: exec_Normal_elim_cases, (blast intro: exec.Seq exec.Guard exec.GuardFault)+)[1] apply (clarsimp elim!: exec_Normal_elim_cases) apply (case_tac s', auto elim!: exec_Normal_elim_cases, (blast intro: exec.Seq exec.Guard exec.GuardFault)+)[1] done lemma exec_statefn_simulates_additional_Guarded_Skip: "exec_statefn_simulates f S (T \ {s. f s \ G}) a b \ exec_statefn_simulates f S T a (b ;; Guard F G Skip)" apply (rule exec_statefn_simulatesI) apply (drule(2) exec_statefn_simulatesD) apply (elim disjE exE) apply (case_tac t, auto elim!: exec_Normal_elim_cases, (blast intro: exec.Seq exec.Skip exec.Guard exec.GuardFault)+)[1] apply (case_tac t, auto elim!: exec_Normal_elim_cases, (blast intro: exec.Seq exec.Skip exec.Guard exec.GuardFault)+)[1] apply (blast intro: exec.Seq exec.Skip exec.Guard exec.GuardFault) done lemmas exec_statefn_simulates_additionals = exec_statefn_simulates_additional_Guarded_Skip exec_statefn_simulates_additional_Guards inductive guards_adjust_by_invariant :: "'s set \ 's set \ ('s, 'x, 'e) com \ ('s, 'x, 'e) com \ bool" where gabi_Skip: "guards_adjust_by_invariant S T Skip Skip" | gabi_Guard: "\ S \ T \ G = S \ T \ G'; guards_adjust_by_invariant S (T \ G) c c' \ \ guards_adjust_by_invariant S T (Guard F G c) (Guard F G' c')" | gabi_Basic: "\ \s. \ s \ S; s \ T \ \ f s \ S \ \ guards_adjust_by_invariant S T (Basic f) (Basic f)" | gabi_Spec: "\ \s t. \ s \ S; s \ T; (s, t) \ R \ \ t \ S \ \ guards_adjust_by_invariant S T (Spec R) (Spec R)" | gabi_Seq: "\ guards_adjust_by_invariant S T c d; guards_adjust_by_invariant S UNIV c' d' \ \ guards_adjust_by_invariant S T (Seq c c') (Seq d d')" | gabi_Cond: "\ guards_adjust_by_invariant S T c d; guards_adjust_by_invariant S T c' d' \ \ guards_adjust_by_invariant S T (Cond C c c') (Cond C d d')" | gabi_While: "\ guards_adjust_by_invariant S UNIV c d \ \ guards_adjust_by_invariant S T (While C c) (While C d)" | gabi_Call :"guards_adjust_by_invariant S T (Call proc) (Call proc)" | gabi_Dyncom :"\ \s. \ s \ S; s \ T \ \ guards_adjust_by_invariant S T (f s) (f' s) \ \ guards_adjust_by_invariant S T (DynCom f) (DynCom f')" | gabi_Throw: "guards_adjust_by_invariant S T Throw Throw" | gabi_Catch: "\ guards_adjust_by_invariant S T c d; guards_adjust_by_invariant S UNIV c' d' \ \ guards_adjust_by_invariant S T (Catch c c') (Catch d d')" definition context_gabi :: "'s set \ ('x \ ('s, 'x, 'e) com) \ ('x \ ('s, 'x, 'e) com) \ bool" where "context_gabi S G G' = (\x. (G x = None) = (G' x = None) \ (G x \ None \ guards_adjust_by_invariant S UNIV (the (G x)) (the (G' x))))" definition xstate_inv_set :: "'s set \ ('s, 'e) xstate set" where "xstate_inv_set S = {xs. case xs of Normal s \ s \ S | Abrupt s \ s \ S | _ \ True}" lemmas xstate_inv_set_simps = xstate_inv_set_def[THEN eqset_imp_iff, simplified, split_simps xstate.split] lemma xstate_inv_set_UNIV: "xstate_inv_set UNIV = UNIV" by (simp add: xstate_inv_set_def split: xstate.split) lemma gabi_simulation: "\ G \ \c, xs\ \ xs'; guards_adjust_by_invariant S T c c'; xs \ xstate_inv_set (S \ T); context_gabi S G G' \ \ G' \ \c', xs\ \ xs' \ xs' \ xstate_inv_set S" proof (induct arbitrary: c' T rule: exec.induct) case (Call proc bdy s t) show ?case using Call.prems Call.hyps apply - apply (erule guards_adjust_by_invariant.cases, simp_all) apply (simp add: context_gabi_def xstate_inv_set_simps) apply (drule_tac x=proc in spec, clarsimp) apply (auto intro: exec.intros guards_adjust_by_invariant.intros)[1] done next case (CallUndefined proc s t) show ?case using CallUndefined.prems CallUndefined.hyps apply - apply (erule guards_adjust_by_invariant.cases, simp_all) apply (simp add: context_gabi_def xstate_inv_set_simps) apply (drule_tac x=proc in spec, clarsimp) apply (auto intro: exec.intros guards_adjust_by_invariant.intros)[1] done next case (WhileTrue s S c s' t) show ?case using WhileTrue.prems WhileTrue.hyps apply - apply (erule guards_adjust_by_invariant.cases, simp_all) apply (clarsimp simp add: xstate_inv_set_simps) apply (erule_tac x=UNIV in meta_allE)+ apply (auto intro: exec.intros guards_adjust_by_invariant.intros)[1] done apply_end (simp_all add: xstate_inv_set_simps) apply_end (((erule guards_adjust_by_invariant.cases, simp_all)[1], clarsimp simp: xstate_inv_set_simps, (fastforce intro: exec.intros guards_adjust_by_invariant.intros)[1])+) qed end