Theory Read_Write_CSPM_Laws
chapter ‹CSPM Laws›
theory Read_Write_CSPM_Laws
imports Step_CSPM_Laws_Extended
begin
subsection ‹The Throw Operator›
lemma Throw_read :
‹inj_on c A ⟹ (c❙?a ∈ A → P a) Θ a ∈ B. Q a =
c❙?a ∈ A → (if c a ∈ B then Q (c a) else P a Θ a ∈ B. Q a)›
by (auto simp add: read_def Throw_Mprefix intro: mono_Mprefix_eq)
lemma Throw_ndet_write :
‹inj_on c A ⟹ (c❙!❙!a ∈ A → P a) Θ a ∈ B. Q a =
c❙!❙!a ∈ A → (if c a ∈ B then Q (c a) else P a Θ a ∈ B. Q a)›
by (auto simp add: ndet_write_def Throw_Mndetprefix intro: mono_Mndetprefix_eq)
lemma Throw_write :
‹(c❙!a → P) Θ a ∈ B. Q a = c❙!a → (if c a ∈ B then Q (c a) else P Θ a ∈ B. Q a)›
by (auto simp add: write_def Throw_Mprefix intro: mono_Mprefix_eq)
lemma Throw_write0 :
‹(a → P) Θ a ∈ B. Q a = a → (if a ∈ B then Q a else P Θ a ∈ B. Q a)›
by (auto simp add: write0_def Throw_Mprefix intro: mono_Mprefix_eq)
subsection ‹The Interrupt Operator›
lemma Interrupt_read :
‹(c❙?a ∈ A → P a) △ Q = Q □ (c❙?a ∈ A → P a △ Q)›
by (auto simp add: read_def Interrupt_Mprefix
intro!: mono_Mprefix_eq arg_cong[where f = ‹λP. Q □ P›])
lemma Interrupt_ndet_write :
‹(c❙!❙!a ∈ A → P a) △ Q = Q □ (c❙!❙!a ∈ A → P a △ Q)›
by (auto simp add: ndet_write_def Interrupt_Mndetprefix
intro!: mono_Mndetprefix_eq arg_cong[where f = ‹λP. Q □ P›])
lemma Interrupt_write : ‹(c❙!a → P) △ Q = Q □ (c❙!a → P △ Q)›
by (auto simp add: write_def Interrupt_Mprefix intro: mono_Mprefix_eq)
lemma Interrupt_write0 : ‹(a → P) △ Q = Q □ (a → P △ Q)›
by (auto simp add: write0_def Interrupt_Mprefix intro: mono_Mprefix_eq)
subsection ‹Global Deterministic Choice›
lemma GlobalDet_read :
‹□a ∈ A. c❙?b ∈ B a → P a b = c❙?b ∈ (⋃a∈A. B a) → ⊓a∈{a ∈ A. b ∈ B a}. P a b›
if ‹inj_on c (⋃a∈A. B a)›
proof -
have * : ‹a ∈ A ⟹ b ∈ B a ⟹
{a ∈ A. inv_into (⋃ (B ` A)) c (c b) ∈ B a} = {a ∈ A. c b ∈ c ` B a}› for a b
by (metis (no_types, opaque_lifting) SUP_upper UN_iff
inj_on_image_mem_iff inv_into_f_eq ‹inj_on c (⋃a∈A. B a)›)
have ‹□a ∈ A. c❙?b ∈ B a → P a b =
□b∈(⋃x∈A. c ` B x) → ⊓a∈{a ∈ A. b ∈ c ` B a}. P a (inv_into (B a) c b)›
by (simp add: read_def GlobalDet_Mprefix)
also have ‹(⋃x∈A. c ` B x) = c ` (⋃a∈A. B a)› by blast
finally show ‹□a ∈ A. c❙?b ∈ B a → P a b = c❙?b ∈ (⋃a∈A. B a) → ⊓a∈{a ∈ A. b ∈ B a}. P a b›
apply (auto simp add: read_def "*" intro!: mono_Mprefix_eq mono_GlobalNdet_eq)
by (metis (lifting) UN_I UN_upper inj_on_subset inv_into_f_eq that)
qed
lemma GlobalDet_write :
‹□a ∈ A. c❙!(b a) → P a = c❙?x ∈ b ` A → ⊓a∈{a ∈ A. x = b a}. P a› if ‹inj_on c (b ` A)›
proof -
from ‹inj_on c (b ` A)› have * : ‹x ∈ A ⟹ {a ∈ A. inv_into (b ` A) c (c (b x)) = b a} =
{a ∈ A. c (b x) = c (b a)}› for x
by (auto simp add: inj_on_eq_iff)
have ‹□a ∈ A. c❙!(b a) → P a = □x∈(⋃a∈A. {c (b a)}) → GlobalNdet {a ∈ A. x = c (b a)} P›
by (simp add: write_def GlobalDet_Mprefix)
also have ‹(⋃a∈A. {c (b a)}) = c ` b ` A› by blast
finally show ‹□a ∈ A. c❙!(b a) → P a = c❙?x ∈ b ` A → ⊓a∈{a ∈ A. x = b a}. P a›
by (auto simp add: read_def "*" intro: mono_Mprefix_eq)
qed
lemma GlobalDet_write0 :
‹□a∈A. b a → P a = □x ∈ (b ` A) → ⊓a ∈ {a ∈ A. x = b a}. P a›
by (auto simp add: GlobalDet_write[where c = ‹λx. x›, simplified write_is_write0] read_def
intro!: mono_Mprefix_eq) (metis (lifting) f_inv_into_f image_eqI)
subsection ‹Multiple Synchronization Product›
lemma MultiSync_read_subset :
‹(❙⟦S❙⟧ m ∈# M. c❙?a ∈ A m → P m a) = (if M = {#} then STOP else
c❙?a ∈ (⋂m ∈ set_mset M. A m) → (❙⟦S❙⟧ m ∈# M. P m a))› (is ‹?lhs = ?rhs›)
if ‹inj_on c (⋃m ∈ set_mset M. A m)› ‹⋀m. m ∈# M ⟹ c ` A m ⊆ S›
proof -
have * : ‹M ≠ {#} ⟹ (⋂m∈set_mset M. c ` A m) = c ` ⋂ (A ` set_mset M)›
by (metis SUP_upper image_INT multiset_nonemptyE that(1))
have ‹?lhs = (if M = {#} then STOP else
□a∈(⋂m∈set_mset M. c ` A m) → ❙⟦S❙⟧ m∈#M. (P m ∘ inv_into (A m) c) a)›
by (simp add: read_def MultiSync_Mprefix_subset that(2))
also have ‹… = ?rhs›
apply (auto simp add: read_def "*" intro!: mono_Mprefix_eq mono_MultiSync_eq)
by (metis (full_types) INF_lower2 INT_I UN_upper inj_on_subset inv_into_f_f that(1))
finally show ‹?lhs = ?rhs› .
qed
lemmas MultiPar_read_subset = MultiSync_read_subset[where S = UNIV, simplified]
lemma MultiSync_read_indep :
‹❙⟦S❙⟧ m ∈# mset_set M. c❙?a ∈ (A m) → P m a =
c❙?a ∈ (⋃m ∈ M. A m) → ⊓m ∈ {m ∈ M. a ∈ A m}. (❙⟦S❙⟧ n ∈# mset_set M. (if n = m then P m a else c❙?b ∈ (A n) → P n b))›
(is ‹?lhs = ?rhs›) if ‹inj_on c (⋃m ∈ M. A m)› ‹finite M› ‹⋀m. m ∈ M ⟹ c ` A m ∩ S = {}›
proof -
have * : ‹(⋃x∈M. c ` A x) = c ` ⋃ (A ` M)› by auto
have ** : ‹m ∈ M ⟹ a ∈ A m ⟹ {m ∈ M. c a ∈ c ` A m} = {m ∈ M. inv_into (⋃ (A ` M)) c (c a) ∈ A m}› for a m
by (auto simp add: image_iff) (metis UN_I inv_into_f_f that(1))+
have ‹?lhs = □a∈(⋃x∈M. c ` A x)
→ ⊓m∈{m ∈ M. a ∈ c ` A m}.
❙⟦S❙⟧ n∈#mset_set M. (if n = m then (P m ∘ inv_into (A m) c) a else Mprefix (c ` A n) (P n ∘ inv_into (A n) c))›
by (simp add: read_def MultiSync_Mprefix_indep that(2, 3))
also have ‹… = ?rhs›
by (auto simp add: read_def "*" "**" intro!: mono_Mprefix_eq mono_GlobalNdet_eq mono_MultiSync_eq)
(metis UN_upper UnionI imageI inj_on_subset inv_into_f_eq that(1))
finally show ‹?lhs = ?rhs› .
qed
lemmas MultiInter_read_indep = MultiSync_read_indep[where S = ‹{}›, simplified]
lemma inv_into_eq_inv_into :
‹inj_on f A ⟹ B ⊆ A ⟹ C ⊆ A ⟹ a ∈ B ⟹ a ∈ C ⟹
inv_into B f (f a) = inv_into C f (f a)›
by (metis inj_on_subset inv_into_f_f)
lemma MultiSync_ndet_write_subset :
‹❙⟦S❙⟧ m ∈# M. c❙!❙!a ∈ A m → P m a = (if M = {#} then STOP else
if ∃a. ∀m m'. m ∈# M ⟶ m' ∈# M - {#m#} ⟶ A m = {a} ∧ A m' = {a}
then c❙!❙!a ∈ (⋂m ∈ set_mset M. A m) → (❙⟦S❙⟧ m ∈# M. P m a)
else (c❙!❙!a ∈ (⋂m ∈ set_mset M. A m) → (❙⟦S❙⟧ m ∈# M. P m a)) ⊓ STOP)›
(is ‹?lhs M = (if M = {#} then STOP else if ?cond M then ?rhs M else ?rhs M ⊓ STOP)›)
if ‹inj_on c (⋃m ∈ set_mset M. A m)› ‹⋀m. m ∈# M ⟹ c ` A m ⊆ S›
proof (induct M rule: induct_subset_mset_empty_single)
case 1 show ?case by simp
next
case (2 m) show ?case by simp
next
case (3 M' m)
from "3"(1-3) that(2) have subset_props : ‹A m ⊆ (⋃m ∈ set_mset M. A m)›
‹⋂ (A ` set_mset M') ⊆ (⋃m ∈ set_mset M. A m)›
‹⋂ (A ` set_mset (add_mset m M')) ⊆ (⋃m ∈ set_mset M. A m)›
‹c ` (⋃m ∈ set_mset M. A m) ⊆ S›
by auto (meson mset_subset_eqD multiset_nonemptyE)
note inj_props = subset_props(1, 2)[THEN inj_on_subset[OF that(1)]]
have $ : ‹c ` A m = c ` ⋂ (A ` set_mset M') ⟷ A m = ⋂ (A ` set_mset M')›
by (simp only: inj_on_image_eq_iff[OF that(1) subset_props(1, 2)])
have $$ : ‹c ` (A m ∩ ⋂ (A ` set_mset M')) = c ` A m ∩ c ` (⋂ (A ` set_mset M'))›
by (fact inj_on_image_Int[OF that(1) subset_props(1, 2)])
from "3"(1, 2)
have * : ‹ndet_write c (A m) (P m) ⟦S⟧ ?rhs M' =
(if ∃a. A m = {a} ∧ ⋂ (A ` set_mset M') = {a}
then c❙!(THE a. ⋂ (A ` set_mset M') = {a}) →
(P m (THE a. A m = {a}) ⟦S⟧
❙⟦S❙⟧ m∈#M'. P m (THE a. ⋂ (A ` set_mset M') = {a}))
else (c❙!❙!x∈(⋂ (A ` set_mset (add_mset m M'))) → ❙⟦S❙⟧ m∈#add_mset m M'. P m x) ⊓ STOP)›
unfolding ndet_write_Sync_ndet_write_subset
[OF subset_props(1, 2)[THEN image_mono, THEN subset_trans[OF _ subset_props(4)]]]
by (auto simp add: "3"(3) write_is_write0 ndet_write_def "$$"
intro!: arg_cong[where f = ‹λP. P ⊓ STOP›] mono_Mndetprefix_eq
arg_cong2[where f = ‹λP Q. P ⟦S⟧ Q›] mono_MultiSync_eq arg_cong[where f = ‹λa. P _ a›]
inv_into_eq_inv_into[OF that(1) subset_props(1, 3), simplified]
inv_into_eq_inv_into[OF that(1) subset_props(2, 3), simplified])
(metis "$" empty_is_image image_insert inj_props(1) inv_into_image_cancel subset_iff,
((metis INT_I inv_into_f_f subset_iff subset_props(1, 2) that(1))+)[2],
metis UN_I inj_onD mset_subset_eqD that(1))
have ** : ‹?cond (add_mset m M') ⟷
(if size M' = 1 then ∃a. A m = {a} ∧ A (THE m. M' = {#m#}) = {a}
else ?cond M' ∧ (∃a. A m = {a} ∧ ⋂ (A ` set_mset M') = {a}))›
by (cases M', auto simp add: "3"(3) split: if_split_asm)
(metis Int_absorb all_not_in_conv insertI1 set_mset_eq_empty_iff singletonD)
from "3.hyps"(1) that(2) have *** : ‹ndet_write c (A m) (P m) ⟦S⟧ STOP = STOP›
by (auto simp add: ndet_write_Sync_STOP inj_props(1) ndet_write_is_STOP_iff Ndet_is_STOP_iff Int_absorb2)
have ‹?lhs (add_mset m M') = ndet_write c (A m) (P m) ⟦S⟧ ❙⟦S❙⟧ m'∈# M'. ndet_write c (A m') (P m')›
by (simp add: "3"(3))
also have ‹… = ndet_write c (A m) (P m) ⟦S⟧
(if ?cond M' then ?rhs M' else ?rhs M' ⊓ STOP)›
by (simp add: "3"(3, 4))
also have ‹… = (if ?cond (add_mset m M') then ?rhs (add_mset m M')
else ?rhs (add_mset m M') ⊓ STOP)› (is ‹?lhs' m M' = ?rhs' m M'›)
proof (split if_split, intro conjI impI)
show ‹?cond (add_mset m M') ⟹ ?lhs' m M' = ?rhs (add_mset m M')›
unfolding "**"
by (cases M', auto simp add: "3"(3) write_Sync_write split: if_split_asm)
(metis "3.hyps"(1) image_insert insert_subset that(2))+
next
show ‹¬ ?cond (add_mset m M') ⟹ ?lhs' m M' = ?rhs (add_mset m M') ⊓ STOP›
unfolding "**"
by (cases ‹size M' = 1›, simp_all add: "*")
(cases M', auto simp add: "*" "***" ndet_write_Sync_STOP Sync_distrib_Ndet_left
write_Sync_STOP "3"(3) write_Sync_write_subset Ndet_aci(1-4))
qed
also have ‹… = ( if add_mset m M' = {#} then STOP
else if ?cond (add_mset m M') then ?rhs (add_mset m M')
else ?rhs (add_mset m M') ⊓ STOP)› by simp
finally show ?case .
qed
lemmas MultiPar_ndet_write_subset = MultiSync_ndet_write_subset[where S = UNIV, simplified]
end