Theory Renaming

section Renaming

text ‹Similar to the bound variables of lambda calculus, location and revision identifiers are meaningless
  names. This theory contains all of the definitions and results required for renaming data structures
  and proving renaming-equivalence.›

theory Renaming
  imports Occurrences
begin

subsection Definitions

abbreviation rename_val :: "('r ⇒ 'r) ⇒ ('l ⇒ 'l) ⇒ ('r,'l,'v) val ⇒ ('r,'l,'v) val" (‹ℛV›) where
  "ℛV α β v ≡ map_val α β id v"

abbreviation rename_expr :: "('r ⇒ 'r) ⇒ ('l ⇒ 'l) ⇒ ('r,'l,'v) expr ⇒ ('r,'l,'v) expr" (‹ℛE›) where
  "ℛE α β e ≡ map_expr α β id e"

abbreviation rename_cntxt :: "('r ⇒ 'r) ⇒ ('l ⇒ 'l) ⇒ ('r,'l,'v) cntxt ⇒ ('r,'l,'v) cntxt" (‹ℛC›) where
  "ℛC α β ℰ ≡ map_cntxt α β id ℰ"

definition is_store_renaming :: "('r ⇒ 'r) ⇒ ('l ⇒ 'l) ⇒ ('r,'l,'v) store ⇒ ('r,'l,'v) store ⇒ bool" where 
  "is_store_renaming α β σ σ' ≡ ∀l. case σ l of None ⇒ σ' (β l) = None | Some v ⇒ σ' (β l) = Some (ℛV α β v)"

notation Option.bind (infixl ‹⤜› 80)

fun ℛS :: "('r ⇒ 'r) ⇒ ('l ⇒ 'l) ⇒ ('r,'l,'v) store ⇒ ('r,'l,'v) store" where
  "ℛS α β σ l = σ (inv β l) ⤜ (λv. Some (ℛV α β v))"

lemma ℛS_implements_renaming: "bij β ⟹ is_store_renaming α β σ (ℛS α β σ)"
proof -
  assume "bij β"
  hence "inj β" using bij_def by auto
  thus ?thesis by (auto simp add: is_store_renaming_def option.case_eq_if)
qed

fun ℛL :: "('r ⇒ 'r) ⇒ ('l ⇒ 'l) ⇒ ('r,'l,'v) local_state ⇒ ('r,'l,'v) local_state" where
  "ℛL α β (σ,τ,e) = (ℛS α β σ, ℛS α β τ, ℛE α β e)"

definition is_global_renaming :: "('r ⇒ 'r) ⇒ ('l ⇒ 'l) ⇒ ('r,'l,'v) global_state ⇒ ('r,'l,'v) global_state ⇒ bool" where 
  "is_global_renaming α β s s' ≡ ∀r. case s r of None ⇒ s' (α r) = None | Some ls ⇒ s' (α r) = Some (ℛL α β ls)"

fun ℛG :: "('r ⇒ 'r) ⇒ ('l ⇒ 'l) ⇒ ('r,'l,'v) global_state ⇒ ('r,'l,'v) global_state" where
  "ℛG α β s r = s (inv α r) ⤜ (λls. Some (ℛL α β ls))"

lemma ℛG_implements_renaming: "bij α ⟹ is_global_renaming α β s (ℛG α β s)"
proof -
  assume "bij α"
  hence "inj α" using bij_def by auto
  thus ?thesis by (auto simp add: is_global_renaming_def option.case_eq_if)
qed

subsection ‹Introduction rules›

lemma ℛSI [intro]:
  assumes
    bij_β: "bij β" and
    none_case: "⋀l. σ l = None ⟹ σ' (β l) = None" and
    some_case: "⋀l v. σ l = Some v ⟹ σ' (β l) = Some (ℛV α β v)"
  shows
    "ℛS α β σ = σ'"
proof (rule ext, subst ℛS.simps)
  fix l
  show "σ (inv β l) ⤜ (λv. Some (ℛV α β v)) = σ' l" (is "?lhs = σ' l")
  proof (cases "σ (inv β l) = None")
    case True
    have lhs_none: "?lhs = None" by (simp add: True)
    have "σ' (β (inv β l)) = None" by (simp add: none_case True)
    hence rhs_none: "σ' l = None" by (simp add: bij_β bijection.intro bijection.inv_right)
    show ?thesis by (simp add: lhs_none rhs_none)
  next
    case False
    from this obtain v where is_some: "σ (inv β l) = Some v" by blast
    hence lhs_some: "?lhs = Some (ℛV α β v)" by auto
    have "σ' (β (inv β l)) = Some (ℛV α β v)" by (simp add: is_some some_case)
    hence rhs_some: "σ' l = Some (ℛV α β v)" by (simp add: bij_β bijection.intro bijection.inv_right)
    then show ?thesis by (simp add: lhs_some)
  qed
qed

lemma ℛGI [intro]: 
  assumes
    bij_α: "bij α" and
    none_case: "⋀r. s r = None ⟹ s' (α r) = None" and
    some_case: "⋀r σ τ e. s r = Some (σ,τ,e) ⟹ s' (α r) = Some (ℛL α β (σ,τ,e))"
  shows
    "ℛG α β s = s'"
proof (rule ext, subst ℛG.simps)
  fix r
  show "s (inv α r) ⤜ (λls. Some (ℛL α β ls)) = s' r" (is "?lhs = s' r")
  proof (cases "s (inv α r) = None")
    case True
    have lhs_none: "?lhs = None" by (simp add: True)
    have "s' (α (inv α r)) = None" by (simp add: none_case True)
    hence rhs_none: "s' r = None" by (simp add: bij_α bijection.intro bijection.inv_right)
    show ?thesis by (simp add: lhs_none rhs_none)
  next
    case False
    from this obtain ls where "s (inv α r) = Some ls" by blast
    from this obtain σ τ e where is_some: "s (inv α r) = Some (σ, τ, e)" by (cases ls) blast
    hence lhs_some: "?lhs = Some (ℛL α β (σ, τ, e))" by auto
    have "s' (α (inv α r)) = Some (ℛL α β (σ, τ, e))" by (simp add: is_some some_case)
    hence rhs_some: "s' r = Some (ℛL α β (σ, τ, e))" by (simp add: bij_α bijection.intro bijection.inv_right)
    then show ?thesis by (simp add: lhs_some)
  qed
qed

subsection ‹Renaming-equivalence›

subsubsection Identity

declare val.map_id [simp]
declare expr.map_id [simp]
declare cntxt.map_id [simp]
lemma ℛS_id [simp]: "ℛS id id σ = σ" by auto
lemma ℛL_id [simp]: "ℛL id id ls = ls" by (cases ls) simp
lemma ℛG_id [simp]: "ℛG id id s = s" by auto

subsubsection Composition

declare val.map_comp [simp]
declare expr.map_comp [simp]
declare cntxt.map_comp [simp]
lemma ℛS_comp [simp]: "⟦ bij β; bij β' ⟧ ⟹ ℛS α' β' (ℛS α β s) = ℛS (α' ∘ α) (β' ∘ β) s"
  by (auto simp add: o_inv_distrib)
lemma ℛL_comp [simp]: "⟦ bij β; bij β' ⟧ ⟹ ℛL α' β' (ℛL α β ls) = ℛL (α' ∘ α) (β' ∘ β) ls"
  by (cases ls) simp
lemma ℛG_comp [simp]: "⟦ bij α; bij α'; bij β; bij β' ⟧ ⟹ ℛG α' β' (ℛG α β s) = ℛG (α' ∘ α) (β' ∘ β) s"
  by (rule ext) (auto simp add: o_inv_distrib)

subsubsection Inverse

lemma ℛV_inv [simp]: "⟦ bij α; bij β ⟧ ⟹ (ℛV (inv α) (inv β) v' = v) = (ℛV α β v = v')"
  by (auto simp add: bijection.intro bijection.inv_comp_right bijection.inv_comp_left)
lemma ℛE_inv [simp]: "⟦ bij α; bij β ⟧ ⟹ (ℛE (inv α) (inv β) e' = e) = (ℛE α β e = e')"
  by (auto simp add: bijection.intro bijection.inv_comp_right bijection.inv_comp_left)
lemma ℛC_inv [simp]: "⟦ bij α; bij β ⟧ ⟹ (ℛC (inv α) (inv β) ℰ' = ℰ) = (ℛC α β ℰ = ℰ')"
  by (auto simp add: bijection.intro bijection.inv_comp_right bijection.inv_comp_left)
lemma ℛS_inv [simp]: "⟦ bij α; bij β ⟧ ⟹ (ℛS (inv α) (inv β) σ' = σ) = (ℛS α β σ = σ')"
  by (auto simp add: bij_imp_bij_inv bijection.intro bijection.inv_comp_right bijection.inv_comp_left)
lemma ℛL_inv [simp]: "⟦ bij α; bij β ⟧ ⟹ (ℛL (inv α) (inv β) ls' = ls) = (ℛL α β ls = ls')"
  by (auto simp add: bij_imp_bij_inv bijection.intro bijection.inv_comp_right bijection.inv_comp_left)
lemma ℛG_inv [simp]: "⟦ bij α; bij β ⟧ ⟹ (ℛG (inv α) (inv β) s' = s) = (ℛG α β s = s')"
  by (auto simp add: bij_imp_bij_inv bijection.intro bijection.inv_comp_right bijection.inv_comp_left)

subsubsection Equivalence

definition eq_states :: "('r,'l,'v) global_state ⇒ ('r,'l,'v) global_state ⇒ bool" (‹_ ≈ _› [100, 100]) where
  "s ≈ s' ≡ ∃α β. bij α ∧ bij β ∧ ℛG α β s = s'"

lemma eq_statesI [intro]:
  "ℛG α β s = s' ⟹ bij α ⟹ bij β ⟹ s ≈ s'"
  using eq_states_def by auto

lemma eq_statesE [elim]:
  "s ≈ s' ⟹ (⋀α β. ℛG α β s = s' ⟹ bij α ⟹ bij β ⟹ P) ⟹ P"
  using eq_states_def by blast

lemma αβ_refl: "s ≈ s" by (rule eq_statesI[of id id s]) auto
 
lemma αβ_trans: "s ≈ s' ⟹ s' ≈ s'' ⟹ s ≈ s''"
proof -
  assume "s ≈ s'"
  from this obtain α β where s_s': "bij α" "bij β" "ℛG α β s = s'" by blast
  assume "s' ≈ s''"
  from this obtain α' β' where s'_s'': "bij α'" "bij β'" "ℛG α' β' s' = s''" by blast
  show "s ≈ s''" by (rule eq_statesI[of "α' ∘ α" "β' ∘ β"]) (use s_s' s'_s'' in ‹auto simp add: bij_comp›)
qed

lemma αβ_sym: "s ≈ s' ⟹ s' ≈ s"
proof -
  assume "s ≈ s'"
  from this obtain α β where s_s': "bij α" "bij β" "ℛG α β s = s'" by blast
  show "s' ≈ s" by (rule eq_statesI[of "inv α" "inv β"]) (use s_s' in ‹auto simp add: bij_imp_bij_inv›)
qed

subsection ‹Distributive laws›

subsubsection Expression

lemma renaming_distr_completion [simp]:
  "ℛE α β (ℰ[e]) = ((ℛC α β ℰ)[ℛE α β e])"
  by (induct ℰ) simp+

subsubsection Store

lemma renaming_distr_combination [simp]: 
  "ℛS α β (σ;;τ) = (ℛS α β σ;;ℛS α β τ)"
  by (rule ext) auto

lemma renaming_distr_store [simp]:
  "bij β ⟹ ℛS α β (σ(l ↦ v)) = (ℛS α β σ)(β l ↦ ℛV α β v)"
  by (auto simp add: bijection.intro bijection.inv_left_eq_iff)

(* distribution law for local follows from the definition *)

subsubsection Global 

lemma renaming_distr_global [simp]:
  "bij α ⟹ ℛG α β (s(r ↦ ls)) = (ℛG α β s)(α r ↦ ℛL α β ls)"
  "bij α ⟹ ℛG α β (s(r := None)) = (ℛG α β s)(α r := None)"
  by (auto simp add: bijection.intro bijection.inv_left_eq_iff)

subsection ‹Miscellaneous laws›

lemma rename_empty [simp]:
  "ℛS α β ε = ε"
  "ℛG α β ε = ε"
  by auto

subsection Swaps

lemma swap_bij: 
  "bij (id(x := x', x' := x))" (is "bij ?f")
proof (rule bijI)
  show "inj ?f" by (simp add: inj_on_def)
  show "surj ?f"
  proof
    show "UNIV ⊆ range (id(x := x', x' := x))"
    proof (rule subsetI)
      fix y
      assume "y ∈ (UNIV :: 'a set)"
      show "y ∈ range (id(x := x', x' := x))" by (cases "y = x"; cases "y = x'") auto
    qed
  qed simp
qed

lemma id_trivial_update [simp]: "id(x := x) = id" by auto (* for solving trivial peaks *)

lemma eliminate_renaming_val_expr [simp]:
  fixes
    v :: "('r,'l,'v) val" and
    e :: "('r,'l,'v) expr"
  shows
    "l ∉ LIDV v ⟹ ℛV α (β(l := l')) v = ℛV α β v"
    "l ∉ LIDE e ⟹ ℛE α (β(l := l')) e = ℛE α β e"
    "r ∉ RIDV v ⟹ ℛV (α(r := r')) β v = ℛV α β v"
    "r ∉ RIDE e ⟹ ℛE (α(r := r')) β e = ℛE α β e"
proof -
  have "(∀α β r r'. r ∉ RIDV v ⟶ ℛV (α(r := r')) β v = ℛV α β v) ∧
    (∀α β r r'. r ∉ RIDE e ⟶ ℛE (α(r := r')) β e = ℛE α β e)"
    by (induct rule: val_expr.induct) simp+
  thus 
    "r ∉ RIDV v ⟹ ℛV (α(r := r')) β v = ℛV α β v" 
    "r ∉ RIDE e ⟹ ℛE (α(r := r')) β e = ℛE α β e"
    by simp+
  have "(∀α β l l'. l ∉ LIDV v ⟶ ℛV α (β(l := l')) v = ℛV α β v) ∧
    (∀α β l l'. l ∉ LIDE e ⟶ ℛE α (β(l := l')) e = ℛE α β e)"
    by (induct rule: val_expr.induct) simp+
  thus 
    "l ∉ LIDV v ⟹ ℛV α (β(l := l')) v = ℛV α β v" and
    "l ∉ LIDE e ⟹ ℛE α (β(l := l')) e = ℛE α β e"
    by simp+
qed

lemma eliminate_renaming_cntxt [simp]:
  "r ∉ RIDC ℰ ⟹ ℛC (α(r := r')) β ℰ = ℛC α β ℰ"
  "l ∉ LIDC ℰ ⟹ ℛC α (β(l := l')) ℰ = ℛC α β ℰ"
  by (induct ℰ rule: cntxt.induct) auto

lemma eliminate_swap_val [simp, intro]:
  "r ∉ RIDV v ⟹ r' ∉ RIDV v ⟹ ℛV (id(r := r', r' := r)) id v = v"
  "l ∉ LIDV v ⟹ l' ∉ LIDV v ⟹ ℛV id (id(l := l', l' := l)) v = v"
  by simp+

lemma eliminate_swap_expr [simp, intro]:
  "r ∉ RIDE e ⟹ r' ∉ RIDE e ⟹ ℛE (id(r := r', r' := r)) id e = e"
  "l ∉ LIDE e ⟹ l' ∉ LIDE e ⟹ ℛE id (id(l := l', l' := l)) e = e"
  by simp+

lemma eliminate_swap_cntxt [simp, intro]:
  "r ∉ RIDC ℰ ⟹ r' ∉ RIDC ℰ ⟹ ℛC (id(r := r', r' := r)) id ℰ = ℰ"
  "l ∉ LIDC ℰ ⟹ l' ∉ LIDC ℰ ⟹ ℛC id (id(l := l', l' := l)) ℰ = ℰ"
  by simp+

lemma eliminate_swap_store_rid [simp, intro]:
  "r ∉ RIDS σ ⟹ r' ∉ RIDS σ ⟹ ℛS (id(r := r', r' := r)) id σ = σ"
  by (rule ℛSI) (auto simp add: swap_bij RIDS_def domIff ranI)

lemma eliminate_swap_store_lid [simp, intro]:
  "l ∉ LIDS σ ⟹ l' ∉ LIDS σ ⟹ ℛS id (id(l := l', l' := l)) σ = σ"
  by (rule ℛSI) (auto simp add: swap_bij LIDS_def domIff ranI)

lemma eliminate_swap_global_rid [simp, intro]:
  "r ∉ RIDG s ⟹ r' ∉ RIDG s ⟹ ℛG (id(r := r', r' := r)) id s = s"
  by (rule ℛGI[OF swap_bij], ((rule sym, auto)[1])+)

lemma eliminate_swap_global_lid [simp, intro]:
  "l ∉ LIDG s ⟹ l' ∉ LIDG s ⟹ ℛG id (id(l := l', l' := l)) s = s"
  by (rule ℛGI) (auto simp add: ID_distr_global_conditional)

end