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 Synchro⇩p⇩t⇩i⇩c⇩k) ‹
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>‹tj› 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 Synchro⇩p⇩t⇩i⇩c⇩k_comm =
Synchro⇩p⇩t⇩i⇩c⇩k ‹(⊗✓)› for tj :: ‹'r ⇒ 's ⇒ 't option› (infixl ‹⊗✓› 100) +
fixes tj_dual :: ‹'s ⇒ 'r ⇒ 'u option› (infixl ‹⊗✓⇩d⇩u⇩a⇩l› 100)
and tj_conv :: ‹'t ⇒ 'u› (‹⊗✓⇒⊗✓⇩d⇩u⇩a⇩l›)
and tj_dual_conv :: ‹'u ⇒ 't› (‹⊗✓⇩d⇩u⇩a⇩l⇒⊗✓›)
assumes tj_None_iff :
‹r ⊗✓ s = ◇ ⟷ s ⊗✓⇩d⇩u⇩a⇩l r = ◇›
and tj_Some_imp :
‹r ⊗✓ s = ⌊r_s⌋ ⟹ s ⊗✓⇩d⇩u⇩a⇩l r = ⌊⊗✓⇒⊗✓⇩d⇩u⇩a⇩l r_s⌋›
and tj_dual_Some_imp :
‹s ⊗✓⇩d⇩u⇩a⇩l r = ⌊s_r⌋ ⟹ r ⊗✓ s = ⌊⊗✓⇩d⇩u⇩a⇩l⇒⊗✓ s_r⌋›
begin
text ‹There is an obvious symmetry over the variables.›
sublocale Synchro⇩p⇩t⇩i⇩c⇩k_comm_dual :
Synchro⇩p⇩t⇩i⇩c⇩k_comm ‹(⊗✓⇩d⇩u⇩a⇩l)› ‹(⊗✓)› ‹⊗✓⇩d⇩u⇩a⇩l⇒⊗✓› ‹⊗✓⇒⊗✓⇩d⇩u⇩a⇩l›
proof unfold_locales
show ‹s ⊗✓⇩d⇩u⇩a⇩l r = ⌊s_r⌋ ⟹ s' ⊗✓⇩d⇩u⇩a⇩l r' = ⌊s_r⌋
⟹ s' = s ∧ r' = r› for s r s_r s' r'
using inj_tj tj_dual_Some_imp by blast
next
show ‹s ⊗✓⇩d⇩u⇩a⇩l r = ◇ ⟷ r ⊗✓ s = ◇› for s r
by (simp add: tj_None_iff)
next
show ‹s ⊗✓⇩d⇩u⇩a⇩l r = ⌊s_r⌋ ⟹ r ⊗✓ s = ⌊⊗✓⇩d⇩u⇩a⇩l⇒⊗✓ s_r⌋› for s r s_r
by (simp add: tj_dual_Some_imp)
next
show ‹r ⊗✓ s = ⌊r_s⌋ ⟹ s ⊗✓⇩d⇩u⇩a⇩l r = ⌊⊗✓⇒⊗✓⇩d⇩u⇩a⇩l r_s⌋› for r s r_s
by (simp add: tj_Some_imp)
qed
notation Synchro⇩p⇩t⇩i⇩c⇩k_comm_dual.Sync⇩p⇩t⇩i⇩c⇩k (‹(_ ⟦_⟧⇩✓⇩d⇩u⇩a⇩l _)› [70, 0, 71] 70)
notation Synchro⇩p⇩t⇩i⇩c⇩k_comm_dual.Inter⇩p⇩t⇩i⇩c⇩k (‹(_ |||⇩✓⇩d⇩u⇩a⇩l _)› [72, 73] 72)
notation Synchro⇩p⇩t⇩i⇩c⇩k_comm_dual.Par⇩p⇩t⇩i⇩c⇩k (‹(_ ||⇩✓⇩d⇩u⇩a⇩l _)› [74, 75] 74)
subsection ‹First Properties›
lemma tj_conv_image_range_tj :
‹⊗✓⇒⊗✓⇩d⇩u⇩a⇩l ` range_tj = Synchro⇩p⇩t⇩i⇩c⇩k_comm_dual.range_tj›
by (simp add: set_eq_iff flip: setcompr_eq_image)
(metis option.inject tj_Some_imp tj_dual_Some_imp)
lemma tj_dual_conv_comp_tj_conv [simp] :
‹r_s ∈ range_tj ⟹ ⊗✓⇩d⇩u⇩a⇩l⇒⊗✓ (⊗✓⇒⊗✓⇩d⇩u⇩a⇩l r_s) = r_s›
using tj_Some_imp tj_dual_Some_imp by fastforce
lemma inj_on_tj_conv : ‹inj_on ⊗✓⇒⊗✓⇩d⇩u⇩a⇩l range_tj›
by (rule inj_onI, simp)
(metis option.inject tj_Some_imp tj_dual_Some_imp)
lemma bij_betw_tj_conv :
‹bij_betw ⊗✓⇒⊗✓⇩d⇩u⇩a⇩l range_tj Synchro⇩p⇩t⇩i⇩c⇩k_comm_dual.range_tj›
proof (rule bij_betw_imageI)
show ‹inj_on ⊗✓⇒⊗✓⇩d⇩u⇩a⇩l range_tj›
by (fact inj_on_tj_conv)
next
show ‹⊗✓⇒⊗✓⇩d⇩u⇩a⇩l ` range_tj = Synchro⇩p⇩t⇩i⇩c⇩k_comm_dual.range_tj›
using tj_conv_image_range_tj by blast
qed
lemma map_tj_dual_conv_map_tj_conv :
‹{r_s. ✓(r_s) ∈ set t} ⊆ range_tj ⟹
map (map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇩d⇩u⇩a⇩l⇒⊗✓) (map (map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇒⊗✓⇩d⇩u⇩a⇩l) t) = t›
proof (induct t)
case Nil show ?case by simp
next
let ?f1 = ‹map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇒⊗✓⇩d⇩u⇩a⇩l›
let ?f2 = ‹map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇩d⇩u⇩a⇩l⇒⊗✓›
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_tj› by auto
with ‹e = ✓(r_s)› inj_on_tj_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 Synchro⇩p⇩t⇩i⇩c⇩k_comm begin
lemma setinterleaves⇩p⇩t⇩i⇩c⇩k_imp_setinterleaves⇩p⇩t⇩i⇩c⇩k_dual :
‹t setinterleaves⇩✓⇘(⊗✓)⇙ ((u, v), A) ⟹
map (map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇒⊗✓⇩d⇩u⇩a⇩l) t
setinterleaves⇩✓⇘(⊗✓⇩d⇩u⇩a⇩l)⇙ ((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 ⊗✓⇒⊗✓⇩d⇩u⇩a⇩l) t'
setinterleaves⇩✓⇘(⊗✓⇩d⇩u⇩a⇩l)⇙ ((v, u), A)› .
moreover from tj_Some_imp[OF "*"(1)]
have ‹s ⊗✓⇩d⇩u⇩a⇩l r = ⌊⊗✓⇒⊗✓⇩d⇩u⇩a⇩l r_s⌋› .
ultimately show ‹map (map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇒⊗✓⇩d⇩u⇩a⇩l) t
setinterleaves⇩✓⇘(⊗✓⇩d⇩u⇩a⇩l)⇙ ((✓(s) # v, ✓(r) # u), A)›
by (simp add: "*"(1, 2))
qed auto
lemma vimage_tj_dual_conv_subset_super_ref_Sync⇩p⇩t⇩i⇩c⇩k_iff :
‹map_event⇩p⇩t⇩i⇩c⇩k id ⊗✓⇩d⇩u⇩a⇩l⇒⊗✓ -` X ⊆ super_ref_Sync⇩p⇩t⇩i⇩c⇩k (⊗✓⇩d⇩u⇩a⇩l) 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 ⊗✓⇩d⇩u⇩a⇩l s of ◇ ⇒ ◇ | ⌊r_s⌋ ⇒ ⌊⊗✓⇩d⇩u⇩a⇩l⇒⊗✓ r_s⌋) =
(λs r. r ⊗✓ s)›
by (intro ext, simp split: option.split)
(metis tj_None_iff tj_dual_Some_imp)
show ?thesis
proof (subst Synchro⇩p⇩t⇩i⇩c⇩k_comm_dual.vimage_inj_on_subset_super_ref_Sync⇩p⇩t⇩i⇩c⇩k_iff)
show ‹inj_on ⊗✓⇩d⇩u⇩a⇩l⇒⊗✓ Synchro⇩p⇩t⇩i⇩c⇩k_comm_dual.range_tj›
by (fact Synchro⇩p⇩t⇩i⇩c⇩k_comm_dual.inj_on_tj_conv)
next
show ‹X ⊆ super_ref_Sync⇩p⇩t⇩i⇩c⇩k
(λr s. case r ⊗✓⇩d⇩u⇩a⇩l s of ◇ ⇒ ◇ | ⌊r_s⌋ ⇒ ⌊⊗✓⇩d⇩u⇩a⇩l⇒⊗✓ 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_dual 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) ⊗✓⇒⊗✓⇩d⇩u⇩a⇩l = Q ⟦A⟧⇩✓⇩d⇩u⇩a⇩l P›
proof -
from inj_on_RenamingTick_Sync⇩p⇩t⇩i⇩c⇩k[OF inj_on_tj_conv]
have ‹RenamingTick (P ⟦A⟧⇩✓ Q) ⊗✓⇒⊗✓⇩d⇩u⇩a⇩l =
Synchro⇩p⇩t⇩i⇩c⇩k.Sync⇩p⇩t⇩i⇩c⇩k
(λr s. case r ⊗✓ s of ◇ ⇒ ◇ | ⌊r_s⌋ ⇒ ⌊⊗✓⇒⊗✓⇩d⇩u⇩a⇩l r_s⌋) P A Q›
(is ‹_ = Synchro⇩p⇩t⇩i⇩c⇩k.Sync⇩p⇩t⇩i⇩c⇩k ?tj' P A Q›) .
also have ‹?tj' = (λr s. s ⊗✓⇩d⇩u⇩a⇩l r)›
by (intro ext)
(simp add: Synchro⇩p⇩t⇩i⇩c⇩k_comm_dual.tj_dual_Some_imp
tj_None_iff split: option.split)
finally show ‹RenamingTick (P ⟦A⟧⇩✓ Q) ⊗✓⇒⊗✓⇩d⇩u⇩a⇩l = Q ⟦A⟧⇩✓⇩d⇩u⇩a⇩l P›
by (metis Synchro⇩p⇩t⇩i⇩c⇩k_comm_dual.Sync⇩p⇩t⇩i⇩c⇩k_dual)
qed
end
end