Theory Substitution

section Substitution

text ‹This theory introduces the substitution operation using a locale, and provides two models.›

theory Substitution
  imports Renaming
begin

subsection Definition

locale substitution =
  fixes subst :: "('r,'l,'v) expr  'v  ('r,'l,'v) expr  ('r,'l,'v) expr"
  assumes 
    renaming_distr_subst: "E α β (subst e x e') = subst (E α β e) x (E α β e')" and (* needed in mimicking *)
    subst_introduces_no_rids: "RIDE (subst e x e')  RIDE e  RIDE e'" and
    subst_introduces_no_lids: "LIDE (subst e x e')  LIDE e  LIDE e'"
begin

lemma rid_substE [dest]: "r  RIDE (subst (VE v) x e)  r  RIDE e  r  RIDV v"
  using subst_introduces_no_rids by fastforce

lemma lid_substE [dest]: "l  LIDE (subst (VE v) x e)  l  LIDE e  l  LIDV v"
  using subst_introduces_no_lids by fastforce

end (* substitution locale *)

subsection ‹Trivial model›

fun constant_function :: "('r,'l,'v) expr  'v  ('r,'l,'v) expr  ('r,'l,'v) expr" where 
  "constant_function e x e' = VE (CV Unit)"

lemma constant_function_models_substitution: 
  "substitution constant_function" by (auto simp add: substitution_def)

subsection ‹Example model›

subsubsection Preliminaries

notation set3_val (𝒱V)
notation set3_expr (𝒱E)

abbreviation rename_vars_val :: "('v  'v)  ('r,'l,'v) val  ('r,'l,'v) val" (ℛ𝒱V) where
  "ℛ𝒱V ζ  map_val id id ζ"

abbreviation rename_vars_expr :: "('v  'v)  ('r,'l,'v) expr  ('r,'l,'v) expr" (ℛ𝒱E) where
  "ℛ𝒱E ζ  map_expr id id ζ"

lemma var_renaming_preserves_size: (* for termination proof *)
  fixes 
    v :: "('r,'l,'v) val" and
    e :: "('r,'l,'v) expr" and
    α :: "'r  'r'" and
    β :: "'l  'l'" and
    ζ :: "'v  'v'"
  shows
  "size (map_val α β ζ v) = size v"
  "size (map_expr α β ζ e) = size e"
proof -
  have "((α :: 'r  'r') (β :: 'l  'l') (ζ :: 'v  'v'). size (map_val α β ζ v) = size v)  
        ((α :: 'r  'r') (β :: 'l  'l') (ζ :: 'v  'v'). size (map_expr α β ζ e) = size e)"
    by (induct rule: val_expr.induct) auto
  thus 
    "size (map_val α β ζ v) = size v" 
    "size (map_expr α β ζ e) = size e" 
    by auto
qed

subsubsection Definition

function
  nat_substV :: "('r,'l,nat) expr  nat  ('r,'l,nat) val  ('r,'l,nat) expr" and
  nat_substE :: "('r,'l,nat) expr  nat  ('r,'l,nat) expr  ('r,'l,nat) expr"
  where
  "nat_substV e x (CV const) = VE (CV const)"
| "nat_substV e x (Var x') = (if x = x' then e else VE (Var x'))"
| "nat_substV e x (Loc l) = VE (Loc l)"
| "nat_substV e x (Rid r) = VE (Rid r)"
| "nat_substV e x (Lambda y e') = VE (
  if x = y then 
    Lambda y e' 
  else 
    let z = Suc (Max (𝒱E e'  𝒱E e)) in
    Lambda z (nat_substE e x (ℛ𝒱E (id(y := z)) e')))"
| "nat_substE e x (VE v') = nat_substV e x v'"
| "nat_substE e x (Apply l r) = Apply (nat_substE e x l) (nat_substE e x r)"
| "nat_substE e x (Ite e1 e2 e3) = Ite (nat_substE e x e1) (nat_substE e x e2) (nat_substE e x e3)"
| "nat_substE e x (Ref e') = Ref (nat_substE e x e')"
| "nat_substE e x (Read e') = Read (nat_substE e x e')"
| "nat_substE e x (Assign l r) = Assign (nat_substE e x l) (nat_substE e x r)"
| "nat_substE e x (Rfork e') = Rfork (nat_substE e x e')"
| "nat_substE e x (Rjoin e')  = Rjoin (nat_substE e x e')"
  by pat_completeness auto
termination 
  by (relation "measure (λx. case x of Inl (e,x,v)  size v | Inr (e,x,e')  size e')")
     (auto simp add: var_renaming_preserves_size(2))

subsubsection ‹Proof obligations›

lemma nat_substE_distr:
  fixes e :: "('r,'l,nat) expr"
  shows "E α β (nat_substE e x e') = nat_substE (E α β e) x (E α β e')"
proof -
  fix v' :: "('r,'l,nat) val"
  have
    "(α β x e ζ. E α β (nat_substV e x (ℛ𝒱V ζ v')) = nat_substV (E α β e) x (V α β (ℛ𝒱V ζ v'))) 
     (α β x e ζ. E α β (nat_substE e x (ℛ𝒱E ζ e')) = nat_substE (E α β e) x (E α β (ℛ𝒱E ζ e')))"
    by (induct rule: val_expr.induct) (auto simp add: expr.set_map(3) fun.map_ident)
  hence "E α β (nat_substE e x (ℛ𝒱E id e')) = nat_substE (E α β e) x (E α β (ℛ𝒱E id e'))" by blast
  thus ?thesis by simp
qed

lemma nat_substE_introduces_no_rids:
  fixes e' :: "('r,'l,nat) expr"
  shows "RIDE (nat_substE e x e')  RIDE e  RIDE e'"
proof -
  fix v' :: "('r,'l,nat) val"
  have 
    "(x e. ζ. RIDE (nat_substV e x (ℛ𝒱V ζ v'))  RIDE e  RIDV (ℛ𝒱V ζ v')) 
     (x e. ζ. RIDE (nat_substE e x (ℛ𝒱E ζ e'))  RIDE e  RIDE (ℛ𝒱E ζ e'))"
    by (induct rule: val_expr.induct) (auto 0 4 simp add: expr.set_map(1))
  hence "RIDE (nat_substE e x (ℛ𝒱E id e'))  RIDE e  RIDE (ℛ𝒱E id e')" by blast
  thus ?thesis by simp
qed

lemma nat_substE_introduces_no_lids: 
  fixes e' :: "('r,'l,nat) expr"
  shows "LIDE (nat_substE e x e')  LIDE e  LIDE e'"
proof -
  fix v' :: "('r,'l,nat) val"
  have 
    "(x e. ζ. LIDE (nat_substV e x (ℛ𝒱V ζ v'))  LIDE e  LIDV (ℛ𝒱V ζ v')) 
     (x e. ζ. LIDE (nat_substE e x (ℛ𝒱E ζ e'))  LIDE e  LIDE (ℛ𝒱E ζ e'))"
    by (induct rule: val_expr.induct) (auto 0 4 simp add: expr.set_map(2))
  hence "LIDE (nat_substE e x (ℛ𝒱E id e'))  LIDE e  LIDE (ℛ𝒱E id e')" by blast
  thus ?thesis by simp
qed

lemma nat_substE_models_substitution: "substitution nat_substE"
  by (simp add: nat_substE_distr nat_substE_introduces_no_lids nat_substE_introduces_no_rids substitution_def)

end