Theory Synchronization_Product_Generalized_Commutativity
chapter ‹Commutativity and Associativity of Synchronization›
section ‹Commutativity›
theory Synchronization_Product_Generalized_Commutativity
imports CSP_PTick_Renaming
begin
subsection ‹Motivation›
text (in Sync⇩p⇩t⇩i⇩c⇩k_locale) ‹
The classical synchronization product is commutative: @{thm Sync_commute[of P A Q]}
but in our generalization such a law cannot be obtained in all generality.
Imagine for example that the \<^term>‹tick_join› parameter is actually \<^term>‹λr s. ⌊(r, s)⌋›:
we easily figure out that in this case the corresponding law should
be something like ‹P ⟦A⟧⇩✓⇩P⇩a⇩i⇩r Q = TickSwap (Q ⟦A⟧⇩✓⇩P⇩a⇩i⇩r P)›.
More generally, in the ⬚‹locale›, when writing \<^term>‹P ⟦A⟧⇩✓ Q›,
\<^term>‹P› is of type \<^typ>‹('a, 'r) process⇩p⇩t⇩i⇩c⇩k› while \<^term>‹Q› is of type \<^typ>‹('a, 's) process⇩p⇩t⇩i⇩c⇩k›
so we want to find an abstract setup in which we can establish a quasi-commutativity.
This is done in the next subsection.
›
subsection ‹Formalization›
locale Sync⇩p⇩t⇩i⇩c⇩k_comm_locale =
Sync⇩p⇩t⇩i⇩c⇩k_locale ‹(⊗✓)› for tick_join :: ‹'r ⇒ 's ⇒ 't option› (infixl ‹⊗✓› 100) +
fixes tick_join_rev :: ‹'s ⇒ 'r ⇒ 'u option› (infixl ‹⊗✓⇩r⇩e⇩v› 100)
and tick_join_conv :: ‹'t ⇒ 'u› (‹⊗✓⇒⊗✓⇩r⇩e⇩v›)
and tick_join_rev_conv :: ‹'u ⇒ 't› (‹⊗✓⇩r⇩e⇩v⇒⊗✓›)
assumes tick_join_None_iff :
‹r ⊗✓ s = ◇ ⟷ s ⊗✓⇩r⇩e⇩v r = ◇›
and tick_join_Some_imp :
‹r ⊗✓ s = ⌊r_s⌋ ⟹ s ⊗✓⇩r⇩e⇩v r = ⌊⊗✓⇒⊗✓⇩r⇩e⇩v r_s⌋›
and tick_join_rev_Some_imp :
‹s ⊗✓⇩r⇩e⇩v r = ⌊s_r⌋ ⟹ r ⊗✓ s = ⌊⊗✓⇩r⇩e⇩v⇒⊗✓ s_r⌋›
begin
text ‹There is an obvious symmetry over the variables.›
sublocale Sync⇩p⇩t⇩i⇩c⇩k_comm_locale_sym :
Sync⇩p⇩t⇩i⇩c⇩k_comm_locale ‹(⊗✓⇩r⇩e⇩v)› ‹(⊗✓)› ‹⊗✓⇩r⇩e⇩v⇒⊗✓› ‹⊗✓⇒⊗✓⇩r⇩e⇩v›
proof unfold_locales
show ‹s ⊗✓⇩r⇩e⇩v r = ⌊s_r⌋ ⟹ s' ⊗✓⇩r⇩e⇩v r' = ⌊s_r⌋
⟹ s' = s ∧ r' = r› for s r s_r s' r'
using inj_tick_join tick_join_rev_Some_imp by blast
next
show ‹s ⊗✓⇩r⇩e⇩v r = ◇ ⟷ r ⊗✓ s = ◇› for s r
by (simp add: tick_join_None_iff)
next
show ‹s ⊗✓⇩r⇩e⇩v r = ⌊s_r⌋ ⟹ r ⊗✓ s = ⌊⊗✓⇩r⇩e⇩v⇒⊗✓ s_r⌋› for s r s_r
by (simp add: tick_join_rev_Some_imp)
next
show ‹r ⊗✓ s = ⌊r_s⌋ ⟹ s ⊗✓⇩r⇩e⇩v r = ⌊⊗✓⇒⊗✓⇩r⇩e⇩v r_s⌋› for r s r_s
by (simp add: tick_join_Some_imp)
qed
notation Sync⇩p⇩t⇩i⇩c⇩k_comm_locale_sym.Sync⇩p⇩t⇩i⇩c⇩k (‹(_ ⟦_⟧⇩✓⇩r⇩e⇩v _)› [70, 0, 71] 70)
notation Sync⇩p⇩t⇩i⇩c⇩k_comm_locale_sym.Inter⇩p⇩t⇩i⇩c⇩k (‹(_ |||⇩✓⇩r⇩e⇩v _)› [72, 73] 72)
notation Sync⇩p⇩t⇩i⇩c⇩k_comm_locale_sym.Par⇩p⇩t⇩i⇩c⇩k (‹(_ ||⇩✓⇩r⇩e⇩v _)› [74, 75] 74)
subsection ‹First Properties›
lemma tick_join_conv_image_range_tick_join :
‹⊗✓⇒⊗✓⇩r⇩e⇩v ` range_tick_join = Sync⇩p⇩t⇩i⇩c⇩k_comm_locale_sym.range_tick_join›
by (simp add: set_eq_iff flip: setcompr_eq_image)
(metis option.inject tick_join_Some_imp tick_join_rev_Some_imp)
lemma tick_join_rev_conv_comp_tick_join_conv [simp] :
‹r_s ∈ range_tick_join ⟹ ⊗✓⇩r⇩e⇩v⇒⊗✓ (⊗✓⇒⊗✓⇩r⇩e⇩v r_s) = r_s›
using tick_join_Some_imp tick_join_rev_Some_imp by fastforce
lemma inj_on_tick_join_conv : ‹inj_on ⊗✓⇒⊗✓⇩r⇩e⇩v range_tick_join›
by (rule inj_onI, simp)
(metis option.inject tick_join_Some_imp tick_join_rev_Some_imp)
lemma bij_betw_tick_join_conv :
‹bij_betw ⊗✓⇒⊗✓⇩r⇩e⇩v range_tick_join Sync⇩p⇩t⇩i⇩c⇩k_comm_locale_sym.range_tick_join›
proof (rule bij_betw_imageI)
show ‹inj_on ⊗✓⇒⊗✓⇩r⇩e⇩v range_tick_join›
by (fact inj_on_tick_join_conv)
next
show ‹⊗✓⇒⊗✓⇩r⇩e⇩v ` range_tick_join = Sync⇩p⇩t⇩i⇩c⇩k_comm_locale_sym.range_tick_join›
using tick_join_conv_image_range_tick_join by blast
qed
lemma map_tick_join_rev_conv_map_tick_join_conv :
‹{r_s. ✓(r_s) ∈ set t} ⊆ range_tick_join ⟹
map (map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇩r⇩e⇩v⇒⊗✓) (map (map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇒⊗✓⇩r⇩e⇩v) t) = t›
proof (induct t)
case Nil show ?case by simp
next
let ?f1 = ‹map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇒⊗✓⇩r⇩e⇩v›
let ?f2 = ‹map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇩r⇩e⇩v⇒⊗✓›
case (Cons e t)
have ‹map ?f2 (map ?f1 (e # t)) = ?f2 (?f1 e) # map ?f2 (map ?f1 t)› by simp
also have ‹?f2 (?f1 e) = e›
proof (cases e)
show ‹e = ev a ⟹ ?f2 (?f1 e) = e› for a by simp
next
fix r_s assume ‹e = ✓(r_s)›
with Cons.prems have ‹r_s ∈ range_tick_join› by auto
with ‹e = ✓(r_s)› inj_on_tick_join_conv
show ‹?f2 (?f1 e) = e› by simp
qed
also have ‹map ?f2 (map ?f1 t) = t›
by (rule Cons.hyps) (use Cons.prems in auto)
finally show ‹map ?f2 (map ?f1 (e # t)) = e # t› .
qed
end
subsection ‹Commutativity›
context Sync⇩p⇩t⇩i⇩c⇩k_comm_locale begin
lemma setinterleaves⇩p⇩t⇩i⇩c⇩k_imp_setinterleaves⇩p⇩t⇩i⇩c⇩k_rev :
‹t setinterleaves⇩✓⇘(⊗✓)⇙ ((u, v), A) ⟹
map (map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇒⊗✓⇩r⇩e⇩v) t
setinterleaves⇩✓⇘(⊗✓⇩r⇩e⇩v)⇙ ((v, u), A)›
proof (induct ‹((⊗✓), u, A, v)› arbitrary: t u v)
case (tick_setinterleaving⇩p⇩t⇩i⇩c⇩k_tick r u s v)
from tick_setinterleaving⇩p⇩t⇩i⇩c⇩k_tick.prems
obtain r_s t'
where * : ‹r ⊗✓ s = ⌊r_s⌋› ‹t = ✓(r_s) # t'›
‹t' setinterleaves⇩✓⇘(⊗✓)⇙ ((u, v), A)›
by (auto split: option.split_asm)
from tick_setinterleaving⇩p⇩t⇩i⇩c⇩k_tick.hyps[OF "*"(1), OF "*"(3)]
have ‹map (map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇒⊗✓⇩r⇩e⇩v) t'
setinterleaves⇩✓⇘(⊗✓⇩r⇩e⇩v)⇙ ((v, u), A)› .
moreover from tick_join_Some_imp[OF "*"(1)]
have ‹s ⊗✓⇩r⇩e⇩v r = ⌊⊗✓⇒⊗✓⇩r⇩e⇩v r_s⌋› .
ultimately show ‹map (map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇒⊗✓⇩r⇩e⇩v) t
setinterleaves⇩✓⇘(⊗✓⇩r⇩e⇩v)⇙ ((✓(s) # v, ✓(r) # u), A)›
by (simp add: "*"(1, 2))
qed auto
lemma vimage_tick_join_rev_conv_subset_super_ref_Sync⇩p⇩t⇩i⇩c⇩k_iff :
‹map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇩r⇩e⇩v⇒⊗✓ -` X ⊆ super_ref_Sync⇩p⇩t⇩i⇩c⇩k (⊗✓⇩r⇩e⇩v) X_Q A X_P
⟷ X ⊆ super_ref_Sync⇩p⇩t⇩i⇩c⇩k (⊗✓) X_P A X_Q›
(is ‹?lhs1 ⊆ ?lhs2 ⟷ X ⊆ ?rhs›)
proof -
have * : ‹(λr s. case r ⊗✓⇩r⇩e⇩v s of ◇ ⇒ ◇ | ⌊r_s⌋ ⇒ ⌊⊗✓⇩r⇩e⇩v⇒⊗✓ r_s⌋) =
(λs r. r ⊗✓ s)›
by (intro ext, simp split: option.split)
(metis tick_join_None_iff tick_join_rev_Some_imp)
show ?thesis
proof (subst Sync⇩p⇩t⇩i⇩c⇩k_comm_locale_sym.vimage_inj_on_subset_super_ref_Sync⇩p⇩t⇩i⇩c⇩k_iff)
show ‹inj_on ⊗✓⇩r⇩e⇩v⇒⊗✓ Sync⇩p⇩t⇩i⇩c⇩k_comm_locale_sym.range_tick_join›
by (fact Sync⇩p⇩t⇩i⇩c⇩k_comm_locale_sym.inj_on_tick_join_conv)
next
show ‹X ⊆ super_ref_Sync⇩p⇩t⇩i⇩c⇩k
(λr s. case r ⊗✓⇩r⇩e⇩v s of ◇ ⇒ ◇ | ⌊r_s⌋ ⇒ ⌊⊗✓⇩r⇩e⇩v⇒⊗✓ r_s⌋) X_Q A X_P
⟷ X ⊆ super_ref_Sync⇩p⇩t⇩i⇩c⇩k (⊗✓) X_P A X_Q›
using super_ref_Sync⇩p⇩t⇩i⇩c⇩k_sym by (simp add: "*") blast
qed
qed
text ‹
In the end, the proof is quite simple: mainly a corollary
of @{thm inj_on_RenamingTick_Sync⇩p⇩t⇩i⇩c⇩k[no_vars]}.
›
theorem Sync⇩p⇩t⇩i⇩c⇩k_commute :
‹RenamingTick (P ⟦A⟧⇩✓ Q) ⊗✓⇒⊗✓⇩r⇩e⇩v = Q ⟦A⟧⇩✓⇩r⇩e⇩v P›
proof -
from inj_on_RenamingTick_Sync⇩p⇩t⇩i⇩c⇩k[OF inj_on_tick_join_conv]
have ‹RenamingTick (P ⟦A⟧⇩✓ Q) ⊗✓⇒⊗✓⇩r⇩e⇩v =
Sync⇩p⇩t⇩i⇩c⇩k_locale.Sync⇩p⇩t⇩i⇩c⇩k
(λr s. case r ⊗✓ s of ◇ ⇒ ◇ | ⌊r_s⌋ ⇒ ⌊⊗✓⇒⊗✓⇩r⇩e⇩v r_s⌋) P A Q›
(is ‹_ = Sync⇩p⇩t⇩i⇩c⇩k_locale.Sync⇩p⇩t⇩i⇩c⇩k ?tick_join' P A Q›) .
also have ‹?tick_join' = (λr s. s ⊗✓⇩r⇩e⇩v r)›
by (intro ext)
(simp add: Sync⇩p⇩t⇩i⇩c⇩k_comm_locale_sym.tick_join_rev_Some_imp
tick_join_None_iff split: option.split)
finally show ‹RenamingTick (P ⟦A⟧⇩✓ Q) ⊗✓⇒⊗✓⇩r⇩e⇩v = Q ⟦A⟧⇩✓⇩r⇩e⇩v P›
by (metis Sync⇩p⇩t⇩i⇩c⇩k_comm_locale_sym.Sync⇩p⇩t⇩i⇩c⇩k_sym)
qed
end
end