Theory OperationalSemantics

section ‹Operational Semantics›

text ‹This theory defines the operational semantics of the concurrent revisions model. It also
  introduces a relaxed formulation of the operational semantics, and proves the main result required
  for establishing their equivalence.›

theory OperationalSemantics
  imports Substitution
begin

context substitution
begin

subsection Definition

inductive revision_step :: "'r ⇒ ('r,'l,'v) global_state ⇒ ('r,'l,'v) global_state ⇒ bool" where
  app: "s r = Some (σ, τ, ℰ[Apply (VE (Lambda x e)) (VE v)]) ⟹ revision_step r s (s(r ↦ (σ, τ, ℰ[subst (VE v) x e])))"
| ifTrue: "s r = Some (σ, τ, ℰ[Ite (VE (CV T)) e1 e2]) ⟹ revision_step r s (s(r ↦ (σ, τ, ℰ[e1])))"
| ifFalse: "s r = Some (σ, τ, ℰ[Ite (VE (CV F)) e1 e2]) ⟹ revision_step r s (s(r ↦ (σ, τ, ℰ[e2])))"
(* store operations *)
| new: "s r = Some (σ, τ, ℰ[Ref (VE v)]) ⟹ l ∉ LIDG s ⟹ revision_step r s (s(r ↦ (σ, τ(l ↦ v), ℰ[VE (Loc l)])))"
| get: "s r = Some (σ, τ, ℰ[Read (VE (Loc l))]) ⟹ l ∈ dom (σ;;τ) ⟹ revision_step r s (s(r ↦ (σ, τ, ℰ[VE (the ((σ;;τ) l))])))"
| set: "s r = Some (σ, τ, ℰ[Assign (VE (Loc l)) (VE v)]) ⟹ l ∈ dom (σ;;τ) ⟹ revision_step r s (s(r ↦ (σ, τ(l ↦ v), ℰ[VE (CV Unit)])))"
(* synchronization operations *)
| fork: "s r = Some (σ, τ, ℰ[Rfork e]) ⟹ r' ∉ RIDG s ⟹ revision_step r s (s(r ↦ (σ, τ, ℰ[VE (Rid r')]), r' ↦ (σ;;τ, ε, e)))"
| join: "s r = Some (σ, τ, ℰ[Rjoin (VE (Rid r'))]) ⟹ s r' = Some (σ', τ', VE v) ⟹ revision_step r s (s(r := Some (σ, (τ;;τ'), ℰ[VE (CV Unit)]), r' := None))"
| joinε: "s r = Some (σ, τ, ℰ[Rjoin (VE (Rid r'))]) ⟹ s r' = None ⟹ revision_step r s ε"

inductive_cases revision_stepE [elim, consumes 1, case_names app ifTrue ifFalse new get set fork join joinε]:
  "revision_step r s s'"

subsection ‹Introduction lemmas for identifiers›

lemma only_new_introduces_lids [intro, dest]:
  assumes 
    step: "revision_step r s s'" and
    not_new: "⋀σ τ ℰ v. s r ≠ Some (σ,τ,ℰ[Ref (VE v)])"
  shows "LIDG s' ⊆ LIDG s"
proof (use step in ‹cases rule: revision_stepE›)
  case fork
  thus ?thesis by (auto simp add: fun_upd_twist ID_distr_global_conditional)
next
  case (join _ _ _ r' _ _ _)
  hence "r ≠ r'" by auto
  thus ?thesis using join by (auto simp add: fun_upd_twist dest!: in_combination_in_component)
qed (auto simp add: not_new fun_upd_twist ID_distr_global_conditional dest: LIDSI(2))

lemma only_fork_introduces_rids [intro, dest]:
  assumes 
    step: "revision_step r s s'" and
    not_fork: "⋀σ τ ℰ e. s r ≠ Some (σ,τ,ℰ[Rfork e])"
  shows "RIDG s' ⊆ RIDG s"
proof (use step in ‹cases rule: revision_stepE›)
next
  case get
  then show ?thesis by (auto simp add: ID_distr_global_conditional)
next
  case fork
  then show ?thesis by (simp add: not_fork)
next
  case (join _ _ _r' _ _ _)
  hence "r ≠ r'" by auto
  then show ?thesis using join by (auto simp add: fun_upd_twist dest!: in_combination_in_component)
qed (auto simp add: ID_distr_global_conditional)

lemma only_fork_introduces_rids' [dest]:
  assumes 
    step: "revision_step r s s'" and
    not_fork: "⋀σ τ ℰ e. s r ≠ Some (σ,τ,ℰ[Rfork e])"
  shows "r' ∉ RIDG s ⟹ r' ∉ RIDG s'"
  using assms by blast

lemma only_new_introduces_lids' [dest]:
  assumes 
    step: "revision_step r s s'" and
    not_new: "⋀σ τ ℰ v. s r ≠ Some (σ,τ,ℰ[Ref (VE v)])"
  shows "l ∉ LIDG s ⟹ l ∉ LIDG s'"
  using assms by blast

subsection ‹Domain subsumption›

subsubsection Definitions

definition domains_subsume :: "('r,'l,'v) local_state ⇒ bool" (‹𝒮›) where
  "𝒮 ls = (LIDL ls ⊆ doms ls)"

definition domains_subsume_globally :: "('r,'l,'v) global_state ⇒ bool" (‹𝒮G›) where
  "𝒮G s = (∀r ls. s r = Some ls ⟶ 𝒮 ls)"

lemma domains_subsume_globallyI [intro]:
  "(⋀r σ τ e. s r = Some (σ,τ,e) ⟹ 𝒮 (σ,τ,e)) ⟹ domains_subsume_globally s"
  using domains_subsume_globally_def by auto

definition subsumes_accessible :: "'r ⇒ 'r ⇒ ('r,'l,'v) global_state ⇒ bool" (‹𝒜›) where
  "𝒜 r1 r2 s = (r2 ∈ RIDL (the (s r1)) ⟶ (LIDS ((the (s r2))σ) ⊆ doms (the (s r1))))"

lemma subsumes_accessibleI [intro]: 
  "(r2 ∈ RIDL (the (s r1)) ⟹ LIDS ((the (s r2))σ) ⊆ doms (the (s r1))) ⟹ 𝒜 r1 r2 s"
  using subsumes_accessible_def by auto

definition subsumes_accessible_globally :: "('r,'l,'v) global_state ⇒ bool" (‹𝒜G›) where
  "𝒜G s = (∀r1 r2. r1 ∈ dom s ⟶ r2 ∈ dom s ⟶ 𝒜 r1 r2 s)"

lemma subsumes_accessible_globallyI [intro]:
  "(⋀r1 σ1 τ1 e1 r2 σ2 τ2 e2. s r1 = Some (σ1,τ1,e1) ⟹ s r2 = Some (σ2,τ2,e2) ⟹ 𝒜 r1 r2 s) ⟹ 𝒜G s"
  using subsumes_accessible_globally_def by auto

subsubsection ‹The theorem›

lemma 𝒮G_imp_𝒜_refl:
  assumes 
    𝒮G_s: "𝒮G s" and
    r_in_dom: "r ∈ dom s"
  shows "𝒜 r r s" 
  using assms by (auto simp add: domains_subsume_def domains_subsume_globally_def subsumes_accessibleI)

lemma step_preserves_𝒮G_and_𝒜G:
  assumes 
    step: "revision_step r s s'" and
    𝒮G_s: "𝒮G s" and
    𝒜G_s: "𝒜G s"
  shows "𝒮G s'" "𝒜G s'"
proof -
  show "𝒮G s'"
  proof (rule domains_subsume_globallyI)
    fix r' σ τ e
    assume s'_r: "s' r' = Some (σ,τ,e)"
    show "𝒮 (σ,τ,e)"
    proof (cases "s' r' = s r'")
      case True
      then show ?thesis using 𝒮G_s domains_subsume_globally_def s'_r by auto
    next
      case r'_was_updated: False
      show ?thesis
      proof (use step in ‹cases rule: revision_stepE›)
        case (app σ' τ' ℰ' _ e' v')
        have "r = r'" by (metis fun_upd_apply app(1) r'_was_updated)
        have "LIDL (the (s' r)) ⊆ LIDS σ' ∪ LIDS τ' ∪ LIDC ℰ' ∪ LIDE e' ∪ LIDV v'" using app(1) by auto
        also have "... = LIDL (the (s r))" using app(2) by auto
        also have "... ⊆ doms (the (s r))" 
          by (metis 𝒮G_s domains_subsume_def domains_subsume_globally_def local.app(2) option.sel)
        also have "... = doms (the (s' r))" using app by simp
        finally have "𝒮 (the (s' r))" by (simp add: domains_subsume_def)
        thus ?thesis by (simp add: ‹r = r'› s'_r)
      next
        case ifTrue
        have "r = r'" by (metis fun_upd_apply ifTrue(1) r'_was_updated)
        have "LIDL (the (s' r)) ⊆ LIDL (the (s r))" using ifTrue by auto
        also have "... ⊆ doms (the (s r))"
          by (metis 𝒮G_s domains_subsume_def domains_subsume_globally_def ifTrue(2) option.sel)
        also have "... = doms (the (s' r))" by (simp add: ifTrue)
        finally have "𝒮 (the (s' r))" by (simp add: domains_subsume_def)
        thus ?thesis by (simp add: ‹r = r'› s'_r)
      next
        case ifFalse
        have "r = r'" by (metis fun_upd_apply ifFalse(1) r'_was_updated)
        have "LIDL (the (s' r)) ⊆ LIDL (the (s r))" using ifFalse by auto
        also have "... ⊆ doms (the (s r))"
          by (metis 𝒮G_s domains_subsume_def domains_subsume_globally_def ifFalse(2) option.sel)
        also have "... = doms (the (s' r))" by (simp add: ifFalse)
        finally have "𝒮 (the (s' r))" by (simp add: domains_subsume_def)
        thus ?thesis by (simp add: ‹r = r'› s'_r)
      next
        case (new σ' τ' ℰ' v' l')
        have "r = r'" by (metis fun_upd_apply new(1) r'_was_updated)
        have "LIDL (the (s' r)) = insert l' (LIDS σ' ∪ LIDS τ' ∪ LIDV v' ∪ LIDC ℰ')"
        proof -
          have "l' ∉ LIDS τ'" using new(2-3) by auto
          thus ?thesis using new(1) by auto
        qed
        also have "... = insert l' (LIDL (the (s r)))" using new by auto
        also have "... ⊆ insert l' (doms (the (s r)))"
          by (metis 𝒮G_s domains_subsume_def domains_subsume_globally_def insert_mono new(2) option.sel)
        also have "... = doms (the (s' r))" using new by auto
        finally have "𝒮 (the (s' r))" by (simp add: domains_subsume_def)
        thus ?thesis by (simp add: ‹r = r'› s'_r)
      next
        case get
        have "r = r'" by (metis fun_upd_apply get(1) r'_was_updated)
        have "LIDL (the (s' r)) = LIDL (the (s r))" using get by auto
        also have "... ⊆ doms (the (s r))"
          by (metis 𝒮G_s domains_subsume_def domains_subsume_globally_def get(2) option.sel)
        also have "... = doms (the (s' r))" by (simp add: get(1-2))
        finally have "𝒮 (the (s' r))" by (simp add: domains_subsume_def)
        thus ?thesis by (simp add: ‹r = r'› s'_r)
      next
        case set
        have "r = r'" by (metis fun_upd_apply set(1) r'_was_updated)
        have "LIDL (the (s' r)) ⊆ LIDL (the (s r))" using set(1-2) by auto
        also have "... ⊆ doms (the (s r))"
          by (metis 𝒮G_s domains_subsume_def domains_subsume_globally_def set(2) option.sel)
        also have "... ⊆ doms (the (s' r))" using set(1-2) by auto
        finally have "𝒮 (the (s' r))" by (simp add: domains_subsume_def)
        thus ?thesis by (simp add: ‹r = r'› s'_r)
      next
        case (fork σ' τ' _ _ r'')
        have "r = r' ∨ r'' = r'" using fork r'_was_updated by auto
        then show ?thesis
        proof (rule disjE)
          assume "r = r'"
          have "LIDL (the (s' r)) ⊆ LIDL (the (s r))" using fork(1-2) by auto
          also have "... ⊆ doms (the (s r))"
            by (metis 𝒮G_s domains_subsume_def domains_subsume_globally_def fork(2) option.sel)
          also have "... = doms (the (s' r))" using fork by auto
          finally have "𝒮 (the (s' r))" by (simp add: domains_subsume_def)
          thus ?thesis by (simp add: ‹r = r'› s'_r)
        next
          assume "r'' = r'"
          have "LIDL (the (s' r'')) ⊆ LIDL (the (s r))" using fork(1-2) by auto
          also have "... ⊆ doms (the (s r))"
            by (metis 𝒮G_s domains_subsume_def domains_subsume_globally_def fork(2) option.sel)
          also have "... = dom σ' ∪ dom τ'" using fork by simp
          also have "... = dom (σ';;τ')"  by (simp add: dom_combination_dom_union)
          also have "... = doms (the (s' r''))" using fork by simp
          finally have "𝒮 (the (s' r''))" by (simp add: domains_subsume_def)
          thus ?thesis by (simp add: ‹r'' = r'› s'_r)
        qed
      next
        case (join σ' τ' _ r'' σ'' τ'' _)
        have "r' = r" by (metis fun_upd_def join(1) option.simps(3) r'_was_updated s'_r)
        have "LIDL (the (s' r)) ⊆ LIDL (the (s r)) ∪ LIDS τ''" using join by auto
        also have "... ⊆ doms (the (s r)) ∪ LIDS τ''"
          by (metis Un_mono 𝒮G_s domains_subsume_def domains_subsume_globally_def join(2) option.sel subset_refl)
        also have "... ⊆ doms (the (s r)) ∪ LIDL (the (s r''))" using join(3) by auto
        also have "... ⊆ doms (the (s r)) ∪ doms (the (s r''))"
          by (metis (no_types, lifting) Un_absorb 𝒮G_s domains_subsume_def domains_subsume_globally_def join(3) option.sel sup.orderI sup_mono)
        also have "... = dom σ' ∪ dom τ' ∪ dom σ'' ∪ dom τ''" using join by auto
        also have "... ⊆ dom σ' ∪ dom τ' ∪ LIDS σ'' ∪ dom τ''" by auto
        also have "... ⊆ dom σ' ∪ dom τ' ∪ dom σ' ∪ dom τ' ∪ dom τ''"
        proof -
          have r_r'': "𝒜 r r'' s" using 𝒜G_s join(2-3) subsumes_accessible_globally_def by auto
          have r_accesses_r'': "r'' ∈ RIDL (the (s r))" using join by auto
          have "LIDS σ'' ⊆ dom σ' ∪ dom τ'" using join subsumes_accessible_def r_r'' r_accesses_r'' by auto
          thus ?thesis by auto
        qed
        also have "... = dom σ' ∪ dom τ' ∪ dom τ''" by auto
        also have "... = dom σ' ∪ dom (τ';;τ'')" by (auto simp add: dom_combination_dom_union)
        also have "... = doms (the (s' r))" using join by auto
        finally have "𝒮 (the (s' r))" by (simp add: domains_subsume_def)
        thus ?thesis using ‹r' = r› s'_r by auto
      next
        case joinε
        then show ?thesis using s'_r by blast
      qed
    qed
  qed
  show "𝒜G s'"
  proof (rule subsumes_accessible_globallyI)
    fix r1 σ1 τ1 e1 r2 σ2 τ2 e2
    assume 
      s'_r1: "s' r1 = Some (σ1, τ1, e1)" and
      s'_r2: "s' r2 = Some (σ2, τ2, e2)"
    show "𝒜 r1 r2 s'"
    proof (cases "r1 = r2")
      case True
      then show ?thesis using 𝒮G_imp_𝒜_refl ‹𝒮G s'› s'_r1 by blast
    next
      case r1_neq_r2: False
      have r1_nor_r2_updated_implies_thesis: "s' r1 = s r1 ⟹ s' r2 = s r2 ⟹ ?thesis"
      proof - 
        assume r1_unchanged: "s' r1 = s r1" and r2_unchanged: "s' r2 = s r2"
        have "𝒜 r1 r2 s"
          by (metis 𝒜G_s domIff option.discI r1_unchanged r2_unchanged s'_r1 s'_r2 subsumes_accessible_globally_def)
        show ?thesis using ‹𝒜 r1 r2 s› r1_unchanged r2_unchanged subsumes_accessible_def by auto
      qed
      have r1_or_r2_updated_implies_thesis: "s' r1 ≠ s r1 ∨ s' r2 ≠ s r2 ⟹ ?thesis"
      proof -
        assume r1_or_r2_updated: "s' r1 ≠ s r1 ∨ s' r2 ≠ s r2"
        show ?thesis
        proof (use step in ‹cases rule: revision_stepE›)
          case app
          have "r1 = r ∨ r2 = r" by (metis fun_upd_other app(1) r1_or_r2_updated)
          then show ?thesis
          proof (rule disjE)
            assume r1_eq_r: "r1 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS ((the (s' r2))σ) ⊆ LIDS ((the (s r2))σ)" using app by auto
              also have "... ⊆ doms (the (s r1))" 
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using app r2_in_s'_r1 r1_eq_r by auto
                have "𝒜 r1 r2 s"
                  by (metis 𝒜G_s domI fun_upd_other app r1_eq_r s'_r2 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))" using app by auto
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          next
            assume r2_eq_r: "r2 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS (the (s' r2)σ) = LIDS (the (s r2)σ)" using app by auto
              also have "... ⊆ doms (the (s r1))"
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using app(1) r1_neq_r2 r2_eq_r r2_in_s'_r1 by auto
                have "𝒜 r1 r2 s"
                  by (metis (no_types, lifting) 𝒜G_s domIff fun_upd_other app option.discI r2_eq_r s'_r1 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))" by (simp add: app)
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          qed
        next
          case ifTrue
          have "r1 = r ∨ r2 = r" by (metis fun_upd_other ifTrue(1) r1_or_r2_updated)
          then show ?thesis
          proof (rule disjE)
            assume r1_eq_r: "r1 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS ((the (s' r2))σ) ⊆ LIDS ((the (s r2))σ)" using ifTrue by auto
              also have "... ⊆ doms (the (s r1))" 
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using ifTrue r2_in_s'_r1 r1_eq_r by auto
                have "𝒜 r1 r2 s"
                  by (metis 𝒜G_s domI fun_upd_other ifTrue r1_eq_r s'_r2 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))" using ifTrue by auto
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          next
            assume r2_eq_r: "r2 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS (the (s' r2)σ) = LIDS (the (s r2)σ)" using ifTrue by auto
              also have "... ⊆ doms (the (s r1))"
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using ifTrue(1) r1_neq_r2 r2_eq_r r2_in_s'_r1 by auto
                have "𝒜 r1 r2 s"
                  by (metis (no_types, lifting) 𝒜G_s domIff fun_upd_other ifTrue option.discI r2_eq_r s'_r1 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))" by (simp add: ifTrue)
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          qed
        next
          case ifFalse
          have "r1 = r ∨ r2 = r" by (metis fun_upd_other ifFalse(1) r1_or_r2_updated)
          then show ?thesis
          proof (rule disjE)
            assume r1_eq_r: "r1 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS ((the (s' r2))σ) ⊆ LIDS ((the (s r2))σ)" using ifFalse by auto
              also have "... ⊆ doms (the (s r1))" 
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using ifFalse r2_in_s'_r1 r1_eq_r by auto
                have "𝒜 r1 r2 s"
                  by (metis 𝒜G_s domI fun_upd_other ifFalse r1_eq_r s'_r2 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))" using ifFalse by auto
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          next
            assume r2_eq_r: "r2 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS (the (s' r2)σ) = LIDS (the (s r2)σ)" using ifFalse by auto
              also have "... ⊆ doms (the (s r1))"
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using ifFalse(1) r1_neq_r2 r2_eq_r r2_in_s'_r1 by auto
                have "𝒜 r1 r2 s"
                  by (metis (no_types, lifting) 𝒜G_s domIff fun_upd_other ifFalse option.discI r2_eq_r s'_r1 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))" by (simp add: ifFalse)
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          qed
        next
          case new
          have "r1 = r ∨ r2 = r" by (metis fun_upd_other new(1) r1_or_r2_updated)
          then show ?thesis
          proof (rule disjE)
            assume r1_eq_r: "r1 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS ((the (s' r2))σ) ⊆ LIDS ((the (s r2))σ)" using new by auto
              also have "... ⊆ doms (the (s r1))" 
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using new r2_in_s'_r1 r1_eq_r by auto
                have "𝒜 r1 r2 s"
                  by (metis 𝒜G_s domI fun_upd_other new(1-2) r1_eq_r s'_r2 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))" using new by auto
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          next
            assume r2_eq_r: "r2 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS (the (s' r2)σ) = LIDS (the (s r2)σ)" using new by auto
              also have "... ⊆ doms (the (s r1))"
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using new(1) r1_neq_r2 r2_eq_r r2_in_s'_r1 by auto
                have "𝒜 r1 r2 s"
                  by (metis (no_types, lifting) 𝒜G_s domIff fun_upd_other new(1-2) option.discI r2_eq_r s'_r1 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))" by (auto simp add: new)
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          qed
        next
          case get
          have "r1 = r ∨ r2 = r" by (metis fun_upd_other get(1) r1_or_r2_updated)
          then show ?thesis
          proof (rule disjE)
            assume r1_eq_r: "r1 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS ((the (s' r2))σ) ⊆ LIDS ((the (s r2))σ)" using get by auto
              also have "... ⊆ doms (the (s r1))" 
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using get r2_in_s'_r1 r1_eq_r apply auto
                  by (meson RIDSI) (* by (auto 1 3) *)
                have "𝒜 r1 r2 s"
                  by (metis 𝒜G_s domI fun_upd_other get(1-2) r1_eq_r s'_r2 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))" using get by auto
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          next
            assume r2_eq_r: "r2 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS (the (s' r2)σ) = LIDS (the (s r2)σ)" using get by auto
              also have "... ⊆ doms (the (s r1))"
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using get(1) r1_neq_r2 r2_eq_r r2_in_s'_r1 by auto
                have "𝒜 r1 r2 s"
                  by (metis (no_types, lifting) 𝒜G_s domIff fun_upd_other get(1-2) option.discI r2_eq_r s'_r1 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))" by (simp add: get)
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          qed
        next
          case set
          have "r1 = r ∨ r2 = r" by (metis fun_upd_other set(1) r1_or_r2_updated)
          then show ?thesis
          proof (rule disjE)
            assume r1_eq_r: "r1 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS ((the (s' r2))σ) ⊆ LIDS ((the (s r2))σ)" using set by auto
              also have "... ⊆ doms (the (s r1))" 
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using set r2_in_s'_r1 r1_eq_r by auto
                have "𝒜 r1 r2 s"
                  by (metis 𝒜G_s domI fun_upd_other set(1-2) r1_eq_r s'_r2 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))" using set by auto
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          next
            assume r2_eq_r: "r2 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS (the (s' r2)σ) = LIDS (the (s r2)σ)" using set by auto
              also have "... ⊆ doms (the (s r1))"
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using set(1) r1_neq_r2 r2_eq_r r2_in_s'_r1 by auto
                have "𝒜 r1 r2 s"
                  by (metis (no_types, lifting) 𝒜G_s domIff fun_upd_other set(1-2) option.discI r2_eq_r s'_r1 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))" by (auto simp add: set)
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          qed
        next
          case (fork σ τ ℰ e r')
          have s'_r: "s' r = Some (σ, τ, ℰ [VE (Rid r')])" using fork by auto
          have s'_r': "s' r' = Some (σ;;τ, ε, e)" 
            by (simp add: local.fork(1))
          have case1: "r1 = r ⟹ r2 ≠ r ⟹ r2 ≠ r' ⟹ ?thesis"
          proof (rule subsumes_accessibleI)
            assume "r1 = r" "r2 ≠ r" "r2 ≠ r'"
            assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
            have "LIDS ((the (s' r2))σ) ⊆ LIDS ((the (s r2))σ)" using fork(1-2) by (simp add: ‹r2 ≠ r'›)
            also have "... ⊆ doms (the (s r1))" 
            proof -
              have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using fork ‹r1 = r› ‹r2 ≠ r'› r2_in_s'_r1 s'_r by auto
              have "𝒜 r1 r2 s"
                by (metis (no_types, lifting) 𝒜G_s ‹r1 = r› ‹r2 ≠ r'› domIff fun_upd_other fork(1-2) option.discI s'_r2 subsumes_accessible_globally_def)
              show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
            qed
            also have "... ⊆ doms (the (s' r1))" by (simp add: ‹r1 = r› fork(2) s'_r)
            finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
          qed
          have case2: "r1 ≠ r ⟹ r1 ≠ r' ⟹ r2 = r ⟹ ?thesis"
          proof (rule subsumes_accessibleI)
            assume "r1 ≠ r" "r1 ≠ r'" "r2 = r"
            assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
            have "LIDS ((the (s' r2))σ) ⊆ LIDS ((the (s r2))σ)"
              using ‹r1 ≠ r'› ‹r1 ≠ r› fork r2_in_s'_r1 s'_r1 by auto
            also have "... ⊆ doms (the (s r1))" 
            proof -
              have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))" using ‹r1 ≠ r'› ‹r1 ≠ r› fork(1) r2_in_s'_r1 by auto
              have "𝒜 r1 r2 s"
                by (metis (no_types, lifting) 𝒜G_s ‹r1 ≠ r'› ‹r2 = r› domIff fun_upd_other fork(1-2) option.discI s'_r1 subsumes_accessible_globally_def)
              show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by auto
            qed
            also have "... ⊆ doms (the (s' r1))" by (simp add: ‹r1 ≠ r'› ‹r1 ≠ r› fork(1))
            finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
          qed
          have case3: "r1 = r' ⟹ r2 ≠ r ⟹ r2 ≠ r' ⟹ ?thesis"
          proof (rule subsumes_accessibleI)
            fix l
            assume "r1 = r'" "r2 ≠ r" "r2 ≠ r'"
            assume "r2 ∈ RIDL (the (s' r1))"
            hence "r2 ∈ RIDL (the (s r))" using RIDLI(3) ‹r1 = r'› fork(2) s'_r' by auto
            have "s r2 = s' r2" by (simp add: ‹r2 ≠ r'› ‹r2 ≠ r› fork(1))
            hence "𝒜 r r2 s" using 𝒜G_s fork(2) s'_r2 subsumes_accessible_globally_def by auto
            hence "LIDS (the (s' r2)σ) ⊆ doms (the (s r))"
              by (simp add: ‹r2 ∈ RIDL (the (s r))› ‹s r2 = s' r2› subsumes_accessible_def)
            also have "... = dom σ ∪ dom τ" by (simp add: fork(2))
            also have "... = dom (σ;;τ)" by (simp add: dom_combination_dom_union)
            also have "... = doms (the (s' r'))" by (simp add: s'_r')
            finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" using ‹r1 = r'› by blast
          qed
          have case4: "r1 ≠ r ⟹ r1 ≠ r' ⟹ r2 = r' ⟹ ?thesis"
          proof -
            assume "r1 ≠ r" "r1 ≠ r'" "r2 = r'"
            have "r2 ∉ RIDL (the (s r1))" using ‹r1 ≠ r'› ‹r1 ≠ r› ‹r2 = r'› fork(1,3) s'_r1 by auto
            hence "r2 ∉ RIDL (the (s' r1))" by (simp add: ‹r1 ≠ r'› ‹r1 ≠ r› fork(1))
            thus ?thesis by blast
          qed
          have case5: "r1 = r ⟹ r2 = r' ⟹ ?thesis"
          proof (rule subsumes_accessibleI)
            assume "r1 = r" "r2 = r'"
            have "LIDS ((the (s' r2))σ) = LIDS (σ;;τ)" by (simp add: ‹r2 = r'› s'_r')
            also have "... ⊆ LIDS σ ∪ LIDS τ" by auto
            also have "... ⊆ LIDL (the (s' r1))" by (simp add: ‹r1 = r› s'_r)
            also have "... ⊆ doms (the (s' r1))"
              by (metis ‹𝒮G s'› ‹r1 = r› domains_subsume_def domains_subsume_globally_def option.sel s'_r)
            finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
          qed
          have case6: "r1 = r' ⟹ r2 = r ⟹ ?thesis"
          proof (rule subsumes_accessibleI)
            assume "r1 = r'" "r2 = r" "r2 ∈ RIDL (the (s' r1))"
            have "LIDS (the (s' r2)σ) ⊆ LIDL (the (s' r2))" by (simp add: s'_r2 subsetI)
            also have "... ⊆ doms (the (s' r2))"
              using ‹𝒮G s'› domains_subsume_def domains_subsume_globally_def s'_r2 by auto
            also have "... = dom σ ∪ dom τ" by (simp add: ‹r2 = r› s'_r)
            also have "... = dom (σ;;τ)" by (simp add: dom_combination_dom_union)
            finally show " LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))"
              using ‹r1 = r'› s'_r' by auto
          qed
          show ?thesis using case1 case2 case3 case4 case5 case6 fork(1) r1_neq_r2 r1_nor_r2_updated_implies_thesis by fastforce
        next
          case (join σ τ ℰ r' σ' τ' v)
          have "r1 = r ∨ r2 = r" by (metis fun_upd_def join(1) option.simps(3) r1_or_r2_updated s'_r1 s'_r2)
          then show ?thesis
          proof (rule disjE)
            assume "r1 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))"
              proof (cases "r2 ∈ RIDS τ'")
                case r2_in_τ': True
                have "LIDS (the (s' r2)σ) = LIDS (the (s r2)σ)" 
                  by (metis ‹r1 = r› fun_upd_def join(1) option.distinct(1) r1_neq_r2 s'_r2)
                also have "... ⊆ doms (the (s r'))"
                proof -
                  have r2_in_s_r': "r2 ∈ RIDL (the (s r'))" by (simp add: join(3) r2_in_τ')
                  have "𝒜 r' r2 s"
                    by (metis 𝒜G_s ‹r1 = r› domI fun_upd_def join(1) join(3) r1_neq_r2 s'_r2 subsumes_accessible_globally_def)
                  show ?thesis using ‹𝒜 r' r2 s› r2_in_s_r' subsumes_accessible_def by blast
                qed
                also have "... = dom σ' ∪ dom τ'" by (simp add: join(3))
                also have "... ⊆ LIDS σ' ∪ dom τ'" by auto
                also have "... ⊆ dom σ ∪ dom τ ∪ dom τ'"
                proof -
                  have "r' ∈ RIDL (the (s r))" by (simp add: join(2))
                  have "𝒜 r r' s" using 𝒜G_s join(2-3) subsumes_accessible_globally_def by auto
                  show ?thesis using ‹𝒜 r r' s› join(2-3) subsumes_accessible_def by auto
                qed
                also have "... = dom σ ∪ dom (τ;;τ')" by (auto simp add: dom_combination_dom_union)
                also have "... = doms (the (s' r1))" using join by (auto simp add: ‹r1 = r›)
                finally show ?thesis by simp
              next
                case r2_nin_τ': False
                have "LIDS (the (s' r2)σ) = LIDS (the (s r2)σ)" 
                  by (metis ‹r1 = r› fun_upd_def join(1) option.distinct(1) r1_neq_r2 s'_r2)
                also have "... ⊆ doms (the (s r1))"
                proof -
                  have r2_in_s_r1: "r2 ∈ RIDL (the (s r))"
                  proof -
                    have "RIDL (the (s' r1)) = RIDS σ ∪ RIDS (τ;;τ') ∪ RIDC ℰ"
                      by (metis (no_types, lifting) ID_distr_completion(1) ID_distr_local(2) ‹r1 = r› expr.simps(153) fun_upd_apply local.join(1) option.discI option.sel s'_r1 sup_bot.right_neutral val.simps(66))
                    hence "r2 ∈ RIDS σ ∪ RIDS τ ∪ RIDC ℰ" using r2_in_s'_r1 r2_nin_τ' by auto
                    thus ?thesis by (simp add: join(2))
                  qed
                  have "𝒜 r1 r2 s" by (metis (no_types, lifting) 𝒜G_s ‹r1 = r› join(1-2) domIff fun_upd_def option.discI s'_r2 subsumes_accessible_globally_def)
                  show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def ‹r1 = r› by blast
                qed
                also have "... = dom σ ∪ dom τ" by (simp add: ‹r1 = r› join(2))
                also have "... ⊆ dom σ ∪ dom (τ;;τ')" by (auto simp add: dom_combination_dom_union)
                also have "... = doms (the (s' r1))" using join ‹r1 = r› by auto
                finally show ?thesis by simp
              qed
            qed
          next
            assume "r2 = r"
            show "𝒜 r1 r2 s'"
            proof (rule subsumes_accessibleI)
              assume r2_in_s'_r1: "r2 ∈ RIDL (the (s' r1))"
              have "LIDS (the (s' r2)σ) = LIDS (the (s r2)σ)"
                by (metis (no_types, lifting) LID_snapshot.simps fun_upd_apply join(1-2) option.discI option.sel s'_r2)
              also have "... ⊆ doms (the (s r1))"
              proof -
                have r2_in_s_r1: "r2 ∈ RIDL (the (s r1))"
                  by (metis ‹r2 = r› fun_upd_apply local.join(1) option.discI r1_neq_r2 r2_in_s'_r1 s'_r1)
                have "𝒜 r1 r2 s"
                  by (metis (no_types, lifting) 𝒜G_s ‹r2 = r› domIff fun_upd_apply join(1-2) option.discI s'_r1 subsumes_accessible_globally_def)
                show ?thesis using ‹𝒜 r1 r2 s› r2_in_s_r1 subsumes_accessible_def by blast
              qed
              also have "... ⊆ doms (the (s' r1))"
                by (metis ‹r2 = r› eq_refl fun_upd_def local.join(1) option.distinct(1) r1_neq_r2 s'_r1)
              finally show "LIDS (the (s' r2)σ) ⊆ doms (the (s' r1))" by simp
            qed
          qed
        next
          case joinε
          thus ?thesis using s'_r1 by blast
        qed
      qed
      show "𝒜 r1 r2 s'" using r1_nor_r2_updated_implies_thesis r1_or_r2_updated_implies_thesis by blast
    qed
  qed
qed

subsection ‹Relaxed definition of the operational semantics›

inductive revision_step_relaxed :: "'r ⇒ ('r,'l,'v) global_state ⇒ ('r,'l,'v) global_state ⇒ bool" where
  app: "s r = Some (σ, τ, ℰ[Apply (VE (Lambda x e)) (VE v)]) ⟹ revision_step_relaxed r s (s(r ↦ (σ, τ, ℰ[subst (VE v) x e])))"
| ifTrue: "s r = Some (σ, τ, ℰ[Ite (VE (CV T)) e1 e2]) ⟹ revision_step_relaxed r s (s(r ↦ (σ, τ, ℰ[e1])))"
| ifFalse: "s r = Some (σ, τ, ℰ[Ite (VE (CV F)) e1 e2]) ⟹ revision_step_relaxed r s (s(r ↦ (σ, τ, ℰ[e2])))"
(* store operations *)
| new: "s r = Some (σ, τ, ℰ[Ref (VE v)]) ⟹ l ∉ ⋃ { doms ls | ls. ls ∈ ran s } ⟹ revision_step_relaxed r s (s(r ↦ (σ, τ(l ↦ v), ℰ[VE (Loc l)])))"
| get: "s r = Some (σ, τ, ℰ[Read (VE (Loc l))]) ⟹ revision_step_relaxed r s (s(r ↦ (σ, τ, ℰ[VE (the ((σ;;τ) l))])))"
| set: "s r = Some (σ, τ, ℰ[Assign (VE (Loc l)) (VE v)]) ⟹ revision_step_relaxed r s (s(r ↦ (σ, τ(l ↦ v), ℰ[VE (CV Unit)])))"
(* synchronization operations *)
| fork: "s r = Some (σ, τ, ℰ[Rfork e]) ⟹ r' ∉ RIDG s ⟹ revision_step_relaxed r s (s(r ↦ (σ, τ, ℰ[VE (Rid r')]), r' ↦ (σ;;τ, ε, e)))"
| join: "s r = Some (σ, τ, ℰ[Rjoin (VE (Rid r'))]) ⟹ s r' = Some (σ', τ', VE v) ⟹ revision_step_relaxed r s (s(r := Some (σ, (τ;;τ'), ℰ[VE (CV Unit)]), r' := None))"
| joinε: "s r = Some (σ, τ, ℰ[Rjoin (VE (Rid r'))]) ⟹ s r' = None ⟹ revision_step_relaxed r s ε"

inductive_cases revision_step_relaxedE [elim, consumes 1, case_names app ifTrue ifFalse new get set fork join joinε]: 
  "revision_step_relaxed r s s'"

end (* substitution locale *)

end (* theory *)