(*<*) theory Fsub imports"HOL-Nominal.Nominal" begin (*>*)
text‹Authors: Christian Urban, Benjamin Pierce, Dimitrios Vytiniotis Stephanie Weirich Steve Zdancewic Julien Narboux Stefan Berghofer with great help from Markus Wenzel.›
section‹Types for Names, Nominal Datatype Declaration for Types and Terms›
text‹The main point of this solution is to use names everywhere (be they bound, binding or free). In System \FSUB{} there are two kinds of names corresponding to type-variables and to term-variables. These two kinds of names are represented in the nominal datatype package as atom-types ‹tyvrs› a
atom_decl tyvrs vrs
text‹There are numerous facts that come with this declaration: for example that there are infinitely many elements in ‹tyvrs› a
text‹The constructors for types and terms in System \FSUB{} contain abstractions over type-variables and term-variables. The nominal datatype package uses ‹«…¬…›to indicate where abstractions occur.›
nominal_datatype ty =
Tvar "tyvrs"
| Top
| Arrow "ty""ty" (infixr‹→› 200)
| Forall "«tyvrs¬ty""ty"
text‹To be polite to the eye, some more familiar notation is introduced. Because of the change in the order of arguments, one needs to use translation rules, instead of syntax annotations at the term-constructors as given above for 🍋‹Arrow›.›
abbreviation
Forall_syn :: "tyvrs ==> ty ==> ty ==> ty" (‹(3∀_🚫./ _)› [0, 0, 10] 10) where "∀X<:T🪙1. T🪙2 ≡ ty.Forall X T🪙2 T🪙1"
abbreviation
Abs_syn :: "vrs ==> ty ==> trm ==> trm" (‹(3λ_:_./ _)› [0, 0, 10] 10) where "λx:T. t ≡ trm.Abs x t T"
abbreviation
TAbs_syn :: "tyvrs ==> ty ==> trm ==> trm" (‹(3λ_🚫./ _)› [0, 0, 10] 10) where "λX<:T. t ≡ trm.TAbs X t T"
text‹Again there are numerous facts that are proved automatically for 🍋‹ty› and 🍋‹trm›: for example that the set of free variables, i.e.~the ‹support›, is finite. However note that nominal-datatype declarations do \emph{not} define ``classical" constructor-based datatypes, but rather define $\alpha$-equivalence classes---we can for example show that $\alpha$-equivalent 🍋‹ty›s and 🍋‹trm›s are equal:›
lemma alpha_illustration: shows"(∀X<:T. Tvar X) = (∀Y<:T. Tvar Y)" and"(λx:T. Var x) = (λy:T. Var y)" by (simp_all add: ty.inject trm.inject alpha calc_atm fresh_atm)
section‹SubTyping Contexts›
nominal_datatype binding =
VarB vrs ty
| TVarB tyvrs ty
type_synonym env = "binding list"
text‹Typing contexts are represented as lists that ``grow" on the left; we thereby deviating from the convention in the POPLmark-paper. The lists contain pairs of type-variables and types (this is sufficient for Part 1A).›
text‹In order to state validity-conditions for typing-contexts, the notion of a ‹dom›of a typing-context is handy.›
nominal_primrec "tyvrs_of" :: "binding ==> tyvrs set" where "tyvrs_of (VarB x y) = {}"
| "tyvrs_of (TVarB x y) = {x}" by auto
nominal_primrec "vrs_of" :: "binding ==> vrs set" where "vrs_of (VarB x y) = {x}"
| "vrs_of (TVarB x y) = {}" by auto
lemma ty_dom_inclusion: assumes a: "(TVarB X T)∈set Γ" shows"X∈(ty_dom Γ)" using a by (induct Γ) (auto)
lemma ty_binding_existence: assumes"X ∈ (tyvrs_of a)" shows"∃T.(TVarB X T=a)" using assms by (nominal_induct a rule: binding.strong_induct) (auto)
lemma ty_dom_existence: assumes a: "X∈(ty_dom Γ)" shows"∃T.(TVarB X T)∈set Γ" using a proof (induction Γ) case Nil thenshow ?caseby simp next case (Cons a Γ) thenshow ?case using ty_binding_existence by fastforce qed
lemma ty_vrs_prm_simp: fixes pi::"vrs prm" and S::"ty" shows"pi∙S = S" by (induct S rule: ty.induct) (auto simp: calc_atm)
lemma fresh_ty_dom_cons: fixes X::"tyvrs" shows"X♯(ty_dom (Y#Γ)) = (X♯(tyvrs_of Y) ∧ X♯(ty_dom Γ))" proof (nominal_induct rule:binding.strong_induct) case (VarB vrs ty) thenshow ?caseby auto next case (TVarB tyvrs ty) thenshow ?case by (simp add: at_fin_set_supp at_tyvrs_inst finite_doms(1) fresh_def supp_atm(1)) qed
lemma tyvrs_fresh: fixes X::"tyvrs" assumes"X ♯ a" shows"X ♯ tyvrs_of a" and"X ♯ vrs_of a" using assms by (nominal_induct a rule:binding.strong_induct) (force simp: fresh_singleton)+
lemma fresh_dom: fixes X::"tyvrs" assumes a: "X♯Γ" shows"X♯(ty_dom Γ)" using a proof (induct Γ) case Nil thenshow ?caseby auto next case (Cons a Γ) thenshow ?case by (meson fresh_list_cons fresh_ty_dom_cons tyvrs_fresh(1)) qed
text‹Not all lists of type 🍋‹env›are well-formed. One condition requires that in 🍋‹TVarB X S#Γ›all free variables of 🍋‹S› must be in the 🍋‹ty_dom›of 🍋‹Γ›, that is 🍋‹S› must be ‹closed› in 🍋‹Γ›. The set of free variables of 🍋‹S› is the ‹support›of 🍋‹S›.›
lemma validE_append: assumes a: "⊨ (Δ@Γ) ok" shows"⊨ Γ ok" using a proof (induct Δ) case (Cons a Γ') thenshow ?case by (nominal_induct a rule:binding.strong_induct) auto qed (auto)
lemma replace_type: assumes a: "⊨ (Δ@(TVarB X T)#Γ) ok" and b: "S closed_in Γ" shows"⊨ (Δ@(TVarB X S)#Γ) ok" using a b proof(induct Δ) case Nil thenshow ?caseby (auto intro: valid_cons simp add: doms_append closed_in_def) next case (Cons a Γ') thenshow ?case by (nominal_induct a rule:binding.strong_induct)
(auto intro!: valid_cons simp add: doms_append closed_in_def) qed
text‹Well-formed contexts have a unique type-binding for a type-variable.›
lemma uniqueness_of_ctxt: fixes Γ::"env" assumes a: "⊨ Γ ok" and b: "(TVarB X T)∈set Γ" and c: "(TVarB X S)∈set Γ" shows"T=S" using a b c proof (induct) case (valid_consT Γ X' T') moreover
{ fix Γ'::"env" assume a: "X'♯(ty_dom Γ')" have"¬(∃T.(TVarB X' T)∈(set Γ'))"using a proof (induct Γ') case (Cons Y Γ') thus"¬ (∃T.(TVarB X' T)∈set(Y#Γ'))" by (simp add: fresh_ty_dom_cons
fresh_fin_union[OF pt_tyvrs_inst at_tyvrs_inst fs_tyvrs_inst]
finite_vrs finite_doms,
auto simp: fresh_atm fresh_singleton) qed (simp)
} ultimatelyshow"T=S"by (auto simp: binding.inject) qed (auto)
lemma uniqueness_of_ctxt': fixes Γ::"env" assumes a: "⊨ Γ ok" and b: "(VarB x T)∈set Γ" and c: "(VarB x S)∈set Γ" shows"T=S" using a b c proof (induct) case (valid_cons Γ x' T') moreover
{ fix Γ'::"env" assume a: "x'♯(trm_dom Γ')" have"¬(∃T.(VarB x' T)∈(set Γ'))"using a proof (induct Γ') case (Cons y Γ') thus"¬ (∃T.(VarB x' T)∈set(y#Γ'))" by (simp add: fresh_fin_union[OF pt_vrs_inst at_vrs_inst fs_vrs_inst]
finite_vrs finite_doms,
auto simp: fresh_atm fresh_singleton) qed (simp)
} ultimatelyshow"T=S"by (auto simp: binding.inject) qed (auto)
section‹Size and Capture-Avoiding Substitution for Types›
lemma subst_eqvt[eqvt]: fixes pi::"tyvrs prm" and T::"ty" shows"pi∙(T[X ↝ T']🪙τ) = (pi∙T)[(pi∙X) ↝ (pi∙T')]🪙τ" by (nominal_induct T avoiding: X T' rule: ty.strong_induct)
(perm_simp add: fresh_bij)+
lemma subst_eqvt'[eqvt]: fixes pi::"vrs prm" and T::"ty" shows"pi∙(T[X ↝ T']🪙τ) = (pi∙T)[(pi∙X) ↝ (pi∙T')]🪙τ" by (nominal_induct T avoiding: X T' rule: ty.strong_induct)
(perm_simp add: fresh_left)+
lemma type_subst_fresh: fixes X::"tyvrs" assumes"X♯T"and"X♯P" shows"X♯T[Y ↝ P]🪙τ" using assms by (nominal_induct T avoiding: X Y P rule:ty.strong_induct)
(auto simp: abs_fresh)
lemma fresh_type_subst_fresh: assumes"X♯T'" shows"X♯T[X ↝ T']🪙τ" using assms by (nominal_induct T avoiding: X T' rule: ty.strong_induct)
(auto simp: fresh_atm abs_fresh)
lemma type_subst_identity: "X♯T ==> T[X ↝ U]🪙τ = T" by (nominal_induct T avoiding: X U rule: ty.strong_induct)
(simp_all add: fresh_atm abs_fresh)
lemma type_substitution_lemma: "X ≠ Y ==> X♯L ==> M[X ↝ N]🪙τ[Y ↝ L]🪙τ = M[Y ↝ L]🪙τ[X ↝ N[Y ↝ L]🪙τ]🪙τ" by (nominal_induct M avoiding: X Y N L rule: ty.strong_induct)
(auto simp: type_subst_fresh type_subst_identity)
lemma type_subst_rename: "Y♯T ==> ([(Y,X)]∙T)[Y ↝ U]🪙τ = T[X ↝ U]🪙τ" by (nominal_induct T avoiding: X Y U rule: ty.strong_induct)
(simp_all add: fresh_atm calc_atm abs_fresh fresh_aux)
nominal_primrec
subst_tyb :: "binding ==> tyvrs ==> ty ==> binding" (‹_[_ ↝ _]🪙b› [100,100,100] 100) where "(TVarB X U)[Y ↝ T]🪙b = TVarB X (U[Y ↝ T]🪙τ)"
| "(VarB X U)[Y ↝ T]🪙b = VarB X (U[Y ↝ T]🪙τ)" by auto
lemma binding_subst_fresh: fixes X::"tyvrs" assumes"X♯a" and"X♯P" shows"X♯a[Y ↝ P]🪙b" using assms by (nominal_induct a rule: binding.strong_induct)
(auto simp: type_subst_fresh)
lemma binding_subst_identity: shows"X♯B ==> B[X ↝ U]🪙b = B" by (induct B rule: binding.induct)
(simp_all add: fresh_atm type_subst_identity)
lemma subst_trm_fresh_tyvar: fixes X::"tyvrs" shows"X♯t ==> X♯u ==> X♯t[x ↝ u]" by (nominal_induct t avoiding: x u rule: trm.strong_induct)
(auto simp: abs_fresh)
lemma subst_trm_fresh_var: "x♯u ==> x♯t[x ↝ u]" by (nominal_induct t avoiding: x u rule: trm.strong_induct)
(simp_all add: abs_fresh fresh_atm ty_vrs_fresh)
lemma subst_trm_eqvt[eqvt]: fixes pi::"tyvrs prm" and t::"trm" shows"pi∙(t[x ↝ u]) = (pi∙t)[(pi∙x) ↝ (pi∙u)]" by (nominal_induct t avoiding: x u rule: trm.strong_induct)
(perm_simp add: fresh_left)+
lemma subst_trm_eqvt'[eqvt]: fixes pi::"vrs prm" and t::"trm" shows"pi∙(t[x ↝ u]) = (pi∙t)[(pi∙x) ↝ (pi∙u)]" by (nominal_induct t avoiding: x u rule: trm.strong_induct)
(perm_simp add: fresh_left)+
lemma subst_trm_rename: "y♯t ==> ([(y, x)] ∙ t)[y ↝ u] = t[x ↝ u]" by (nominal_induct t avoiding: x y u rule: trm.strong_induct)
(simp_all add: fresh_atm calc_atm abs_fresh fresh_aux ty_vrs_fresh perm_fresh_fresh)
lemma subst_trm_ty_fresh: fixes X::"tyvrs" shows"X♯t ==> X♯T ==> X♯t[Y ↝🪙τ T]" by (nominal_induct t avoiding: Y T rule: trm.strong_induct)
(auto simp: abs_fresh type_subst_fresh)
lemma subst_trm_ty_fresh': "X♯T ==> X♯t[X ↝🪙τ T]" by (nominal_induct t avoiding: X T rule: trm.strong_induct)
(simp_all add: abs_fresh fresh_type_subst_fresh fresh_atm)
lemma subst_trm_ty_eqvt[eqvt]: fixes pi::"tyvrs prm" and t::"trm" shows"pi∙(t[X ↝🪙τ T]) = (pi∙t)[(pi∙X) ↝🪙τ (pi∙T)]" by (nominal_induct t avoiding: X T rule: trm.strong_induct)
(perm_simp add: fresh_bij subst_eqvt)+
lemma subst_trm_ty_eqvt'[eqvt]: fixes pi::"vrs prm" and t::"trm" shows"pi∙(t[X ↝🪙τ T]) = (pi∙t)[(pi∙X) ↝🪙τ (pi∙T)]" by (nominal_induct t avoiding: X T rule: trm.strong_induct)
(perm_simp add: fresh_left subst_eqvt')+
lemma subst_trm_ty_rename: "Y♯t ==> ([(Y, X)] ∙ t)[Y ↝🪙τ U] = t[X ↝🪙τ U]" by (nominal_induct t avoiding: X Y U rule: trm.strong_induct)
(simp_all add: fresh_atm calc_atm abs_fresh fresh_aux type_subst_rename)
section‹Subtyping-Relation›
text‹The definition for the subtyping-relation follows quite closely what is written in the POPLmark-paper, except for the premises dealing with well-formed contexts and the freshness constraint 🍋‹X♯Γ›in the ‹S_Forall›-rule. (The freshness constraint is specific to the \emph{nominal approach}. Note, however, that the constraint does \emph{not} make the subtyping-relation ``partial"\ldots because we work over $\alpha$-equivalence classes.)›
inductive
subtype_of :: "env ==> ty ==> ty ==> bool" (‹_⊨_🚫› [100,100,100] 100) where
SA_Top[intro]: "[⊨ Γ ok; S closed_in Γ]==> Γ ⊨ S <: Top"
| SA_refl_TVar[intro]: "[⊨ Γ ok; X ∈ ty_dom Γ]==> Γ ⊨ Tvar X <: Tvar X"
| SA_trans_TVar[intro]: "[(TVarB X S) ∈ set Γ; Γ ⊨ S <: T]==> Γ ⊨ (Tvar X) <: T"
| SA_arrow[intro]: "[Γ ⊨ T🪙1 <: S🪙1; Γ ⊨ S🪙2 <: T🪙2]==> Γ ⊨ (S🪙1 → S🪙2) <: (T🪙1 → T🪙2)"
| SA_all[intro]: "[Γ ⊨ T🪙1 <: S🪙1; ((TVarB X T🪙1)#Γ) ⊨ S🪙2 <: T🪙2]==> Γ ⊨ (∀X<:S🪙1. S🪙2) <: (∀X<:T🪙1. T🪙2)"
lemma subtype_implies_ok: fixes X::"tyvrs" assumes a: "Γ ⊨ S <: T" shows"⊨ Γ ok" using a by (induct) (auto)
lemma subtype_implies_closed: assumes a: "Γ ⊨ S <: T" shows"S closed_in Γ ∧ T closed_in Γ" using a proof (induct) case (SA_Top Γ S) have"Top closed_in Γ"by (simp add: closed_in_def ty.supp) moreover have"S closed_in Γ"by fact ultimatelyshow"S closed_in Γ ∧ Top closed_in Γ"by simp next case (SA_trans_TVar X S Γ T) have"(TVarB X S)∈set Γ"by fact hence"X ∈ ty_dom Γ"by (rule ty_dom_inclusion) hence"(Tvar X) closed_in Γ"by (simp add: closed_in_def ty.supp supp_atm) moreover have"S closed_in Γ ∧ T closed_in Γ"by fact hence"T closed_in Γ"by force ultimatelyshow"(Tvar X) closed_in Γ ∧ T closed_in Γ"by simp qed (auto simp: closed_in_def ty.supp supp_atm abs_supp)
lemma subtype_implies_fresh: fixes X::"tyvrs" assumes a1: "Γ ⊨ S <: T" and a2: "X♯Γ" shows"X♯S ∧ X♯T" proof - from a1 have"⊨ Γ ok"by (rule subtype_implies_ok) with a2 have"X♯ty_dom(Γ)"by (simp add: fresh_dom) moreover from a1 have"S closed_in Γ ∧ T closed_in Γ"by (rule subtype_implies_closed) hence"supp S ⊆ ((supp (ty_dom Γ))::tyvrs set)" and"supp T ⊆ ((supp (ty_dom Γ))::tyvrs set)"by (simp_all add: ty_dom_supp closed_in_def) ultimatelyshow"X♯S ∧ X♯T"by (force simp: supp_prod fresh_def) qed
lemma valid_ty_dom_fresh: fixes X::"tyvrs" assumes valid: "⊨ Γ ok" shows"X♯(ty_dom Γ) = X♯Γ" using valid proof induct case valid_nil thenshow ?caseby auto next case (valid_consT Γ X T) thenshow ?case by (auto simp: fresh_list_cons closed_in_fresh
fresh_fin_insert [OF pt_tyvrs_inst at_tyvrs_inst fs_tyvrs_inst] finite_doms) next case (valid_cons Γ x T) thenshow ?case using fresh_atm by (auto simp: fresh_list_cons closed_in_fresh) qed
lemma subtype_reflexivity: assumes a: "⊨ Γ ok" and b: "T closed_in Γ" shows"Γ ⊨ T <: T" using a b proof(nominal_induct T avoiding: Γ rule: ty.strong_induct) case (Forall X T🪙1 T🪙2) have ih_T🪙1: "∧Γ. [⊨ Γ ok; T🪙1 closed_in Γ]==> Γ ⊨ T🪙1 <: T🪙1"by fact have ih_T🪙2: "∧Γ. [⊨ Γ ok; T🪙2 closed_in Γ]==> Γ ⊨ T🪙2 <: T🪙2"by fact have fresh_cond: "X♯Γ"by fact hence fresh_ty_dom: "X♯(ty_dom Γ)"by (simp add: fresh_dom) have"(∀X<:T🪙2. T🪙1) closed_in Γ"by fact hence closed🪙T2: "T🪙2 closed_in Γ"and closed🪙T1: "T🪙1 closed_in ((TVarB X T🪙2)#Γ)" by (auto simp: closed_in_def ty.supp abs_supp) have ok: "⊨ Γ ok"by fact hence ok': "⊨ ((TVarB X T🪙2)#Γ) ok"using closed🪙T2 fresh_ty_dom by simp have"Γ ⊨ T🪙2 <: T🪙2"using ih_T🪙2 closed🪙T2 ok by simp moreover have"((TVarB X T🪙2)#Γ) ⊨ T🪙1 <: T🪙1"using ih_T🪙1 closed🪙T1 ok' by simp ultimatelyshow"Γ ⊨ (∀X<:T🪙2. T🪙1) <: (∀X<:T🪙2. T🪙1)"using fresh_cond by (simp add: subtype_of.SA_all) qed (auto simp: closed_in_def ty.supp supp_atm)
lemma subtype_reflexivity_semiautomated: assumes a: "⊨ Γ ok" and b: "T closed_in Γ" shows"Γ ⊨ T <: T" using a b apply(nominal_induct T avoiding: Γ rule: ty.strong_induct) apply(auto simp: ty.supp abs_supp supp_atm closed_in_def) 🍋‹Too bad that this instantiation cannot be found automatically by \isakeyword{auto}; \isakeyword{blast} would find it if we had not used an explicit definition for ‹closed_in_def›.› apply(drule_tac x="(TVarB tyvrs ty2)#Γ"in meta_spec) apply(force dest: fresh_dom simp add: closed_in_def) done
section‹Weakening›
text‹In order to prove weakening we introduce the notion of a type-context extending another. This generalization seems to make the proof for weakening to be smoother than if we had strictly adhered to the version in the POPLmark-paper.›
definition extends :: "env ==> env ==> bool" (‹_ extends _› [100,100] 100) where "Δ extends Γ ≡∀X Q. (TVarB X Q)∈set Γ ⟶ (TVarB X Q)∈set Δ"
lemma extends_ty_dom: assumes"Δ extends Γ" shows"ty_dom Γ ⊆ ty_dom Δ" using assms by (meson extends_def subsetI ty_dom_existence ty_dom_inclusion)
lemma extends_memb: assumes a: "Δ extends Γ" and b: "(TVarB X T) ∈ set Γ" shows"(TVarB X T) ∈ set Δ" using a b by (simp add: extends_def)
lemma weakening: assumes a: "Γ ⊨ S <: T" and b: "⊨ Δ ok" and c: "Δ extends Γ" shows"Δ ⊨ S <: T" using a b c proof (nominal_induct Γ S T avoiding: Δ rule: subtype_of.strong_induct) case (SA_Top Γ S) have lh_drv_prem: "S closed_in Γ"by fact have"⊨ Δ ok"by fact moreover have"Δ extends Γ"by fact hence"S closed_in Δ"using lh_drv_prem by (simp only: extends_closed) ultimatelyshow"Δ ⊨ S <: Top"by force next case (SA_trans_TVar X S Γ T) have lh_drv_prem: "(TVarB X S) ∈ set Γ"by fact have ih: "∧Δ. ⊨ Δ ok ==> Δ extends Γ ==> Δ ⊨ S <: T"by fact have ok: "⊨ Δ ok"by fact have extends: "Δ extends Γ"by fact have"(TVarB X S) ∈ set Δ"using lh_drv_prem extends by (simp only: extends_memb) moreover have"Δ ⊨ S <: T"using ok extends ih by simp ultimatelyshow"Δ ⊨ Tvar X <: T"using ok by force next case (SA_refl_TVar Γ X) have lh_drv_prem: "X ∈ ty_dom Γ"by fact have"⊨ Δ ok"by fact moreover have"Δ extends Γ"by fact hence"X ∈ ty_dom Δ"using lh_drv_prem by (force dest: extends_ty_dom) ultimatelyshow"Δ ⊨ Tvar X <: Tvar X"by force next case (SA_arrow Γ T🪙1 S🪙1 S🪙2 T🪙2) thus"Δ ⊨ S🪙1 → S🪙2 <: T🪙1 → T🪙2"by blast next case (SA_all Γ T🪙1 S🪙1 X S🪙2 T🪙2) have fresh_cond: "X♯Δ"by fact hence fresh_dom: "X♯(ty_dom Δ)"by (simp add: fresh_dom) have ih🪙1: "∧Δ. ⊨ Δ ok ==> Δ extends Γ ==> Δ ⊨ T🪙1 <: S🪙1"by fact have ih🪙2: "∧Δ. ⊨ Δ ok ==> Δ extends ((TVarB X T🪙1)#Γ) ==> Δ ⊨ S🪙2 <: T🪙2"by fact have lh_drv_prem: "Γ ⊨ T🪙1 <: S🪙1"by fact hence closed🪙T1: "T🪙1 closed_in Γ"by (simp add: subtype_implies_closed) have ok: "⊨ Δ ok"by fact have ext: "Δ extends Γ"by fact have"T🪙1 closed_in Δ"using ext closed🪙T1 by (simp only: extends_closed) hence"⊨ ((TVarB X T🪙1)#Δ) ok"using fresh_dom ok by force moreover have"((TVarB X T🪙1)#Δ) extends ((TVarB X T🪙1)#Γ)"using ext by (force simp: extends_def) ultimatelyhave"((TVarB X T🪙1)#Δ) ⊨ S🪙2 <: T🪙2"using ih🪙2 by simp moreover have"Δ ⊨ T🪙1 <: S🪙1"using ok ext ih🪙1 by simp ultimatelyshow"Δ ⊨ (∀X<:S🪙1. S🪙2) <: (∀X<:T🪙1. T🪙2)"using ok by (force intro: SA_all) qed
text‹In fact all ``non-binding" cases can be solved automatically:›
lemma weakening_more_automated: assumes a: "Γ ⊨ S <: T" and b: "⊨ Δ ok" and c: "Δ extends Γ" shows"Δ ⊨ S <: T" using a b c proof (nominal_induct Γ S T avoiding: Δ rule: subtype_of.strong_induct) case (SA_all Γ T🪙1 S🪙1 X S🪙2 T🪙2) have fresh_cond: "X♯Δ"by fact hence fresh_dom: "X♯(ty_dom Δ)"by (simp add: fresh_dom) have ih🪙1: "∧Δ. ⊨ Δ ok ==> Δ extends Γ ==> Δ ⊨ T🪙1 <: S🪙1"by fact have ih🪙2: "∧Δ. ⊨ Δ ok ==> Δ extends ((TVarB X T🪙1)#Γ) ==> Δ ⊨ S🪙2 <: T🪙2"by fact have lh_drv_prem: "Γ ⊨ T🪙1 <: S🪙1"by fact hence closed🪙T1: "T🪙1 closed_in Γ"by (simp add: subtype_implies_closed) have ok: "⊨ Δ ok"by fact have ext: "Δ extends Γ"by fact have"T🪙1 closed_in Δ"using ext closed🪙T1 by (simp only: extends_closed) hence"⊨ ((TVarB X T🪙1)#Δ) ok"using fresh_dom ok by force moreover have"((TVarB X T🪙1)#Δ) extends ((TVarB X T🪙1)#Γ)"using ext by (force simp: extends_def) ultimatelyhave"((TVarB X T🪙1)#Δ) ⊨ S🪙2 <: T🪙2"using ih🪙2 by simp moreover have"Δ ⊨ T🪙1 <: S🪙1"using ok ext ih🪙1 by simp ultimatelyshow"Δ ⊨ (∀X<:S🪙1. S🪙2) <: (∀X<:T🪙1. T🪙2)"using ok by (force intro: SA_all) qed (blast intro: extends_closed extends_memb dest: extends_ty_dom)+
section‹Transitivity and Narrowing›
text‹Some inversion lemmas that are needed in the transitivity and narrowing proof.›
lemma S_ForallE_left: shows"[Γ ⊨ (∀X<:S🪙1. S🪙2) <: T; X♯Γ; X♯S🪙1; X♯T] ==> T = Top ∨ (∃T🪙1 T🪙2. T = (∀X<:T🪙1. T🪙2) ∧ Γ ⊨ T🪙1 <: S🪙1 ∧ ((TVarB X T🪙1)#Γ) ⊨ S🪙2 <: T🪙2)" using subtype_of.strong_cases[where X="X"] by(force simp: abs_fresh ty.inject alpha)
text‹Next we prove the transitivity and narrowing for the subtyping-relation. The POPLmark-paper says the following: \begin{quote}
java.lang.NullPointerException \begin{enumerate} \item If 🍋‹Γ ⊨ S🚫›and 🍋‹Γ ⊨ Q🚫›, then 🍋‹Γ ⊨ S🚫›. \item If ‹Γ,X🚫,Δ ⊨ M🚫›and 🍋‹Γ ⊨ P🚫› then ‹Γ,X🚫,Δ ⊨ M🚫›. \end{enumerate} \end{lemma} The two parts are proved simultaneously, by induction on the size of 🍋‹Q›. The argument for part (2) assumes that part (1) has been established already for the 🍋‹Q›in question; part (1) uses part (2) only for strictly smaller 🍋‹Q›. \end{quote} For the induction on the size of 🍋‹Q›, we use the induction-rule ‹measure_induct_rule›: \begin{center} @{thm measure_induct_rule[of "size_ty",no_vars]} \end{center} That means in order to show a property 🍋‹P a›for all 🍋‹a›, the induct-rule requires to prove that for all 🍋‹x›🍋‹P x› holds using the assumption that for all 🍋‹y›whose size is strictly smaller than that of 🍋‹x›the property 🍋‹P y› holds.›
lemma shows subtype_transitivity: "Γ⊨S<:Q ==> Γ⊨Q<:T ==> Γ⊨S<:T" and subtype_narrow: "(Δ@[(TVarB X Q)]@Γ)⊨M<:N ==> Γ⊨P<:Q ==> (Δ@[(TVarB X P)]@Γ)⊨M<:N" proof (induct Q arbitrary: Γ S T Δ X P M N taking: "size_ty" rule: measure_induct_rule) case (less Q) have IH_trans: "∧Q' Γ S T. [size_ty Q' < size_ty Q; Γ⊨S<:Q'; Γ⊨Q'<:T]==> Γ⊨S<:T"by fact have IH_narrow: "∧Q' Δ Γ X M N P. [size_ty Q' < size_ty Q; (Δ@[(TVarB X Q')]@Γ)⊨M<:N; Γ⊨P<:Q'] ==> (Δ@[(TVarB X P)]@Γ)⊨M<:N"by fact
{ fix Γ S T have"[Γ ⊨ S <: Q; Γ ⊨ Q <: T]==> Γ ⊨ S <: T" proof (induct Γ S Q≡Q rule: subtype_of.induct) case (SA_Top Γ S) thenhave rh_drv: "Γ ⊨ Top <: T"by simp thenhave T_inst: "T = Top"by (auto elim: S_TopE) from‹⊨ Γ ok›and‹S closed_in Γ› have"Γ ⊨ S <: Top"by auto thenshow"Γ ⊨ S <: T"using T_inst by simp next case (SA_trans_TVar Y U Γ) thenhave IH_inner: "Γ ⊨ U <: T"by simp have"(TVarB Y U) ∈ set Γ"by fact with IH_inner show"Γ ⊨ Tvar Y <: T"by auto next case (SA_refl_TVar Γ X) thenshow"Γ ⊨ Tvar X <: T"by simp next case (SA_arrow Γ Q🪙1 S🪙1 S🪙2 Q🪙2) thenhave rh_drv: "Γ ⊨ Q🪙1 → Q🪙2 <: T"by simp from‹Q🪙1 → Q🪙2 = Q› have Q🪙12_less: "size_ty Q🪙1 < size_ty Q""size_ty Q🪙2 < size_ty Q"by auto have lh_drv_prm🪙1: "Γ ⊨ Q🪙1 <: S🪙1"by fact have lh_drv_prm🪙2: "Γ ⊨ S🪙2 <: Q🪙2"by fact from rh_drv have"T=Top ∨ (∃T🪙1 T🪙2. T=T🪙1→T🪙2 ∧ Γ⊨T🪙1<:Q🪙1 ∧ Γ⊨Q🪙2<:T🪙2)" by (auto elim: S_ArrowE_left) moreover have"S🪙1 closed_in Γ"and"S🪙2 closed_in Γ" using lh_drv_prm🪙1 lh_drv_prm🪙2 by (simp_all add: subtype_implies_closed) hence"(S🪙1 → S🪙2) closed_in Γ"by (simp add: closed_in_def ty.supp) moreover have"⊨ Γ ok"using rh_drv by (rule subtype_implies_ok) moreover
{ assume"∃T🪙1 T🪙2. T = T🪙1→T🪙2 ∧ Γ ⊨ T🪙1 <: Q🪙1 ∧ Γ ⊨ Q🪙2 <: T🪙2" thenobtain T🪙1 T🪙2 where T_inst: "T = T🪙1 → T🪙2" and rh_drv_prm🪙1: "Γ ⊨ T🪙1 <: Q🪙1" and rh_drv_prm🪙2: "Γ ⊨ Q🪙2 <: T🪙2"by force from IH_trans[of "Q🪙1"] have"Γ ⊨ T🪙1 <: S🪙1"using Q🪙12_less rh_drv_prm🪙1 lh_drv_prm🪙1 by simp moreover from IH_trans[of "Q🪙2"] have"Γ ⊨ S🪙2 <: T🪙2"using Q🪙12_less rh_drv_prm🪙2 lh_drv_prm🪙2 by simp ultimatelyhave"Γ ⊨ S🪙1 → S🪙2 <: T🪙1 → T🪙2"by auto thenhave"Γ ⊨ S🪙1 → S🪙2 <: T"using T_inst by simp
} ultimatelyshow"Γ ⊨ S🪙1 → S🪙2 <: T"by blast next case (SA_all Γ Q🪙1 S🪙1 X S🪙2 Q🪙2) thenhave rh_drv: "Γ ⊨ (∀X<:Q🪙1. Q🪙2) <: T"by simp have lh_drv_prm🪙1: "Γ ⊨ Q🪙1 <: S🪙1"by fact have lh_drv_prm🪙2: "((TVarB X Q🪙1)#Γ) ⊨ S🪙2 <: Q🪙2"by fact thenhave"X♯Γ"by (force dest: subtype_implies_ok simp add: valid_ty_dom_fresh) thenhave fresh_cond: "X♯Γ""X♯Q🪙1""X♯T"using rh_drv lh_drv_prm🪙1 by (simp_all add: subtype_implies_fresh) from rh_drv have"T = Top ∨ (∃T🪙1 T🪙2. T = (∀X<:T🪙1. T🪙2) ∧ Γ ⊨ T🪙1 <: Q🪙1 ∧ ((TVarB X T🪙1)#Γ) ⊨ Q🪙2 <: T🪙2)" using fresh_cond by (simp add: S_ForallE_left) moreover have"S🪙1 closed_in Γ"and"S🪙2 closed_in ((TVarB X Q🪙1)#Γ)" using lh_drv_prm🪙1 lh_drv_prm🪙2 by (simp_all add: subtype_implies_closed) thenhave"(∀X<:S🪙1. S🪙2) closed_in Γ"by (force simp: closed_in_def ty.supp abs_supp) moreover have"⊨ Γ ok"using rh_drv by (rule subtype_implies_ok) moreover
{ assume"∃T🪙1 T🪙2. T=(∀X<:T🪙1. T🪙2) ∧ Γ⊨T🪙1<:Q🪙1 ∧ ((TVarB X T🪙1)#Γ)⊨Q🪙2<:T🪙2" thenobtain T🪙1 T🪙2 where T_inst: "T = (∀X<:T🪙1. T🪙2)" and rh_drv_prm🪙1: "Γ ⊨ T🪙1 <: Q🪙1" and rh_drv_prm🪙2:"((TVarB X T🪙1)#Γ) ⊨ Q🪙2 <: T🪙2"by force have"(∀X<:Q🪙1. Q🪙2) = Q"by fact thenhave Q🪙12_less: "size_ty Q🪙1 < size_ty Q""size_ty Q🪙2 < size_ty Q" using fresh_cond by auto from IH_trans[of "Q🪙1"] have"Γ ⊨ T🪙1 <: S🪙1"using lh_drv_prm🪙1 rh_drv_prm🪙1 Q🪙12_less by blast moreover from IH_narrow[of "Q🪙1""[]"] have"((TVarB X T🪙1)#Γ) ⊨ S🪙2 <: Q🪙2"using Q🪙12_less lh_drv_prm🪙2 rh_drv_prm🪙1 by simp with IH_trans[of "Q🪙2"] have"((TVarB X T🪙1)#Γ) ⊨ S🪙2 <: T🪙2"using Q🪙12_less rh_drv_prm🪙2 by simp ultimatelyhave"Γ ⊨ (∀X<:S🪙1. S🪙2) <: (∀X<:T🪙1. T🪙2)" using fresh_cond by (simp add: subtype_of.SA_all) hence"Γ ⊨ (∀X<:S🪙1. S🪙2) <: T"using T_inst by simp
} ultimatelyshow"Γ ⊨ (∀X<:S🪙1. S🪙2) <: T"by blast qed
} note transitivity_lemma = this
{ 🍋‹The transitivity proof is now by the auxiliary lemma.› case 1 from‹Γ ⊨ S 🚫Q›and‹Γ ⊨ Q 🚫T› show"Γ ⊨ S <: T"by (rule transitivity_lemma) next case 2 from‹(Δ@[(TVarB X Q)]@Γ) ⊨ M 🚫N› and‹Γ ⊨ P🚫› show"(Δ@[(TVarB X P)]@Γ) ⊨ M <: N" proof (induct "Δ@[(TVarB X Q)]@Γ" M N arbitrary: Γ X Δ rule: subtype_of.induct) case (SA_Top S Γ X Δ) from‹Γ ⊨ P 🚫Q› have"P closed_in Γ"by (simp add: subtype_implies_closed) with‹⊨ (Δ@[(TVarB X Q)]@Γ) ok›have"⊨ (Δ@[(TVarB X P)]@Γ) ok" by (simp add: replace_type) moreover from‹S closed_in (Δ@[(TVarB X Q)]@Γ)›have"S closed_in (Δ@[(TVarB X P)]@Γ)" by (simp add: closed_in_def doms_append) ultimatelyshow"(Δ@[(TVarB X P)]@Γ) ⊨ S <: Top"by (simp add: subtype_of.SA_Top) next case (SA_trans_TVar Y S N Γ X Δ) thenhave IH_inner: "(Δ@[(TVarB X P)]@Γ) ⊨ S <: N" and lh_drv_prm: "(TVarB Y S) ∈ set (Δ@[(TVarB X Q)]@Γ)" and rh_drv: "Γ ⊨ P<:Q" and ok🪙Q: "⊨ (Δ@[(TVarB X Q)]@Γ) ok"by (simp_all add: subtype_implies_ok) thenhave ok🪙P: "⊨ (Δ@[(TVarB X P)]@Γ) ok"by (simp add: subtype_implies_ok) show"(Δ@[(TVarB X P)]@Γ) ⊨ Tvar Y <: N" proof (cases "X=Y") case False have"X≠Y"by fact hence"(TVarB Y S)∈set (Δ@[(TVarB X P)]@Γ)"using lh_drv_prm by (simp add:binding.inject) with IH_inner show"(Δ@[(TVarB X P)]@Γ) ⊨ Tvar Y <: N"by (simp add: subtype_of.SA_trans_TVar) next case True have memb🪙XQ: "(TVarB X Q)∈set (Δ@[(TVarB X Q)]@Γ)"by simp have memb🪙XP: "(TVarB X P)∈set (Δ@[(TVarB X P)]@Γ)"by simp have eq: "X=Y"by fact hence"S=Q"using ok🪙Q lh_drv_prm memb🪙XQ by (simp only: uniqueness_of_ctxt) hence"(Δ@[(TVarB X P)]@Γ) ⊨ Q <: N"using IH_inner by simp moreover have"(Δ@[(TVarB X P)]@Γ) extends Γ"by (simp add: extends_def) hence"(Δ@[(TVarB X P)]@Γ) ⊨ P <: Q"using rh_drv ok🪙P by (simp only: weakening) ultimatelyhave"(Δ@[(TVarB X P)]@Γ) ⊨ P <: N"by (simp add: transitivity_lemma) thenshow"(Δ@[(TVarB X P)]@Γ) ⊨ Tvar Y <: N"using memb🪙XP eq by auto qed next case (SA_refl_TVar Y Γ X Δ) from‹Γ ⊨ P 🚫Q› have"P closed_in Γ"by (simp add: subtype_implies_closed) with‹⊨ (Δ@[(TVarB X Q)]@Γ) ok›have"⊨ (Δ@[(TVarB X P)]@Γ) ok" by (simp add: replace_type) moreover from‹Y ∈ ty_dom (Δ@[(TVarB X Q)]@Γ)›have"Y ∈ ty_dom (Δ@[(TVarB X P)]@Γ)" by (simp add: doms_append) ultimatelyshow"(Δ@[(TVarB X P)]@Γ) ⊨ Tvar Y <: Tvar Y"by (simp add: subtype_of.SA_refl_TVar) next case (SA_arrow S🪙1 Q🪙1 Q🪙2 S🪙2 Γ X Δ) thenshow"(Δ@[(TVarB X P)]@Γ) ⊨ Q🪙1 → Q🪙2 <: S🪙1 → S🪙2"by blast next case (SA_all T🪙1 S🪙1 Y S🪙2 T🪙2 Γ X Δ) have IH_inner🪙1: "(Δ@[(TVarB X P)]@Γ) ⊨ T🪙1 <: S🪙1" and IH_inner🪙2: "(((TVarB Y T🪙1)#Δ)@[(TVarB X P)]@Γ) ⊨ S🪙2 <: T🪙2" by (fastforce intro: SA_all)+ thenshow"(Δ@[(TVarB X P)]@Γ) ⊨ (∀Y<:S🪙1. S🪙2) <: (∀Y<:T🪙1. T🪙2)"by auto qed
} qed
section‹Typing›
inductive
typing :: "env ==> trm ==> ty ==> bool" (‹_ ⊨ _ : _› [60,60,60] 60) where
T_Var[intro]: "[ VarB x T ∈ set Γ; ⊨ Γ ok ]==> Γ ⊨ Var x : T"
| T_App[intro]: "[ Γ ⊨ t🪙1 : T🪙1 → T🪙2; Γ ⊨ t🪙2 : T🪙1 ]==> Γ ⊨ t🪙1 ⋅ t🪙2 : T🪙2"
| T_Abs[intro]: "[ VarB x T🪙1 # Γ ⊨ t🪙2 : T🪙2 ]==> Γ ⊨ (λx:T🪙1. t🪙2) : T🪙1 → T??2"
| T_Sub[intro]: "[ Γ ⊨ t : S; Γ ⊨ S <: T ]==> Γ ⊨ t : T"
| T_TAbs[intro]:"[ TVarB X T🪙1 # Γ ⊨ t🪙2 : T🪙2 ]==> Γ ⊨ (λX<:T🪙1. t🪙2) : (∀X<:T🪙1. T🪙2)"
| T_TApp[intro]:"[X♯(Γ,t🪙1,T🪙2); Γ ⊨ t🪙1 : (∀X<:T🪙11. T🪙12); Γ ⊨ T🪙2 <: T🪙11]==> Γ ⊨ t🪙1 ⋅🪙τ T🪙2 : (T🪙12[X ↝ T🪙2]🪙τ)"
equivariance typing
lemma better_T_TApp: assumes H1: "Γ ⊨ t🪙1 : (∀X<:T11. T12)" and H2: "Γ ⊨ T2 <: T11" shows"Γ ⊨ t🪙1 ⋅🪙τ T2 : (T12[X ↝ T2]🪙τ)" proof - obtain Y::tyvrs where Y: "Y ♯ (X, T12, Γ, t🪙1, T2)" by (rule exists_fresh) (rule fin_supp) thenhave"Y ♯ (Γ, t🪙1, T2)"by simp moreoverfrom Y have"(∀X<:T11. T12) = (∀Y<:T11. [(Y, X)] ∙ T12)" by (auto simp: ty.inject alpha' fresh_prod fresh_atm) with H1 have"Γ ⊨ t🪙1 : (∀Y<:T11. [(Y, X)] ∙ T12)"by simp ultimatelyhave"Γ ⊨ t🪙1 ⋅🪙τ T2 : (([(Y, X)] ∙ T12)[Y ↝ T2]🪙τ)"using H2 by (rule T_TApp) with Y show ?thesis by (simp add: type_subst_rename) qed
lemma typing_ok: assumes"Γ ⊨ t : T" shows"⊨ Γ ok" using assms by (induct) (auto)
lemma ok_imp_VarB_closed_in: assumes ok: "⊨ Γ ok" shows"VarB x T ∈ set Γ ==> T closed_in Γ"using ok by induct (auto simp: binding.inject closed_in_def)
lemma tyvrs_of_subst: "tyvrs_of (B[X ↝ T]🪙b) = tyvrs_of B" by (nominal_induct B rule: binding.strong_induct) simp_all
lemma typing_closed_in: assumes"Γ ⊨ t : T" shows"T closed_in Γ" using assms proof induct case (T_Var x T Γ) from‹⊨ Γ ok›and‹VarB x T ∈ set Γ› show ?caseby (rule ok_imp_VarB_closed_in) next case (T_App Γ t🪙1 T🪙1 T🪙2 t🪙2) thenshow ?caseby (auto simp: ty.supp closed_in_def) next case (T_Abs x T🪙1 Γ t🪙2 T🪙2) from‹VarB x T🪙1 # Γ ⊨ t🪙2 : T🪙2› have"T🪙1 closed_in Γ"by (auto dest: typing_ok) with T_Abs show ?caseby (auto simp: ty.supp closed_in_def) next case (T_Sub Γ t S T) from‹Γ ⊨ S 🚫T›show ?caseby (simp add: subtype_implies_closed) next case (T_TAbs X T🪙1 Γ t🪙2 T🪙2) from‹TVarB X T🪙1 # Γ ⊨ t🪙2 : T🪙2› have"T🪙1 closed_in Γ"by (auto dest: typing_ok) with T_TAbs show ?caseby (auto simp: ty.supp closed_in_def abs_supp) next case (T_TApp X Γ t🪙1 T2 T11 T12) thenhave"T12 closed_in (TVarB X T11 # Γ)" by (auto simp: closed_in_def ty.supp abs_supp) moreoverfrom T_TApp have"T2 closed_in Γ" by (simp add: subtype_implies_closed) ultimatelyshow ?caseby (rule subst_closed_in') qed
subsection‹Evaluation›
inductive
val :: "trm ==> bool" where
Abs[intro]: "val (λx:T. t)"
| TAbs[intro]: "val (λX<:T. t)"
lemma ty_dom_cons: shows"ty_dom (Γ@[VarB X Q]@Δ) = ty_dom (Γ@Δ)" by (induct Γ) (auto)
lemma closed_in_cons: assumes"S closed_in (Γ @ VarB X Q # Δ)" shows"S closed_in (Γ@Δ)" using assms ty_dom_cons closed_in_def by auto
lemma closed_in_weaken: "T closed_in (Δ @ Γ) ==> T closed_in (Δ @ B # Γ)" by (auto simp: closed_in_def doms_append)
lemma closed_in_weaken': "T closed_in Γ ==> T closed_in (Δ @ Γ)" by (auto simp: closed_in_def doms_append)
lemma valid_subst: assumes ok: "⊨ (Δ @ TVarB X Q # Γ) ok" and closed: "P closed_in Γ" shows"⊨ (Δ[X ↝ P]🪙e @ Γ) ok"using ok closed proof (induct Δ) case Nil thenshow ?case by auto next case (Cons a Δ) thenhave *: "⊨ (a # Δ @ TVarB X Q # Γ) ok" by fastforce thenshow ?case apply (rule validE) using Cons apply (simp add: at_tyvrs_inst closed doms_append(1) finite_doms(1) fresh_fin_insert fs_tyvrs_inst pt_tyvrs_inst subst_closed_in ty_dom_subst) by (simp add: doms_append(2) subst_closed_in Cons.hyps closed trm_dom_subst) qed
lemma ty_dom_vrs: shows"ty_dom (G @ [VarB x Q] @ D) = ty_dom (G @ D)" by (induct G) (auto)
lemma valid_cons': assumes"⊨ (Γ @ VarB x Q # Δ) ok" shows"⊨ (Γ @ Δ) ok" using assms proof (induct "Γ @ VarB x Q # Δ" arbitrary: Γ Δ) case valid_nil have"[] = Γ @ VarB x Q # Δ"by fact thenhave"False"by auto thenshow ?caseby auto next case (valid_consT G X T) thenshow ?case proof (cases Γ) case Nil with valid_consT show ?thesis by simp next case (Cons b bs) with valid_consT have"⊨ (bs @ Δ) ok"by simp moreoverfrom Cons and valid_consT have"X ♯ ty_dom (bs @ Δ)" by (simp add: doms_append) moreoverfrom Cons and valid_consT have"T closed_in (bs @ Δ)" by (simp add: closed_in_def doms_append) ultimatelyhave"⊨ (TVarB X T # bs @ Δ) ok" by (rule valid_rel.valid_consT) with Cons and valid_consT show ?thesis by simp qed next case (valid_cons G x T) thenshow ?case proof (cases Γ) case Nil with valid_cons show ?thesis by simp next case (Cons b bs) with valid_cons have"⊨ (bs @ Δ) ok"by simp moreoverfrom Cons and valid_cons have"x ♯ trm_dom (bs @ Δ)" by (simp add: doms_append finite_doms
fresh_fin_insert [OF pt_vrs_inst at_vrs_inst fs_vrs_inst]) moreoverfrom Cons and valid_cons have"T closed_in (bs @ Δ)" by (simp add: closed_in_def doms_append) ultimatelyhave"⊨ (VarB x T # bs @ Δ) ok" by (rule valid_rel.valid_cons) with Cons and valid_cons show ?thesis by simp qed qed
text‹A.5(6)›
lemma type_weaken: assumes"(Δ@Γ) ⊨ t : T" and"⊨ (Δ @ B # Γ) ok" shows"(Δ @ B # Γ) ⊨ t : T" using assms proof(nominal_induct "Δ @ Γ" t T avoiding: Δ Γ B rule: typing.strong_induct) case (T_Var x T) thenshow ?caseby auto next case (T_App X t🪙1 T🪙2 T🪙11 T🪙12) thenshow ?caseby force next case (T_Abs y T🪙1 t🪙2 T🪙2 Δ Γ) thenhave"VarB y T🪙1 # Δ @ Γ ⊨ t🪙2 : T🪙2"by simp thenhave closed: "T🪙1 closed_in (Δ @ Γ)" by (auto dest: typing_ok) have"⊨ (VarB y T🪙1 # Δ @ B # Γ) ok" by (simp add: T_Abs closed closed_in_weaken fresh_list_append fresh_list_cons fresh_trm_dom) thenhave"⊨ ((VarB y T🪙1 # Δ) @ B # Γ) ok"by simp with _ have"(VarB y T🪙1 # Δ) @ B # Γ ⊨ t🪙2 : T🪙2" by (rule T_Abs) simp thenhave"VarB y T🪙1 # Δ @ B # Γ ⊨ t🪙2 : T🪙2"by simp thenshow ?caseby (rule typing.T_Abs) next case (T_Sub t S T Δ Γ) from refl and‹⊨ (Δ @ B # Γ) ok› have"Δ @ B # Γ ⊨ t : S"by (rule T_Sub) moreoverfrom‹(Δ @ Γ)⊨S🚫›and‹⊨ (Δ @ B # Γ) ok› have"(Δ @ B # Γ)⊨S<:T" by (rule weakening) (simp add: extends_def T_Sub) ultimatelyshow ?caseby (rule typing.T_Sub) next case (T_TAbs X T🪙1 t🪙2 T🪙2 Δ Γ) from‹TVarB X T🪙1 # Δ @ Γ ⊨ t🪙2 : T🪙2› have closed: "T🪙1 closed_in (Δ @ Γ)" by (auto dest: typing_ok) have"⊨ (TVarB X T🪙1 # Δ @ B # Γ) ok" by (simp add: T_TAbs at_tyvrs_inst closed closed_in_weaken doms_append finite_doms finite_vrs
fresh_dom fresh_fin_union fs_tyvrs_inst pt_tyvrs_inst tyvrs_fresh) thenhave"⊨ ((TVarB X T🪙1 # Δ) @ B # Γ) ok"by simp with _ have"(TVarB X T🪙1 # Δ) @ B # Γ ⊨ t🪙2 : T🪙2" by (rule T_TAbs) simp thenhave"TVarB X T🪙1 # Δ @ B # Γ ⊨ t🪙2 : T🪙2"by simp thenshow ?caseby (rule typing.T_TAbs) next case (T_TApp X t🪙1 T2 T11 T12 Δ Γ) have"Δ @ B # Γ ⊨ t🪙1 : (∀X<:T11. T12)" by (rule T_TApp refl)+ moreoverfrom‹(Δ @ Γ)⊨T2🚫›and‹⊨ (Δ @ B # Γ) ok› have"(Δ @ B # Γ)⊨T2<:T11" by (rule weakening) (simp add: extends_def T_TApp) ultimatelyshow ?caseby (rule better_T_TApp) qed
lemma type_weaken': "Γ ⊨ t : T ==>⊨ (Δ@Γ) ok ==> (Δ@Γ) ⊨ t : T" proof (induct Δ) case Nil thenshow ?caseby auto next case (Cons a Δ) thenshow ?case by (metis append_Cons append_Nil type_weaken validE(3)) qed
text‹A.6›
lemma strengthening: assumes"(Γ @ VarB x Q # Δ) ⊨ S <: T" shows"(Γ@Δ) ⊨ S <: T" using assms proof (induct "Γ @ VarB x Q # Δ" S T arbitrary: Γ) case (SA_Top S) thenhave"⊨ (Γ @ Δ) ok"by (auto dest: valid_cons') moreoverhave"S closed_in (Γ @ Δ)"using SA_Top by (auto dest: closed_in_cons) ultimatelyshow ?caseusing subtype_of.SA_Top by auto next case (SA_refl_TVar X) from‹⊨ (Γ @ VarB x Q # Δ) ok› have h1:"⊨ (Γ @ Δ) ok"by (auto dest: valid_cons') have"X ∈ ty_dom (Γ @ VarB x Q # Δ)"using SA_refl_TVar by auto thenhave h2:"X ∈ ty_dom (Γ @ Δ)"using ty_dom_vrs by auto show ?caseusing h1 h2 by auto next case (SA_all T1 S1 X S2 T2) have h1:"((TVarB X T1 # Γ) @ Δ)⊨S2<:T2"by (fastforce intro: SA_all) have h2:"(Γ @ Δ)⊨T1<:S1"using SA_all by auto thenshow ?caseusing h1 h2 by auto qed (auto)
lemma narrow_type: 🍋‹A.7› assumes H: "Δ @ (TVarB X Q) # Γ ⊨ t : T" shows"Γ ⊨ P <: Q ==> Δ @ (TVarB X P) # Γ ⊨ t : T" using H proof (nominal_induct "Δ @ (TVarB X Q) # Γ" t T avoiding: P arbitrary: Δ rule: typing.strong_induct) case (T_Var x T P D) thenhave"VarB x T ∈ set (D @ TVarB X P # Γ)" and"⊨ (D @ TVarB X P # Γ) ok" by (auto intro: replace_type dest!: subtype_implies_closed) thenshow ?caseby auto next case (T_App t1 T1 T2 t2 P D) thenshow ?caseby force next case (T_Abs x T1 t2 T2 P D) thenshow ?caseby (fastforce dest: typing_ok) next case (T_Sub t S T P D) thenshow ?caseusing subtype_narrow by fastforce next case (T_TAbs X' T1 t2 T2 P D) thenshow ?caseby (fastforce dest: typing_ok) next case (T_TApp X' t1 T2 T11 T12 P D) thenhave"D @ TVarB X P # Γ ⊨ t1 : Forall X' T12 T11"by fastforce moreoverhave"(D @ [TVarB X Q] @ Γ) ⊨ T2<:T11"using T_TApp by auto thenhave"(D @ [TVarB X P] @ Γ) ⊨ T2<:T11"using‹Γ⊨P🚫› by (rule subtype_narrow) moreoverfrom T_TApp have"X' ♯ (D @ TVarB X P # Γ, t1, T2)" by (simp add: fresh_list_append fresh_list_cons fresh_prod) ultimatelyshow ?caseby auto qed
subsection‹Substitution lemmas›
subsubsection ‹Substition Preserves Typing›
theorem subst_type: 🍋‹A.8› assumes H: "(Δ @ (VarB x U) # Γ) ⊨ t : T" shows"Γ ⊨ u : U ==> Δ @ Γ ⊨ t[x ↝ u] : T"using H proof (nominal_induct "Δ @ (VarB x U) # Γ" t T avoiding: x u arbitrary: Δ rule: typing.strong_induct) case (T_Var y T x u D) show ?case proof (cases "x = y") assume eq:"x=y" thenhave"T=U"using T_Var uniqueness_of_ctxt' by auto thenshow ?caseusing eq T_Var by (auto intro: type_weaken' dest: valid_cons') next assume"x≠y" thenshow ?caseusing T_Var by (auto simp:binding.inject dest: valid_cons') qed next case (T_App t1 T1 T2 t2 x u D) thenshow ?caseby force next case (T_Abs y T1 t2 T2 x u D) thenshow ?caseby force next case (T_Sub t S T x u D) thenhave"D @ Γ ⊨ t[x ↝ u] : S"by auto moreoverhave"(D @ Γ) ⊨ S<:T"using T_Sub by (auto dest: strengthening) ultimatelyshow ?caseby auto next case (T_TAbs X T1 t2 T2 x u D) from‹TVarB X T1 # D @ VarB x U # Γ ⊨ t2 : T2›have"X ♯ T1" by (auto simp: valid_ty_dom_fresh dest: typing_ok intro!: closed_in_fresh) with‹X ♯ u›and T_TAbs show ?caseby fastforce next case (T_TApp X t1 T2 T11 T12 x u D) thenhave"(D@Γ) ⊨T2<:T11"using T_TApp by (auto dest: strengthening) thenshow"((D @ Γ) ⊨ ((t1 ⋅🪙τ T2)[x ↝ u]) : (T12[X ↝ T2]🪙τ))"using T_TApp by (force simp: fresh_prod fresh_list_append fresh_list_cons subst_trm_fresh_tyvar) qed
lemma substT_subtype: 🍋‹A.10› assumes H: "(Δ @ ((TVarB X Q) # Γ)) ⊨ S <: T" shows"Γ ⊨ P <: Q ==> (Δ[X ↝ P]🪙e @ Γ) ⊨ S[X ↝ P]🪙τ <: T[X ↝ P]🪙τ" using H proof (nominal_induct "Δ @ TVarB X Q # Γ" S T avoiding: X P arbitrary: Δ rule: subtype_of.strong_induct) case (SA_Top S X P D) thenhave"⊨ (D @ TVarB X Q # Γ) ok"by simp moreoverhave closed: "P closed_in Γ"using SA_Top subtype_implies_closed by auto ultimatelyhave"⊨ (D[X ↝ P]🪙e @ Γ) ok"by (rule valid_subst) moreoverfrom SA_Top have"S closed_in (D @ TVarB X Q # Γ)"by simp thenhave"S[X ↝ P]🪙τ closed_in (D[X ↝ P]🪙e @ Γ)"using closed by (rule subst_closed_in) ultimatelyshow ?caseby auto next case (SA_trans_TVar Y S T X P D) have h:"(D @ TVarB X Q # Γ)⊨S<:T"by fact thenhave ST: "(D[X ↝ P]🪙e @ Γ) ⊨ S[X ↝ P]🪙τ <: T[X ↝ P]🪙τ"using SA_trans_TVar by auto from h have G_ok: "⊨ (D @ TVarB X Q # Γ) ok"by (rule subtype_implies_ok) from G_ok and SA_trans_TVar have X_Γ_ok: "⊨ (TVarB X Q # Γ) ok" by (auto intro: validE_append) show"(D[X ↝ P]🪙e @ Γ) ⊨ Tvar Y[X ↝ P]🪙τ<:T[X ↝ P]🪙τ" proof (cases "X = Y") assume eq: "X = Y" from eq and SA_trans_TVar have"TVarB Y Q ∈ set (D @ TVarB X Q # Γ)"by simp with G_ok have QS: "Q = S"using‹TVarB Y S ∈ set (D @ TVarB X Q # Γ)› by (rule uniqueness_of_ctxt) from X_Γ_ok have"X ♯ ty_dom Γ"and"Q closed_in Γ"by auto thenhave XQ: "X ♯ Q"by (rule closed_in_fresh) note‹Γ⊨P🚫› moreoverfrom ST have"⊨ (D[X ↝ P]🪙e @ Γ) ok"by (rule subtype_implies_ok) moreoverhave"(D[X ↝ P]🪙e @ Γ) extends Γ"by (simp add: extends_def) ultimatelyhave"(D[X ↝ P]🪙e @ Γ) ⊨ P<:Q"by (rule weakening) with QS have"(D[X ↝ P]🪙e @ Γ) ⊨ P<:S"by simp moreoverfrom XQ and ST and QS have"(D[X ↝ P]🪙e @ Γ) ⊨ S<:T[X ↝ P]🪙τ" by (simp add: type_subst_identity) ultimatelyhave"(D[X ↝ P]🪙e @ Γ) ⊨ P<:T[X ↝ P]🪙τ" by (rule subtype_transitivity) with eq show ?caseby simp next assume neq: "X ≠ Y" with SA_trans_TVar have"TVarB Y S ∈ set D ∨ TVarB Y S ∈ set Γ" by (simp add: binding.inject) thenshow ?case proof assume"TVarB Y S ∈ set D" thenhave"TVarB Y (S[X ↝ P]🪙τ) ∈ set (D[X ↝ P]🪙e)" by (rule ctxt_subst_mem_TVarB) thenhave"TVarB Y (S[X ↝ P]🪙τ) ∈ set (D[X ↝ P]🪙e @ Γ)"by simp with neq and ST show ?thesis by auto next assume Y: "TVarB Y S ∈ set Γ" from X_Γ_ok have"X ♯ ty_dom Γ"and"⊨ Γ ok"by auto thenhave"X ♯ Γ"by (simp add: valid_ty_dom_fresh) with Y have"X ♯ S" by (induct Γ) (auto simp: fresh_list_nil fresh_list_cons) with ST have"(D[X ↝ P]🪙e @ Γ)⊨S<:T[X ↝ P]🪙τ" by (simp add: type_subst_identity) moreoverfrom Y have"TVarB Y S ∈ set (D[X ↝ P]🪙e @ Γ)"by simp ultimatelyshow ?thesis using neq by auto qed qed next case (SA_refl_TVar Y X P D) note‹⊨ (D @ TVarB X Q # Γ) ok› moreoverfrom SA_refl_TVar have closed: "P closed_in Γ" by (auto dest: subtype_implies_closed) ultimatelyhave ok: "⊨ (D[X ↝ P]🪙e @ Γ) ok"using valid_subst by auto from closed have closed': "P closed_in (D[X ↝ P]🪙e @ Γ)" by (simp add: closed_in_weaken') show ?case proof (cases "X = Y") assume"X = Y" with closed' and ok show ?thesis by (auto intro: subtype_reflexivity) next assume neq: "X ≠ Y" with SA_refl_TVar have"Y ∈ ty_dom (D[X ↝ P]🪙e @ Γ)" by (simp add: ty_dom_subst doms_append) with neq and ok show ?thesis by auto qed next case (SA_arrow T1 S1 S2 T2 X P D) thenhave h1:"(D[X ↝ P]🪙e @ Γ)⊨T1[X ↝ P]🪙τ<:S1[X ↝ P]🪙τ"using SA_arrow by auto from SA_arrow have h2:"(D[X ↝ P]🪙e @ Γ)⊨S2[X ↝ P]🪙τ<:T2[X ↝ P]🪙τ"using SA_arrow by auto show ?caseusing subtype_of.SA_arrow h1 h2 by auto next case (SA_all T1 S1 Y S2 T2 X P D) thenhave Y: "Y ♯ ty_dom (D @ TVarB X Q # Γ)" by (auto dest: subtype_implies_ok intro: fresh_dom) moreoverfrom SA_all have"S1 closed_in (D @ TVarB X Q # Γ)" by (auto dest: subtype_implies_closed) ultimatelyhave S1: "Y ♯ S1"by (rule closed_in_fresh) from SA_all have"T1 closed_in (D @ TVarB X Q # Γ)" by (auto dest: subtype_implies_closed) with Y have T1: "Y ♯ T1"by (rule closed_in_fresh) with SA_all and S1 show ?caseby force qed
theorem substT_type: 🍋‹A.11› assumes H: "(D @ TVarB X Q # G) ⊨ t : T" shows"G ⊨ P <: Q ==> (D[X ↝ P]🪙e @ G) ⊨ t[X ↝🪙τ P] : T[X ↝ P]🪙τ"using H proof (nominal_induct "D @ TVarB X Q # G" t T avoiding: X P arbitrary: D rule: typing.strong_induct) case (T_Var x T X P D') have"G⊨P<:Q"by fact thenhave"P closed_in G"using subtype_implies_closed by auto moreovernote‹⊨ (D' @ TVarB X Q # G) ok› ultimatelyhave"⊨ (D'[X ↝ P]🪙e @ G) ok"using valid_subst by auto moreovernote‹VarB x T ∈ set (D' @ TVarB X Q # G)› thenhave"VarB x T ∈ set D' ∨ VarB x T ∈ set G"by simp thenhave"(VarB x (T[X ↝ P]🪙τ)) ∈ set (D'[X ↝ P]🪙e @ G)" proof assume"VarB x T ∈ set D'" thenhave"VarB x (T[X ↝ P]🪙τ) ∈ set (D'[X ↝ P]🪙e)" by (rule ctxt_subst_mem_VarB) thenshow ?thesis by simp next assume x: "VarB x T ∈ set G" from T_Var have ok: "⊨ G ok"by (auto dest: subtype_implies_ok) thenhave"X ♯ ty_dom G"using T_Var by (auto dest: validE_append) with ok have"X ♯ G"by (simp add: valid_ty_dom_fresh) moreoverfrom x have"VarB x T ∈ set (D' @ G)"by simp thenhave"VarB x (T[X ↝ P]🪙τ) ∈ set ((D' @ G)[X ↝ P]🪙e)" by (rule ctxt_subst_mem_VarB) ultimatelyshow ?thesis by (simp add: ctxt_subst_append ctxt_subst_identity) qed ultimatelyshow ?caseby auto next case (T_App t1 T1 T2 t2 X P D') thenhave"D'[X ↝ P]🪙e @ G ⊨ t1[X ↝🪙τ P] : (T1 → T2)[X ↝ P]🪙τ"by auto moreoverfrom T_App have"D'[X ↝ P]🪙e @ G ⊨ t2[X ↝🪙τ P] : T1[X ↝ P]🪙τ"by auto ultimatelyshow ?caseby auto next case (T_Abs x T1 t2 T2 X P D') thenshow ?caseby force next case (T_Sub t S T X P D') thenshow ?caseusing substT_subtype by force next case (T_TAbs X' T1 t2 T2 X P D') thenhave"X' ♯ ty_dom (D' @ TVarB X Q # G)" and"T1 closed_in (D' @ TVarB X Q # G)" by (auto dest: typing_ok) thenhave"X' ♯ T1"by (rule closed_in_fresh) with T_TAbs show ?caseby force next case (T_TApp X' t1 T2 T11 T12 X P D') thenhave"X' ♯ ty_dom (D' @ TVarB X Q # G)" by (simp add: fresh_dom) moreoverfrom T_TApp have"T11 closed_in (D' @ TVarB X Q # G)" by (auto dest: subtype_implies_closed) ultimatelyhave X': "X' ♯ T11"by (rule closed_in_fresh) from T_TApp have"D'[X ↝ P]🪙e @ G ⊨ t1[X ↝🪙τ P] : (∀X'<:T11. T12)[X ↝ P]🪙τ" by simp with X' and T_TApp show ?case by (auto simp: fresh_atm type_substitution_lemma
fresh_list_append fresh_list_cons
ctxt_subst_fresh' type_subst_fresh subst_trm_ty_fresh
intro: substT_subtype) qed
lemma Abs_type: 🍋‹A.13(1)› assumes H: "Γ ⊨ (λx:S. s) : T" and H': "Γ ⊨ T <: U → U'" and H'': "x ♯ Γ" obtains S' where"Γ ⊨ U <: S" and"(VarB x S) # Γ ⊨ s : S'" and"Γ ⊨ S' <: U'" using H H' H'' proof (nominal_induct Γ t ≡"λx:S. s" T avoiding: x arbitrary: U U' S s rule: typing.strong_induct) case (T_Abs y T🪙1 Γ t🪙2 T🪙2) from‹Γ ⊨ T🪙1 → T🪙2 🚫U → U'› obtain ty1: "Γ ⊨ U <: S"and ty2: "Γ ⊨ T🪙2 <: U'"using T_Abs by cases (simp_all add: ty.inject trm.inject alpha fresh_atm) from T_Abs have"VarB y S # Γ ⊨ [(y, x)] ∙ s : T🪙2" by (simp add: trm.inject alpha fresh_atm) thenhave"[(y, x)] ∙ (VarB y S # Γ) ⊨ [(y, x)] ∙ [(y, x)] ∙ s : [(y, x)] ∙ T🪙2" by (rule typing.eqvt) moreoverfrom T_Abs have"y ♯ Γ" by (auto dest!: typing_ok simp add: fresh_trm_dom) ultimatelyhave"VarB x S # Γ ⊨ s : T🪙2"using T_Abs by (perm_simp add: ty_vrs_prm_simp) with ty1 show ?caseusing ty2 by (rule T_Abs) next case (T_Sub Γ t S T) thenshow ?caseusing subtype_transitivity by blast qed simp_all
lemma subtype_reflexivity_from_typing: assumes"Γ ⊨ t : T" shows"Γ ⊨ T <: T" using assms subtype_reflexivity typing_ok typing_closed_in by simp
lemma Abs_type': assumes H: "Γ ⊨ (λx:S. s) : U → U'" and H': "x ♯ Γ" obtains S' where"Γ ⊨ U <: S" and"(VarB x S) # Γ ⊨ s : S'" and"Γ ⊨ S' <: U'" using H subtype_reflexivity_from_typing [OF H] H' by (rule Abs_type)
lemma TAbs_type: 🍋‹A.13(2)› assumes H: "Γ ⊨ (λX<:S. s) : T" and H': "Γ ⊨ T <: (∀X<:U. U')" and fresh: "X ♯ Γ""X ♯ S""X ♯ U" obtains S' where"Γ ⊨ U <: S" and"(TVarB X U # Γ) ⊨ s : S'" and"(TVarB X U # Γ) ⊨ S' <: U'" using H H' fresh proof (nominal_induct Γ t ≡"λX<:S. s" T avoiding: X U U' S arbitrary: s rule: typing.strong_induct) case (T_TAbs Y T🪙1 Γ t🪙2 T🪙2) from‹TVarB Y T🪙1 # Γ ⊨ t🪙2 : T🪙2›have Y: "Y ♯ Γ" by (auto dest!: typing_ok simp add: valid_ty_dom_fresh) from‹Y ♯ U'›and‹Y ♯ X› have"(∀X<:U. U') = (∀Y<:U. [(Y, X)] ∙ U')" by (simp add: ty.inject alpha' fresh_atm) with T_TAbs have"Γ ⊨ (∀Y<:S. T🪙2) <: (∀Y<:U. [(Y, X)] ∙ U')"by (simp add: trm.inject) thenobtain ty1: "Γ ⊨ U <: S"and ty2: "(TVarB Y U # Γ) ⊨ T🪙2 <: ([(Y, X)] ∙ U')"using T_TAbs Y by (cases rule: subtype_of.strong_cases [where X=Y]) (simp_all add: ty.inject alpha abs_fresh) note ty1 moreoverfrom T_TAbs have"TVarB Y S # Γ ⊨ ([(Y, X)] ∙ s) : T🪙2" by (simp add: trm.inject alpha fresh_atm) thenhave"[(Y, X)] ∙ (TVarB Y S # Γ) ⊨ [(Y, X)] ∙ [(Y, X)] ∙ s : [(Y, X)] ∙ T🪙2" by (rule typing.eqvt) with‹X ♯ Γ›‹X ♯ S› Y ‹Y ♯ S›have"TVarB X S # Γ ⊨ s : [(Y, X)] ∙ T🪙2" by perm_simp thenhave"TVarB X U # Γ ⊨ s : [(Y, X)] ∙ T🪙2"using ty1 by (rule narrow_type [of "[]", simplified]) moreoverfrom ty2 have"([(Y, X)] ∙ (TVarB Y U # Γ)) ⊨ ([(Y, X)] ∙ T🪙2) <: ([(Y, X)] ∙ [(Y, X)] ∙ U')" by (rule subtype_of.eqvt) with‹X ♯ Γ›‹X ♯ U› Y ‹Y ♯ U›have"(TVarB X U # Γ) ⊨ ([(Y, X)] ∙ T🪙2) <: U'" by perm_simp ultimatelyshow ?caseby (rule T_TAbs) next case (T_Sub Γ t S T) thenshow ?caseusing subtype_transitivity by blast qed simp_all
lemma TAbs_type': assumes H: "Γ ⊨ (λX<:S. s) : (∀X<:U. U')" and fresh: "X ♯ Γ""X ♯ S""X ♯ U" obtains S' where"Γ ⊨ U <: S" and"(TVarB X U # Γ) ⊨ s : S'" and"(TVarB X U # Γ) ⊨ S' <: U'" using H subtype_reflexivity_from_typing [OF H] fresh by (rule TAbs_type)
theorem preservation: 🍋‹A.20› assumes H: "Γ ⊨ t : T" shows"t ⟼ t' ==> Γ ⊨ t' : T"using H proof (nominal_induct avoiding: t' rule: typing.strong_induct) case (T_App Γ t🪙1 T🪙11 T🪙12 t🪙2 t') obtain x::vrs where x_fresh: "x ♯ (Γ, t🪙1 ⋅ t🪙2, t')" by (rule exists_fresh) (rule fin_supp) obtain X::tyvrs where"X ♯ (t🪙1 ⋅ t🪙2, t')" by (rule exists_fresh) (rule fin_supp) with‹t🪙1 ⋅ t🪙2 ⟼ t'›show ?case proof (cases rule: eval.strong_cases [where x=x and X=X]) case (E_Abs v🪙2 T🪙11' t🪙12) with T_App and x_fresh have h: "Γ ⊨ (λx:T🪙11'. t🪙12) : T🪙11 → T🪙12" by (simp add: trm.inject fresh_prod) moreoverfrom x_fresh have"x ♯ Γ"by simp ultimatelyobtain S' where T🪙11: "Γ ⊨ T🪙11 <: T🪙11'" and t🪙12: "(VarB x T🪙11') # Γ ⊨ t🪙12 : S'" and S': "Γ ⊨ S' <: T🪙12" by (rule Abs_type') blast from‹Γ ⊨ t🪙2 : T🪙11› have"Γ ⊨ t🪙2 : T🪙11'"using T🪙11 by (rule T_Sub) with t🪙12 have"Γ ⊨ t🪙12[x ↝ t🪙2] : S'" by (rule subst_type [where Δ="[]", simplified]) hence"Γ ⊨ t🪙12[x ↝ t🪙2] : T🪙12"using S' by (rule T_Sub) with E_Abs and x_fresh show ?thesis by (simp add: trm.inject fresh_prod) next case (E_App1 t''' t'' u) hence"t🪙1 ⟼ t''"by (simp add:trm.inject) hence"Γ ⊨ t'' : T🪙11 → T🪙12"by (rule T_App) hence"Γ ⊨ t'' ⋅ t🪙2 : T🪙12"using‹Γ ⊨ t🪙2 : T🪙11› by (rule typing.T_App) with E_App1 show ?thesis by (simp add:trm.inject) next case (E_App2 v t''' t'') hence"t🪙2 ⟼ t''"by (simp add:trm.inject) hence"Γ ⊨ t'' : T🪙11"by (rule T_App) with T_App(1) have"Γ ⊨ t🪙1 ⋅ t'' : T🪙12" by (rule typing.T_App) with E_App2 show ?thesis by (simp add:trm.inject) qed (simp_all add: fresh_prod) next case (T_TApp X Γ t🪙1 T🪙2 T🪙11 T🪙12 t') obtain x::vrs where"x ♯ (t🪙1 ⋅🪙τ T🪙2, t')" by (rule exists_fresh) (rule fin_supp) with‹t🪙1 ⋅🪙τ T🪙2 ⟼ t'› show ?case proof (cases rule: eval.strong_cases [where X=X and x=x]) case (E_TAbs T🪙11' T🪙2' t🪙12) with T_TApp have"Γ ⊨ (λX<:T🪙11'. t🪙12) : (∀X<:T🪙11. T🪙12)"and"X ♯ Γ"and"X ♯ T🪙11'" by (simp_all add: trm.inject) moreoverfrom‹Γ⊨T🪙2🚫🪙11›and‹X ♯ Γ›have"X ♯ T🪙11" by (blast intro: closed_in_fresh fresh_dom dest: subtype_implies_closed) ultimatelyobtain S' where"TVarB X T🪙11 # Γ ⊨ t🪙12 : S'" and"(TVarB X T🪙11 # Γ) ⊨ S' <: T🪙12" by (rule TAbs_type') blast hence"TVarB X T🪙11 # Γ ⊨ t🪙12 : T🪙12"by (rule T_Sub) hence"Γ ⊨ t🪙12[X ↝🪙τ T🪙2] : T🪙12[X ↝ T🪙2]🪙τ"using‹Γ ⊨ T🪙2 🚫T🪙11› by (rule substT_type [where D="[]", simplified]) with T_TApp and E_TAbs show ?thesis by (simp add: trm.inject) next case (E_TApp t''' t'' T) from E_TApp have"t🪙1 ⟼ t''"by (simp add: trm.inject) thenhave"Γ ⊨ t'' : (∀X<:T🪙11. T🪙12)"by (rule T_TApp) thenhave"Γ ⊨ t'' ⋅🪙τ T🪙2 : T🪙12[X ↝ T🪙2]🪙τ"using‹Γ ⊨ T🪙2 🚫T🪙11› by (rule better_T_TApp) with E_TApp show ?thesis by (simp add: trm.inject) qed (simp_all add: fresh_prod) next case (T_Sub Γ t S T t') have"t ⟼ t'"by fact hence"Γ ⊨ t' : S"by (rule T_Sub) moreoverhave"Γ ⊨ S <: T"by fact ultimatelyshow ?caseby (rule typing.T_Sub) qed (auto)
lemma Fun_canonical: 🍋‹A.14(1)› assumes ty: "[] ⊨ v : T🪙1 → T🪙2" shows"val v ==>∃x t S. v = (λx:S. t)"using ty proof (induct "[]::env" v "T🪙1 → T🪙2" arbitrary: T🪙1 T🪙2) case (T_Sub t S) from‹[] ⊨ S 🚫T🪙1 → T🪙2› obtain S🪙1 S🪙2 where S: "S = S🪙1 → S🪙2" by cases (auto simp: T_Sub) thenshow ?caseusing‹val t›by (rule T_Sub) qed (auto)
lemma TyAll_canonical: 🍋‹A.14(3)› fixes X::tyvrs assumes ty: "[] ⊨ v : (∀X<:T🪙1. T🪙2)" shows"val v ==>∃X t S. v = (λX<:S. t)"using ty proof (induct "[]::env" v "∀X<:T🪙1. T🪙2" arbitrary: X T🪙1 T🪙2) case (T_Sub t S) from‹[] ⊨ S 🚫(∀X🚫🪙1. T🪙2)› obtain X S🪙1 S🪙2 where S: "S = (∀X<:S🪙1. S🪙2)" by cases (auto simp: T_Sub) thenshow ?caseusing T_Sub by auto qed (auto)
theorem progress: assumes"[] ⊨ t : T" shows"val t ∨ (∃t'. t ⟼ t')" using assms proof (induct "[]::env" t T) case (T_App t🪙1 T🪙11 T🪙12 t🪙2) hence"val t🪙1 ∨ (∃t'. t🪙1 ⟼ t')"by simp thus ?case proof assume t🪙1_val: "val t🪙1" with T_App obtain x t3 S where t🪙1: "t🪙1 = (λx:S. t3)" by (auto dest!: Fun_canonical) from T_App have"val t🪙2 ∨ (∃t'. t🪙2 ⟼ t')"by simp thus ?case proof assume"val t🪙2" with t🪙1 have"t🪙1 ⋅ t🪙2 ⟼ t3[x ↝ t🪙2]"by auto thus ?caseby auto next assume"∃t'. t🪙2 ⟼ t'" thenobtain t' where"t🪙2 ⟼ t'"by auto with t🪙1_val have"t🪙1 ⋅ t🪙2 ⟼ t🪙1 ⋅ t'"by auto thus ?caseby auto qed next assume"∃t'. t🪙1 ⟼ t'" thenobtain t' where"t🪙1 ⟼ t'"by auto hence"t🪙1 ⋅ t🪙2 ⟼ t' ⋅ t🪙2"by auto thus ?caseby auto qed next case (T_TApp X t🪙1 T🪙2 T🪙11 T🪙12) hence"val t🪙1 ∨ (∃t'. t🪙1 ⟼ t')"by simp thus ?case proof assume"val t🪙1" with T_TApp obtain x t S where"t🪙1 = (λx<:S. t)" by (auto dest!: TyAll_canonical) hence"t🪙1 ⋅🪙τ T🪙2 ⟼ t[x ↝🪙τ T🪙2]"by auto thus ?caseby auto next assume"∃t'. t🪙1 ⟼ t'"thus ?caseby auto qed qed (auto)
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.69 Sekunden
(vorverarbeitet am 2026-04-26)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.