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 *)