(* * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) * * SPDX-License-Identifier: BSD-2-Clause *) (* Adds positivity law to separation algebra, as well as defining the septraction and sep-coimplication operators, providing lemmas for each. *) theory Extended_Separation_Algebra imports Lib.Lib "Sep_Tactics" begin no_notation pred_and (infixr "and" 35) no_notation pred_or (infixr "or" 30) no_notation pred_not ("not _" [40] 40) no_notation pred_imp (infixr "imp" 25) lemma sep_conj_exists_left[simp]: "((\s. \x. (P x) s) \* R) \ (EXS x. (P x \* R)) " apply (rule eq_reflection) by (clarsimp simp: sep_conj_def, fastforce) instantiation "bool" :: stronger_sep_algebra begin definition "zero_bool \ True" definition "plus_bool \ \(x :: bool) (y :: bool). x \ y" definition "sep_disj_bool \ \(x :: bool) (y :: bool). x \ y" instance by (intro_classes; fastforce simp: zero_bool_def plus_bool_def sep_disj_bool_def) end instantiation "prod" :: (stronger_sep_algebra, stronger_sep_algebra) stronger_sep_algebra begin definition "zero_prod \ (0,0)" definition "plus_prod p p' \ (fst p + fst p', snd p + snd p')" definition "sep_disj_prod p p' \ fst p ## fst p' \ snd p ## snd p'" instance apply (intro_classes; simp add: zero_prod_def plus_prod_def sep_disj_prod_def) apply (simp add: sep_add_assoc | fastforce simp: sep_disj_commute sep_add_commute)+ done end instantiation "fun" :: (type, pre_sep_algebra) pre_sep_algebra begin definition "zero_fun = (\x. 0)" definition "plus_fun f f' \ (\x. (f x) + (f' x) )" definition "sep_disj_fun \ (\f f'. \x. f x ## f' x ) :: ('a \ 'b) \ ('a \ 'b) \ bool " instance apply (intro_classes) apply (clarsimp simp: comp_def sep_disj_fun_def ) apply (clarsimp simp: zero_fun_def sep_disj_fun_def plus_fun_def ) apply (clarsimp simp: zero_fun_def comp_def sep_disj_fun_def plus_fun_def ) apply (simp add: sep_disj_commute) apply (clarsimp simp: zero_fun_def sep_disj_commuteI sep_disj_fun_def plus_fun_def) apply (clarsimp simp: zero_fun_def sep_disj_commuteI sep_disj_fun_def plus_fun_def sep_add_commute) apply (clarsimp simp: zero_fun_def sep_disj_commuteI sep_disj_fun_def plus_fun_def sep_add_commute sep_add_assoc) done end instantiation "fun" :: (type, sep_algebra) sep_algebra begin instance apply (intro_classes) apply (clarsimp simp: zero_fun_def sep_disj_fun_def plus_fun_def ) using sep_disj_addD apply blast apply (clarsimp simp: zero_fun_def comp_def sep_disj_fun_def plus_fun_def ) by (simp add: sep_disj_addI1) end instantiation option :: (type) sep_algebra begin definition "sep_disj_option (h :: 'a option) (h' :: 'a option) = (case h of (Some x) \ h' = None | _ \ h = None)" definition "plus_option (h :: 'a option) (h' :: 'a option) = (case h of (Some x) \ h | _ \ h')" definition "zero_option = None" instance apply (intro_classes) by (clarsimp simp: sep_disj_option_def zero_option_def plus_option_def split: option.splits)+ end instantiation option :: (type) cancellative_sep_algebra begin instance apply (intro_classes) apply (simp add: option.case_eq_if plus_option_def sep_disj_option_def) apply (clarsimp simp: zero_option_def option.case_eq_if plus_option_def sep_disj_option_def split: if_split_asm option.splits) apply (clarsimp simp: zero_option_def option.case_eq_if plus_option_def sep_disj_option_def split: if_split_asm option.splits) done end instantiation "fun" :: (type, cancellative_sep_algebra) cancellative_sep_algebra begin instance apply (intro_classes) apply (clarsimp simp: plus_fun_def sep_disj_fun_def zero_fun_def) apply (safe; fastforce) apply (clarsimp simp: plus_fun_def sep_disj_fun_def zero_fun_def) apply (rule ext) apply (meson sep_disj_positive) apply (rule ext) apply (clarsimp simp: plus_fun_def sep_disj_fun_def zero_fun_def) by (meson sep_add_cancel) end lemma sep_substate_antisym: "x \ y \ y \ x \ x = (y :: 'a ::cancellative_sep_algebra)" apply (clarsimp simp: sep_substate_def) apply (rename_tac h' h) apply (subgoal_tac "h' = 0") apply (clarsimp) apply (drule_tac trans[where s=x and t="x+0"]) apply (clarsimp) apply (subgoal_tac "(x + h' + h = x + 0) \ ((0 + x) = (h' + h) + x)") apply (drule mp, clarsimp) apply (metis sep_add_cancelD sep_add_disj_eq sep_disj_commuteI sep_disj_positive_zero sep_disj_zero) by (metis sep_add_assoc sep_add_commute sep_add_zero sep_add_zero_sym sep_disj_commuteI) context sep_algebra begin definition septraction :: "('a \ bool) \ ('a \ bool) \ ('a \ bool)" (infix "-*" 25) where "septraction P Q = (not (P \* not Q))" lemma septraction_impl1: "(P -* Q) s \ (\s. P s \ P' s) \ (P' -* Q) s " apply (clarsimp simp: septraction_def pred_neg_def) using sep_impl_def by auto lemma septraction_impl2: "(P -* Q) s \ (\s. Q s \ Q' s) \ (P -* Q') s " apply (clarsimp simp: septraction_def pred_neg_def) using sep_impl_def by auto definition sep_coimpl :: "('a \ bool) \ ('a \ bool) \ ('a \ bool)" (infix "\*" 24) where "sep_coimpl P Q \ \s. \ (P \* not Q) s" lemma sep_septraction_snake: "(P -* Q) s \ (\s. Q s \ (P \* Q') s) \ Q' s" apply (clarsimp simp: sep_coimpl_def septraction_def pred_neg_def sep_conj_def sep_impl_def) using sep_add_commute sep_disj_commute by auto lemma sep_snake_septraction: "Q s \ (\s. (P -* Q) s \ Q' s) \ (P \* Q') s " apply (clarsimp simp: sep_coimpl_def septraction_def pred_neg_def sep_conj_def sep_impl_def) using sep_add_commute sep_disj_commute by fastforce lemma septraction_snake_trivial: "(P -* (P \* R)) s \ R s" by (erule sep_septraction_snake) end lemma sep_impl_impl: "(P \* Q) s\ (\s. Q s \ Q' s) \ (P \* Q') s" by (metis sep_implD sep_implI) lemma disjointness_equiv: "(\P (s :: 'a :: sep_algebra). strictly_exact P \ \P 0 \ (P \* (P \* sep_false)) s) = (\h :: 'a. h ## h \ h = 0)" apply (rule iffI) apply (clarsimp) apply (erule_tac x="(=) h" in allE) apply (drule mp) apply (clarsimp simp: strictly_exact_def) apply (rule ccontr) apply (drule mp) apply (clarsimp) apply (erule_tac x="h + h" in allE) apply (clarsimp simp: sep_coimpl_def sep_conj_def pred_neg_def) apply (erule_tac x=h in allE, clarsimp) apply (erule_tac x=0 in allE, clarsimp) apply (clarsimp) apply (clarsimp simp: sep_coimpl_def sep_conj_def pred_neg_def strictly_exact_def) apply (erule_tac x=x in allE, erule_tac x=xa in allE, clarsimp simp: sep_empty_def) apply (erule_tac x=x in allE, clarsimp) using sep_disj_addD1 by blast definition sep_min :: "(('a :: sep_algebra) \ bool) \ ('a \ bool)" where "sep_min P \ P and (P \* \)" definition sep_subtract :: "(('a :: sep_algebra) \ bool) \ ('a \ bool) \ ('a \ bool)" where "sep_subtract P Q \ P and (Q \* \)" lemma sep_min_subtract_subtract: "sep_min P = sep_subtract P P" apply (clarsimp simp: sep_subtract_def sep_min_def) done lemma sep_subtract_distrib_disj: "sep_subtract (P or Q) R = ((sep_subtract P R) or (sep_subtract Q R))" apply (rule ext, rule iffI) apply (clarsimp simp: pred_disj_def pred_conj_def sep_subtract_def) apply (clarsimp simp: pred_disj_def pred_conj_def sep_subtract_def) apply (safe) done lemma sep_snake_sep_impl: "(P \* R) s \ (\ s. R s \ (P \* sep_false) s) \ (not P \* (not (P -* R))) s" apply (drule sep_impl_impl[where Q'="(P \* sep_false)"]) apply (atomize) apply (erule allE, drule mp, assumption) apply (assumption) apply (erule contrapos_pp) apply (clarsimp simp: sep_impl_def sep_coimpl_def sep_conj_def pred_neg_def septraction_def) apply (erule_tac x=0 in allE) apply (erule_tac x=s in allE) apply (clarsimp) apply (rule_tac x=0 in exI) apply (clarsimp) by (metis (full_types) disjoint_zero_sym sep_add_commute sep_add_zero_sym sep_disj_commuteI) lemma sep_snake_mp: "(P \* Q) s \ (P \* sep_true) s \ (P \* Q) s " apply (clarsimp simp: sep_coimpl_def) apply (clarsimp simp: sep_conj_def sep_coimpl_def pred_neg_def) apply (fastforce) done lemma sep_coimpl_contrapos: "(P \* Q) = ((not Q) \* (not P))" by (rule ext, rule iffI; simp add: sep_coimpl_def pred_neg_def sep_conj_commute) lemma sep_coimpl_def': "(\ (P \* Q) s) = ((P \* (not Q)) s)" by (simp add: pred_neg_def sep_coimpl_def) lemma rewrite_sp: "(\R s. (P \* R) s \ (Q \* R) (f s)) \ (\R s. R s \ (Q \* (P -* R)) (f s) )" apply (rule iffI) apply (clarsimp) apply (erule_tac x="P -* R" in allE) apply (erule_tac x=s in allE) apply (drule mp) apply (erule (1) sep_snake_septraction) apply (assumption) apply (clarsimp) apply (erule_tac x="P \* R" in allE) apply (erule_tac x=s in allE) apply (clarsimp) apply (sep_cancel) apply (erule (1) sep_septraction_snake) done lemma sep_coimpl_weaken: "(P \* Q) s \ (\s. P' s \ P s) \ (P' \* Q) s" apply (clarsimp simp: sep_coimpl_def sep_conj_def pred_neg_def) apply (fastforce) done lemma sep_curry': "R s \ (P \* (P \* R)) s" by (simp add: sep_wand_trivial) lemma sep_coimpl_mp_gen: "(P \* Q) s \ (P' \* Q') s \ (\s. P s \ P' s) \ ((P and P') \* (Q and Q')) s" apply (clarsimp simp: sep_coimpl_def sep_conj_def pred_conj_def pred_neg_def) by (fastforce simp: sep_disj_commute sep_add_commute) lemma ex_pull: "\h s. P h s \ Q h \ \h. Q h \ (\s. P h s)" apply (fastforce) done lemma sep_mp_snake_mp: "(P \* (P \* (P \* Q))) s \ (P \* Q) s" apply (clarsimp simp: sep_conj_def) apply (rename_tac x y) apply (rule_tac x=x in exI) apply (rule_tac x=y in exI) apply (clarsimp) apply (clarsimp simp: sep_impl_def) apply (erule_tac x=x in allE) apply (clarsimp simp: sep_disj_commute) apply (clarsimp simp: sep_conj_def sep_coimpl_def pred_neg_def) by (fastforce simp: sep_disj_commute sep_add_commute) lemma septract_cancel: "(P -* Q) s \ (\s. P s \ P' s) \ (\s. Q s \ Q' s) \ (P' -* Q') s" apply (clarsimp simp: septraction_def sep_impl_def pred_neg_def) apply (fastforce) done lemma sep_coimpl_mp_zero: "(P \* Q) s \ P s \ Q (0)" apply (clarsimp simp: sep_coimpl_def sep_conj_def) apply (erule_tac x=s in allE) apply (clarsimp, erule_tac x="0" in allE) apply (clarsimp simp: pred_neg_def) done lemma sep_neg_not: "(P \* sep_false) s \ \P s" apply (cases "P s") apply (drule(1) sep_coimpl_mp_zero) apply (clarsimp) apply (simp) done lemma sep_antimp': "P s \ (Q \* (Q -* P)) s \ P s" apply (clarsimp) apply (erule sep_snake_septraction, assumption) done definition sep_precise_conj :: "(('a :: sep_algebra) \ bool) \ ('a \ bool)" where "sep_precise_conj P \ P and (ALLS R. (sep_true \* (P \* R)))" notation sep_precise_conj (infix "\@" 50) definition coprecise :: "(('a :: sep_algebra) \ bool) \ bool" where "coprecise P = (\s h h'. P h \ P h' \ s \ h \ s \ h' \ s \ 0 \ h = h')" definition cointuitionistic :: "(('a :: sep_algebra) \ bool) \ bool" where "cointuitionistic P = (\h h'. P h \ h' \ h \ P h')" lemma intuitionistic_def': "intuitionistic P = (\s R. (P \* R) s \ P s)" apply (rule iffI) apply (clarsimp simp: intuitionistic_def) apply (clarsimp simp: sep_conj_def) using sep_substate_disj_add apply blast apply (clarsimp simp: intuitionistic_def) apply (erule_tac x=h' in allE) apply (drule mp) apply (rule_tac x=sep_true in exI) apply (clarsimp simp:sep_conj_def sep_substate_def, fastforce) apply (assumption) done lemma cointuitionistic_def': "cointuitionistic P = (\s R. P s \ (R \* P) s)" apply (rule iffI) apply (clarsimp) apply (clarsimp simp: sep_coimpl_def) apply (clarsimp simp: sep_conj_def pred_neg_def cointuitionistic_def) apply (rename_tac R x y) apply (erule_tac x="x + y" in allE) apply (erule_tac x=y in allE) apply (clarsimp) using sep_disj_commuteI sep_substate_disj_add' apply blast apply (clarsimp simp: cointuitionistic_def) apply (erule_tac x=h in allE) apply (clarsimp) apply (clarsimp simp: sep_substate_def) apply (erule_tac x="\s. s = z" in allE) apply (clarsimp simp: sep_coimpl_def sep_conj_def pred_neg_def) apply (fastforce simp: sep_disj_commute sep_add_commute) done lemma saturated_split: "cointuitionistic P \ P s \ (Q \* R) s \ ((P and Q) \* (P and R)) s" apply (clarsimp simp: cointuitionistic_def sep_conj_def pred_conj_def) apply (rule_tac x=x in exI) apply (rule_tac x=y in exI) apply (clarsimp) using sep_disj_commuteI sep_substate_disj_add sep_substate_disj_add' by blast lemma sep_wand_dne: "((P \* sep_false) \* sep_false) s \ \s. P s" apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def sep_conj_def sep_coimpl_def) apply (erule_tac x=0 in allE) apply (clarsimp) done lemma sep_snake_dne: "(sep_true \* P) s \ ((P \* sep_false) \* sep_false) s" apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def sep_conj_def sep_coimpl_def) apply (rename_tac x y) apply (erule_tac x=y in allE) apply (erule_tac x=x in allE) apply (rule_tac x=x in exI) apply (rule_tac x=0 in exI) apply (clarsimp) apply (fastforce simp: sep_disj_commute sep_add_commute) done lemma strictly_exactI: "(\P s. ((P -* R) -* R) s \ P (s :: 'a :: cancellative_sep_algebra)) \ strictly_exact R" apply (atomize) apply (clarsimp simp: strictly_exact_def) apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def sep_conj_def sep_coimpl_def strictly_exact_def) apply (rename_tac h h') apply (erule_tac x="\s. s = h" in allE) by (metis disjoint_zero_sym sep_add_commute sep_add_zero sep_disj_zero) lemma strictly_exact_septractD: "strictly_exact R \ ((P -* R) -* R) s \ P (s :: 'a :: cancellative_sep_algebra)" apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def sep_conj_def sep_coimpl_def strictly_exact_def) by (metis sep_add_cancel sep_add_commute sep_disj_commuteI) lemma strictly_exact_def': "(\P s. ((P -* R) -* R) s \ P (s :: 'a :: cancellative_sep_algebra)) = strictly_exact R" using strictly_exactI strictly_exact_septractD by auto lemma copreciseI: "(\(s ) R. (P -* R) s \ (P \* R) s) \ coprecise P" apply (clarsimp simp: coprecise_def) apply (clarsimp simp: sep_substate_def) apply (erule_tac x="0" in allE) apply (rename_tac s h h') apply (erule_tac x="\s'. s' = s + h" in allE) apply (drule mp) apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def) apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def) done lemma sep_implI': "strictly_exact P \ (P -* R) s \ (P \* R) s" apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def coprecise_def strictly_exact_def) apply (fastforce) done lemma "\s P. (P -* R) s \ (P \* R) s \ \s. R s \ R s" apply (clarsimp simp: coprecise_def) apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def) by (metis disjoint_zero_sym sep_add_zero_sym) lemma strictly_exactI': "\s R. (P -* R) s \ (P \* R) s \ strictly_exact P" apply (clarsimp simp: strictly_exact_def) apply (erule_tac x="0" in allE) apply (rename_tac h h') apply (erule_tac x="\h. h = h'" in allE) apply (drule mp) apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def) apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def) done lemma strictly_exact_def'': "(\s R. (P -* R) s \ (P \* R) s) = strictly_exact P" using sep_implI' strictly_exactI' by blast lemma conj_coimpl_precise: "(\s R. (P \* R) s \ (P \* R) s) \ precise P" apply (clarsimp simp: precise_def) apply (clarsimp simp: sep_substate_def) apply (rename_tac h h' z z') apply (erule_tac x="h + z" in allE) apply (erule_tac x="\s. s= z" in allE) apply (drule mp) apply (clarsimp simp: sep_conj_def) apply (fastforce) apply (clarsimp simp: sep_coimpl_def sep_conj_def pred_neg_def) using sep_add_cancel by fastforce lemma precise_conj_coimpl: "precise P \ (\s R. (P \* R) s \ (P \* R) s)" apply (clarsimp simp: precise_def) apply (clarsimp simp: sep_conj_def sep_coimpl_def pred_neg_def) by (metis cancellative_sep_algebra_class.sep_add_cancelD sep_add_commute sep_disj_commuteI sep_substate_disj_add) lemma septract_cancel_eq_precise: "(\s. ((P -* (P \* R)) s \ R s)) = (\s. (P \* R) s \ (P \* R) s)" apply (rule iffI) apply (clarsimp) apply (clarsimp simp: sep_conj_def sep_impl_def septraction_def pred_neg_def sep_coimpl_def) apply (rule ccontr) apply (rename_tac x y h h') apply (erule_tac x=h' in allE) apply (clarsimp) apply (erule_tac x=h in allE) apply (clarsimp simp: sep_disj_commute) apply (erule_tac x=x in allE) apply (clarsimp) apply (erule_tac x=y in allE) apply (clarsimp) apply (fastforce simp: sep_disj_commute sep_add_commute) apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def) by (metis pred_neg_def sep_coimpl_def sep_conjI sep_conj_commuteI) lemma sep_coimpl_cancel: "(P \* Q) s \ ((P \* Q) s \ (P \* Q') s) \ (P \* Q') s" apply (clarsimp simp: sep_coimpl_def pred_neg_def) apply (clarsimp simp: sep_conj_def) by blast lemma sep_cases: "R s \ (P \* (P -* R)) s \ (P \* (sep_false)) s" apply (safe) apply (clarsimp simp: sep_coimpl_def) apply (rule ccontr) by (meson sep_antimp' sep_conj_sep_true_right sep_snake_mp) lemma contra: "(\s. P s \ Q s) \ (\s. \ Q s \ \ P s )" apply (safe) by (fastforce) lemma "(\R s. (P \* R) (s) \ (Q \* R) (f s) ) = (\R s. (Q \* R) (f s) \ (P \* R) ( s))" apply (clarsimp simp: sep_coimpl_def) apply (rule iffI) apply (clarsimp) apply (clarsimp) by (meson sep_coimpl_def sep_coimpl_def') lemma "R s \ strictly_exact R \ (P \* R) s' \ (P -* R) s' \ s' \ s \ (P \* sep_true) s" apply (clarsimp simp: sep_conj_def sep_coimpl_def pred_neg_def septraction_def sep_impl_def) by (metis sep_add_commute sep_disj_commuteI strictly_exact_def) lemma sep_coimpl_comb: " (R \* P) s \ (R \* Q) s \ (R \* (P and Q)) s" apply (clarsimp simp: sep_coimpl_def sep_conj_def pred_neg_def pred_conj_def) done lemma sep_coimpl_contra: "(R \* (not Q)) s \ (R \* Q) s \ (R \* sep_false) s" apply (drule sep_coimpl_comb, assumption) apply (clarsimp simp: pred_neg_def pred_conj_def) done lemma sep_comb': "((not Q) \* P) s \ (Q \* R) s \ ((R or P) \* sep_true) s" apply (clarsimp simp: sep_coimpl_def sep_conj_def pred_neg_def) by (metis (full_types) disjoint_zero_sym pred_disj_def sep_add_zero sep_add_zero_sym sep_disj_zero) lemma sep_coimpl_dne: "((R \* sep_false) \* sep_false) s \ (R \* sep_true) s" by (metis sep_coimpl_def sep_conj_sep_true_right sep_neg_not) lemma sep_antimp_contrapos: " (R) s \ ((P \* not R) \* (not P)) s " by (metis pred_neg_def sep_coimpl_def' sep_mp_gen) lemma sep_snake_trivial: "(sep_true \* Q) s \ Q s" by (metis pred_neg_def sep_coimpl_def sep_conj_sep_true') lemma min_predD: "(R \* \) s \ (R \* sep_true) s \ R s" using Sep_Cancel_Set.sep_conj_empty' sep_coimpl_dne sep_snake_mp by blast lemma septract_sep_wand: "(P -* R) s \ (P \* Q) s \ (P -* (Q and R)) s" apply (clarsimp simp: sep_impl_def septraction_def pred_neg_def) by (fastforce simp: pred_conj_def) lemma "(P -* (P \* R)) s \ (P \* Q) s \ (\s. (Q and (P \* R)) s \ (P \* R) s) \ R s" using sep_septraction_snake septract_sep_wand by blast lemma sep_elsewhereD: "(P -* sep_true) s \ (P \* (P \* R)) s \ R s" apply (drule (1) septract_sep_wand, simp add: pred_conj_def) using sep_septraction_snake by blast lemma sep_conj_coimplI: "(Q \* R) s \ ((P \* Q) \* (P -* R)) s " by (metis sep_coimpl_def sep_coimpl_def' sep_conj_commuteI sep_mp_frame septraction_def) lemma sep_conj_septract_curry: "((P \* Q) -* R) s \ (P -* (Q -* R)) s" by (smt sep_antimp' sep_conj_coimplI sep_septraction_snake) lemma sep_snake_boxI: "Q s \ (\ \* Q) s" by (simp add: pred_neg_def sep_coimpl_def) lemma sep_snake_boxD: "(Q \* \) s \ ((Q \* sep_false) or Q) s" apply (simp only: pred_disj_def) apply (safe) using Sep_Cancel_Set.sep_conj_empty' sep_coimpl_cancel by blast lemma septract_wandD: "(( R \* (not Q)) -* Q) s \ (not R) s" apply (erule sep_septraction_snake) by (simp add: sep_antimp_contrapos) lemma sep_impl_septractD: "(P \* Q) s \ (R -* (not Q)) s \ ((R and not P) -* (not Q)) s" apply (clarsimp simp: sep_impl_def pred_neg_def septraction_def) apply (erule_tac x=h' in allE) apply (clarsimp simp: pred_conj_def) apply (fastforce) done lemma sep_neg_impl: "(not (R \* Q)) = (R -* (not Q)) " apply (clarsimp simp: pred_neg_def septraction_def) done lemma "P s \ (R -* Q) s \ ((R and (P -* Q)) -* Q) s" apply (clarsimp simp: septraction_def sep_impl_def pred_neg_def pred_conj_def) by (fastforce simp: sep_add_commute sep_disj_commute) lemma sep_coimpl_notempty: "(Q \* (not \)) s \ (not Q) s" apply (clarsimp simp: sep_coimpl_def pred_neg_def) done method sep_subst uses add = (sep_frule (direct) add) lemma septract_empty_empty: "(P -* \) s \ \ (s :: 'a :: cancellative_sep_algebra)" apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def sep_empty_def) done lemma septract_trivial: "P s \ (sep_true -* P) s" apply (clarsimp simp: septraction_def pred_neg_def sep_impl_def sep_empty_def) using sep_disj_zero by fastforce lemma sep_empty_and_conj: "\ s \ (P \* Q) s \ P (s :: 'a :: cancellative_sep_algebra)" by (metis sep_conj_def sep_disj_positive_zero sep_empty_def) lemma sep_conj_coimpl_mp: "(P \* R) s \ (P \* Q) s \ (P \* (Q and R)) s" apply (drule (2) sep_coimpl_mp_gen, clarsimp simp: pred_conj_def conj_commute) done lemma sep_conj_coimpl_contrapos_mp: "(P \* Q) s \ (R \* (not Q)) s \ (Q \* (P and (not R))) s" apply (subst (asm) sep_coimpl_contrapos) apply (clarsimp simp: pred_neg_def) apply (sep_drule (direct) sep_conj_coimpl_mp[where P=Q], assumption) apply (clarsimp simp: pred_conj_def conj_commute) done end