Theory Determinacy
section Determinacy
text ‹This section proves that the concurrent revisions model is determinate modulo renaming-equivalence.›
theory Determinacy
imports Executions
begin
context substitution
begin
subsection ‹Rule determinism›
lemma app_deterministic [simp]:
assumes
s_r: "s r = Some (σ, τ, ℰ [Apply (VE (Lambda x e)) (VE v)])"
shows "(revision_step r s s') = (s' = (s(r ↦ (σ, τ, ℰ [subst (VE v) x e]))))" (is "?l = ?r")
proof (rule iffI)
assume ?l
thus ?r by (cases rule: revision_stepE) (use s_r in auto)
qed (simp add: s_r revision_step.app)
lemma ifTrue_deterministic [simp]:
assumes
s_r: "s r = Some (σ, τ, ℰ [Ite (VE (CV T)) e1 e2])"
shows "(revision_step r s s') = (s' = (s(r ↦ (σ, τ, ℰ [e1]))))" (is "?l = ?r")
proof (rule iffI)
assume ?l
thus ?r by (cases rule: revision_stepE) (use s_r in auto)
qed (simp add: s_r revision_step.ifTrue)
lemma ifFalse_deterministic [simp]:
assumes
s_r: "s r = Some (σ, τ, ℰ [Ite (VE (CV F)) e1 e2])"
shows "(revision_step r s s') = (s' = (s(r ↦ (σ, τ, ℰ [e2]))))" (is "?l = ?r")
proof (rule iffI)
assume ?l
thus ?r by (cases rule: revision_stepE) (use s_r in auto)
qed (simp add: s_r revision_step.ifFalse)
lemma new_pseudodeterministic [simp]:
assumes
s_r: "s r = Some (σ, τ, ℰ [Ref (VE v)])"
shows "(revision_step r s s') = (∃l. l ∉ LID⇩G s ∧ s' = (s(r ↦ (σ, τ(l ↦ v), ℰ [VE (Loc l)]))))" (is "?l = ?r")
proof (rule iffI)
assume ?l
thus ?r by (cases rule: revision_stepE) (use s_r in auto)
qed (auto simp add: s_r revision_step.new)
lemma get_deterministic [simp]:
assumes
s_r: "s r = Some (σ, τ, ℰ [Read (VE (Loc l))])"
shows "(revision_step r s s') = (l ∈ dom (σ;;τ) ∧ s' = (s(r ↦ (σ, τ, ℰ [VE (the ((σ;;τ) l))]))))" (is "?l = ?r")
proof (rule iffI)
assume ?l
thus ?r by (cases rule: revision_stepE) (use s_r in auto)
qed (use revision_step.get in ‹auto simp add: s_r›)
lemma set_deterministic [simp]:
assumes
s_r: "s r = Some (σ, τ, ℰ [Assign (VE (Loc l)) (VE v)])"
shows "(revision_step r s s') = (l ∈ dom (σ;;τ) ∧ s' = (s(r ↦ (σ, τ(l ↦ v), ℰ [VE (CV Unit)]))))" (is "?l = ?r")
proof (rule iffI)
assume ?l
thus ?r by (cases rule: revision_stepE) (use s_r in auto)
qed (auto simp add: s_r revision_step.set)
lemma fork_pseudodeterministic [simp]:
assumes
s_r: "s r = Some (σ, τ, ℰ [Rfork e])"
shows "(revision_step r s s') = (∃r'. r' ∉ RID⇩G (s(r ↦ (σ, τ, ℰ [Rfork e]))) ∧ s' = (s(r ↦ (σ, τ, ℰ [VE (Rid r')]), r' ↦ (σ;;τ, ε, e))))" (is "?l = ?r")
proof (rule iffI)
assume step: ?l
show ?r
proof (use step in ‹cases rule: revision_stepE›)
case (fork σ τ ℰ e r')
show ?thesis by (rule exI[where x=r']) (use fork s_r in auto)
qed (auto simp add: s_r)
qed (auto simp add: s_r revision_step.fork map_upd_triv)
lemma rjoin_deterministic [simp]:
assumes
s_r: "s r = Some (σ, τ, ℰ [Rjoin (VE (Rid r'))])" and
s_r': "s r' = Some (σ', τ', VE v)"
shows "(revision_step r s s') = (s' = (s(r := Some (σ, τ;;τ', ℰ [VE (CV Unit)]), r' := None)))" (is "?l = ?r")
proof (rule iffI)
assume step: ?l
show ?r by (cases rule: revision_stepE[OF step]) (use s_r s_r' in auto)
qed (meson s_r s_r' revision_step.join)
lemma rjoin⇩ε_deterministic [simp]:
assumes
s_r: "s r = Some (σ, τ, ℰ [Rjoin (VE (Rid r'))])" and
s_r': "s r' = None"
shows "(revision_step r s s') = (s' = ε)" (is "?l = ?r")
proof (rule iffI)
assume step: ?l
show ?r by (cases rule: revision_stepE[OF step]) (use s_r s_r' in auto)
qed (simp add: revision_step.join⇩ε s_r s_r')
subsection ‹Strong local confluence›
subsubsection ‹Local determinism›
lemma local_determinism:
assumes
left: "revision_step r s⇩1 s⇩2" and
right: "revision_step r s⇩1 s⇩2'"
shows "s⇩2 ≈ s⇩2'"
proof (use left in ‹induct rule:revision_stepE›)
case (new σ τ ℰ v l)
from new(2) right obtain l' where
side: "l' ∉ LID⇩G s⇩1" and
s⇩2': "s⇩2' = s⇩1(r ↦ (σ, τ(l' ↦ v), ℰ[VE (Loc l')]))"
by auto
let "?β" = "id(l := l', l' := l)"
have bij_β: "bij ?β" by (rule swap_bij)
have renaming: "ℛ⇩G id ?β s⇩2 = s⇩2'"
by (use new side s⇩2' bij_β in ‹auto simp add: ID_distr_global_conditional›)
show ?case by (rule eq_statesI[OF renaming bij_id bij_β])
next
case (fork σ τ ℰ e r')
from fork(2) right obtain r'' where
side: "r'' ∉ RID⇩G s⇩1" and
s⇩2': "s⇩2' = s⇩1(r ↦ (σ, τ, ℰ [VE (Rid r'')]), r'' ↦ (σ;;τ, ε, e))"
by (auto simp add: ID_distr_global_conditional)
let "?α" = "id(r' := r'', r'' := r')"
have bij_α: "bij ?α" by (rule swap_bij)
have renaming: "ℛ⇩G ?α id s⇩2 = s⇩2'"
by (use fork side s⇩2' bij_α in ‹auto simp add: ID_distr_global_conditional›)
show ?case by (rule eq_statesI[OF renaming bij_α bij_id])
qed ((rule eq_statesI[of id id], use assms in auto)[1])+
subsubsection ‹General principles›
lemma SLC_sym:
"∃s⇩3' s⇩3. s⇩3' ≈ s⇩3 ∧ (revision_step r' s⇩2 s⇩3' ∨ s⇩2 = s⇩3') ∧ (revision_step r s⇩2' s⇩3 ∨ s⇩2' = s⇩3) ⟹
∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r s⇩2' s⇩3 ∨ s⇩2' = s⇩3) ∧ (revision_step r' s⇩2 s⇩3' ∨ s⇩2 = s⇩3')"
by (metis αβ_sym)
lemma SLC_commute:
"⟦ s⇩3 = s⇩3'; revision_step r' s⇩2 s⇩3; revision_step r s⇩2' s⇩3' ⟧ ⟹
s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
using αβ_refl by auto
subsubsection ‹Case join-epsilon›
lemma SLC_join⇩ε:
assumes
s⇩1_r: "s⇩1 r = Some (σ, τ, ℰ[Rjoin (VE (Rid r''))])" and
s⇩2: "s⇩2 = ε" and
side: "s⇩1 r'' = None" and
right: "revision_step r' s⇩1 s⇩2'" and
neq: "r ≠ r'"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
proof -
have right_collapsed_case: "s⇩2' = ε ⟹ ?thesis"
by (rule exI[where x=ε], rule exI[where x=ε], use s⇩2 in auto)
have left_step_still_available_case: "s⇩2' ≠ ε ⟹ s⇩2' r = s⇩1 r ⟹ s⇩2' r'' = None ⟹ ?thesis"
by (rule exI[where x=ε], rule exI[where x=ε]) (use assms in auto)
show ?thesis
proof (use right in ‹cases rule: revision_stepE›)
case (join _ _ _ right_joinee)
have r_unchanged_left: "s⇩2' r = s⇩1 r" using join assms by auto
have r'_unchanged_right: "s⇩2' r'' = None" using join assms by auto
have "right_joinee ≠ r'" using join(2-3) by auto
hence s⇩2'_nonempty: "s⇩2' ≠ ε" using assms join by (auto simp add: fun_upd_twist)
show ?thesis by (rule left_step_still_available_case[OF s⇩2'_nonempty r_unchanged_left r'_unchanged_right])
next
case join⇩ε
show ?thesis by (rule right_collapsed_case, use join⇩ε(2-3) right in auto)
qed ((rule left_step_still_available_case, use side neq s⇩1_r right in auto)[1])+
qed
subsubsection ‹Case join›
lemma join_and_local_commute:
assumes
"s⇩2 = s⇩1(r := Some (σ, τ;;τ', ℰ[VE (CV Unit)]), r'' := None)"
"s⇩2' = s⇩1(r' ↦ ls)"
"r ≠ r'"
"r' ≠ r''"
"revision_step r' s⇩2 (s⇩1(r := Some (σ, τ;;τ', ℰ[VE (CV Unit)]), r'' := None, r' := Some ls))"
"s⇩2' r = Some (σ, τ, ℰ [Rjoin (VE (Rid r''))])"
"s⇩2' r'' = Some (σ', τ', VE v)"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
apply (rule exI[where x="s⇩1(r := Some (σ, τ;;τ', ℰ[VE (CV Unit)]), r'' := None, r' := Some ls)"])
apply (rule exI[where x="s⇩1(r' := Some ls, r := Some (σ, τ;;τ', ℰ[VE (CV Unit)]), r'' := None)"])
by (rule SLC_commute, use assms in auto)
lemma SLC_join:
assumes
s⇩1_r: "s⇩1 r = Some (σ, τ, ℰ[Rjoin (VE (Rid r''))])" and
s⇩2: "s⇩2 = (s⇩1(r := Some (σ, (τ;;τ'), ℰ[VE (CV Unit)]), r'' := None))" and
side: "s⇩1 r'' = Some (σ', τ', VE v)" and
right: "revision_step r' s⇩1 s⇩2'" and
neq: "r ≠ r'"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
proof -
have left_step: "revision_step r s⇩1 s⇩2" using s⇩1_r s⇩2 side by auto
have r'_not_joined: "r' ≠ r''" using right side by auto
show ?thesis
proof (use right in ‹cases rule: revision_stepE›)
case (new _ _ _ _ l)
have l_fresh_left: "l ∉ LID⇩G s⇩2" by (rule only_new_introduces_lids'[OF left_step]) (use new right s⇩1_r in auto)
show ?thesis by (rule join_and_local_commute, use assms r'_not_joined new l_fresh_left in auto)
next
case (fork _ _ _ _ r''')
have r'_unchanged_left: "s⇩2 r' = s⇩1 r'" using fork assms by auto
have r'''_fresh_left: "r''' ∉ RID⇩G s⇩2" using left_step fork(3) only_fork_introduces_rids' s⇩1_r by auto
have r_unchanged_right: "s⇩2' r = s⇩1 r" using fork assms by auto
have r''_unchanged_right: "s⇩2' r'' = s⇩1 r''" using fork assms by auto
let "?s⇩3" = "s⇩2(r' := s⇩2' r', r''' := s⇩2' r''')"
let "?s⇩3'" = "s⇩2'(r := s⇩2 r, r'' := None)"
show ?thesis
proof (rule exI[where x="?s⇩3"],rule exI[where x="?s⇩3'"], rule SLC_commute)
show "?s⇩3 = ?s⇩3'" using fork(1) fork(3) neq r'_not_joined s⇩1_r s⇩2 by (auto simp add: ID_distr_global_conditional)
show "revision_step r' s⇩2 ?s⇩3" using fork(1-2) r'_unchanged_left r'''_fresh_left by (auto simp add: ID_distr_global_conditional)
show "revision_step r s⇩2' ?s⇩3'" using r''_unchanged_right r_unchanged_right s⇩1_r s⇩2 side by auto
qed
next
case (join _ _ _ r''')
have r'_unchanged_left: "s⇩2 r' = s⇩1 r'" using join(2) neq r'_not_joined s⇩2 by auto
have r_unchanged_right: "s⇩2' r = s⇩1 r" using join(1,3) neq s⇩1_r by auto
show ?thesis
proof (cases "r'' = r'''")
case True
have r'''_none_left: "s⇩2 r''' = None" by (simp add: True s⇩2)
have r''_none_right: "s⇩2' r'' = None" by (simp add: True join(1))
show ?thesis
proof (rule exI[where x=ε], rule exI[where x=ε], rule SLC_commute)
show "ε = ε" by (rule refl)
show "revision_step r' s⇩2 ε" using r'_unchanged_left r'''_none_left join(2) by auto
show "revision_step r s⇩2' ε" using r_unchanged_right r''_none_right s⇩1_r by auto
qed
next
case False
have r'''_unchanged_left: "s⇩2 r''' = s⇩1 r'''" using False join(1,3) s⇩2 r_unchanged_right by auto
have r''_unchanged_right': "s⇩2' r'' = s⇩1 r''" using False join(1) r'_not_joined side by auto
let "?s⇩3" = "s⇩2(r' := s⇩2' r', r''' := None)"
let "?s⇩3'" = "s⇩2'(r := s⇩2 r, r'' := None)"
show ?thesis
proof (rule exI[where x="?s⇩3"], rule exI[where x="?s⇩3'"], rule SLC_commute)
show "?s⇩3 = ?s⇩3'" using join(1) neq r'_not_joined r_unchanged_right s⇩1_r s⇩2 s⇩1_r by fastforce
show "revision_step r' s⇩2 ?s⇩3" by (simp add: join r'''_unchanged_left r'_unchanged_left)
show "revision_step r s⇩2' ?s⇩3'" using r''_unchanged_right' r_unchanged_right s⇩1_r side s⇩2 by auto
qed
qed
next
case join⇩ε
show ?thesis by (rule SLC_sym, rule SLC_join⇩ε, use left_step neq right join⇩ε in auto)
qed ((rule join_and_local_commute, use assms r'_not_joined in auto)[1])+
qed
subsubsection ‹Case local›
lemma local_steps_commute:
assumes
"s⇩2 = s⇩1(r ↦ x)"
"s⇩2' = s⇩1(r' ↦ y)"
"revision_step r' (s⇩1(r ↦ x)) (s⇩1(r ↦ x, r' ↦ y))"
"revision_step r (s⇩1(r' ↦ y)) (s⇩1(r' ↦ y, r ↦ x))"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
by (metis (no_types, lifting) assms fun_upd_twist fun_upd_upd local_determinism)
lemma local_and_fork_commute:
assumes
"s⇩2 = s⇩1(r ↦ x)"
"s⇩2' = s⇩1(r' ↦ (σ, τ, ℰ [VE (Rid r'')]), r'' ↦ (σ;;τ, ε, e))"
"s⇩2 r' = Some (σ, τ, ℰ[Rfork e])"
"r'' ∉ RID⇩G s⇩2"
"revision_step r s⇩2' (s⇩1(r' ↦ (σ, τ, ℰ [VE (Rid r'')]), r'' ↦ (σ;;τ, ε, e), r ↦ x))"
"r ≠ r'"
"r ≠ r''"
shows
"∃s⇩3 s⇩3'. (s⇩3 ≈ s⇩3') ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
proof(rule exI[where x="s⇩1(r ↦ x, r' ↦ (σ, τ, ℰ [VE (Rid r'')]), r'' ↦ (σ;;τ, ε, e))"],
rule exI[where x="s⇩1(r' ↦ (σ, τ, ℰ [VE (Rid r'')]), r'' ↦ (σ;;τ, ε, e), r ↦ x)"],
rule SLC_commute)
show "s⇩1(r ↦ x, r' ↦ (σ, τ, ℰ [VE (Rid r'')]), r'' ↦ (σ;;τ, ε, e)) =
s⇩1(r' ↦ (σ, τ, ℰ [VE (Rid r'')]), r'' ↦ (σ;;τ, ε, e), r ↦ x)"
using assms revision_step.fork by auto
show "revision_step r' s⇩2 (s⇩1(r ↦ x, r' ↦ (σ, τ, ℰ [VE (Rid r'')]), r'' ↦ (σ;;τ, ε, e)))"
using assms(1) assms(3) assms(4) revision_step.fork by blast
show "revision_step r s⇩2' (s⇩1(r' ↦ (σ, τ, ℰ [VE (Rid r'')]), r'' ↦ (σ;;τ, ε, e), r ↦ x))"
using assms(5) by blast
qed
lemma SLC_app:
assumes
s⇩1_r: "s⇩1 r = Some (σ, τ, ℰ[Apply (VE (Lambda x e)) (VE v)])" and
s⇩2: "s⇩2 = s⇩1(r ↦ (σ, τ, ℰ[subst (VE v) x e]))" and
right: "revision_step r' s⇩1 s⇩2'" and
neq: "r ≠ r'"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
proof -
have left_step: "revision_step r s⇩1 s⇩2" using s⇩1_r s⇩2 by auto
show ?thesis
proof (use right in ‹cases rule: revision_stepE›)
case new: (new _ _ _ _ l)
have l_fresh_left: "l ∉ LID⇩G s⇩2"
by (rule only_new_introduces_lids'[OF left_step]) (simp add: s⇩1_r new(3))+
show ?thesis by (rule local_steps_commute) (use new l_fresh_left assms in auto)
next
case (fork _ _ _ _ r'')
have r''_fresh_left: "r'' ∉ RID⇩G s⇩2"
by (rule only_fork_introduces_rids'[OF left_step]) (simp add: s⇩1_r fork(3))+
show ?thesis by (rule local_and_fork_commute[OF s⇩2 fork(1)]) (use fork neq s⇩2 r''_fresh_left s⇩1_r in auto)
next
case join
show ?thesis by (rule SLC_sym, rule SLC_join, use join left_step right neq in auto)
next
case join⇩ε
show ?thesis by (rule SLC_sym, rule SLC_join⇩ε, use join⇩ε left_step right neq in auto)
qed ((rule local_steps_commute[OF s⇩2], use assms in auto)[1])+
qed
lemma SLC_ifTrue:
assumes
s⇩1_r: "s⇩1 r = Some (σ, τ, ℰ[Ite (VE (CV T)) e1 e2])" and
s⇩2: "s⇩2 = s⇩1(r ↦ (σ, τ, ℰ[e1]))" and
right: "revision_step r' s⇩1 s⇩2'" and
neq: "r ≠ r'"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
proof -
have left_step: "revision_step r s⇩1 s⇩2" using s⇩1_r s⇩2 by auto
show ?thesis
proof (use right in ‹cases rule: revision_stepE›)
case (new _ _ _ _ l)
have l_fresh_left: "l ∉ LID⇩G s⇩2"
by (rule only_new_introduces_lids'[OF left_step]) (simp add: s⇩1_r new(3))+
show ?thesis by (rule local_steps_commute) (use new l_fresh_left assms in auto)
next
case (fork _ _ _ _ r'')
have r''_fresh_left: "r'' ∉ RID⇩G s⇩2"
by (rule only_fork_introduces_rids'[OF left_step]) (simp add: s⇩1_r fork(3))+
show ?thesis by (rule local_and_fork_commute[OF s⇩2 fork(1)]) (use fork neq s⇩2 r''_fresh_left s⇩1_r in auto)
next
case join
show ?thesis by (rule SLC_sym, rule SLC_join, use join left_step right neq in auto)
next
case join⇩ε
show ?thesis by (rule SLC_sym, rule SLC_join⇩ε, use join⇩ε left_step right neq in auto)
qed ((rule local_steps_commute[OF s⇩2], use assms in auto)[1])+
qed
lemma SLC_ifFalse:
assumes
s⇩1_r: "s⇩1 r = Some (σ, τ, ℰ[Ite (VE (CV F)) e1 e2])" and
s⇩2: "s⇩2 = s⇩1(r ↦ (σ, τ, ℰ[e2]))" and
right: "revision_step r' s⇩1 s⇩2'" and
neq: "r ≠ r'"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
proof -
have left_step: "revision_step r s⇩1 s⇩2" using s⇩1_r s⇩2 by auto
show ?thesis
proof (use right in ‹cases rule: revision_stepE›)
next
case (new _ _ _ _ l)
have l_fresh_left: "l ∉ LID⇩G s⇩2"
by (rule only_new_introduces_lids'[OF left_step]) (simp add: s⇩1_r new(3))+
show ?thesis by (rule local_steps_commute) (use new l_fresh_left assms in auto)
next
case (fork _ _ _ _ r'')
have r''_fresh_left: "r'' ∉ RID⇩G s⇩2"
by (rule only_fork_introduces_rids'[OF left_step]) (simp add: s⇩1_r fork(3))+
show ?thesis by (rule local_and_fork_commute[OF s⇩2 fork(1)]) (use fork neq s⇩2 r''_fresh_left s⇩1_r in auto)
next
case join
show ?thesis by (rule SLC_sym, rule SLC_join, use join left_step right neq in auto)
next
case join⇩ε
show ?thesis by (rule SLC_sym, rule SLC_join⇩ε, use join⇩ε left_step right neq in auto)
qed ((rule local_steps_commute[OF s⇩2], use assms in auto)[1])+
qed
lemma SLC_set:
assumes
s⇩1_r: "s⇩1 r = Some (σ, τ, ℰ[Assign (VE (Loc l)) (VE v)])" and
s⇩2: "s⇩2 = s⇩1(r ↦ (σ, τ(l ↦ v), ℰ[VE (CV Unit)]))" and
side: "l ∈ dom (σ;;τ)" and
right: "revision_step r' s⇩1 s⇩2'" and
neq: "r ≠ r'"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
proof -
have left_step: "revision_step r s⇩1 s⇩2" using s⇩1_r s⇩2 side by auto
show ?thesis
proof (use right in ‹cases rule: revision_stepE›)
case (new _ _ _ _ l)
have l_fresh_left: "l ∉ LID⇩G s⇩2"
by (rule only_new_introduces_lids'[OF left_step]) (simp add: s⇩1_r new(3))+
show ?thesis by (rule local_steps_commute) (use new l_fresh_left assms in auto)
next
case (fork _ _ _ _ r'')
have r''_fresh_left: "r'' ∉ RID⇩G s⇩2"
by (rule only_fork_introduces_rids'[OF left_step]) (simp add: s⇩1_r fork(3))+
show ?thesis by (rule local_and_fork_commute[OF s⇩2 fork(1)]) (use fork neq s⇩2 r''_fresh_left s⇩1_r side in auto)
next
case join
show ?thesis by (rule SLC_sym, rule SLC_join, use join left_step neq in auto)
next
case join⇩ε
show ?thesis by (rule SLC_sym, rule SLC_join⇩ε, use join⇩ε left_step neq in auto)
qed ((rule local_steps_commute[OF s⇩2], use assms in auto)[1])+
qed
lemma SLC_get:
assumes
s⇩1_r: "s⇩1 r = Some (σ, τ, ℰ [Read (VE (Loc l))])" and
s⇩2: "s⇩2 = s⇩1(r ↦ (σ, τ, ℰ[VE (the ((σ;;τ) l))]))" and
side: "l ∈ dom (σ;;τ)" and
right: "revision_step r' s⇩1 s⇩2'" and
neq: "r ≠ r'"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
proof -
have left_step: "revision_step r s⇩1 s⇩2" using s⇩1_r s⇩2 side by auto
show ?thesis
proof (use right in ‹cases rule: revision_stepE›)
case (new _ _ _ _ l)
have l_fresh_left: "l ∉ LID⇩G s⇩2"
by (rule only_new_introduces_lids'[OF left_step]) (simp add: s⇩1_r new(3))+
show ?thesis by (rule local_steps_commute) (use new l_fresh_left assms in auto)
next
case (fork _ _ _ _ r'')
have r''_fresh_left: "r'' ∉ RID⇩G s⇩2"
by (rule only_fork_introduces_rids'[OF left_step]) (simp add: s⇩1_r fork(3))+
show ?thesis by (rule local_and_fork_commute[OF s⇩2 fork(1)]) (use fork neq s⇩2 r''_fresh_left s⇩1_r side in auto)
next
case join
show ?thesis by (rule SLC_sym, rule SLC_join, use join left_step neq in auto)
next
case join⇩ε
show ?thesis by (rule SLC_sym, rule SLC_join⇩ε, use join⇩ε left_step neq in auto)
qed ((rule local_steps_commute[OF s⇩2], use assms in auto)[1])+
qed
subsubsection ‹Case new›
lemma SLC_new:
assumes
s⇩1_r: "s⇩1 r = Some (σ, τ, ℰ[Ref (VE v)])" and
s⇩2: "s⇩2 = s⇩1(r ↦ (σ, τ(l ↦ v), ℰ [VE (Loc l)]))" and
side: "l ∉ LID⇩G s⇩1" and
right: "revision_step r' s⇩1 s⇩2'" and
neq: "r ≠ r'" and
reach: "reachable (s⇩1 :: ('r,'l,'v) global_state)" and
lid_inf: "infinite (UNIV :: 'l set)"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
proof -
have left_step: "revision_step r s⇩1 s⇩2" using s⇩1_r s⇩2 side by auto
show ?thesis
proof (use right in ‹cases rule: revision_stepE›)
case app
show ?thesis by (rule SLC_sym, rule SLC_app) (use app assms(1-5) in auto)
next
case ifTrue
show ?thesis by (rule SLC_sym, rule SLC_ifTrue) (use ifTrue assms(1-5) in auto)
next
case ifFalse
show ?thesis by (rule SLC_sym, rule SLC_ifFalse) (use ifFalse assms(1-5) in auto)
next
case (new σ' τ' ℰ' v' l')
have r'_unchanged_left: "s⇩2 r' = s⇩1 r'" using new(2) neq s⇩2 by auto
have r_unchanged_right: "s⇩2' r = s⇩1 r" by (simp add: new(1) neq s⇩1_r)
show ?thesis
proof (cases "l = l'")
case True
obtain l'' where l''_fresh_left: "l'' ∉ LID⇩G s⇩2"
by (meson ex_new_if_finite left_step lid_inf reach RID⇩L_finite_invariant reachable_imp_identifiers_finite(2))
hence l_l'': "l ≠ l''" by (auto simp add: s⇩2)
have l''_fresh_s⇩1: "l'' ∉ LID⇩G s⇩1" using assms True new l''_fresh_left by (auto simp add: ID_distr_global_conditional)
hence l''_fresh_right': "l'' ∉ LID⇩G s⇩2'" using True l_l'' new(1-2) by auto
let "?β" = "id(l := l'', l'' := l)"
have bij_β: "bij ?β" by (simp add: swap_bij)
let "?s⇩3" = "s⇩2(r' ↦ (σ', τ'(l'' ↦ v'), ℰ' [VE (Loc l'')]))"
have left_convergence: "revision_step r' s⇩2 ?s⇩3"
using l''_fresh_left new(2) r'_unchanged_left by auto
let "?s⇩3'" = "s⇩2'(r ↦ (σ, τ(l'' ↦ v), ℰ [VE (Loc l'')]))"
have right_convergence: "revision_step r s⇩2' ?s⇩3'"
using l''_fresh_right' new(1) neq s⇩1_r by auto
have equiv: "?s⇩3 ≈ ?s⇩3'"
proof (rule eq_statesI[of id ?β])
show "ℛ⇩G id ?β ?s⇩3 = ?s⇩3'"
proof -
have s⇩1: "ℛ⇩G id ?β s⇩1 = s⇩1" using l''_fresh_s⇩1 side by auto
have σ: "ℛ⇩S id ?β σ = σ" using l''_fresh_s⇩1 s⇩1_r side by auto
have ℰ: "ℛ⇩C id ?β ℰ = ℰ"
proof
show "l ∉ LID⇩C ℰ" using s⇩1_r side by auto
show "l'' ∉ LID⇩C ℰ" using l''_fresh_left s⇩2 by auto
qed
have τlv: "ℛ⇩S id (id(l := l'', l'' := l)) (τ(l ↦ v)) = (τ(l'' ↦ v))"
proof -
have τ: "ℛ⇩S id ?β τ = τ" using l''_fresh_s⇩1 s⇩1_r side by auto
have v: "ℛ⇩V id ?β v = v"
proof
show "l ∉ LID⇩V v" using s⇩1_r side by auto
show "l'' ∉ LID⇩V v" using l''_fresh_s⇩1 s⇩1_r by auto
qed
show ?thesis by (simp add: τ v bij_β)
qed
have σ': "ℛ⇩S id ?β σ' = σ'" using l''_fresh_s⇩1 new(2-3) by (auto simp add: True ID_distr_global_conditional)
have ℰ': "ℛ⇩C id ?β ℰ' = ℰ'" using l''_fresh_s⇩1 new(2-3) by (auto simp add: True ID_distr_global_conditional)
have τl''v: "ℛ⇩S id (id(l := l'', l'' := l)) (τ'(l'' ↦ v')) = (τ'(l ↦ v'))"
proof -
have τ': "ℛ⇩S id ?β τ' = τ'" using new(2-3) l''_fresh_s⇩1 by (auto simp add: True ID_distr_global_conditional)
have v': "ℛ⇩V id ?β v' = v'" using new(2-3) l''_fresh_s⇩1 by (auto simp add: True ID_distr_global_conditional)
show ?thesis by (simp add: τ' v' bij_β)
qed
show ?thesis using True neq s⇩1 σ ℰ τlv σ' ℰ' τl''v s⇩2 l_l'' new(1) by auto
qed
qed (simp add: bij_β)+
show ?thesis using left_convergence right_convergence equiv by blast
next
case False
have l_fresh_left: "l ∉ LID⇩G s⇩2'"
by (rule revision_stepE[OF left_step]) (use False side new(1-2) in ‹auto simp add: s⇩1_r›)
have l'_fresh_right: "l' ∉ LID⇩G s⇩2"
by (rule revision_stepE[OF right]) (use False new(3) assms(1-3) in ‹auto simp add: new(2)›)
show ?thesis by (rule local_steps_commute[OF s⇩2 new(1)]) (use new assms l_fresh_left l'_fresh_right s⇩2 in auto)
qed
next
case get
show ?thesis by (rule SLC_sym, rule SLC_get) (use get assms(1-5) in auto)
next
case set
show ?thesis by (rule SLC_sym, rule SLC_set) (use set assms(1-5) in auto)
next
case (fork _ _ _ _ r'')
have r''_fresh_left: "r'' ∉ RID⇩G s⇩2"
by (rule only_fork_introduces_rids'[OF left_step]) (simp add: s⇩1_r fork(3))+
have l_fresh_right: "l ∉ LID⇩G s⇩2'"
by (rule only_new_introduces_lids'[OF right]) (simp add: side fork(2))+
show ?thesis by (rule local_and_fork_commute[OF s⇩2 fork(1)]) (use fork(1-2) neq s⇩2 l_fresh_right r''_fresh_left s⇩1_r in auto)
next
case join
show ?thesis by (rule SLC_sym, rule SLC_join, use join left_step neq in auto)
next
case join⇩ε
show ?thesis by (rule SLC_sym, rule SLC_join⇩ε, use join⇩ε left_step neq in auto)
qed
qed
subsubsection ‹Case fork›
lemma SLC_fork:
assumes
s⇩1_r: "s⇩1 r = Some (σ, τ, ℰ [Rfork e])" and
s⇩2: "s⇩2 = (s⇩1(r ↦ (σ, τ, ℰ[VE (Rid left_forkee)]), left_forkee ↦ (σ;;τ, ε, e)))" and
side: "left_forkee ∉ RID⇩G s⇩1" and
right: "revision_step r' s⇩1 s⇩2'" and
neq: "r ≠ r'" and
reach: "reachable (s⇩1 :: ('r,'l,'v) global_state)" and
rid_inf: "infinite (UNIV :: 'r set)"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
proof -
have left_step: "revision_step r s⇩1 s⇩2" using s⇩1_r s⇩2 side by (auto simp add: ID_distr_global_conditional)
show ?thesis
proof (use right in ‹cases rule: revision_stepE›)
case app
show ?thesis by (rule SLC_sym, rule SLC_app) (use assms(1-5) app in ‹auto simp add: ID_distr_global_conditional›)
next
case ifTrue
show ?thesis by (rule SLC_sym, rule SLC_ifTrue) (use assms(1-5) ifTrue in ‹auto simp add: ID_distr_global_conditional›)
next
case ifFalse
show ?thesis by (rule SLC_sym, rule SLC_ifFalse) (use assms(1-5) ifFalse in ‹auto simp add: ID_distr_global_conditional›)
next
case (new _ _ _ _ l)
have l_fresh_left: "l ∉ LID⇩G s⇩2"
by (rule only_new_introduces_lids'[OF left_step]) (simp add: s⇩1_r new(3))+
have r''_fresh_right: "left_forkee ∉ RID⇩G s⇩2'"
by (rule only_fork_introduces_rids'[OF right]) (simp add: side new(2))+
show ?thesis by (rule SLC_sym, rule local_and_fork_commute[OF new(1) s⇩2]) (use new(1-2) neq s⇩1_r r''_fresh_right l_fresh_left s⇩2 in auto)
next
case get
show ?thesis by (rule SLC_sym, rule SLC_get) (use assms(1-5) get in ‹auto simp add: ID_distr_global_conditional›)
next
case set
show ?thesis by (rule SLC_sym, rule SLC_set) (use assms(1-5) set in ‹auto simp add: ID_distr_global_conditional›)
next
case (fork σ' τ' ℰ' e' right_forkee)
have r'_unchanged_left: "s⇩2 r' = s⇩1 r'" using side fork(2) neq s⇩2 by auto
have r_unchanged_right: "s⇩2' r = s⇩1 r" using fork(1,3) neq s⇩1_r by auto
have "r ≠ left_forkee" using s⇩1_r side by auto
have "r ≠ right_forkee" using fork(3) s⇩1_r by auto
have "r' ≠ left_forkee" using fork(2) side by auto
have "r' ≠ right_forkee" using fork(2) fork(3) by auto
show ?thesis
proof (cases "left_forkee = right_forkee")
case True
obtain r'' where r''_fresh_left: "r'' ∉ RID⇩G s⇩2"
using RID⇩G_finite_invariant ex_new_if_finite left_step reach reachable_imp_identifiers_finite(1) rid_inf by blast
hence "r'' ≠ left_forkee" using assms(2) by auto
have "r'' ≠ r" using r''_fresh_left s⇩2 by auto
have "r'' ≠ r'" using fork(2) r''_fresh_left r'_unchanged_left by auto
have "r'' ∉ RID⇩G (s⇩1(r ↦ (σ, τ, ℰ[VE (Rid left_forkee)])))"
by (metis (mono_tags, lifting) RID⇩G_def True UnI1 ‹r ≠ right_forkee› domIff fun_upd_other fun_upd_triv in_restricted_global_in_updated_global(1) fork(3) r''_fresh_left s⇩2)
hence "r'' ∉ RID⇩G (s⇩1(r := None))" by blast
have r''_fresh_s⇩1: "r'' ∉ RID⇩G s⇩1"
using ‹r ≠ left_forkee› s⇩2 r''_fresh_left s⇩1_r ‹r'' ≠ r› ‹r'' ∉ RID⇩G (s⇩1(r := None))›
by (auto simp add: ID_distr_global_conditional)
have r''_fresh_right: "r'' ∉ RID⇩G s⇩2'"
using True ‹r'' ≠ left_forkee› ‹r' ≠ right_forkee› ‹r'' ≠ r'› r''_fresh_s⇩1 fork(2) r''_fresh_s⇩1
by (auto simp add: fork(1) ID_distr_global_conditional fun_upd_twist)
let ?α = "id(left_forkee := r'', r'' := left_forkee)"
have bij_α: "bij ?α" by (simp add: swap_bij)
let "?s⇩3" = "s⇩2(r' ↦ (σ', τ', ℰ' [VE (Rid r'')]), r'' ↦ (σ';;τ', ε, e'))"
have left_convergence: "revision_step r' s⇩2 ?s⇩3"
using fork(2) r''_fresh_left r'_unchanged_left revision_step.fork by auto
let "?s⇩3'" = "s⇩2'(r ↦ (σ, τ, ℰ[VE (Rid r'')]), r'' ↦ (σ;;τ, ε, e))"
have right_convergence: "revision_step r s⇩2' ?s⇩3'"
using r''_fresh_right r_unchanged_right revision_step.fork s⇩1_r by auto
have equiv: "?s⇩3 ≈ ?s⇩3'"
proof (rule eq_statesI[of ?α id])
show "ℛ⇩G ?α id ?s⇩3 = ?s⇩3'"
proof -
have s⇩1: "ℛ⇩G ?α id s⇩1 = s⇩1" using r''_fresh_s⇩1 side by auto
have σ: "ℛ⇩S ?α id σ = σ" using r''_fresh_s⇩1 s⇩1_r True fork(3) by auto
have τ: "ℛ⇩S ?α id τ = τ" using r''_fresh_s⇩1 s⇩1_r True fork(3) by auto
have ℰ: "ℛ⇩C ?α id ℰ = ℰ"
proof
show "left_forkee ∉ RID⇩C ℰ" using s⇩1_r side by auto
show "r'' ∉ RID⇩C ℰ" using True ‹r ≠ right_forkee› r''_fresh_left s⇩2 by auto
qed
have e: "ℛ⇩E ?α id e = e"
proof
show "left_forkee ∉ RID⇩E e" using s⇩1_r side by auto
show "r'' ∉ RID⇩E e" using True ‹r ≠ right_forkee› r''_fresh_left s⇩2 by auto
qed
have σ': "ℛ⇩S ?α id σ' = σ'" using fork(2) r''_fresh_s⇩1 side by auto
have τ': "ℛ⇩S ?α id τ' = τ'" using fork(2) r''_fresh_s⇩1 side by auto
have ℰ': "ℛ⇩C ?α id ℰ' = ℰ'"
proof
show "left_forkee ∉ RID⇩C ℰ'" using fork(2) side by auto
show "r'' ∉ RID⇩C ℰ'" using fork(2) r''_fresh_s⇩1 by auto
qed
have e': "ℛ⇩E ?α id e' = e'"
proof
show "left_forkee ∉ RID⇩E e'" using fork(2) side by auto
show "r'' ∉ RID⇩E e'" using fork(2) r''_fresh_s⇩1 by auto
qed
show ?thesis using True fork(1) neq σ τ ℰ e σ' τ' ℰ' e' s⇩1 s⇩2
bij_α ‹r'' ≠ left_forkee› ‹r' ≠ left_forkee› ‹r ≠ left_forkee› ‹r'' ≠ r› ‹r'' ≠ r'›
by auto
qed
qed (simp add: bij_α)+
show ?thesis using equiv left_convergence right_convergence by blast
next
case False
have right_forkee_fresh_left: "right_forkee ∉ RID⇩G s⇩2"
using False ‹r ≠ left_forkee› ‹r ≠ right_forkee› fork(3) s⇩1_r
by (auto simp add: s⇩2 ID_distr_global_conditional, auto)
have left_forkee_fresh_right: "left_forkee ∉ RID⇩G s⇩2'"
using False ‹r' ≠ right_forkee› ‹r' ≠ left_forkee› side fork(2)
by (auto simp add: fork(1) ID_distr_global_conditional fun_upd_twist)
show ?thesis
proof(rule exI[where x="s⇩2(r' := s⇩2' r', right_forkee := s⇩2' right_forkee)"],
rule exI[where x="s⇩2'(r := s⇩2 r, left_forkee := s⇩2 left_forkee)"],
rule SLC_commute)
show "s⇩2(r' := s⇩2' r', right_forkee := s⇩2' right_forkee) = s⇩2'(r := s⇩2 r, left_forkee := s⇩2 left_forkee)"
using False ‹r ≠ right_forkee› ‹r' ≠ left_forkee› ‹r' ≠ right_forkee› fork(1) neq s⇩2 by auto
show "revision_step r' s⇩2 (s⇩2(r' := s⇩2' r', right_forkee := s⇩2' right_forkee))"
using fork(1-2) r'_unchanged_left revision_step.fork right_forkee_fresh_left by auto
show "revision_step r s⇩2' (s⇩2'(r := s⇩2 r, left_forkee := s⇩2 left_forkee))"
using left_forkee_fresh_right r_unchanged_right revision_step.fork s⇩1_r s⇩2 by auto
qed
qed
next
case join
show ?thesis by (rule SLC_sym, rule SLC_join, use join left_step assms(3-5) in auto)
next
case join⇩ε
show ?thesis by (rule SLC_sym, rule SLC_join⇩ε, use join⇩ε left_step assms(3-5) in auto)
qed
qed
subsubsection ‹The theorem›
theorem strong_local_confluence:
assumes
l: "revision_step r s⇩1 s⇩2" and
r: "revision_step r' s⇩1 s⇩2'" and
reach: "reachable (s⇩1 :: ('r,'l,'v) global_state)" and
lid_inf: "infinite (UNIV :: 'l set)" and
rid_inf: "infinite (UNIV :: 'r set)"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ (revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3) ∧ (revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3')"
proof (cases "r = r'")
case True
thus ?thesis by (metis l local_determinism r)
next
case neq: False
thus ?thesis by (cases rule: revision_stepE[OF l]) (auto simp add: assms SLC_app SLC_ifTrue
SLC_ifFalse SLC_new SLC_get SLC_set SLC_fork SLC_join SLC_join⇩ε)
qed
subsection ‹Diagram Tiling›
subsubsection ‹Strong local confluence diagrams›
lemma SLC:
assumes
s⇩1s⇩2: "s⇩1 ↝ s⇩2" and
s⇩1s⇩2': "s⇩1 ↝ s⇩2'" and
reach: "reachable (s⇩1 :: ('r,'l,'v) global_state)" and
lid_inf: "infinite (UNIV :: 'l set)" and
rid_inf: "infinite (UNIV :: 'r set)"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ s⇩2 ↝⇧= s⇩3 ∧ s⇩2' ↝⇧= s⇩3'"
proof -
from s⇩1s⇩2 obtain r where l: "revision_step r s⇩1 s⇩2" by auto
from s⇩1s⇩2' obtain r' where r: "revision_step r' s⇩1 s⇩2'" by auto
obtain s⇩3 s⇩3' where
s⇩3_eq_s⇩3': "s⇩3 ≈ s⇩3'" and
l_join: "revision_step r' s⇩2 s⇩3 ∨ s⇩2 = s⇩3" and
r_join: "revision_step r s⇩2' s⇩3' ∨ s⇩2' = s⇩3'"
using l r reach lid_inf rid_inf strong_local_confluence by metis
have s⇩2s⇩3: "s⇩2 ↝⇧= s⇩3" using l_join steps_def by auto
have s⇩2's⇩3: "s⇩2' ↝⇧= s⇩3'" using r_join steps_def by auto
show ?thesis using s⇩2's⇩3 s⇩2s⇩3 s⇩3_eq_s⇩3' by blast
qed
lemma SLC_top_relaxed:
assumes
s⇩1s⇩2: "s⇩1 ↝⇧= s⇩2" and
s⇩1s⇩2': "s⇩1 ↝ s⇩2'" and
reach: "reachable (s⇩1 :: ('r,'l,'v) global_state)" and
lid_inf: "infinite (UNIV :: 'l set)" and
rid_inf: "infinite (UNIV :: 'r set)"
shows
"∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ s⇩2 ↝⇧= s⇩3 ∧ s⇩2' ↝⇧= s⇩3'"
proof -
have 1: "s⇩1 ↝ s⇩2 ⟹ s⇩1 ↝ s⇩2' ⟹ ?thesis" using SLC lid_inf reach rid_inf by blast
have 2: "s⇩1 = s⇩2 ⟹ s⇩1 ↝ s⇩2' ⟹ ?thesis"
by (rule exI[where x="s⇩2'"], rule exI[where x="s⇩2'"]) (auto simp add: αβ_refl)
show ?thesis using assms 1 2 by auto
qed
subsubsection ‹Mimicking diagrams›
declare bind_eq_None_conv [simp]
declare bind_eq_Some_conv [simp]
lemma in_renamed_in_unlabelled_val:
"bij α ⟹ (α r ∈ RID⇩V (ℛ⇩V α β v)) = (r ∈ RID⇩V v)"
"bij β ⟹ (β l ∈ LID⇩V (ℛ⇩V α β v)) = (l ∈ LID⇩V v)"
by (auto simp add: bij_is_inj inj_image_mem_iff val.set_map(1-2))
lemma in_renamed_in_unlabelled_expr:
"bij α ⟹ (α r ∈ RID⇩E (ℛ⇩E α β v)) = (r ∈ RID⇩E v)"
"bij β ⟹ (β l ∈ LID⇩E (ℛ⇩E α β v)) = (l ∈ LID⇩E v)"
by (auto simp add: bij_is_inj inj_image_mem_iff expr.set_map(1-2))
lemma in_renamed_in_unlabelled_store:
assumes
bij_α: "bij α" and
bij_β: "bij β"
shows
"(α r ∈ RID⇩S (ℛ⇩S α β σ)) = (r ∈ RID⇩S σ)"
"(β l ∈ LID⇩S (ℛ⇩S α β σ)) = (l ∈ LID⇩S σ)"
proof -
show "(α r ∈ RID⇩S (ℛ⇩S α β σ)) = (r ∈ RID⇩S σ)"
proof (rule iffI)
assume "α r ∈ RID⇩S (ℛ⇩S α β σ)"
thus "r ∈ RID⇩S σ"
proof (rule RID⇩SE)
fix l v
assume map: "ℛ⇩S α β σ l = Some v" and αr: "α r ∈ RID⇩V v"
hence "σ (inv β l) = Some (ℛ⇩V (inv α) (inv β) v)"
using bij_α bij_β by (auto simp add: bij_is_inj)
have "r ∈ RID⇩V (ℛ⇩V (inv α) (inv β) v)"
using bij_α bij_β αr map by (auto simp add: bij_is_inj in_renamed_in_unlabelled_val(1))
show "r ∈ RID⇩S σ"
using ‹σ (inv β l) = Some (ℛ⇩V (inv α) (inv β) v)› ‹r ∈ RID⇩V (ℛ⇩V (inv α) (inv β) v)› by blast
qed
next
assume "r ∈ RID⇩S σ"
thus "α r ∈ RID⇩S (ℛ⇩S α β σ)"
by (metis (mono_tags, lifting) RID⇩SE RID⇩SI bij_α bij_β fun_upd_same fun_upd_triv
in_renamed_in_unlabelled_val(1) renaming_distr_store)
qed
show "(β l ∈ LID⇩S (ℛ⇩S α β σ)) = (l ∈ LID⇩S σ)"
proof (rule iffI)
assume "β l ∈ LID⇩S (ℛ⇩S α β σ)"
thus "l ∈ LID⇩S σ"
proof (rule LID⇩SE)
assume "β l ∈ dom (ℛ⇩S α β σ)"
thus "l ∈ LID⇩S σ" by (auto simp add: LID⇩SI(1) bij_β bijection.intro bijection.inv_left)
next
fix v l'
assume "ℛ⇩S α β σ l' = Some v" "β l ∈ LID⇩V v"
thus "l ∈ LID⇩S σ" using bij_β by (auto simp add: LID⇩SI(2) in_renamed_in_unlabelled_val(2))
qed
next
assume "l ∈ LID⇩S σ"
thus "β l ∈ LID⇩S (ℛ⇩S α β σ)"
proof (rule LID⇩SE)
assume "l ∈ dom σ"
hence "∃σ' v. σ = (σ'(l ↦ v))" by fastforce
hence "β l ∈ dom (ℛ⇩S α β σ)" using bij_β by auto
thus "β l ∈ LID⇩S (ℛ⇩S α β σ)" by auto
next
fix v l'
assume "σ l' = Some v" and l_in_v: "l ∈ LID⇩V v"
hence "∃σ'. σ = (σ'(l' ↦ v))" by force
thus "β l ∈ LID⇩S (ℛ⇩S α β σ)"
using l_in_v bij_β by (auto simp add: LID⇩SI(2) in_renamed_in_unlabelled_val(2))
qed
qed
qed
lemma in_renamed_in_unlabelled_local:
assumes
bij_α: "bij α" and
bij_β: "bij β"
shows
"(α r ∈ RID⇩L (ℛ⇩L α β ls)) = (r ∈ RID⇩L ls)"
"(β l ∈ LID⇩L (ℛ⇩L α β ls)) = (l ∈ LID⇩L ls)"
by (cases ls, simp add: assms in_renamed_in_unlabelled_expr in_renamed_in_unlabelled_store)+
lemma in_renamed_in_unlabelled_global:
assumes
bij_α: "bij α" and
bij_β: "bij β"
shows
"(α r ∈ RID⇩G (ℛ⇩G α β s)) = (r ∈ RID⇩G s)"
"(β l ∈ LID⇩G (ℛ⇩G α β s)) = (l ∈ LID⇩G s)"
proof -
show "(α r ∈ RID⇩G (ℛ⇩G α β s)) = (r ∈ RID⇩G s)"
proof (rule iffI)
assume "α r ∈ RID⇩G (ℛ⇩G α β s)"
thus "r ∈ RID⇩G s"
proof (rule RID⇩GE)
assume "α r ∈ dom (ℛ⇩G α β s)"
hence "r ∈ dom s" by (metis bij_α domIff fun_upd_same fun_upd_triv renaming_distr_global(2))
thus "r ∈ RID⇩G s" by auto
next
fix r' ls
assume ℛsr': "ℛ⇩G α β s r' = Some ls" and αr: "α r ∈ RID⇩L ls"
have s_inv_αr': "s (inv α r') = Some (ℛ⇩L (inv α) (inv β) ls)"
proof -
have "inv α r' ∈ dom s" using ℛsr' by auto
then obtain ls' where s_inv_αr: "s (inv α r') = Some ls'" by blast
hence "ℛ⇩G α β s r' = Some (ℛ⇩L α β ls')" by simp
hence "ls = (ℛ⇩L α β ls')" using ℛsr' by auto
thus ?thesis by (metis ℛ⇩L_inv s_inv_αr bij_α bij_β)
qed
have r_in: "r ∈ RID⇩L (ℛ⇩L (inv α) (inv β) ls)"
by (metis bij_α bij_β bij_imp_bij_inv bijection.intro bijection.inv_left in_renamed_in_unlabelled_local(1) αr)
show "r ∈ RID⇩G s"
using r_in s_inv_αr' by blast
qed
next
assume "r ∈ RID⇩G s"
thus "α r ∈ RID⇩G (ℛ⇩G α β s)"
proof (rule RID⇩GE)
assume "r ∈ dom s"
hence "α r ∈ dom (ℛ⇩G α β s)"
by (metis (mono_tags, lifting) bij_α domD domI fun_upd_same fun_upd_triv renaming_distr_global(1))
thus "α r ∈ RID⇩G (ℛ⇩G α β s)" by auto
next
fix r' ls
assume "s r' = Some ls" "r ∈ RID⇩L ls"
thus "α r ∈ RID⇩G (ℛ⇩G α β s)"
by (metis ID_distr_global(1) UnI2 bij_α bij_β fun_upd_triv in_renamed_in_unlabelled_local(1) insertI2 renaming_distr_global(1))
qed
qed
show "(β l ∈ LID⇩G (ℛ⇩G α β s)) = (l ∈ LID⇩G s)"
proof (rule iffI)
assume "β l ∈ LID⇩G (ℛ⇩G α β s)"
from this obtain r ls where Rs_ls: "ℛ⇩G α β s r = Some ls" and βl_in_ls: "β l ∈ LID⇩L ls" by blast
hence "l ∈ LID⇩L (ℛ⇩L (inv α) (inv β) ls)"
by (metis bij_α bij_β bij_imp_bij_inv bijection.intro bijection.inv_left in_renamed_in_unlabelled_local(2))
hence "l ∈ LID⇩G (ℛ⇩G (inv α) (inv β) (ℛ⇩G α β s))"
by (metis (mono_tags, lifting) LID⇩GI Rs_ls bij_α bij_imp_bij_inv fun_upd_idem_iff renaming_distr_global(1))
thus "l ∈ LID⇩G s" using bij_α bij_β by (metis ℛ⇩G_inv)
next
assume "l ∈ LID⇩G s"
then obtain r s' ls where "s = (s'(r ↦ ls))" "l ∈ LID⇩L ls" by (metis LID⇩GE fun_upd_triv)
thus "β l ∈ LID⇩G (ℛ⇩G α β s)" by (simp add: bij_α bij_β in_renamed_in_unlabelled_local(2))
qed
qed
lemma mimicking:
assumes
step: "revision_step r s s'" and
bij_α: "bij α" and
bij_β: "bij β"
shows "revision_step (α r) (ℛ⇩G α β s) (ℛ⇩G α β s')"
proof (use step in ‹cases rule: revision_stepE›)
case app
then show ?thesis by (auto simp add: bij_α bij_β bijection.intro bijection.inv_left renaming_distr_subst)
next
case (new _ _ _ _ l)
have βl_fresh: "β l ∉ LID⇩G (ℛ⇩G α β s)"
by (simp add: bij_α bij_β in_renamed_in_unlabelled_global(2) new(3))
show ?thesis using βl_fresh new by (auto simp add: bij_α bij_β bijection.intro bijection.inv_left)
next
case (fork σ τ ℰ e r')
have αr'_fresh: "α r' ∉ RID⇩G (ℛ⇩G α β s)"
by (simp add: bij_α bij_β in_renamed_in_unlabelled_global(1) fork(3))
have s_r_as_upd: "s = (s(r ↦ (σ, τ, ℰ [Rfork e])))" using fork(2) by auto
have src: "ℛ⇩G α β s (α r) = Some (ℛ⇩S α β σ, ℛ⇩S α β τ, (ℛ⇩C α β ℰ) [Rfork (ℛ⇩E α β e)])"
by (subst s_r_as_upd, simp add: bij_α)
show ?thesis using αr'_fresh src revision_step.fork fork(1) bij_α by auto
qed (auto simp add: bij_α bij_β bijection.intro bijection.inv_left)
lemma mimic_single_step:
assumes
s⇩1s⇩1': "s⇩1 ≈ s⇩1'" and
s⇩1s⇩2: "s⇩1 ↝ s⇩2"
shows "∃s⇩2'. (s⇩2 ≈ s⇩2') ∧ s⇩1' ↝ s⇩2'"
proof -
from s⇩1s⇩1' obtain α β where
bij_α: "bij α" and
bij_β: "bij β" and
R: "ℛ⇩G α β s⇩1 = s⇩1'" by blast
from s⇩1s⇩2 obtain r where step: "revision_step r s⇩1 s⇩2" by auto
have mirrored_step: "revision_step (α r) s⇩1' (ℛ⇩G α β s⇩2)"
using R bij_α bij_β step mimicking by auto
have eq: "s⇩2 ≈ (ℛ⇩G α β s⇩2)" using bij_α bij_β by blast
have s⇩1's⇩2': "s⇩1' ↝ (ℛ⇩G α β s⇩2)" using mirrored_step by auto
from eq s⇩1's⇩2' show ?thesis by blast
qed
lemma mimic_trans:
assumes
s⇩1_eq_s⇩1': "s⇩1 ≈ s⇩1'" and
s⇩1s⇩2: "s⇩1 ↝⇧* s⇩2"
shows "∃s⇩2'. s⇩2 ≈ s⇩2' ∧ s⇩1' ↝⇧* s⇩2'"
proof -
from s⇩1_eq_s⇩1' obtain α β where
bij_α: "bij α" and
bij_β: "bij β" and
R: "ℛ⇩G α β s⇩1 = s⇩1'"
by blast
from s⇩1s⇩2 obtain n where "(s⇩1,s⇩2) ∈ [↝]^^n" using rtrancl_power by blast
thus ?thesis
proof (induct n arbitrary: s⇩2)
case 0
thus ?case using s⇩1_eq_s⇩1' by auto
next
case (Suc n)
obtain x where n_steps: "(s⇩1, x) ∈ [↝]^^n" and step: "x ↝ s⇩2" using Suc.prems by auto
obtain x' where x_eq_x': "x ≈ x'" and s⇩1'x: "s⇩1' ↝⇧* x'" using Suc.hyps n_steps by blast
obtain s⇩2' where s⇩2_eq_s⇩2': "s⇩2 ≈ s⇩2'" and x's⇩2': "x' ↝ s⇩2'"
by (meson step mimic_single_step x_eq_x')
show ?case using s⇩1'x s⇩2_eq_s⇩2' trancl_into_rtrancl x's⇩2' by auto
qed
qed
subsubsection ‹Strip diagram›
lemma strip_lemma:
assumes
s⇩1s⇩2: "s⇩1 ↝⇧* s⇩2" and
s⇩1s⇩2': "s⇩1 ↝⇧= s⇩2'" and
reach: "reachable (s⇩1 :: ('r,'l,'v) global_state)" and
lid_inf: "infinite (UNIV :: 'l set)" and
rid_inf: "infinite (UNIV :: 'r set)"
shows "∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ s⇩2 ↝⇧* s⇩3 ∧ s⇩2' ↝⇧* s⇩3'"
proof -
from s⇩1s⇩2 obtain n where "(s⇩1, s⇩2) ∈ [↝]^^n" using rtrancl_power by blast
from reach s⇩1s⇩2' and this show ?thesis
proof (induct n arbitrary: s⇩1 s⇩2 s⇩2')
case 0
hence "s⇩1 = s⇩2" by simp
hence s⇩2s⇩2': "s⇩2 ↝⇧* s⇩2'" using "0.prems"(2) by blast
show ?case by (rule exI[where x=s⇩2'], rule exI[where x=s⇩2']) (use s⇩2s⇩2' in ‹simp add: αβ_refl›)
next
case (Suc n)
obtain a where s⇩1a: "s⇩1 ↝ a" and as⇩2: "(a, s⇩2) ∈ [↝]^^n" by (meson Suc.prems(3) relpow_Suc_D2)
obtain b c where "b ≈ c" "a ↝⇧= b" "s⇩2' ↝⇧= c"
by (metis (mono_tags, lifting) SLC_top_relaxed Suc.prems(1) Suc.prems(2) αβ_sym lid_inf rid_inf s⇩1a)
obtain d e where "d ≈ e" "s⇩2 ↝⇧* d" "b ↝⇧* e"
by (meson Suc.hyps Suc.prems(1) ‹a ↝⇧= b› as⇩2 reachability_closed_under_execution_step s⇩1a valid_stepE)
obtain f where "c ↝⇧* f" "e ≈ f"
by (meson ‹b ≈ c› ‹b ↝⇧* e› mimic_trans)
have "d ≈ f" using αβ_trans ‹d ≈ e› ‹e ≈ f› by auto
then show ?case by (metis (no_types, lifting) ‹c ↝⇧* f› ‹s⇩2 ↝⇧* d› ‹s⇩2' ↝⇧= c› r_into_rtrancl rtrancl_reflcl rtrancl_trans)
qed
qed
subsubsection ‹Confluence diagram›
lemma confluence_modulo_equivalence:
assumes
s⇩1s⇩2: "s⇩1 ↝⇧* s⇩2" and
s⇩1s⇩2': "s⇩1' ↝⇧* s⇩2'" and
equiv: "s⇩1 ≈ s⇩1'" and
reach: "reachable (s⇩1 :: ('r,'l,'v) global_state)" and
lid_inf: "infinite (UNIV :: 'l set)" and
rid_inf: "infinite (UNIV :: 'r set)"
shows "∃s⇩3 s⇩3'. s⇩3 ≈ s⇩3' ∧ s⇩2 ↝⇧* s⇩3 ∧ s⇩2' ↝⇧* s⇩3'"
proof -
obtain n where "(s⇩1, s⇩2) ∈ [↝]^^n" using s⇩1s⇩2 rtrancl_power by blast
from reach equiv s⇩1s⇩2' and this show ?thesis
proof (induct n arbitrary: s⇩1 s⇩1' s⇩2 s⇩2')
case base: 0
hence "s⇩1 = s⇩2" by simp
obtain s⇩2'' where "s⇩1 ↝⇧* s⇩2''" "s⇩2' ≈ s⇩2''"
using αβ_sym base.prems(2,3) mimic_trans by blast
have "s⇩2 ↝⇧* s⇩2''" using ‹s⇩1 = s⇩2› ‹s⇩1 ↝⇧* s⇩2''› by blast
show ?case by (rule exI[where x=s⇩2''], rule exI[where x=s⇩2']) (auto simp add: αβ_sym ‹s⇩2 ↝⇧* s⇩2''› ‹s⇩2' ≈ s⇩2''›)
next
case step: (Suc n)
obtain a where s⇩1a: "(s⇩1, a) ∈ [↝]^^n" and as⇩2: "a ↝ s⇩2" using step.prems(4) by auto
have "reachable a" using reachability_closed_under_execution relpow_imp_rtrancl s⇩1a step.prems(1) by blast
obtain b c where "a ↝⇧* b" "s⇩2' ↝⇧* c" "b ≈ c"
using s⇩1a step.hyps step.prems(1-3) by blast
have "a ↝⇧* s⇩2" by (simp add: as⇩2 r_into_rtrancl)
obtain s⇩3 d where "s⇩3 ≈ d" "s⇩2 ↝⇧* s⇩3" "b ↝⇧* d"
by (meson αβ_sym ‹a ↝⇧* b› ‹reachable a› as⇩2 lid_inf refl_rewritesI rid_inf strip_lemma)
obtain s⇩3' where "s⇩3 ≈ s⇩3'" "c ↝⇧* s⇩3'"
by (meson αβ_trans ‹b ≈ c› ‹b ↝⇧* d› ‹s⇩3 ≈ d› mimic_trans)
show ?case by (meson ‹c ↝⇧* s⇩3'› ‹s⇩2 ↝⇧* s⇩3› ‹s⇩2' ↝⇧* c› ‹s⇩3 ≈ s⇩3'› transD trans_rtrancl)
qed
qed
subsection ‹Determinacy›
theorem determinacy:
assumes
prog_expr: "program_expr e" and
e_terminates_in_s: "e ↓ s" and
e_terminates_in_s': "e ↓ s'" and
lid_inf: "infinite (UNIV :: 'l set)" and
rid_inf: "infinite (UNIV :: 'r set)"
shows "s ≈ s'"
proof -
obtain r where x: "(ε(r ↦ (ε,ε,e))) ↝⇧* s"
by (metis e_terminates_in_s execution_def maximal_execution_def terminates_in_def)
obtain r' where y: "(ε(r' ↦ (ε,ε,e))) ↝⇧* s'"
by (metis e_terminates_in_s' execution_def maximal_execution_def terminates_in_def)
let "?α" = "id(r := r', r' := r)"
have bij_α: "bij ?α" by (simp add: swap_bij)
have equiv: "(ε(r ↦ (ε,ε,e))) ≈ (ε(r' ↦ (ε,ε,e)))"
proof (rule eq_statesI[of ?α id])
show "ℛ⇩G ?α id (ε(r ↦ (ε, ε, e))) = ε(r' ↦ (ε, ε, e))"
using bij_α prog_expr by auto
qed (simp add: bij_α)+
have reach: "reachable (ε(r ↦ (ε,ε,e)))"
by (simp add: initial_state_reachable prog_expr)
have "∃a b. (a ≈ b) ∧ s ↝⇧* a ∧ s' ↝⇧* b"
by (rule confluence_modulo_equivalence[OF x y equiv reach lid_inf rid_inf])
from this obtain a b where "s ↝⇧* a" "s' ↝⇧* b" "a ≈ b" by blast
have "s = a" by (meson ‹s ↝⇧* a› e_terminates_in_s maximal_execution_def rtranclD terminates_in_def tranclD)
have "s' = b" by (meson ‹s' ↝⇧* b› converse_rtranclE e_terminates_in_s' maximal_execution_def terminates_in_def)
show ?thesis using ‹a ≈ b› ‹s = a› ‹s' = b› by auto
qed
end
end