Theory TypedSigma
section ‹First Order Types for Sigma terms›
theory TypedSigma imports "../preliminary/Environments" Sigma begin
subsubsection ‹Types and typing rules›
text‹The inductive definition of the typing relation.›
definition
return :: "(type × type) ⇒ type" where
"return a = fst a"
definition
param :: "(type × type) ⇒ type" where
"param a = snd a"
primrec
do :: "type ⇒ (Label set)"
where
"do (Object l) = (dom l)"
primrec
type_get :: "type ⇒ Label ⇒ (type × type) option " ("_^_" 1000)
where
"(Object l)^n = (l n)"
inductive
typing :: "(type environment) ⇒ sterm ⇒ type ⇒ bool"
("_ ⊢ _ : _" [80, 0, 80] 230)
where
T_Var[intro!]:
"⟦ ok env; x ∈ env_dom env; (the (env!x)) = T ⟧
⟹ env ⊢ (Fvar x) : T"
| T_Obj[intro!]:
"⟦ ok env; dom b = do A; finite F;
∀l∈do A. ∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p
⟶ env⦇s:A⦈⦇p:param(the (A^l))⦈
⊢ (the (b l)⇗[Fvar s,Fvar p]⇖) : return(the (A^l)) ⟧
⟹ env ⊢ (Obj b A) : A"
| T_Upd[intro!]:
"⟦ finite F;
∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p
⟶ env⦇s:A⦈⦇p:param(the (A^l))⦈
⊢ (n⇗[Fvar s,Fvar p]⇖) : return(the (A^l));
env ⊢ a : A; l ∈ do A ⟧ ⟹ env ⊢ Upd a l n : A"
| T_Call[intro!]:
"⟦ env ⊢ a : A; env ⊢ b : param(the (A^l)); l ∈ do A ⟧
⟹ env ⊢ (Call a l b) : return(the (A^l))"
inductive_cases typing_elims [elim!]:
"e ⊢ Obj b T : T"
"e ⊢ Fvar x : T"
"e ⊢ Call a l b : T"
"e ⊢ Upd a l n : T"
subsubsection ‹Basic lemmas›
text‹Basic treats of the type system.›
lemma not_bvar: "e ⊢ t : T ⟹ ∀i. t ≠ Bvar i"
by (erule typing.cases, simp_all)
lemma typing_regular': "e ⊢ t : T ⟹ ok e"
by (induct rule:typing.induct, auto)
lemma typing_regular'': "e ⊢ t : T ⟹ lc t"
by (induct rule:typing.induct, auto)
theorem typing_regular: "e ⊢ t : T ⟹ ok e ∧ lc t"
by (simp add: typing_regular' typing_regular'')
lemma obj_inv: "e ⊢ Obj f U : A ⟹ A = U"
by (erule typing.cases, auto)
lemma obj_inv_elim:
"e ⊢ Obj f U : U
⟹ (dom f = do U)
∧ (∃F. finite F ∧ (∀l∈do U. ∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p
⟶ e⦇s:U⦈⦇p:param(the U^l)⦈
⊢ (the (f l)⇗[Fvar s,Fvar p]⇖) : return(the (U^l))))"
by (erule typing.cases, simp_all, blast)
lemma typing_induct[consumes 1, case_names Fvar Call Upd Obj Bnd]:
fixes
env :: "type environment" and t :: sterm and T :: type and
P1 :: "type environment ⇒ sterm ⇒ type ⇒ bool" and
P2 :: "type environment ⇒ sterm ⇒ type ⇒ Label ⇒ bool"
assumes
"env ⊢ t : T" and
"⋀env T x. ⟦ ok env; x ∈ env_dom env; the env!x = T ⟧
⟹ P1 env (Fvar x) T" and
"⋀env T t l p. ⟦ env ⊢ t : T; P1 env t T; env ⊢ p : param (the(T^l));
P1 env p (param (the(T^l))); l ∈ do T ⟧
⟹ P1 env (Call t l p) (return (the(T^l)))" and
"⋀env T t l u. ⟦ env ⊢ t : T; P1 env t T; l ∈ do T; P2 env u T l ⟧
⟹ P1 env (Upd t l u) T" and
"⋀env T f. ⟦ ok env; dom f = do T; ∀l∈dom f. P2 env (the(f l)) T l ⟧
⟹ P1 env (Obj f T) T" and
"⋀env T l t L. ⟦ ok env; finite L;
∀s p. s ∉ L ∧ p ∉ L ∧ s ≠ p
⟶ env⦇s:T⦈⦇p:param (the(T^l))⦈
⊢ (t⇗[Fvar s, Fvar p]⇖) : return (the(T^l))
∧ P1 (env⦇s:T⦈⦇p:param (the(T^l))⦈) (t⇗[Fvar s, Fvar p]⇖)
(return (the(T^l))) ⟧
⟹ P2 env t T l"
shows
"P1 env t T"
using assms by (induct rule: typing.induct, auto simp: typing_regular')
lemma ball_Tltsp:
fixes
P1 :: "type ⇒ Label ⇒ sterm ⇒ string ⇒ string ⇒ bool" and
P2 :: "type ⇒ Label ⇒ sterm ⇒ string ⇒ string ⇒ bool"
assumes
"⋀l t t'. ⟦ ∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p ⟶ P1 T l t s p ⟧
⟹ ∀s p. s ∉ F' ∧ p ∉ F' ∧ s ≠ p ⟶ P2 T l t s p" and
"∀l∈do T. ∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p ⟶ P1 T l (the(f l)) s p"
shows "∀l∈do T. ∀s p. s ∉ F' ∧ p ∉ F' ∧ s ≠ p ⟶ P2 T l (the(f l)) s p"
proof
fix l assume "l ∈ do T"
with assms(2)
have "∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p ⟶ P1 T l (the(f l)) s p"
by simp
with assms(1)
show "∀s p. s ∉ F' ∧ p ∉ F' ∧ s ≠ p ⟶ P2 T l (the(f l)) s p"
by simp
qed
lemma ball_ex_finite:
fixes
S :: "'a set" and F :: "'b set" and x :: 'a and
P :: "'a ⇒ 'b ⇒ 'b ⇒ bool"
assumes
"finite S" and "finite F" and
"∀x∈S. (∃F'. finite F'
∧ (∀s p. s ∉ F' ∪ F ∧ p ∉ F' ∪ F ∧ s ≠ p
⟶ P x s p))"
shows
"∃F'. finite F'
∧ (∀x∈S. ∀s p. s ∉ F' ∪ F ∧ p ∉ F' ∪ F ∧ s ≠ p
⟶ P x s p)"
proof -
from assms show ?thesis
proof (induct S)
case empty thus ?case by force
next
case (insert x S)
from insert(5)
have
"∀y∈S. (∃F'. finite F'
∧ (∀s p. s ∉ F' ∪ F ∧ p ∉ F' ∪ F ∧ s ≠ p
⟶ P y s p))"
by simp
from insert(3)[OF ‹finite F› this]
obtain F1 where
"finite F1" and
pred_S: "∀y∈S. ∀s p. s ∉ F1 ∪ F ∧ p ∉ F1 ∪ F ∧ s ≠ p
⟶ P y s p"
by auto
from insert(5)
obtain F2 where
"finite F2" and
"∀s p. s ∉ F2 ∪ F ∧ p ∉ F2 ∪ F ∧ s ≠ p ⟶ P x s p"
by auto
with pred_S have
"∀y∈insert x S. ∀s p. s ∉ F1 ∪ F2 ∪ F ∧ p ∉ F1 ∪ F2 ∪ F ∧ s ≠ p
⟶ P y s p"
by auto
moreover
from ‹finite F1› ‹finite F2› have "finite (F1 ∪ F2)" by simp
ultimately
show ?case by blast
qed
qed
lemma bnd_renaming_lem:
assumes
"s ∉ FV t'" and "p ∉ FV t'" and "x ∉ FV t'" and "y ∉ FV t'" and
"x ∉ env_dom env'" and "y ∉ env_dom env'" and "s ≠ p" and "x ≠ y" and
"t = {Suc n → [Fvar s, Fvar p]} t'" and "env = env'⦇s:A⦈⦇p:B⦈" and
pred_bnd:
"∀sa pa. sa ∉ F ∧ pa ∉ F ∧ sa ≠ pa
⟶ env⦇sa:T⦈⦇pa:param(the(T^l))⦈ ⊢ (t⇗[Fvar sa,Fvar pa]⇖) : return(the(T^l))
∧ (∀env'' t'' s' p' x' y' A' B' n'.
s' ∉ FV t'' ⟶ p' ∉ FV t'' ⟶ x' ∉ FV t'' ⟶ y' ∉ FV t'' ⟶
x' ∉ env_dom env'' ⟶ y' ∉ env_dom env'' ⟶ x' ≠ y' ⟶ s' ≠ p'
⟶ (t⇗[Fvar sa,Fvar pa]⇖) = {n' → [Fvar s',Fvar p']} t''
⟶ env⦇sa:T⦈⦇pa:param(the(T^l))⦈ = env''⦇s':A'⦈⦇p':B'⦈
⟶ env''⦇x':A'⦈⦇y':B'⦈
⊢ {n' → [Fvar x',Fvar y']} t'' : return(the(T^l)))" and
"FV t' ⊆ F'"
shows
"∀sa pa. sa ∉ F ∪ {s,p,x,y} ∪ F' ∪ env_dom env'
∧ pa ∉ F ∪ {s,p,x,y} ∪ F' ∪ env_dom env'
∧ sa ≠ pa
⟶ env'⦇x:A⦈⦇y:B⦈⦇sa:T⦈⦇pa:param(the(T^l))⦈
⊢ ({Suc n → [Fvar x, Fvar y]} t'⇗[Fvar sa,Fvar pa]⇖) : return (the(T^l))"
proof (intro strip, elim conjE)
fix sa pa
assume
nin_sa: "sa ∉ F ∪ {s,p,x,y} ∪ F' ∪ env_dom env'" and
nin_pa: "pa ∉ F ∪ {s,p,x,y} ∪ F' ∪ env_dom env'" and "sa ≠ pa"
hence "sa ∉ F ∧ pa ∉ F ∧ sa ≠ pa" by auto
moreover
{
fix a assume "a ∉ FV t'" and "a ∈ {s,p,x,y}"
with
‹FV t' ⊆ F'› nin_sa nin_pa ‹sa ≠ pa›
sopen_FV[of 0 "Fvar sa" "Fvar pa" t']
have "a ∉ FV (t'⇗[Fvar sa,Fvar pa]⇖)" by (auto simp: openz_def)
} note
this[OF ‹s ∉ FV t'›] this[OF ‹p ∉ FV t'›]
this[OF ‹x ∉ FV t'›] this[OF ‹y ∉ FV t'›]
moreover
from
not_in_env_bigger_2[OF ‹x ∉ env_dom env'›]
not_in_env_bigger_2[OF ‹y ∉ env_dom env'›]
nin_sa nin_pa
have
"x ∉ env_dom (env'⦇sa:T⦈⦇pa:param(the(T^l))⦈)
∧ y ∉ env_dom (env'⦇sa:T⦈⦇pa:param(the(T^l))⦈)" by auto
moreover
from ‹t = {Suc n → [Fvar s, Fvar p]} t'› sopen_commute[OF Suc_not_Zero]
have "(t⇗[Fvar sa,Fvar pa]⇖) = {Suc n → [Fvar s,Fvar p]} (t'⇗[Fvar sa,Fvar pa]⇖)"
by (auto simp: openz_def)
moreover
from
subst_add[of s sa env' A T] subst_add[of sa p "env'⦇s:A⦈" T B]
subst_add[of s pa "env'⦇sa:T⦈" A "param(the(T^l))"]
subst_add[of p pa "env'⦇sa:T⦈⦇s:A⦈" B "param(the(T^l))"]
‹env = env'⦇s:A⦈⦇p:B⦈› nin_sa nin_pa
have "env⦇sa:T⦈⦇pa:param(the(T^l))⦈ = env'⦇sa:T⦈⦇pa:param(the(T^l))⦈⦇s:A⦈⦇p:B⦈"
by auto
ultimately
have
"env'⦇sa:T⦈⦇pa:param(the T^l)⦈⦇x:A⦈⦇y:B⦈
⊢ {Suc n → [Fvar x, Fvar y]} (t'⇗[Fvar sa,Fvar pa]⇖) : return(the(T^l))"
using ‹s ≠ p› ‹x ≠ y› pred_bnd by auto
moreover
from
subst_add[of y sa "env'⦇x:A⦈" B T] subst_add[of x sa env' A T]
subst_add[of y pa "env'⦇sa:T⦈⦇x:A⦈" B "param(the(T^l))"]
subst_add[of x pa "env'⦇sa:T⦈" A "param(the(T^l))"]
nin_sa nin_pa
have
"env'⦇x:A⦈⦇y:B⦈⦇sa:T⦈⦇pa:param(the(T^l))⦈
= env'⦇sa:T⦈⦇pa:param(the(T^l))⦈⦇x:A⦈⦇y:B⦈"
by auto
ultimately
show
"env'⦇x:A⦈⦇y:B⦈⦇sa:T⦈⦇pa:param(the(T^l))⦈
⊢ ({Suc n → [Fvar x, Fvar y]} t'⇗[Fvar sa,Fvar pa]⇖) : return (the(T^l))"
using sopen_commute[OF not_sym[OF Suc_not_Zero]]
by (simp add: openz_def)
qed
lemma type_renaming'[rule_format]:
"e ⊢ t : C ⟹
(⋀env t' s p x y A B n. ⟦ s ∉ FV t'; p ∉ FV t'; x ∉ FV t'; y ∉ FV t';
x ∉ env_dom env; y ∉ env_dom env; s ≠ p; x ≠ y;
t = {n → [Fvar s,Fvar p]} t'; e = env⦇s:A⦈⦇p:B⦈ ⟧
⟹ env⦇x:A⦈⦇y:B⦈ ⊢ {n → [Fvar x,Fvar y]} t' : C)"
proof (induct set:typing)
case (T_Call env t1 T t2 l env' t' s p x y A B n)
with sopen_eq_Call[OF sym[OF ‹Call t1 l t2 = {n → [Fvar s,Fvar p]} t'›]]
show ?case by auto
next
case (T_Var env a T env' t' s p x y A B n)
from ‹ok env› ‹env = env'⦇s:A⦈⦇p:B⦈› ok_add_2[of env' s A p B]
have "ok env'" by simp
from
ok_add_ok[OF ok_add_ok[OF this ‹x ∉ env_dom env'›]
not_in_env_bigger[OF ‹y ∉ env_dom env'› not_sym[OF ‹x ≠ y›]]]
have ok: "ok (env'⦇x:A⦈⦇y:B⦈)" by assumption
from sopen_eq_Fvar[OF sym[OF ‹Fvar a = {n → [Fvar s,Fvar p]} t'›]]
show ?case
proof (elim disjE conjE)
assume "t' = Fvar a" with T_Var(4-7)
obtain "a ≠ s" and "a ≠ p" and "a ≠ x" and "a ≠ y" by auto
note in_env_smaller2[OF _ this(1-2)]
from ‹a ∈ env_dom env› ‹env = env'⦇s:A⦈⦇p:B⦈› this[of env' A B]
have "a ∈ env_dom env'" by simp
from env_bigger2[OF ‹x ∉ env_dom env'› ‹y ∉ env_dom env'› this ‹x ≠ y›]
have inenv: "a ∈ env_dom (env'⦇x:A⦈⦇y:B⦈)" by assumption
note get_env_bigger2[OF _ ‹a ≠ s› ‹a ≠ p›]
from
this[of env' A B] ‹a ∈ env_dom env› ‹the env!a = T›
‹env = env'⦇s:A⦈⦇p:B⦈› get_env_bigger2[OF inenv ‹a ≠ x› ‹a ≠ y›]
have "the (env'⦇x:A⦈⦇y:B⦈!a) = T" by simp
from typing.T_Var[OF ok inenv this] ‹t' = Fvar a› show ?case by simp
next
assume "a = s" and "t' = Bvar (Self n)"
from
this(1) ‹ok env› ‹env = env'⦇s:A⦈⦇p:B⦈› ‹the env!a = T›
add_get2_1[of env' s A p B]
have "T = A" by simp
moreover
from ‹t' = Bvar (Self n)› have "{n → [Fvar x,Fvar y]} t' = Fvar x" by simp
ultimately
show ?case using in_add_2[OF ok] typing.T_Var[OF ok _ add_get2_1[OF ok]]
by simp
next
note subst = subst_add[OF ‹x ≠ y›]
from subst[of env' A B] ok have ok': "ok (env'⦇y:B⦈⦇x:A⦈)" by simp
assume "a = p" and "t' = Bvar (Param n)"
from
this(1) ‹ok env› ‹env = env'⦇s:A⦈⦇p:B⦈› ‹the env!a = T›
add_get2_2[of env' s A p B]
have "T = B" by simp
moreover
from ‹t' = Bvar (Param n)› have "{n → [Fvar x,Fvar y]} t' = Fvar y" by simp
ultimately
show ?case
using
subst[of env' A B] in_add_2[OF ok']
typing.T_Var[OF ok' _ add_get2_1[OF ok']]
by simp
qed
next
case (T_Upd F env T l t2 t1 env' t' s p x y A B n)
from sopen_eq_Upd[OF sym[OF ‹Upd t1 l t2 = {n → [Fvar s,Fvar p]} t'›]]
obtain t1' t2' where
t1: "t1 = {n → [Fvar s,Fvar p]} t1'" and
t2: "t2 = {Suc n → [Fvar s,Fvar p]} t2'" and
t': "t' = Upd t1' l t2'"
by auto
{ fix a assume "a ∉ FV t'" with t' have "a ∉ FV t1'" by simp }
note
t1' = T_Upd(4)[OF this[OF ‹s ∉ FV t'›] this[OF ‹p ∉ FV t'›]
this[OF ‹x ∉ FV t'›] this[OF ‹y ∉ FV t'›]
‹x ∉ env_dom env'› ‹y ∉ env_dom env'›
‹s ≠ p› ‹x ≠ y› t1 ‹env = env'⦇s:A⦈⦇p:B⦈›]
from ok_finite[of env'] ok_add_2[OF typing_regular'[OF this]]
have findom: "finite (env_dom env')" by simp
{ fix a assume "a ∉ FV t'" with t' have "a ∉ FV t2'" by simp }
note
bnd_renaming_lem[OF this[OF ‹s ∉ FV t'›] this[OF ‹p ∉ FV t'›]
this[OF ‹x ∉ FV t'›] this[OF ‹y ∉ FV t'›]
‹x ∉ env_dom env'› ‹y ∉ env_dom env'›
‹s ≠ p› ‹x ≠ y› t2 ‹env = env'⦇s:A⦈⦇p:B⦈›]
from this[of F T l "FV t2'"] T_Upd(2)
have
"∀sa pa. sa ∉ F ∪ {s, p, x, y} ∪ FV t2' ∪ env_dom env'
∧ pa ∉ F ∪ {s, p, x, y} ∪ FV t2' ∪ env_dom env'
∧ sa ≠ pa
⟶ env'⦇x:A⦈⦇y:B⦈⦇sa:T⦈⦇pa:param(the(T^l))⦈
⊢ ({Suc n → [Fvar x,Fvar y]} t2'⇗[Fvar sa,Fvar pa]⇖) : return(the(T^l))"
by simp
from
typing.T_Upd[OF _ this t1' ‹l ∈ do T›]
‹finite F› findom t'
show ?case by simp
next
case (T_Obj env f T F env' t' s p x y A B n)
from ‹ok env› ‹env = env'⦇s:A⦈⦇p:B⦈› ok_add_2[of env' s A p B]
have "ok env'" by simp
from
ok_add_ok[OF ok_add_ok[OF this ‹x ∉ env_dom env'›]
not_in_env_bigger[OF ‹y ∉ env_dom env'› not_sym[OF ‹x ≠ y›]]]
have ok: "ok (env'⦇x:A⦈⦇y:B⦈)" by assumption
from sopen_eq_Obj[OF sym[OF ‹Obj f T = {n → [Fvar s,Fvar p]} t'›]]
obtain f' where
obj: "{n → [Fvar s,Fvar p]} Obj f' T = Obj f T" and
t': "t' = Obj f' T" by auto
from
this(1) ‹dom f = do T›
sym[OF dom_sopenoption_lem[of "Suc n" "Fvar s" "Fvar p" f']]
dom_sopenoption_lem[of "Suc n" "Fvar x" "Fvar y" f']
have dom: "dom (λl. sopen_option (Suc n) (Fvar x) (Fvar y) (f' l)) = do T"
by simp
from
‹finite F› finite_FV[of "Obj f' T"]
ok_finite[of env'] ok_add_2[OF ok]
have finF: "finite (F ∪ {s,p,x,y} ∪ FV (Obj f' T) ∪ env_dom env')"
by simp
have
"∀l∈do T. ∀sa pa. sa ∉ F ∪ {s, p, x, y} ∪ FV (Obj f' T) ∪ env_dom env'
∧ pa ∉ F ∪ {s, p, x, y} ∪ FV (Obj f' T) ∪ env_dom env'
∧ sa ≠ pa
⟶ env'⦇x:A⦈⦇y:B⦈⦇sa:T⦈⦇pa:param(the(T^l))⦈
⊢ (the(sopen_option (Suc n) (Fvar x) (Fvar y) (f' l))⇗[Fvar sa,Fvar pa]⇖) :
return(the(T^l))"
proof
fix l assume "l ∈ do T" with T_Obj(4)
have cof:
"∀sa pa. sa ∉ F ∧ pa ∉ F ∧ sa ≠ pa
⟶ env⦇sa:T⦈⦇pa:param(the(T^l))⦈
⊢ (the(f l)⇗[Fvar sa,Fvar pa]⇖) : return(the(T^l))
∧ (∀env'' t'' s' p' x' y' A' B' n'.
s' ∉ FV t'' ⟶ p' ∉ FV t'' ⟶ x' ∉ FV t'' ⟶ y' ∉ FV t''
⟶ x' ∉ env_dom env'' ⟶ y' ∉ env_dom env'' ⟶ x' ≠ y'
⟶ s' ≠ p'
⟶ (the(f l)⇗[Fvar sa,Fvar pa]⇖) = {n' → [Fvar s',Fvar p']} t''
⟶ env⦇sa:T⦈⦇pa:param(the(T^l))⦈ = env''⦇s':A'⦈⦇p':B'⦈
⟶ env''⦇x':A'⦈⦇y':B'⦈
⊢ {n' → [Fvar x',Fvar y']} t'' : return(the(T^l)))"
by simp
from
‹l ∈ do T› ‹dom f = do T› ‹Obj f T = {n → [Fvar s,Fvar p]} t'› obj t'
dom_sopenoption_lem[of "Suc n" "Fvar s" "Fvar p" f']
have indomf': "l ∈ dom f'" by auto
hence
opened: "the (sopen_option (Suc n) (Fvar x) (Fvar y) (f' l))
= {Suc n → [Fvar x,Fvar y]} the(f' l)"
by force
from indomf' have FVsubset: "FV (the(f' l)) ⊆ FV (Obj f' T)" by force
with
‹s ∉ FV t'› ‹p ∉ FV t'› ‹x ∉ FV t'› ‹y ∉ FV t'› obj t'
indomf' FV_option_lem[of f']
obtain
"s ∉ FV (the(f' l))" and "p ∉ FV (the(f' l))" and
"x ∉ FV (the(f' l))" and "y ∉ FV (the(f' l))" and
"the(f l) = {Suc n → [Fvar s,Fvar p]} the(f' l)" by auto
from
bnd_renaming_lem[OF this(1-4) ‹x ∉ env_dom env'› ‹y ∉ env_dom env'›
‹s ≠ p› ‹x ≠ y› this(5) ‹env = env'⦇s:A⦈⦇p:B⦈›
cof FVsubset]
show
"∀sa pa. sa ∉ F ∪ {s, p, x, y} ∪ FV (Obj f' T) ∪ env_dom env'
∧ pa ∉ F ∪ {s, p, x, y} ∪ FV (Obj f' T) ∪ env_dom env'
∧ sa ≠ pa
⟶ env'⦇x:A⦈⦇y:B⦈⦇sa:T⦈⦇pa:param(the(T^l))⦈
⊢ (the(sopen_option (Suc n) (Fvar x) (Fvar y) (f' l))⇗[Fvar sa,Fvar pa]⇖) :
return(the(T^l))"
by (subst opened, assumption)
qed
from typing.T_Obj[OF ok dom finF this] t' show ?case by simp
qed
lemma type_renaming:
"⟦ e⦇s:A⦈⦇p:B⦈ ⊢ {n → [Fvar s,Fvar p]} t : T;
s ∉ FV t; p ∉ FV t; x ∉ FV t; y ∉ FV t;
x ∉ env_dom e; y ∉ env_dom e; x ≠ y; s ≠ p⟧
⟹ e⦇x:A⦈⦇y:B⦈ ⊢ {n → [Fvar x,Fvar y]} t : T"
by (auto simp: type_renaming')
lemma obj_inv_elim':
assumes
"e ⊢ Obj f U : U" and
nin_s: "s ∉ FV (Obj f U) ∪ env_dom e" and
nin_p: "p ∉ FV (Obj f U) ∪ env_dom e" and "s ≠ p"
shows
"(dom f = do U) ∧ (∀l∈do U. e⦇s:U⦈⦇p:param(the(U^l))⦈
⊢ (the(f l)⇗[Fvar s,Fvar p]⇖) : return(the(U^l)))"
using assms
proof (cases rule: typing.cases)
case (T_Obj F)
thus ?thesis
proof (simp, intro strip)
fix l assume "l ∈ do U"
from ‹finite F› finite_FV[of "Obj f U"] have "finite (F ∪ FV (Obj f U) ∪ {s,p})"
by simp
from exFresh_s_p_cof[OF this]
obtain sa pa where
"sa ≠ pa" and
nin_sa: "sa ∉ F ∪ FV (Obj f U)" and
nin_pa: "pa ∉ F ∪ FV (Obj f U)" by auto
with ‹l ∈ do U› T_Obj(4)
have
"e⦇sa:U⦈⦇pa:param(the(U^l))⦈
⊢ (the(f l)⇗[Fvar sa,Fvar pa]⇖) : return(the(U^l))"
by simp
moreover
from ‹l ∈ do U› ‹dom f = do U›
have "l ∈ dom f" by simp
with nin_s nin_p nin_sa nin_pa FV_option_lem[of f]
have
"sa ∉ FV (the(f l)) ∧ pa ∉ FV (the(f l))
∧ s ∉ FV (the(f l)) ∧ p ∉ FV (the(f l))
∧ s ∉ env_dom e ∧ p ∉ env_dom e" by auto
ultimately
show
"e⦇s:U⦈⦇p:param(the(U^l))⦈
⊢ (the(f l)⇗[Fvar s,Fvar p]⇖) : return(the(U^l))"
using type_renaming[OF _ _ _ _ _ _ _ ‹s ≠ p› ‹sa ≠ pa›]
by (simp add: openz_def)
qed
qed
lemma dom_lem: "e ⊢ Obj f (Object fun) : Object fun ⟹ dom f = dom fun"
by (erule typing.cases, auto)
lemma abs_typeE:
assumes "e ⊢ Call (Obj f U) l b : T"
shows
"(∃F. finite F
∧ (∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p
⟶ e⦇s:U⦈⦇p: param(the(U^l))⦈ ⊢ (the(f l)⇗[Fvar s,Fvar p]⇖) : T) ⟹ P)
⟹ P"
using assms
proof (cases rule: typing.cases)
case (T_Call A )
assume
cof: "∃F. finite F
∧ (∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p
⟶ e⦇s:U⦈⦇p: param(the(U^l))⦈ ⊢ (the(f l)⇗[Fvar s,Fvar p]⇖) : T)
⟹ P"
from
‹T = return(the(A^l))›
‹e ⊢ Obj f U : A› ‹l ∈ do A› obj_inv[of e f U A]
obtain "e ⊢ (Obj f U) : U" and "T = return(the(U^l))" and "l ∈ do U"
by simp
from obj_inv_elim[OF this(1)] this(2-3) cof show ?thesis by blast
qed
subsubsection ‹Substitution preserves Well-Typedness›
lemma bigger_env_lemma[rule_format]:
assumes "e ⊢ t : T"
shows "∀x X. x ∉ env_dom e ⟶ e⦇x:X⦈ ⊢ t: T"
proof -
define pred_cof
where "pred_cof L env t T l ⟷
(∀s p. s ∉ L ∧ p ∉ L ∧ s ≠ p
⟶ env⦇s:T⦈⦇p:param (the(T^l))⦈ ⊢ (t⇗[Fvar s,Fvar p]⇖) : return (the(T^l)))"
for L env t T l
from assms show ?thesis
proof (induct
taking: "λenv t T l. ∀x X. x ∉ env_dom env
⟶ (∃L. finite L ∧ pred_cof L (env⦇x:X⦈) t T l)"
rule: typing_induct)
case Call thus ?case by auto
next
case (Fvar env Ta xa) thus ?case
proof (intro strip)
fix x X assume "x ∉ env_dom env"
from
get_env_smaller[OF ‹xa ∈ env_dom env› this]
T_Var[OF ok_add_ok[OF ‹ok env› this]
env_bigger[OF this ‹xa ∈ env_dom env›]]
‹the env!xa = Ta›
show "env⦇x:X⦈ ⊢ Fvar xa : Ta" by simp
qed
next
case (Obj env Ta f) note pred_o = this(3)
define pred_cof'
where "pred_cof' x X b l ⟷ (∃L. finite L ∧ pred_cof L (env⦇x:X⦈) (the b) Ta l)" for x X b l
from pred_o
have pred: "∀x X. x ∉ env_dom env ⟶ (∀l∈dom f. pred_cof' x X (f l) l)"
by (intro fmap_ball_all2'[of f "λx X. x ∉ env_dom env" pred_cof'],
unfold pred_cof_def pred_cof'_def, simp)
show ?case
proof (intro strip)
fix x X
define pred_bnd
where "pred_bnd s p b l ⟷
env⦇x:X⦈⦇s:Ta⦈⦇p:param (the(Ta^l))⦈ ⊢ (the b⇗[Fvar s,Fvar p]⇖) : return (the(Ta^l))"
for s p b l
assume "x ∉ env_dom env"
with pred fmap_ex_cof[of f pred_bnd] ‹dom f = do Ta›
obtain L where
"finite L" and "∀l∈do Ta. pred_cof L (env⦇x:X⦈) (the(f l)) Ta l"
unfolding pred_bnd_def pred_cof_def pred_cof'_def
by auto
from
T_Obj[OF ok_add_ok[OF ‹ok env› ‹x ∉ env_dom env›]
‹dom f = do Ta› this(1)]
this(2)
show "env⦇x:X⦈ ⊢ Obj f Ta : Ta"
unfolding pred_cof_def
by simp
qed
next
case (Upd env Ta t l u)
note pred_t = this(2) and pred_u = this(4)
show ?case
proof (intro strip)
fix x X assume "x ∉ env_dom env"
with pred_u obtain L where
"finite L" and "pred_cof L (env⦇x:X⦈) u Ta l" by auto
with ‹l ∈ do Ta› ‹x ∉ env_dom env› pred_t
show "env⦇x:X⦈ ⊢ Upd t l u : Ta"
unfolding pred_cof_def
by auto
qed
next
case (Bnd env Ta l t L) note pred = this(3)
show ?case
proof (intro strip)
fix x X assume "x ∉ env_dom env"
thus "∃L. finite L ∧ pred_cof L (env⦇x:X⦈) t Ta l"
proof (rule_tac x = "L ∪ {x}" in exI, simp add: ‹finite L›,
unfold pred_cof_def, auto)
fix s p
assume
"s ∉ L" and "p ∉ L" and "s ≠ p" and
"s ≠ x" and "p ≠ x"
note
subst_add[OF not_sym[OF ‹s ≠ x›]]
subst_add[OF not_sym[OF ‹p ≠ x›]]
from
this(1)[of env X Ta] this(2)[of "env⦇s:Ta⦈" X "param (the(Ta^l))"]
pred ‹s ∉ L› ‹p ∉ L› ‹s ≠ p›
not_in_env_bigger_2[OF ‹x ∉ env_dom env›
not_sym[OF ‹s ≠ x›] not_sym[OF ‹p ≠ x›]]
show
"env⦇x:X⦈⦇s:Ta⦈⦇p:param (the(Ta^l))⦈
⊢ (t⇗[Fvar s,Fvar p]⇖) : return (the(Ta^l))"
by auto
qed
qed
qed
qed
lemma bnd_disj_env_lem:
assumes
"ok e1" and "env_dom e1 ∩ env_dom e2 = {}" and "ok e2" and
"∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p
⟶ e1⦇s:T⦈⦇p:param(the(T^l))⦈
⊢ (t2⇗[Fvar s,Fvar p]⇖) : return(the(T^l))
∧ (env_dom (e1⦇s:T⦈⦇p:param(the(T^l))⦈) ∩ env_dom e2 = {}
⟶ ok e2
⟶ e1⦇s:T⦈⦇p:param(the(T^l))⦈+e2
⊢ (t2⇗[Fvar s,Fvar p]⇖) : return(the(T^l)))"
shows
"∀s p. s ∉ F ∪ env_dom (e1+e2) ∧ p ∉ F ∪ env_dom (e1+e2) ∧ s ≠ p
⟶ (e1+e2)⦇s:T⦈⦇p:param(the(T^l))⦈ ⊢ (t2⇗[Fvar s,Fvar p]⇖) : return(the(T^l))"
proof (intro strip, elim conjE)
fix s p assume
nin_s: "s ∉ F ∪ env_dom (e1+e2)" and
nin_p: "p ∉ F ∪ env_dom (e1+e2)" and "s ≠ p"
from
this(1-2) env_add_dom_2[OF assms(1) _ _ this(3)]
assms(2) env_app_dom[OF assms(1-3)]
have "env_dom (e1⦇s:T⦈⦇p:param(the(T^l))⦈) ∩ env_dom e2 = {}" by simp
with
env_app_add2[OF assms(1-3) _ _ _ _ ‹s ≠ p›]
env_app_dom[OF assms(1-3)] ‹ok e2› assms(4) nin_s nin_p ‹s ≠ p›
show "(e1+e2)⦇s:T⦈⦇p:param(the(T^l))⦈ ⊢ (t2⇗[Fvar s,Fvar p]⇖) : return(the(T^l))"
by auto
qed
lemma disjunct_env:
assumes "e ⊢ t : A"
shows "(env_dom e ∩ env_dom e' = {} ⟹ ok e' ⟹ e + e' ⊢ t : A)"
using assms
proof (induct rule: typing.induct)
case T_Call thus ?case by auto
next
case (T_Var env x T)
from
env_app_dom[OF ‹ok env› ‹env_dom env ∩ env_dom e' = {}› ‹ok e'›]
‹x ∈ env_dom env›
have indom: "x ∈ env_dom (env+e')" by simp
from
‹ok env› ‹x ∈ env_dom env› ‹the env!x = T› ‹env_dom env ∩ env_dom e' = {}›
‹ok e'›
have "the (env+e')!x = T" by simp
from
typing.T_Var[OF env_app_ok[OF ‹ok env› ‹env_dom env ∩ env_dom e' = {}›
‹ok e'›]
indom this]
show ?case by assumption
next
case (T_Upd F env T l t2 t1)
from
typing.T_Upd[OF _ bnd_disj_env_lem[OF typing_regular'[OF ‹env ⊢ t1 : T›]
‹env_dom env ∩ env_dom e' = {}› ‹ok e'›
T_Upd(2)]
T_Upd(4)[OF ‹env_dom env ∩ env_dom e' = {}› ‹ok e'›]
‹l ∈ do T›]
‹finite F› ok_finite[OF env_app_ok[OF typing_regular'[OF ‹env ⊢ t1 : T›]
‹env_dom env ∩ env_dom e' = {}› ‹ok e'›]]
show ?case by simp
next
case (T_Obj env f T F)
from
ok_finite[OF env_app_ok[OF ‹ok env› ‹env_dom env ∩ env_dom e' = {}› ‹ok e'›]]
‹finite F›
have finF: "finite (F ∪ env_dom (env+e'))" by simp
note
ball_Tltsp[of F
"λT l t s p. env⦇s:T⦈⦇p:param(the(T^l))⦈ ⊢ (t⇗[Fvar s,Fvar p]⇖) : return(the(T^l))
∧ (env_dom (env⦇s:T⦈⦇p:param(the(T^l))⦈) ∩ env_dom e' = {}
⟶ ok e'
⟶ env⦇s:T⦈⦇p:param(the(T^l))⦈+e'
⊢ (t⇗[Fvar s,Fvar p]⇖) : return(the(T^l)))"
T "F ∪ env_dom (env+e')"
"λT l t s p. (env+e')⦇s:T⦈⦇p:param(the(T^l))⦈
⊢ (t⇗[Fvar s,Fvar p]⇖) : return(the(T^l))"]
from
this[OF _ T_Obj(4)]
bnd_disj_env_lem[OF ‹ok env› ‹env_dom env ∩ env_dom e' = {}› ‹ok e'›]
typing.T_Obj[OF env_app_ok[OF ‹ok env›
‹env_dom env ∩ env_dom e' = {}› ‹ok e'›]
‹dom f = do T› finF]
show ?case by simp
qed
text ‹Typed in the Empty Environment implies typed in any Environment›
lemma empty_env:
assumes "(Env Map.empty) ⊢ t : A" and "ok env"
shows "env ⊢ t : A"
proof -
from ‹ok env› have "env = (Env Map.empty)+env" by (cases env, auto)
with disjunct_env[OF assms(1) _ assms(2)] show ?thesis by simp
qed
lemma bnd_open_lem:
assumes
pred_bnd:
"∀sa pa. sa ∉ F ∧ pa ∉ F ∧ sa ≠ pa
⟶ env⦇sa:T⦈⦇pa:param(the(T^l))⦈
⊢ (t⇗[Fvar sa,Fvar pa]⇖) : return(the(T^l))
∧ (∀env'' t'' s' p' x' y' A' B' n'. s' ∉ FV t'' ∪ FV x' ∪ FV y'
⟶ p' ∉ FV t'' ∪ FV x' ∪ FV y' ⟶ s' ≠ p'
⟶ env'' ⊢ x' : A' ⟶ env'' ⊢ y' : B'
⟶ (t⇗[Fvar sa,Fvar pa]⇖) = {n' → [Fvar s',Fvar p']} t''
⟶ env⦇sa:T⦈⦇pa:param(the(T^l))⦈ = env''⦇s':A'⦈⦇p':B'⦈
⟶ env'' ⊢ {n' → [x',y']} t'' : return(the(T^l)))" and
"ok env" and "env = env'⦇s:A⦈⦇p:B⦈" and
"s ∉ FV t'' ∪ FV x ∪ FV y" and "p ∉ FV t'' ∪ FV x ∪ FV y" and "s ≠ p" and
"env' ⊢ x : A" and "env' ⊢ y : B" and
"t = {Suc n → [Fvar s,Fvar p]} t'" and "FV t' ⊆ FV t''"
shows
"∀sa pa. sa ∉ F ∪ {s,p} ∪ env_dom env'
∧ pa ∉ F ∪ {s,p} ∪ env_dom env' ∧ sa ≠ pa
⟶ env'⦇sa:T⦈⦇pa:param(the(T^l))⦈
⊢ ({Suc n → [x,y]} t'⇗[Fvar sa, Fvar pa]⇖) : return(the(T^l))"
proof (intro strip, elim conjE)
fix sa pa assume
nin_sa: "sa ∉ F ∪ {s,p} ∪ env_dom env'" and
nin_pa: "pa ∉ F ∪ {s,p} ∪ env_dom env'" and "sa ≠ pa"
hence "sa ∉ F ∧ pa ∉ F ∧ sa ≠ pa" by auto
moreover
{
fix a assume "a ∉ FV t'' ∪ FV x ∪ FV y" and "a ∈ {s,p}"
with
‹FV t' ⊆ FV t''› nin_sa nin_pa ‹sa ≠ pa›
sopen_FV[of 0 "Fvar sa" "Fvar pa" t']
have "a ∉ FV (t'⇗[Fvar sa,Fvar pa]⇖) ∪ FV x ∪ FV y" by (auto simp: openz_def)
} note
this[OF ‹s ∉ FV t'' ∪ FV x ∪ FV y›]
this[OF ‹p ∉ FV t'' ∪ FV x ∪ FV y›]
moreover
{
from ‹ok env› ‹env = env'⦇s:A⦈⦇p:B⦈› ok_add_2[of env' s A p B]
have "ok env'" by simp
from nin_sa nin_pa ‹sa ≠ pa› env_add_dom[OF this]
obtain "sa ∉ env_dom env'" and "pa ∉ env_dom (env'⦇sa:T⦈)" by auto
note
bigger_env_lemma[OF bigger_env_lemma[OF ‹env' ⊢ x : A› this(1)] this(2)]
bigger_env_lemma[OF bigger_env_lemma[OF ‹env' ⊢ y : B› this(1)] this(2)]
}note
this(1)[of "param(the(T^l))"]
this(2)[of "param(the(T^l))"]
moreover
from ‹t = {Suc n → [Fvar s,Fvar p]} t'› sopen_commute[of 0 "Suc n" sa pa s p t']
have "(t⇗[Fvar sa,Fvar pa]⇖) = {Suc n → [Fvar s,Fvar p]} (t'⇗[Fvar sa,Fvar pa]⇖)"
by (simp add: openz_def)
moreover
from
subst_add[of p sa "env'⦇s:A⦈" B T] subst_add[of s sa env' A T]
subst_add[of p pa "env'⦇sa:T⦈⦇s:A⦈" B "param(the(T^l))"]
subst_add[of s pa "env'⦇sa:T⦈" A "param(the(T^l))"]
‹env = env'⦇s:A⦈⦇p:B⦈› nin_sa nin_pa
have "env⦇sa:T⦈⦇pa:param(the(T^l))⦈ = env'⦇sa:T⦈⦇pa:param(the(T^l))⦈⦇s:A⦈⦇p:B⦈"
by auto
ultimately
show
"env'⦇sa:T⦈⦇pa:param(the(T^l))⦈
⊢ ({Suc n → [x,y]} t'⇗[Fvar sa, Fvar pa]⇖) : return(the(T^l))"
using
pred_bnd ‹s ≠ p›
sopen_commute_gen[OF lc_Fvar[of sa] lc_Fvar[of pa]
typing_regular''[OF ‹env' ⊢ x : A›]
typing_regular''[OF ‹env' ⊢ y : B›]
not_sym[OF Suc_not_Zero]]
by (auto simp: openz_def)
qed
lemma open_lemma':
shows
"e ⊢ t : C
⟹ (⋀env t' s p x y A B n. s ∉ FV t' ∪ FV x ∪ FV y
⟹ p ∉ FV t' ∪ FV x ∪ FV y ⟹ s ≠ p
⟹ env ⊢ x : A ⟹ env ⊢ y : B
⟹ t = {n → [Fvar s,Fvar p]} t'
⟹ e = env⦇s:A⦈⦇p:B⦈
⟹ env ⊢ {n → [x,y]} t' : C)"
proof (induct set:typing)
case (T_Var env x T env' t' s p y z A B n)
from sopen_eq_Fvar[OF sym[OF ‹Fvar x = {n → [Fvar s,Fvar p]} t'›]]
show ?case
proof (elim disjE conjE)
assume "t' = Fvar x"
with ‹s ∉ FV t' ∪ FV y ∪ FV z› ‹p ∉ FV t' ∪ FV y ∪ FV z›
obtain "x ≠ s" and "x ≠ p" by auto
from ‹x ∈ env_dom env› ‹env = env'⦇s:A⦈⦇p:B⦈› in_env_smaller2[OF _ this]
have indom: "x ∈ env_dom env'" by simp
from
‹ok env› ‹the env!x = T› ‹env = env'⦇s:A⦈⦇p:B⦈›
ok_add_2[of env' s A p B] get_env_smaller2[OF this _ _ ‹s ≠ p›]
have "the env'!x = T" by simp
from
‹ok env› ‹env = env'⦇s:A⦈⦇p:B⦈› ‹t' = Fvar x›
ok_add_2[of env' s A p B] typing.T_Var[OF _ indom this]
show ?case by simp
next
assume "x = s"
with
‹ok env› ‹the env!x = T› ‹env = env'⦇s:A⦈⦇p:B⦈›
add_get2_1[of env' s A p B]
have "T = A" by simp
moreover assume "t' = Bvar (Self n)"
ultimately show ?thesis using ‹env' ⊢ y : A› by simp
next
assume "x = p"
with
‹ok env› ‹the env!x = T› ‹env = env'⦇s:A⦈⦇p:B⦈›
add_get2_2[of env' s A p B] have "T = B" by simp
moreover assume "t' = Bvar (Param n)"
ultimately show ?thesis using ‹env' ⊢ z : B› by simp
qed
next
case (T_Upd F env T l t2 t1 env' t' s p x y A B n)
from sopen_eq_Upd[OF sym[OF ‹Upd t1 l t2 = {n → [Fvar s,Fvar p]} t'›]]
obtain t1' t2' where
t1': "t1 = {n → [Fvar s,Fvar p]} t1'" and
t2': "t2 = {Suc n → [Fvar s,Fvar p]} t2'" and
t': "t' = Upd t1' l t2'" by auto
hence "FV t2' ⊆ FV t'" by auto
from
‹s ∉ FV t' ∪ FV x ∪ FV y› ‹p ∉ FV t' ∪ FV x ∪ FV y›
t' ‹finite F› ok_finite[OF typing_regular'[OF ‹env' ⊢ x : A›]]
typing.T_Upd[OF _ bnd_open_lem[OF T_Upd(2)
typing_regular'[OF ‹env ⊢ t1 : T›]
‹env = env'⦇s:A⦈⦇p:B⦈›
‹s ∉ FV t' ∪ FV x ∪ FV y›
‹p ∉ FV t' ∪ FV x ∪ FV y› ‹s ≠ p›
‹env' ⊢ x : A› ‹env' ⊢ y : B› t2' this]
T_Upd(4)[OF _ _ ‹s ≠ p› ‹env' ⊢ x : A› ‹env' ⊢ y : B›
t1' ‹env = env'⦇s:A⦈⦇p:B⦈›] ‹l ∈ do T›]
show ?case by simp
next
case (T_Obj env f T F env' t' s p x y A B n)
from sopen_eq_Obj[OF sym[OF ‹Obj f T = {n → [Fvar s,Fvar p]} t'›]]
obtain f' where
obj: "Obj f T = {n → [Fvar s,Fvar p]} Obj f' T" and
t': "t' = Obj f' T" by auto
from
sym[OF this(1)] ‹dom f = do T›
sym[OF dom_sopenoption_lem[of "Suc n" "Fvar s" "Fvar p" f']]
dom_sopenoption_lem[of "Suc n" x y f']
have dom: "dom (λl. sopen_option (Suc n) x y (f' l)) = do T" by simp
from ‹finite F› ok_finite[OF typing_regular'[OF ‹env' ⊢ x : A›]]
have finF: "finite (F ∪ {s,p} ∪ env_dom env')"
by simp
have
"∀l∈do T. ∀sa pa. sa ∉ F ∪ {s,p} ∪ env_dom env'
∧ pa ∉ F ∪ {s,p} ∪ env_dom env'
∧ sa ≠ pa
⟶ env'⦇sa:T⦈⦇pa:param(the(T^l))⦈
⊢ (the(sopen_option (Suc n) x y (f' l))⇗[Fvar sa,Fvar pa]⇖) : return(the(T^l))"
proof
fix l assume "l ∈ do T" with T_Obj(4)
have
cof:
"∀sa pa. sa ∉ F ∧ pa ∉ F ∧ sa ≠ pa
⟶ env⦇sa:T⦈⦇pa:param(the(T^l))⦈
⊢ (the(f l)⇗[Fvar sa,Fvar pa]⇖) : return(the(T^l))
∧ (∀env'' t'' s' p' x' y' A' B' n'.
s' ∉ FV t'' ∪ FV x' ∪ FV y' ⟶ p' ∉ FV t'' ∪ FV x' ∪ FV y'
⟶ s' ≠ p' ⟶ env'' ⊢ x' : A' ⟶ env'' ⊢ y' : B'
⟶ (the(f l)⇗[Fvar sa,Fvar pa]⇖) = {n' → [Fvar s',Fvar p']} t''
⟶ env⦇sa:T⦈⦇pa:param(the(T^l))⦈ = env''⦇s':A'⦈⦇p':B'⦈
⟶ env'' ⊢ {n' → [x',y']} t'' : return(the(T^l)))"
by simp
from
‹l ∈ do T› ‹dom f = do T› ‹Obj f T = {n → [Fvar s,Fvar p]} t'› obj t'
dom_sopenoption_lem[of "Suc n" "Fvar s" "Fvar p" f']
have indomf': "l ∈ dom f'" by auto
with obj sopen_option_lem[of f' "Suc n" "Fvar s" "Fvar p"] FV_option_lem[of f'] t'
obtain
"the(f l) = {Suc n → [Fvar s,Fvar p]} the(f' l)" and
"FV (the(f' l)) ⊆ FV t'" by auto
from
bnd_open_lem[OF cof ‹ok env› ‹env = env'⦇s:A⦈⦇p:B⦈›
‹s ∉ FV t' ∪ FV x ∪ FV y› ‹p ∉ FV t' ∪ FV x ∪ FV y›
‹s ≠ p› ‹env' ⊢ x : A› ‹env' ⊢ y : B› this]
indomf' sopen_option_lem[of f' "Suc n" x y] T_Obj(4)
show
"∀sa pa. sa ∉ F ∪ {s,p} ∪ env_dom env'
∧ pa ∉ F ∪ {s,p} ∪ env_dom env' ∧ sa ≠ pa
⟶ env'⦇sa:T⦈⦇pa:param(the(T^l))⦈
⊢ (the(sopen_option (Suc n) x y (f' l))⇗[Fvar sa,Fvar pa]⇖) : return(the(T^l))"
by simp
qed
from typing.T_Obj[OF typing_regular'[OF ‹env' ⊢ x : A›] dom finF this] t'
show ?case by simp
next
case (T_Call env t1 T t2 l env' t' s p x y A B n)
from sopen_eq_Call[OF sym[OF ‹Call t1 l t2 = {n → [Fvar s,Fvar p]} t'›]]
obtain t1' t2' where
t1: "t1 = {n → [Fvar s,Fvar p]} t1'" and
t2: "t2 = {n → [Fvar s,Fvar p]} t2'" and
t': "t' = Call t1' l t2'" by auto
{ fix a assume "a ∉ FV t' ∪ FV x ∪ FV y"
with t' have "a ∉ FV t1' ∪ FV x ∪ FV y" by simp
}note
t1' = T_Call(2)[OF this[OF ‹s ∉ FV t' ∪ FV x ∪ FV y›]
this[OF ‹p ∉ FV t' ∪ FV x ∪ FV y›]
‹s ≠ p› ‹env' ⊢ x : A› ‹env' ⊢ y : B›
t1 ‹env = env'⦇s:A⦈⦇p:B⦈›]
{ fix a assume "a ∉ FV t' ∪ FV x ∪ FV y"
with t' have "a ∉ FV t2' ∪ FV x ∪ FV y" by simp
}
from
typing.T_Call[OF t1' T_Call(4)[OF this[OF ‹s ∉ FV t' ∪ FV x ∪ FV y›]
this[OF ‹p ∉ FV t' ∪ FV x ∪ FV y›]
‹s ≠ p› ‹env' ⊢ x : A› ‹env' ⊢ y : B›
t2 ‹env = env'⦇s:A⦈⦇p:B⦈›]
‹l ∈ do T›]
t'
show ?case by simp
qed
lemma open_lemma:
"⟦ env⦇s:A⦈⦇p:B⦈ ⊢ {n → [Fvar s,Fvar p]} t : T;
s ∉ FV t ∪ FV x ∪ FV y; p ∉ FV t ∪ FV x ∪ FV y; s ≠ p;
env ⊢ x : A; env ⊢ y : B ⟧
⟹ env ⊢ {n → [x,y]} t : T"
by (simp add: open_lemma')
subsubsection ‹Subject reduction›
lemma type_dom[simp]: "env ⊢ (Obj a A) : A ⟹ dom a = do A"
by (erule typing.cases, auto)
lemma select_preserve_type[simp]:
assumes
"env ⊢ Obj f (Object t) : Object t" and "s ∉ FV a" and "p ∉ FV a" and
"env⦇s:(Object t)⦈⦇p:param(the(t l2))⦈ ⊢ (a⇗[Fvar s,Fvar p]⇖) : return(the(t l2))" and
"l1 ∈ dom t" and "l2 ∈ dom t"
shows
"∃F. finite F
∧ (∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p
⟶ env⦇s:(Object t)⦈⦇p:param(the(t l1))⦈
⊢ (the((f(l2 ↦ a)) l1)⇗[Fvar s,Fvar p]⇖) : return(the(t l1)))"
proof -
from ok_finite[OF typing_regular'[OF ‹env ⊢ Obj f (Object t) : Object t›]]
have finF: "finite ({s,p} ∪ env_dom env)" by simp
{
note
ok_env = typing_regular'[OF ‹env ⊢ Obj f (Object t) : Object t›] and
ok_env_sp = typing_regular'[OF assms(4)]
fix sa pa assume
nin_sa: "sa ∉ {s,p} ∪ env_dom env" and
nin_pa: "pa ∉ {s,p} ∪ env_dom env" and "sa ≠ pa"
from this(1) ok_add_2[OF ok_env_sp] env_add_dom_2[OF ok_env]
have "sa ∉ env_dom (env⦇s:Object t⦈⦇p:param(the(t l2))⦈)" by simp
from
nin_sa bigger_env_lemma[OF assms(4) this]
subst_add[of sa p "env⦇s:Object t⦈" "Object t" "param(the(t l2))"]
subst_add[of sa s env "Object t" "Object t"]
have
aT_sa: "env⦇sa:Object t⦈⦇s:Object t⦈⦇p:param(the(t l2))⦈
⊢ (a⇗[Fvar s,Fvar p]⇖) : return(the(t l2))" by simp
from
‹sa ≠ pa› nin_sa nin_pa env_add_dom[OF ok_env]
ok_add_2[OF ok_env_sp]
obtain
"s ∉ env_dom (env⦇sa:Object t⦈)" and
"p ∉ env_dom (env⦇sa:Object t⦈)" and "s ≠ p" and
"sa ∉ env_dom env" and "pa ∉ env_dom (env⦇sa:Object t⦈)"
by auto
with env_add_dom_2[OF ok_add_ok[OF ok_env this(4)] this(1-3)] nin_pa
have "pa ∉ env_dom (env⦇sa:Object t⦈⦇s:Object t⦈⦇p:param(the(t l2))⦈)"
by simp
from
nin_pa bigger_env_lemma[OF aT_sa this]
subst_add[of pa p "env⦇sa:Object t⦈⦇s:Object t⦈"
"param(the(t l2))" "param(the(t l2))"]
subst_add[of pa s "env⦇sa:Object t⦈" "param(the(t l2))" "Object t"]
have
aT_sapa:
"env⦇sa:Object t⦈⦇pa:param(the(t l2))⦈⦇s:Object t⦈⦇p:param(the(t l2))⦈
⊢ {0 → [Fvar s, Fvar p]} a : return(the(t l2))" by (simp add: openz_def)
from nin_sa nin_pa ‹s ∉ FV a› ‹p ∉ FV a› ok_add_2[OF ok_env_sp]
obtain
ninFV_s: "s ∉ FV a ∪ FV (Fvar sa) ∪ FV (Fvar pa)" and
ninFV_p: "p ∉ FV a ∪ FV (Fvar sa) ∪ FV (Fvar pa)" and "s ≠ p"
by auto
from ok_add_2[OF typing_regular'[OF aT_sapa]]
have ok_env_sapa: "ok (env⦇sa:Object t⦈⦇pa:param(the(t l2))⦈)"
by simp
with ok_add_reverse[OF this]
have ok_env_pasa: "ok (env⦇pa:param(the(t l2))⦈⦇sa:Object t⦈)"
by simp
from
open_lemma[OF aT_sapa ninFV_s ninFV_p ‹s ≠ p› _
T_Var[OF ok_env_sapa in_add[OF ok_env_sapa]
add_get2_2[OF ok_env_sapa]]]
T_Var[OF ok_env_pasa in_add[OF ok_env_pasa] add_get2_2[OF ok_env_pasa]]
ok_add_reverse[OF ok_env_sapa]
have
"env⦇sa:(Object t)⦈⦇pa:param(the(t l2))⦈
⊢ (a⇗[Fvar sa,Fvar pa]⇖) : return(the(t l2))"
by (simp add: openz_def)
}note alem = this
show ?thesis
proof (cases "l1 = l2")
case True with assms obj_inv_elim'[OF assms(1)] show ?thesis
by (simp (no_asm_simp), rule_tac x = "{s,p} ∪ env_dom env" in exI,
auto simp: finF alem)
next
case False
from obj_inv_elim[OF ‹env ⊢ Obj f (Object t) : Object t›]
obtain F where
"finite F" and
"∀l∈dom t.
∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p
⟶ env⦇s:Object t⦈⦇p:param(the(Object t^l))⦈
⊢ (the(f l)⇗[Fvar s,Fvar p]⇖) : return(the(Object t^l))"
by auto
from this(2) ‹l1 ∈ dom t›
have
"∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p
⟶ env⦇s:Object t⦈⦇p:param(the(Object t^l1))⦈
⊢ (the(f l1)⇗[Fvar s,Fvar p]⇖) : return(the(Object t^l1))"
by auto
thus ?thesis using ‹finite F› ‹l1 ≠ l2› by (simp,blast)
qed
qed
text ‹Main Lemma›
lemma subject_reduction: "e ⊢ t : T ⟹ (⋀t'. t →⇩β t' ⟹ e ⊢ t' : T)"
proof (induct set: typing)
case (T_Var env x T t')
from Fvar_beta[OF ‹Fvar x →⇩β t'›] show ?case by simp
next
case (T_Upd F env T l t2 t1 t')
from Upd_beta[OF ‹Upd t1 l t2 →⇩β t'›] show ?case
proof (elim disjE exE conjE)
fix t1' assume "t1 →⇩β t1'" and "t' = Upd t1' l t2"
from
this(2) T_Upd(2)
typing.T_Upd[OF ‹finite F› _ T_Upd(4)[OF this(1)] ‹l ∈ do T›]
show ?case by simp
next
fix t2' F'
assume
"finite F'" and
pred_F': "∀s p. s ∉ F' ∧ p ∉ F' ∧ s ≠ p
⟶ (∃t''. t2⇗[Fvar s,Fvar p]⇖ →⇩β t'' ∧ t2' = σ[s,p] t'')" and
t': "t' = Upd t1 l t2'"
have
"∀s p. s ∉ F ∪ F' ∧ p ∉ F ∪ F' ∧ s ≠ p
⟶ env⦇s:T⦈⦇p:param(the(T^l))⦈ ⊢ (t2'⇗[Fvar s,Fvar p]⇖) : return(the(T^l))"
proof (intro strip, elim conjE)
fix s p assume
nin_s: "s ∉ F ∪ F'" and
nin_p: "p ∉ F ∪ F'" and "s ≠ p"
with pred_F' obtain t'' where "t2⇗[Fvar s,Fvar p]⇖ →⇩β t''" and "t2' = σ[s,p] t''"
by auto
with beta_lc[OF this(1)] sopen_sclose_eq_t[of t'' 0 s p]
have "t2⇗[Fvar s,Fvar p]⇖ →⇩β (t2'⇗[Fvar s,Fvar p]⇖)"
by (simp add: openz_def closez_def)
with nin_s nin_p ‹s ≠ p› T_Upd(2)
show "env⦇s:T⦈⦇p:param(the(T^l))⦈ ⊢ (t2'⇗[Fvar s,Fvar p]⇖) : return(the(T^l))"
by auto
qed
from t' ‹finite F› ‹finite F'› typing.T_Upd[OF _ this ‹env ⊢ t1 : T› ‹l ∈ do T›]
show ?case by simp
next
fix f U assume
"l ∈ dom f" and "Obj f U = t1" and
t': "t' = Obj (f(l ↦ t2)) U"
from this(1-2) ‹env ⊢ t1 : T› obj_inv[of env f U T]
obtain t where
objT: "env ⊢ Obj f (Object t) : (Object t)" and
"Object t = T" and "T = U"
by (cases T, auto)
from obj_inv_elim[OF objT] ‹Object t = T› ‹l ∈ dom f›
have domf': "dom (f(l ↦ t2)) = do T" by auto
have
exF: "∀l'∈do T.
(∃F'. finite F'
∧ (∀s p. s ∉ F' ∪ (F ∪ FV t2) ∧ p ∉ F' ∪ (F ∪ FV t2) ∧ s ≠ p
⟶ env⦇s:T⦈⦇p:param(the(T^l'))⦈
⊢ (the ((f(l ↦ t2)) l')⇗[Fvar s,Fvar p]⇖) : return(the(T^l'))))"
proof
fix l' assume "l' ∈ do T"
with dom_lem[OF objT] ‹l ∈ dom f› ‹Object t = T›
obtain ll': "l' ∈ dom t" and "l ∈ dom t" by auto
from ‹finite F› have "finite (F ∪ FV t2)" by simp
from exFresh_s_p_cof[OF this]
obtain s p where
nin_s: "s ∉ F ∪ FV t2" and
nin_p: "p ∉ F ∪ FV t2" and "s ≠ p"
by auto
with T_Upd(2) ‹Object t = T›
have
"env⦇s:Object t⦈⦇p:param(the(t l))⦈
⊢ (t2⇗[Fvar s,Fvar p]⇖) : return(the(t l))"
by auto
from
select_preserve_type[OF objT _ _ this ll'] sym[OF ‹Object t = T›]
nin_s nin_p ‹l ∈ dom t›
obtain F' where
"finite F'" and
"∀s p. s ∉ F' ∧ p ∉ F' ∧ s ≠ p
⟶ env⦇s:T⦈⦇p:param(the(T^l'))⦈
⊢ (the ((f(l ↦ t2)) l')⇗[Fvar s,Fvar p]⇖) : return(the(T^l'))"
by auto
thus
"∃F'. finite F'
∧ (∀s p. s ∉ F' ∪ (F ∪ FV t2) ∧ p ∉ F' ∪ (F ∪ FV t2) ∧ s ≠ p
⟶ env⦇s:T⦈⦇p:param(the(T^l'))⦈
⊢ (the ((f(l ↦ t2)) l')⇗[Fvar s,Fvar p]⇖) : return(the(T^l')))"
by blast
qed
{ fix Ta from finite_dom_fmap have "finite (do Ta)" by (cases Ta, auto) }
note fin_doT = this ball_ex_finite[of "do T" "F ∪ FV t2"]
from this(2)[OF this(1)[of T] _ exF] ‹finite F›
obtain F' where
"finite F'" and
"∀l'∈do T. ∀s p. s ∉ F' ∪ (F ∪ FV t2) ∧ p ∉ F' ∪ (F ∪ FV t2) ∧ s ≠ p
⟶ env⦇s:T⦈⦇p:param(the(T^l'))⦈
⊢ (the ((f(l ↦ t2)) l')⇗[Fvar s,Fvar p]⇖) : return(the(T^l'))"
by auto
moreover
from ‹finite F'› ‹finite F› have "finite (F' ∪ (F ∪ FV t2))" by simp
note typing.T_Obj[OF typing_regular'[OF ‹env ⊢ t1 : T›] domf' this]
ultimately show ?case using t' ‹T = U› by auto
qed
next
case (T_Obj env f T F t')
from Obj_beta[OF ‹Obj f T →⇩β t'›] show ?case
proof (elim exE conjE)
fix l f' a a' F' assume
"dom f = dom f'" and "f = f'(l ↦ a)" and "l ∈ dom f'" and
t': "t' = Obj (f'(l ↦ a')) T" and "finite F'" and
red_sp: "∀s p. s ∉ F' ∧ p ∉ F' ∧ s ≠ p
⟶ (∃t''. a⇗[Fvar s, Fvar p]⇖ →⇩β t'' ∧ a' = σ[s,p] t'')"
from this(2) ‹dom f = do T› have domf': "dom (f'(l ↦ a')) = do T" by auto
have
exF: "∀l'∈do T. ∀s p. s ∉ F ∪ F' ∧ p ∉ F ∪ F' ∧ s ≠ p
⟶ env⦇s:T⦈⦇p:param(the(T^l'))⦈
⊢ (the ((f'(l ↦ a')) l')⇗[Fvar s,Fvar p]⇖) : return(the(T^l'))"
proof (intro strip, elim conjE)
fix l' s p assume
"l' ∈ do T" and
nin_s: "s ∉ F ∪ F'" and
nin_p: "p ∉ F ∪ F'" and "s ≠ p"
with red_sp obtain t'' where "a⇗[Fvar s,Fvar p]⇖ →⇩β t''" and "a' = σ[s,p] t''"
by auto
with
beta_lc[OF this(1)] sopen_sclose_eq_t[of t'' 0 s p]
‹f = f'(l ↦ a)›
have "the (f l)⇗[Fvar s,Fvar p]⇖ →⇩β (the((f'(l ↦ a')) l)⇗[Fvar s,Fvar p]⇖)"
by (simp add: openz_def closez_def)
with T_Obj(4) nin_s nin_p ‹s ≠ p› ‹l' ∈ do T› ‹f = f'(l ↦ a)›
show
"env⦇s:T⦈⦇p:param(the(T^l'))⦈
⊢ (the((f'(l ↦ a')) l')⇗[Fvar s,Fvar p]⇖) : return(the(T^l'))"
by auto
qed
from typing.T_Obj[OF ‹ok env› domf' _ this] ‹finite F› ‹finite F'› t'
show ?case by (simp (no_asm_simp))
qed
next
case (T_Call env t1 T t2 l t')
from Call_beta[OF ‹Call t1 l t2 →⇩β t'›] show ?case
proof (elim disjE conjE exE)
fix t1' assume "t1 →⇩β t1'" and "t' = Call t1' l t2"
from
typing.T_Call[OF T_Call(2)[OF this(1)]
‹env ⊢ t2 : param(the(T^l))› ‹l ∈ do T›]
this(2)
show ?case by simp
next
fix t2' assume "t2 →⇩β t2'" and "t' = Call t1 l t2'"
from
typing.T_Call[OF ‹env ⊢ t1 : T› T_Call(4)[OF this(1)] ‹l ∈ do T›]
this(2)
show ?case by simp
next
fix f U assume "Obj f U = t1" and "l ∈ dom f" and t': "t' = (the(f l)⇗[Obj f U,t2]⇖)"
from
typing.T_Call[OF ‹env ⊢ t1 : T› ‹env ⊢ t2 : param(the(T^l))› ‹l ∈ do T›]
sym[OF this(1)] ‹env ⊢ t1 : T› ‹env ⊢ t2 : param(the(T^l))›
obj_inv[of env f U T]
obtain
objT: "env ⊢ (Obj f T) : T" and "T = U" and
callT: "env ⊢ Call (Obj f T) l t2 : return(the(T^l))"
by auto
have
"(∃F. finite F
∧ (∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p
⟶ env⦇s:T⦈⦇p:param(the(T^l))⦈
⊢ (the(f l)⇗[Fvar s,Fvar p]⇖) : return(the(T^l)))
⟹ env ⊢ (the (f l)⇗[Obj f T,t2]⇖) : return (the(T^l)))"
proof (elim exE conjE)
fix F
assume
"finite F" and
pred_F:
"∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p
⟶ env⦇s:T⦈⦇p:param(the(T^l))⦈
⊢ (the(f l)⇗[Fvar s,Fvar p]⇖) : return(the(T^l))"
from this(1) finite_FV[of "Obj f T"]
have "finite (F ∪ FV (Obj f T) ∪ FV t2)" by simp
from exFresh_s_p_cof[OF this]
obtain s p where
nin_s: "s ∉ F ∪ FV (Obj f T) ∪ FV t2" and
nin_p: "p ∉ F ∪ FV (Obj f T) ∪ FV t2" and "s ≠ p"
by auto
with pred_F
have
type_opened: "env⦇s:T⦈⦇p:param(the(T^l))⦈
⊢ {0 → [Fvar s,Fvar p]} the(f l) : return(the(T^l))"
by (auto simp: openz_def)
from nin_s nin_p FV_option_lem[of f] objT ‹l ∈ do T›
obtain
"s ∉ FV (the(f l)) ∪ FV (Obj f T) ∪ FV t2" and
"p ∉ FV (the(f l)) ∪ FV (Obj f T) ∪ FV t2" by auto
from
open_lemma[OF type_opened this ‹s ≠ p›
objT ‹env ⊢ t2 : param(the(T^l))›]
show ?thesis by (simp add: openz_def)
qed
with abs_typeE[OF callT] t' ‹T = U› show ?case by auto
qed
qed
theorem subject_reduction': "t →⇩β⇧* t' ⟹ e ⊢ t : T ⟹ e ⊢ t' : T"
by (induct set: rtranclp) (iprover intro: subject_reduction)+
lemma type_members_equal:
fixes A :: type and B :: type
assumes "do A = do B" and "∀i. (A^i) = (B^i)"
shows "A = B"
proof (cases A)
case (Object ta) thus ?thesis
proof (cases B)
case (Object tb)
from ‹∀i. (A^i) = (B^i)› ‹A = Object ta› ‹B = Object tb›
have "⋀i. ta i = tb i" by auto
with ‹A = Object ta› ‹B = Object tb› show ?thesis by (simp add: ext)
qed
qed
lemma not_var: "Env Map.empty ⊢ a : A ⟹ ∀x. a ≠ Fvar x"
by (rule allI, case_tac x, auto)
lemma Call_label_range: "(Env Map.empty) ⊢ Call (Obj c T) l b : A ⟹ l ∈ dom c"
by (erule typing_elims, erule typing.cases, simp_all)
lemma Call_subterm_type: "Env Map.empty ⊢ Call t l b: T
⟹ (∃T'. Env Map.empty ⊢ t : T') ∧ (∃T'. Env Map.empty ⊢ b : T')"
by (erule typing.cases) auto
lemma Upd_label_range: "Env Map.empty ⊢ Upd (Obj c T) l x : A ⟹ l ∈ dom c"
by (erule typing_elims, erule typing.cases, simp_all)
lemma Upd_subterm_type:
"Env Map.empty ⊢ Upd t l x : T ⟹ ∃T'. Env Map.empty ⊢ t : T'"
by (erule typing.cases) auto
lemma no_var: "∃T. Env Map.empty ⊢ Fvar x : T ⟹ False"
by (case_tac x, auto)
lemma no_bvar: "e ⊢ Bvar x : T ⟹ False"
by (erule typing.cases, auto)
subsubsection‹Unique Type›
theorem type_unique[rule_format]:
assumes "env ⊢ a: T"
shows "∀T'. env ⊢ a: T' ⟶ T = T'"
using assms
proof (induct rule: typing.induct)
case T_Var thus ?case by (auto simp: add_get_eq)
next
case T_Obj show ?case by (auto simp: sym[OF obj_inv])
next
case T_Call from this(2) show ?case by auto
next
case T_Upd from this(4) show ?case by auto
qed
subsubsection‹Progress›
text ‹Final Type Soundness Lemma›
theorem progress:
assumes "Env Map.empty ⊢ t : A" and "¬(∃c A. t = Obj c A)"
shows "∃b. t →⇩β b"
proof -
fix f
have
"(∀A. Env Map.empty ⊢ t : A ⟶ ¬(∃c T. t = Obj c T) ⟶ (∃b. t →⇩β b))
&(∀A. Env Map.empty ⊢ Obj f A : A ⟶ ¬(∃c T. Obj f A = Obj c T)
⟶ (∃b. Obj f A →⇩β b))"
proof (induct rule: sterm_induct)
case (Bvar b) with no_bvar[of "Env Map.empty" b] show ?case
by auto
next
case (Fvar x) with Fvar_beta[of x] show ?case
by auto
next
case Obj show ?case by auto
next
case empty thus ?case by auto
next
case insert show ?case by auto
next
case (Call t1 l t2) show ?case
proof (clarify)
fix T assume
"Env Map.empty ⊢ t1 : T" and "Env Map.empty ⊢ t2 : param(the(T^l))" and "l ∈ do T"
note lc = typing_regular''[OF this(1)] typing_regular''[OF this(2)]
from
‹Env Map.empty ⊢ t1 : T›
‹∀A. Env Map.empty ⊢ t1 : A ⟶ ¬ (∃c T. t1 = Obj c T) ⟶ (∃b. t1 →⇩β b)›
have "(∃c B. t1 = Obj c B) ∨ (∃b. t1 →⇩β b)" by auto
thus "∃b. Call t1 l t2 →⇩β b"
proof (elim disjE exE)
fix c B assume "t1 = Obj c B"
with
‹Env Map.empty ⊢ t1 : T› obj_inv[of "Env Map.empty" c B T]
‹l ∈ do T› obj_inv_elim[of "Env Map.empty" c B]
have "l ∈ dom c" by auto
with ‹t1 = Obj c B› lc beta.beta[of l c B t2]
show ?thesis by auto
next
fix b assume "t1 →⇩β b"
from beta.beta_CallL[OF this lc(2)] show ?thesis by auto
qed
qed
next
case (Upd t1 l t2) show ?case
proof (clarify)
fix T F
assume
"finite F" and
"∀s p. s ∉ F ∧ p ∉ F ∧ s ≠ p
⟶ Env Map.empty⦇s:T⦈⦇p:param(the(T^l))⦈
⊢ (t2⇗[Fvar s,Fvar p]⇖) : return(the(T^l))" and
"Env Map.empty ⊢ t1 : T" and
"l ∈ do T"
from typing_regular''[OF T_Upd[OF this]] lc_upd[of t1 l t2]
obtain "lc t1" and "body t2" by auto
from
‹Env Map.empty ⊢ t1 : T›
‹∀A. Env Map.empty ⊢ t1 : A ⟶ ¬ (∃c T. t1 = Obj c T) ⟶ (∃b. t1 →⇩β b)›
have "(∃c B. t1 = Obj c B) ∨ (∃b. t1 →⇩β b)" by auto
thus "∃b. Upd t1 l t2 →⇩β b"
proof (elim disjE exE)
fix c B assume "t1 = Obj c B"
with
‹Env Map.empty ⊢ t1 : T› obj_inv[of "Env Map.empty" c B T]
‹l ∈ do T› obj_inv_elim[of "Env Map.empty" c B]
have "l ∈ dom c" by auto
with ‹t1 = Obj c B› ‹lc t1› ‹body t2› beta.beta_Upd[of l c B t2]
show ?thesis by auto
next
fix b assume "t1 →⇩β b"
from beta.beta_UpdL[OF this ‹body t2›] show ?thesis by auto
qed
qed
qed
with assms show ?thesis by auto
qed
end