theory DynamicLemmas
imports Main "HOL-Library.Multiset"
Dynamic "HOL-Eisbach.Eisbach"
begin
lemma find_firsts_in_store: "f ∈# find_firsts s h v e ⟹ f ∈# s"
by (auto simp add: find_firsts_def)
lemma find_firsts_subset: "find_firsts s h v e ⊆# s"
by (auto simp add: find_firsts_def)
lemma min_subset_min_finite:
assumes "finite xs"
and "f x = Min (f ` xs)"
and "xs' ⊆ xs"
and "x ∈ xs'"
shows "f x = Min (f ` xs')"
proof -
have fin_all: "finite (f ` xs')"
using assms finite_subset finite_imageI by blast+
have x_min_xs': "∀y ∈ xs'. f x ≤ f y"
using assms fin_all by auto
have fx_in_xs': "f x ∈ f ` xs'"
using assms by blast
have f_reverse: "∀fx'. (∃x'. x' ∈ xs' ∧ f x' = fx') ∨ fx' ∉ f ` xs'"
by blast
show "f x = Min (f ` xs')"
using fin_all fx_in_xs' x_min_xs' f_reverse
by (metis (no_types) Min_eqI)
qed
lemma find_firsts_min_in_subset: "f ∈# find_firsts s h v e ⟹ s' ⊆# s ⟹ f ∈# s' ⟹ f ∈# find_firsts s' h v e"
apply (clarsimp simp add: find_firsts_def)
using min_subset_min_finite
by (metis set_mset_mono finite_set_mset)
method elim_Ev = (elim EvFire.cases EvExec.cases EvMatch.cases EvGather.cases; clarsimp)
method intro_Ev = (intro EvMatches.intros EvExec.intros EvMatch.intros EvGain.intros EvGather.intros EvSelect.intros EvConsume.intros)
lemma new_is_added:
"asub | store ⊢ rul ⇓ fread | dspent | dnew | store' FIRE ⟹
dnew ⊆# store'"
using mset_subset_eq_add_right
by (elim EvFire.cases; blast)
lemma spent_is_subset:
"asub | store ⊢ rul ⇓ fread | dspent | dnew | store' FIRE ⟹
dspent ⊆# store"
by elim_Ev
lemma spent_read_is_subset_EvMatches:
"rn | asub | store | h ⊢ matches ⇓ fread | dspent | ahas | h' MATCHES ⟹
fread ⊆# store"
proof (induct rule: EvMatches.induct)
case (EvMatchCons n a s h m ag ds h' ms ag' ds' h'')
then show ?case
by (elim_Ev; metis EvSelect.cases find_firsts_in_store mset_subset_eqD multiset_filter_subset)
qed auto
lemma spent_read_is_subset:
"asub | store ⊢ rul ⇓ fread | dspent | dnew | store' FIRE ⟹
fread ∪# dspent ⊆# store"
using spent_read_is_subset_EvMatches
by elim_Ev
lemma frame_constriction_EvMatches:
"rn | asub | store | h ⊢ matches ⇓ fread | dspent | ahas | h' MATCHES ⟹
fread ∪# dspent ⊆# ds' ⟹ ds' ⊆# store ⟹
rn | asub | ds' | h ⊢ matches ⇓ fread | dspent | ahas | h' MATCHES"
proof (induct arbitrary: ds' rule: EvMatches.induct)
case (EvMatchCons n a s h m f w ag h' ms fs ds ag' h'' fs' ds' ag'')
obtain x gather sel con gain where match_is:
"m = match x gather sel con gain"
using match.exhaust by blast
from EvMatchCons match_is have IHrest:
"n | a | ds' | h(x := f) ⊢ ms ⇓ fs | ds | ag' | h'' MATCHES"
by (elim_Ev; metis EvMatchCons.hyps(3) mset_subset_eq_add_right subset_mset.sup.absorb_iff1 subset_mset.sup.bounded_iff)
from EvMatchCons match_is show ?case
apply (elim_Ev)
apply (elim EvSelect.cases; clarsimp)
apply (intro_Ev; (rule refl)?; simp add: IHrest)
apply (intro_Ev; (rule refl)?; (simp add: IHrest)?)
apply (rule find_firsts_min_in_subset)
apply assumption
using multiset_filter_mono
apply blast
by (metis count_filter_mset find_firsts_in_store not_in_iff)
qed (auto intro: EvMatches.intros)
lemma frame_constriction:
"asub | store ⊢ rul ⇓ fread | dspent | dnew | store' FIRE ⟹
asub | (fread ∪# dspent) ⊢ rul ⇓ fread | dspent | dnew | (dnew + (fread - dspent)) FIRE"
apply (elim EvFire.cases; clarsimp)
apply (intro EvFire.intros; assumption?)
apply (rule frame_constriction_EvMatches; simp)
apply (simp add: spent_read_is_subset_EvMatches)
by (simp add: spent_read_is_subset_EvMatches subset_mset.sup_commute sup_subset_mset_def)+
lemma spend_only_accessible_EvMatches:
"rn | asub | store | h ⊢ matches ⇓ fread | dspent | ahas | h' MATCHES ⟹
(∀f ∈# fread ∪# dspent. can_see_fact asub f)"
proof (induct rule: EvMatches.induct)
case (EvMatchCons n a s h m f w ag h' ms fs ds ag' h'' fs' ds' ag'')
then show ?case
apply (elim_Ev; elim EvSelect.cases)
using check_gather_def find_firsts_def by auto
qed auto
lemma spend_only_accessible:
"asub | store ⊢ rul ⇓ fread | dspent | dnew | store' FIRE ⟹
(∀f ∈# fread ∪# dspent. can_see_fact asub f)"
by (elim EvFire.cases; force simp add: spend_only_accessible_EvMatches)
lemma check_gather_inaccessible_empty:
" (∀f ∈# others. ¬(can_see_fact asub f)) ⟹
filter_mset (check_gather asub env v ctor pred) others = {#}"
apply (unfold check_gather_def)
using set_mset_eq_empty_iff by fastforce
lemma store_weaken_inaccessible_EvMatches:
"rn | asub | store | h ⊢ matches ⇓ fread | dspent | ahas | h' MATCHES ⟹
(∀f ∈# others. ¬(can_see_fact asub f)) ⟹
rn | asub | (store + others) | h ⊢ matches ⇓ fread | dspent | ahas | h' MATCHES"
proof (induct rule: EvMatches.induct)
case (EvMatchNil n a s h)
then show ?case
using EvMatches.EvMatchNil by blast
next
case (EvMatchCons n a s h m f w ag h' ms fs ds ag' h'' fs' ds' ag'')
then show ?case
apply (elim_Ev; elim EvSelect.cases)
apply (intro_Ev; (rule refl)?; (simp add: fun_upd_def)?)
apply (subst check_gather_inaccessible_empty[where others=others];
simp add: EvSelect.simps)
apply (intro_Ev; (rule refl)?; (simp add: fun_upd_def)?)
by (subst check_gather_inaccessible_empty[where others=others];
simp add: EvSelect.simps)
qed
lemma store_weaken_inaccessible:
"asub | store ⊢ rul ⇓ fread | dspent | dnew | store' FIRE ⟹
(∀f ∈# others. ¬(can_see_fact asub f)) ⟹
asub | (store + others) ⊢ rul ⇓ fread | dspent | dnew | (store' + others) FIRE"
apply (elim EvFire.cases; clarsimp)
apply (intro EvFire.intros)
using store_weaken_inaccessible_EvMatches
apply blast
apply blast
apply (simp add: subset_mset.add_increasing2)
apply (metis ab_semigroup_add_class.add_ac(1) add.commute subset_mset.add_diff_assoc2)
by blast
lemma new_auth_gained_from_spent_EvMatches:
"rn | asub | store | h ⊢ matches ⇓ fread | dspent | ahas | h' MATCHES ⟹
∀a ∈ ahas. ∃d ∈# fread ∪# dspent. a ∈ fact_by d"
proof (induct rule: EvMatches.induct)
case (EvMatchCons n a s h m ag fw s' h' ms ag' ds' h'')
then show ?case
by (elim_Ev;
elim EvGain.cases;
clarsimp;
blast)
qed auto
lemma new_auth_gained_from_spent:
"asub | store ⊢ rul ⇓ fread | dspent | dnew | store' FIRE ⟹
∀f ∈# dnew. ∀a ∈ fact_by f. ∃d ∈# fread ∪# dspent. a ∈ fact_by d"
using new_auth_gained_from_spent_EvMatches
by (elim EvFire.cases; blast)
fun matches_only_any :: "match list ⇒ bool" where
"matches_only_any matches = list_all (λm. case m of match x gath sel con gain ⇒ sel = select_any) matches"
fun rule_only_any :: "rule ⇒ bool" where
"rule_only_any (rule _ matches _) = matches_only_any matches"
lemma auth_weaken_EvMatches:
"rn | asub | store | h ⊢ matches ⇓ fread | dspent | ahas | h' MATCHES ⟹
matches_only_any matches ⟹
rn | (asub ∪ others) | store | h ⊢ matches ⇓ fread | dspent | ahas | h' MATCHES"
proof (induct rule: EvMatches.induct)
case (EvMatchNil n a s h)
then show ?case
by (simp add: EvMatches.EvMatchNil)
next
case (EvMatchCons n a s h m ag ds h' ms ag' ds' h'' ag'' ds'')
then show ?case
apply (elim_Ev)
apply (elim EvSelect.cases; clarsimp)
apply (intro_Ev; (rule refl)?; (simp add: check_gather_def can_see_fact_def)?)
using EvMatchCons.hyps(3) matches_only_any.elims
by blast+
qed
lemma auth_weaken:
"asub | store ⊢ rul ⇓ fread | dspent | dnew | store' FIRE ⟹
rule_only_any rul ⟹
(asub ∪ others) | store ⊢ rul ⇓ fread | dspent | dnew | store' FIRE"
apply (elim EvFire.cases)
using auth_weaken_EvMatches
by (metis EvFire.intros diff_union_cancelL mset_subset_eq_exists_conv rule_only_any.simps union_commute)
lemma store_weaken_if_any_EvMatches:
"rn | asub | store | h ⊢ matches ⇓ fread | dspent | ahas | h' MATCHES ⟹
matches_only_any matches ⟹
rn | asub | (store + others) | h ⊢ matches ⇓ fread | dspent | ahas | h' MATCHES"
proof (induct rule: EvMatches.induct)
case (EvMatchNil n a s h)
then show ?case
by (simp add: EvMatches.EvMatchNil)
next
case (EvMatchCons n a s h m ag ds h' ms ag' ds' h'' ag'' ds'')
then show ?case
apply (elim_Ev; elim EvSelect.cases; clarsimp)
apply (intro_Ev; (rule refl)?; simp?)
using EvMatchCons.hyps(3) matches_only_any.elims
by blast
qed
lemma store_weaken_if_any:
"asub | store ⊢ rul ⇓ fread | dspent | dnew | store' FIRE ⟹
rule_only_any rul ⟹
asub | (store + others) ⊢ rul ⇓ fread | dspent | dnew | (store' + others) FIRE"
apply (elim EvFire.cases EvExec.cases; clarsimp)
apply (intro EvFire.intros EvExec.intros; (rule refl)?; assumption?)
apply (simp add: store_weaken_if_any_EvMatches)
apply (simp add: subset_mset.add_increasing2)
by (metis add.commute add.left_commute subset_mset.add_diff_assoc)
end