From 41c4adfdbc8d771a1bdce99ea2b131a30558b4b2 Mon Sep 17 00:00:00 2001 From: Corey Lewis Date: Mon, 28 Aug 2023 19:08:40 +1000 Subject: [PATCH] squash lib/monads/trace: update Trace_Empty_Fail as required Signed-off-by: Corey Lewis --- lib/Monads/trace/Trace_Empty_Fail.thy | 85 ++++++++++++++++++--------- 1 file changed, 57 insertions(+), 28 deletions(-) diff --git a/lib/Monads/trace/Trace_Empty_Fail.thy b/lib/Monads/trace/Trace_Empty_Fail.thy index 02dd0b2a3c..b468cabd9f 100644 --- a/lib/Monads/trace/Trace_Empty_Fail.thy +++ b/lib/Monads/trace/Trace_Empty_Fail.thy @@ -14,14 +14,15 @@ begin section \Monads that are wellformed w.r.t. failure\ text \ - Usually, well-formed monads constructed from the primitives in Nondet_Monad will have the following - property: if they return an empty set of results, they will have the failure flag set.\ -definition empty_fail :: "('s,'a) nondet_monad \ bool" where - "empty_fail m \ \s. fst (m s) = {} \ snd (m s)" + Usually, well-formed monads constructed from the primitives in Trace_Monad will have the following + property: if they return an empty set of completed results, there exists a trace corresponding to + a failed result.\ +definition empty_fail :: "('s,'a) tmonad \ bool" where + "empty_fail m \ \s. mres (m s) = {} \ Failed \ snd ` (m s)" text \Useful in forcing otherwise unknown executions to have the @{const empty_fail} property.\ -definition mk_ef :: "'a set \ bool \ 'a set \ bool" where - "mk_ef S \ (fst S, fst S = {} \ snd S)" +\ \definition mk_ef :: "'a set \ bool \ 'a set \ bool" where + "mk_ef S \ (fst S, fst S = {} \ snd S)"\ subsection \WPC setup\ @@ -36,27 +37,29 @@ wpc_setup "\m. empty_fail m" wpc_helper_empty_fail_final subsection \@{const empty_fail} intro/dest rules\ lemma empty_failI: - "(\s. fst (m s) = {} \ snd (m s)) \ empty_fail m" + "(\s. mres (m s) = {} \ Failed \ snd ` (m s)) \ empty_fail m" by (simp add: empty_fail_def) lemma empty_failD: - "\ empty_fail m; fst (m s) = {} \ \ snd (m s)" + "\ empty_fail m; mres (m s) = {} \ \ Failed \ snd ` (m s)" by (simp add: empty_fail_def) lemma empty_fail_not_snd: - "\ \ snd (m s); empty_fail m \ \ \v. v \ fst (m s)" + "\ Failed \ snd ` (m s); empty_fail m \ \ \v. v \ mres (m s)" by (fastforce simp: empty_fail_def) lemmas empty_failD2 = empty_fail_not_snd[rotated] lemma empty_failD3: - "\ empty_fail f; \ snd (f s) \ \ fst (f s) \ {}" + "\ empty_fail f; Failed \ snd ` (f s) \ \ mres (f s) \ {}" by (drule(1) empty_failD2, clarsimp) lemma empty_fail_bindD1: "empty_fail (a >>= b) \ empty_fail a" unfolding empty_fail_def bind_def - by (fastforce simp: split_def image_image) + apply clarsimp + apply (drule_tac x=s in spec) + by (force simp: split_def mres_def vimage_def split: tmres.splits) subsection \Wellformed monads\ @@ -91,32 +94,58 @@ lemma empty_fail_If_applied[empty_fail_cond]: lemma empty_fail_put[empty_fail_term]: "empty_fail (put f)" - by (simp add: put_def empty_fail_def) + by (simp add: put_def empty_fail_def mres_def vimage_def) lemma empty_fail_modify[empty_fail_term]: "empty_fail (modify f)" - by (simp add: empty_fail_def simpler_modify_def) + by (simp add: empty_fail_def simpler_modify_def mres_def vimage_def) lemma empty_fail_gets[empty_fail_term]: "empty_fail (gets f)" - by (simp add: empty_fail_def simpler_gets_def) + by (simp add: empty_fail_def simpler_gets_def mres_def vimage_def) lemma empty_fail_select[empty_fail_cond]: "S \ {} \ empty_fail (select S)" - by (simp add: empty_fail_def select_def) - -lemma empty_fail_select_f[empty_fail_cond]: - assumes ef: "fst S = {} \ snd S" - shows "empty_fail (select_f S)" - by (fastforce simp add: empty_fail_def select_f_def intro: ef) + by (simp add: empty_fail_def select_def mres_def image_def) + +lemma mres_bind_empty: + "mres ((f >>= g) s) = {} + \ mres (f s) = {} \ (\res\mres (f s). mres (g (fst res) (snd res)) = {})" + apply clarsimp + apply (clarsimp simp: mres_def split_def vimage_def bind_def) + apply (rename_tac rv s' trace) + apply (drule_tac x=rv in spec, drule_tac x=s' in spec) + apply (clarsimp simp: image_def) + apply fastforce + done + +lemma bind_FailedI1: + "Failed \ snd ` f s \ Failed \ snd ` (f >>= g) s" + by (force simp: bind_def vimage_def) + +lemma bind_FailedI2: + "\\res\mres (f s). Failed \ snd ` (g (fst res) (snd res)); mres (f s) \ {}\ + \ Failed \ snd ` (f >>= g) s" + by (force simp: bind_def mres_def image_def split_def) + +\ \FIXME: move\ +lemma context_disjE: + "\P \ Q; P \ R; \\P; Q\ \ R\ \ R" + by auto lemma empty_fail_bind[empty_fail_cond]: "\ empty_fail a; \x. empty_fail (b x) \ \ empty_fail (a >>= b)" - by (fastforce simp: bind_def empty_fail_def split_def) + unfolding empty_fail_def + apply clarsimp + apply (drule mres_bind_empty) + apply (erule context_disjE) + apply (fastforce intro: bind_FailedI1) + apply (fastforce intro!: bind_FailedI2) + done lemma empty_fail_return[empty_fail_term]: "empty_fail (return x)" - by (simp add: empty_fail_def return_def) + by (simp add: empty_fail_def return_def mres_def vimage_def) lemma empty_fail_returnOk[empty_fail_term]: "empty_fail (returnOk v)" @@ -166,9 +195,9 @@ lemma empty_fail_assert_opt[empty_fail_term]: "empty_fail (assert_opt x)" by (simp add: assert_opt_def empty_fail_term split: option.splits) -lemma empty_fail_mk_ef[empty_fail_term]: +\ \lemma empty_fail_mk_ef[empty_fail_term]: "empty_fail (mk_ef o m)" - by (simp add: empty_fail_def mk_ef_def) + by (simp add: empty_fail_def mk_ef_def)\ lemma empty_fail_gets_the[empty_fail_term]: "empty_fail (gets_the f)" @@ -191,7 +220,7 @@ lemma empty_fail_assertE[empty_fail_term]: lemma empty_fail_get[empty_fail_term]: "empty_fail get" - by (simp add: empty_fail_def get_def) + by (simp add: empty_fail_def get_def mres_def vimage_def) lemma empty_fail_catch[empty_fail_cond]: "\ empty_fail f; \x. empty_fail (g x) \ \ empty_fail (catch f g)" @@ -203,7 +232,7 @@ lemma empty_fail_guard[empty_fail_term]: lemma empty_fail_spec[empty_fail_term]: "empty_fail (state_select F)" - by (clarsimp simp: state_select_def empty_fail_def) + by (clarsimp simp: state_select_def empty_fail_def default_elem_def mres_def image_def) lemma empty_fail_when[empty_fail_cond]: "(P \ empty_fail x) \ empty_fail (when P x)" @@ -321,7 +350,7 @@ subsection \Equations and legacy names\ lemma empty_fail_select_eq[simp]: "empty_fail (select V) = (V \ {})" - by (clarsimp simp: select_def empty_fail_def) + by (clarsimp simp: select_def empty_fail_def mres_def image_def) lemma empty_fail_liftM_eq[simp]: "empty_fail (liftM f m) = empty_fail m" @@ -330,7 +359,7 @@ lemma empty_fail_liftM_eq[simp]: lemma empty_fail_liftE_eq[simp]: "empty_fail (liftE f) = empty_fail f" - by (fastforce simp: liftE_def empty_fail_def bind_def) + by (auto simp: liftE_def empty_fail_bindD1) lemma liftME_empty_fail_eq[simp]: "empty_fail (liftME f m) = empty_fail m"