# HG changeset patch # User urbanc # Date 1134753603 -3600 # Node ID a37f06555c079fa9b8c42aa52836ed76471c853c # Parent d7859164447f6aaf84f74abc01f28203ac372829 tuned more proofs diff -r d7859164447f -r a37f06555c07 src/HOL/Nominal/Examples/Fsub.thy --- a/src/HOL/Nominal/Examples/Fsub.thy Fri Dec 16 16:59:32 2005 +0100 +++ b/src/HOL/Nominal/Examples/Fsub.thy Fri Dec 16 18:20:03 2005 +0100 @@ -4,35 +4,47 @@ imports "../nominal" begin -text {* Authors: Christian Urban - Benjamin Pierce - Steve Zdancewic - Stephanie Weihrich - Dimitrios Vytiniotis +text {* Authors: Christian Urban, + Benjamin Pierce, + Steve Zdancewic. + Stephanie Weihrich and + Dimitrios Vytiniotis; - with help from Stefan Berghofer, Markus Wenzel + with help from Stefan Berghofer and Markus Wenzel. *} +section {* Atom Types, Types and Terms *} + atom_decl tyvrs vrs -section {* Types *} +nominal_datatype ty = + TVar "tyvrs" + | Top + | Arrow "ty" "ty" ("_ \ _" [900,900] 900) + | TAll "\tyvrs\ty" "ty" -nominal_datatype ty = TyVar "tyvrs" - | Top - | Arrow "ty" "ty" ("_ \ _" [900,900] 900) - | TAll "\tyvrs\ty" "ty" +nominal_datatype trm = + Var "vrs" + | Lam "\vrs\trm" "ty" + | TAbs "\tyvrs\trm" "ty" + | App "trm" "trm" + | TApp "trm" "ty" syntax TAll_syn :: "tyvrs \ ty \ ty \ ty" ("\ [_<:_]._" [900,900,900] 900) + Lam_syn :: "vrs \ ty \ trm \ trm" ("Lam [_:_]._" [100,100,100] 100) + TAbs_syn :: "tyvrs \ ty \ trm \ trm" ("TAbs [_<:_]._" [100,100,100] 100) + translations - "(\[a<:ty1].ty2)" \ "TAll a ty2 ty1" + "\[a<:ty1].ty2" \ "TAll a ty2 ty1" + "Lam [a:tys].t" \ "trm.Lam a t tys" + "TAbs [a<:tys].t" \ "trm.TAbs a t tys" -section {* typing contexts and their domains *} +subsection {* Typing contexts and Their Domains *} types ty_context = "(tyvrs\ty) list" -text {* domain of a context --- (the name "dom" is already used elsewhere) *} consts "domain" :: "ty_context \ tyvrs set" primrec @@ -49,26 +61,28 @@ shows "finite (domain \)" by (induct \, auto) -lemma domain_inclusion[rule_format]: - shows "(X,T)\set \ \ X\(domain \)" - by (induct \, auto) +lemma domain_inclusion: + assumes a: "(X,T)\set \" + shows "X\(domain \)" + using a by (induct \, auto) -lemma domain_existence[rule_format]: - shows "X\(domain \) \ (\T.(X,T)\set \)" - by (induct \, auto) +lemma domain_existence: + assumes a: "X\(domain \)" + shows "\T.(X,T)\set \" + using a by (induct \, auto) lemma domain_append: shows "domain (\@\) = ((domain \) \ (domain \))" by (induct \, auto) -section {* Two functions over types *} +section {* Size Functions and Capture Avoiding Substitutiuon for Types *} text {* they cannot yet be defined conveniently unless we have a recursion combinator *} consts size_ty :: "ty \ nat" lemma size_ty[simp]: - shows "size_ty (TyVar X) = 1" + shows "size_ty (TVar X) = 1" and "size_ty (Top) = 1" and "\size_ty t1 = m ; size_ty t2 = n\ \ size_ty (t1 \ t2) = m + n + 1" and "\size_ty t1 = m ; size_ty t2 = n\ \ size_ty (\ [a<:t1].t2) = m + n + 1" @@ -77,7 +91,7 @@ consts subst_ty :: "ty \ tyvrs \ ty \ ty" lemma subst_ty[simp]: - shows "subst_ty (TyVar X) Y T = (if X=Y then T else (TyVar X))" + shows "subst_ty (TVar X) Y T = (if X=Y then T else (TVar X))" and "subst_ty Top Y T = Top" and "subst_ty (T1 \ T2) Y T = (subst_ty T1 Y T) \ (subst_ty T2 Y T)" and "X\(Y,T) \ subst_ty (\[X<:T1].T2) Y T = (\[X<:(subst_ty T1 Y T)].(subst_ty T2 Y T))" @@ -90,7 +104,7 @@ "subst_ctxt [] Y T = []" "subst_ctxt (XT#Xs) Y T = (fst XT, subst_ty (snd XT) Y T)#(subst_ctxt Xs Y T)" -text {* valid contexts *} +subsection {* valid contexts *} constdefs "closed_in" :: "ty \ ty_context \ bool" ("_ closed'_in _" [100,100] 100) @@ -108,7 +122,7 @@ shows "(pi\S) closed_in (pi\\)" using a proof (unfold "closed_in_def") - assume "supp S \ (domain \)" + assume "supp S \ (domain \)" hence "pi\(supp S) \ pi\(domain \)" by (simp add: pt_subseteq_eqvt[OF pt_tyvrs_inst, OF at_tyvrs_inst]) thus "(supp (pi\S)) \ (domain (pi\\))" @@ -142,7 +156,7 @@ proof (simp, rule valid_rel.v2) show "\ (pi \ \) ok" using a1 by simp next - show "(pi\X)\(pi\\)" using a2 by (simp add: pt_fresh_bij[OF pt_tyvrs_inst, OF at_tyvrs_inst]) + show "(pi\X)\(pi\\)" using a2 by (simp add: fresh_eqvt) next show "(pi\T) closed_in (pi\\)" using a3 by (rule closed_in_eqvt) qed @@ -153,24 +167,20 @@ shows "\ \ ok \ X\\ \ T closed_in \" using a by (cases, auto) -lemma validE_append[rule_format]: - shows "\ (\@\) ok \ \ \ ok" - by (induct \, auto dest: validE) +lemma validE_append: + assumes a: "\ (\@\) ok" + shows "\ \ ok" + using a by (induct \, auto dest: validE) -lemma domain_fresh[rule_format]: +lemma domain_fresh: fixes X::"tyvrs" - shows "\ \ ok \ (X\(domain \) = X\\)" + assumes a: "\ \ ok" + shows "X\(domain \) = X\\" +using a apply(induct \) -apply(simp add: fresh_list_nil fresh_set_empty) -apply(simp add: fresh_list_cons fresh_prod - fresh_fin_insert[OF pt_tyvrs_inst, OF at_tyvrs_inst, OF fs_tyvrs_inst, OF finite_domain]) -apply(rule impI) -apply(clarify) -apply(simp add: fresh_prod) -apply(drule validE) -apply(simp) -apply(simp add: closed_in_def2 fresh_def) -apply(force) +apply(auto simp add: fresh_list_nil fresh_list_cons fresh_set_empty fresh_prod fresh_atm + fresh_fin_insert[OF pt_tyvrs_inst, OF at_tyvrs_inst, OF fs_tyvrs_inst, OF finite_domain]) +apply(force simp add: closed_in_def2 fresh_def) done lemma closed_in_fresh: @@ -186,8 +196,11 @@ apply(force) done -lemma replace_type[rule_format]: - shows "\ (\@(X,T)#\) ok \ S closed_in \ \ \ (\@(X,S)#\) ok" +lemma replace_type: + assumes a: "\ (\@(X,T)#\) ok" + and b: "S closed_in \" + shows "\ (\@(X,S)#\) ok" +using a b apply(induct \) apply(auto dest!: validE intro!: v2 simp add: fresh_list_append fresh_list_cons fresh_prod) apply(drule validE_append) @@ -199,9 +212,11 @@ apply(simp add: domain_append) done -lemma fresh_implies_not_member[rule_format]: +lemma fresh_implies_not_member: fixes \::"ty_context" - shows "X\\ \ \(\T.(X,T)\(set \))" + assumes a: "X\\" + shows "\(\T.(X,T)\(set \))" + using a apply (induct \) apply (auto dest: validE simp add: fresh_list_cons fresh_prod fresh_atm) done @@ -227,8 +242,8 @@ inductive subtype_of_rel intros S_Top[intro]: "\\ \ ok; S closed_in \\ \ \ \ S <: Top" -S_Var[intro]: "\\ \ ok; (X,S) \ (set \); \ \ S <: T\ \ \ \ (TyVar X) <: T" -S_Refl[intro]: "\\ \ ok; X \ (domain \)\\ \ \ TyVar X <: TyVar X" +S_Var[intro]: "\\ \ ok; (X,S) \ set \; \ \ S <: T\ \ \ \ (TVar X) <: T" +S_Refl[intro]: "\\ \ ok; X \ domain \\\ \ \ TVar X <: TVar X" S_Arrow[intro]: "\\ \ T1 <: S1; \ \ S2 <: T2\ \ \ \ (S1 \ S2) <: (T1 \ T2)" S_All[intro]: "\\ \ T1 <: S1; X\\; ((X,T1)#\) \ S2 <: T2\ \ \ \ \ [X<:S1].S2 <: \ [X<:T1].T2" @@ -239,37 +254,21 @@ using a proof (induct) case (S_Top S \) - have "Top closed_in \" - by (simp add: closed_in_def ty.supp) + have "Top closed_in \" by (simp add: closed_in_def ty.supp) moreover have "S closed_in \" by fact ultimately show "S closed_in \ \ Top closed_in \" by simp next case (S_Var S T X \) have "(X,S)\set \" by fact - hence "X\(domain \)" by (rule domain_inclusion) - hence "(TyVar X) closed_in \" by (simp add: closed_in_def ty.supp supp_atm) + hence "X \ domain \" by (rule domain_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 - ultimately show "(TyVar X) closed_in \ \ T closed_in \" by simp -next - case S_Refl thus ?case - by (simp add: closed_in_def ty.supp supp_atm) -next - case S_Arrow thus ?case by (force simp add: closed_in_def ty.supp) -next - case S_All thus ?case by (auto simp add: closed_in_def ty.supp abs_supp) -qed + ultimately show "(TVar X) closed_in \ \ T closed_in \" by simp +qed (auto simp add: closed_in_def ty.supp supp_atm abs_supp) -text {* a completely automated proof *} -lemma subtype_implies_closed: - assumes a: "\ \ S <: T" - shows "S closed_in \ \ T closed_in \" -using a -apply (induct) -apply (auto simp add: closed_in_def ty.supp abs_supp domain_inclusion supp_atm) -done lemma subtype_implies_ok: fixes X::"tyvrs" @@ -281,14 +280,15 @@ fixes X::"tyvrs" assumes a1: "\ \ S <: T" and a2: "X\\" - shows "X\(S,T)" + shows "X\S \ X\T" proof - from a1 have "\ \ ok" by (rule subtype_implies_ok) - with a2 have b0: "X\domain(\)" by (simp add: domain_fresh) + with a2 have "X\domain(\)" by (simp add: domain_fresh) + moreover from a1 have "S closed_in \ \ T closed_in \" by (rule subtype_implies_closed) - hence b1: "supp S \ ((supp (domain \))::tyvrs set)" - and b2: "supp T \ ((supp (domain \))::tyvrs set)" by (simp_all add: closed_in_def2) - thus "X\(S,T)" using b0 b1 b2 by (force simp add: supp_prod fresh_def) + hence "supp S \ ((supp (domain \))::tyvrs set)" + and "supp T \ ((supp (domain \))::tyvrs set)" by (simp_all add: closed_in_def2) + ultimately show "X\S \ X\T" by (force simp add: supp_prod fresh_def) qed lemma silly_eqvt1: @@ -322,10 +322,10 @@ lemma subtype_of_rel_induct[consumes 1, case_names S_Top S_Var S_Refl S_Arrow S_All]: fixes P :: "'a::fs_tyvrs\ty_context \ ty \ ty \bool" assumes a: "\ \ S <: T" - and a1: "\\ S x. (\ \ ok) \ (S closed_in \) \ P x \ S Top" - and a2: "\\ X S T x. (\ \ ok) \ ((X,S)\set \) \ (\ \ S <: T) \ (\z. P z \ S T) - \ P x \ (TyVar X) T" - and a3: "\\ X x. (\ \ ok) \ X\domain \ \ P x \ (TyVar X) (TyVar X)" + and a1: "\\ S x. \ \ ok \ S closed_in \ \ P x \ S Top" + and a2: "\\ X S T x. \ \ ok \ (X,S)\set \ \ \ \ S <: T \ (\z. P z \ S T) + \ P x \ (TVar X) T" + and a3: "\\ X x. \ \ ok \ X\domain \ \ P x \ (TVar X) (TVar X)" and a4: "\\ S1 S2 T1 T2 x. \ \ T1 <: S1 \ (\z. P z \ T1 S1) \ \ \ S2 <: T2 \ (\z. P z \ S2 T2) \ P x \ (S1 \ S2) (T1 \ T2)" and a5: "\\ X S1 S2 T1 T2 x. @@ -335,13 +335,8 @@ proof - from a have "\(pi::tyvrs prm) (x::'a::fs_tyvrs). P x (pi\\) (pi\S) (pi\T)" proof (induct) - case (S_Top S \) - have b1: "\ \ ok" by fact - have b2: "S closed_in \" by fact - from b1 have "\ (pi\\) ok" by (rule valid_eqvt) - moreover - from b2 have "(pi\S) closed_in (pi\\)" by (rule closed_in_eqvt) - ultimately show "P x (pi \ \) (pi \ S) (pi\Top)" by (simp add: a1) + case (S_Top S \) + thus "P x (pi\\) (pi\S) (pi\Top)" by (force intro: valid_eqvt closed_in_eqvt a1) next case (S_Var S T X \) have b1: "\ \ ok" by fact @@ -357,7 +352,7 @@ moreover from b4 have "\x. P x (pi\\) (pi\S) (pi\T)" by simp ultimately - show "P x (pi\\) (pi\(TyVar X)) (pi\T)" by (simp add: a2) + show "P x (pi\\) (pi\(TVar X)) (pi\T)" by (simp add: a2) next case (S_Refl X \) have b1: "\ \ ok" by fact @@ -366,9 +361,9 @@ moreover from b2 have "(pi\X)\pi\domain \" by (rule pt_set_bij2[OF pt_tyvrs_inst, OF at_tyvrs_inst]) hence "(pi\X)\domain (pi\\)" by (simp add: domain_eqvt pt_list_set_pi[OF pt_tyvrs_inst]) - ultimately show "P x (pi\\) (pi\(TyVar X)) (pi\(TyVar X))" by (simp add: a3) + ultimately show "P x (pi\\) (pi\(TVar X)) (pi\(TVar X))" by (simp add: a3) next - case S_Arrow thus ?case by (simp, auto intro!: a4 subtype_eqvt) + case S_Arrow thus ?case by (auto intro: a4 subtype_eqvt) next case (S_All S1 S2 T1 T2 X \) have b1: "\ \ T1 <: S1" by fact @@ -376,7 +371,7 @@ have b4: "((X,T1)#\) \ S2 <: T2" by fact have b5: "\(pi::tyvrs prm) x. P x (pi\((X,T1)#\)) (pi\S2) (pi\T2)" by fact have b3': "X\\" by fact - have b3'': "X\(T1,S1)" using b1 b3' by (rule subtype_implies_fresh) + have b3'': "X\T1" "X\S1" using b1 b3' by (simp_all add: subtype_implies_fresh) have b3: "X\(\,S1,T1)" using b3' b3'' by (simp add: fresh_prod) have "\C::tyvrs. C\(pi\X,pi\S2,pi\T2,pi\S1,pi\T1,pi\\,x)" by (rule at_exists_fresh[OF at_tyvrs_inst], simp add: fs_tyvrs1) @@ -423,27 +418,28 @@ thus ?thesis by simp qed -section {* Two proofs for reflexivity of subtyping *} +subsection {* Reflexivity of Subtyping *} lemma subtype_reflexivity: assumes a: "\ \ ok" - and b: "T closed_in \" + and b: "T closed_in \" shows "\ \ T <: T" using a b proof(nominal_induct T avoiding: \ rule: ty.induct_unsafe) - case (TAll X T1 T2) - have i1: "\\. \ \ ok \ T1 closed_in \ \ \ \ T1 <: T1" by fact - have i2: "\\. \ \ ok \ T2 closed_in \ \ \ \ T2 <: T2" by fact - have f: "X\\" by fact - have "(\[X<:T2].T1) closed_in \" by fact - hence b1: "T2 closed_in \" and b2: "T1 closed_in ((X,T2)#\)" - by (auto simp add: closed_in_def ty.supp abs_supp) - have c1: "\ \ ok" by fact - hence c2: "\ ((X,T2)#\) ok" using b1 f by force - have "\ \ T2 <: T2" using i2 b1 c1 by simp + case (TAll X T\<^isub>1 T\<^isub>2) + have ih_T\<^isub>1: "\\. \ \ ok \ T\<^isub>1 closed_in \ \ \ \ T\<^isub>1 <: T\<^isub>1" by fact + have ih_T\<^isub>2: "\\. \ \ ok \ T\<^isub>2 closed_in \ \ \ \ T\<^isub>2 <: T\<^isub>2" by fact + have fresh_cond: "X\\" by fact + have "(\[X<:T\<^isub>2].T\<^isub>1) closed_in \" by fact + hence closed\<^isub>T\<^isub>2: "T\<^isub>2 closed_in \" and closed\<^isub>T\<^isub>1: "T\<^isub>1 closed_in ((X,T\<^isub>2)#\)" + by (auto simp add: closed_in_def ty.supp abs_supp) + have ok: "\ \ ok" by fact + hence ok': "\ ((X,T\<^isub>2)#\) ok" using closed\<^isub>T\<^isub>2 fresh_cond by force + have "\ \ T\<^isub>2 <: T\<^isub>2" using ih_T\<^isub>2 closed\<^isub>T\<^isub>2 ok by simp moreover - have "((X,T2)#\) \ T1 <: T1" using i1 b2 c2 by simp - ultimately show "\ \ \[X<:T2].T1 <: \[X<:T2].T1" using f by force + have "((X,T\<^isub>2)#\) \ T\<^isub>1 <: T\<^isub>1" using ih_T\<^isub>1 closed\<^isub>T\<^isub>1 ok' by simp + ultimately show "\ \ \[X<:T\<^isub>2].T\<^isub>1 <: \[X<:T\<^isub>2].T\<^isub>1" using fresh_cond + by (simp add: subtype_of_rel.S_All) qed (auto simp add: closed_in_def ty.supp supp_atm) lemma subtype_reflexivity: @@ -453,24 +449,24 @@ using a b apply(nominal_induct T avoiding: \ rule: ty.induct_unsafe) apply(auto simp add: ty.supp abs_supp closed_in_def supp_atm) -(* too bad that this cannot be found automatically *) +--{* Too bad that this instantiation cannot be found automatically. *} apply(drule_tac x="(tyvrs, ty2)#\" in meta_spec) apply(force simp add: closed_in_def) done -text {* Inversion lemmas. . . *} +text {* Inversion lemmas *} lemma S_TopE: - shows "\ \ Top <: T \ T = Top" -apply(ind_cases "\ \ Top <: T", auto) -done + assumes a: "\ \ Top <: T" + shows "T = Top" +using a by (cases, auto) lemma S_ArrowE_left: assumes a: "\ \ S1 \ S2 <: T" shows "T = Top \ (\T1 T2. T = T1 \ T2 \ \ \ T1 <: S1 \ \ \ S2 <: T2)" -using a by (cases, auto simp add: ty.inject) +using a by (cases, auto simp add: ty.inject) lemma S_AllE_left: - shows "\\ \ \[X<:S1].S2 <: T; X\(\,S1)\ + shows "\\ \ \[X<:S1].S2 <: T; X\\; X\S1\ \ T = Top \ (\T1 T2. T = \[X<:T1].T2 \ \ \ T1 <: S1 \ ((X,T1)#\) \ S2 <: T2)" apply(frule subtype_implies_ok) apply(ind_cases "\ \ \[X<:S1].S2 <: T") @@ -486,10 +482,9 @@ (* 1st conjunct *) apply(rule conjI) apply(simp add: pt_fresh_left[OF pt_tyvrs_inst, OF at_tyvrs_inst] calc_atm) - apply(simp add: fresh_prod) apply(drule_tac \="((Xa,T1)#\)" in subtype_implies_closed)+ apply(simp add: closed_in_def) - apply(auto simp add: domain_fresh[of "\" "X", symmetric]) + apply(simp add: domain_fresh[of "\" "X", symmetric]) apply(simp add: fresh_def) apply(subgoal_tac "X \ (insert Xa (domain \))")(*A*) apply(force) @@ -497,7 +492,7 @@ apply(simp add: at_fin_set_supp[OF at_tyvrs_inst, OF finite_domain]) (* 2nd conjunct *) apply(frule_tac X="X" in subtype_implies_fresh) - apply(simp add: fresh_prod) + apply(assumption) apply(drule_tac X="Xa" in subtype_implies_fresh) apply(assumption) apply(simp add: fresh_prod) @@ -506,19 +501,22 @@ apply(simp add: pt_fresh_fresh[OF pt_tyvrs_inst, OF at_tyvrs_inst]) done -section {* Type substitution *} +section {* Type Substitution *} -lemma subst_ty_fresh[rule_format]: - fixes P :: "ty" - and X :: "tyvrs" - shows "X\(T,P) \ X\(subst_ty T Y P)" +lemma subst_ty_fresh: + fixes X :: "tyvrs" + assumes a: "X\(T,P)" + shows "X\(subst_ty T Y P)" + using a apply (nominal_induct T avoiding : T Y P rule: ty.induct_unsafe) apply (auto simp add: fresh_prod abs_fresh) done -lemma subst_ctxt_fresh[rule_format]: +lemma subst_ctxt_fresh: fixes X::"tyvrs" - shows "X\(\,P) \ X\(subst_ctxt \ Y P)" + assumes a: "X\(\,P)" + shows "X\(subst_ctxt \ Y P)" + using a apply (induct \) apply (auto intro: subst_ty_fresh simp add: fresh_prod fresh_list_cons) done @@ -596,10 +594,16 @@ using a1 a2 by (auto dest: extends_domain simp add: closed_in_def) +lemma extends_memb: + assumes a: "\ extends \" + and b: "(X,T) \ set \" + shows "(X,T) \ set \" + using a b by (simp add: extends_def) + lemma weakening: assumes a: "\ \ S <: T" - and b: "\ \ ok" - and c: "\ extends \" + and b: "\ \ ok" + and c: "\ extends \" shows "\ \ S <: T" using a b c proof (nominal_induct \ S T avoiding: \ rule: subtype_of_rel_induct) @@ -608,7 +612,7 @@ have "\ \ ok" by fact moreover have "\ extends \" by fact - hence "S closed_in \" using lh_drv_prem by (rule_tac extends_closed) + hence "S closed_in \" using lh_drv_prem by (simp only: extends_closed) ultimately show "\ \ S <: Top" by force next case (S_Var \ X S T) @@ -616,10 +620,10 @@ have ih: "\\. \ \ ok \ \ extends \ \ \ \ S <: T" by fact have ok: "\ \ ok" by fact have extends: "\ extends \" by fact - have "(X,S) \ set \" using lh_drv_prem extends by (simp add: extends_def) + have "(X,S) \ set \" using lh_drv_prem extends by (simp only: extends_memb) moreover have "\ \ S <: T" using ok extends ih by simp - ultimately show "\ \ TyVar X <: T" using ok by force + ultimately show "\ \ TVar X <: T" using ok by force next case (S_Refl \ X) have lh_drv_prem: "X \ domain \" by fact @@ -627,90 +631,84 @@ moreover have "\ extends \" by fact hence "X \ domain \" using lh_drv_prem by (force dest: extends_domain) - ultimately show "\ \ TyVar X <: TyVar X" by force + ultimately show "\ \ TVar X <: TVar X" by force next - case S_Arrow thus ?case by force + case (S_Arrow \ S\<^isub>1 S\<^isub>2 T\<^isub>1 T\<^isub>2) thus "\ \ S\<^isub>1 \ S\<^isub>2 <: T\<^isub>1 \ T\<^isub>2" by blast next - case (S_All \ X S1 S2 T1 T2) - have fresh: "X\\" by fact - have ih1: "\\. \ \ ok \ \ extends \ \ \ \ T1 <: S1" by fact - have ih2: "\\. \ \ ok \ \ extends ((X,T1)#\) \ \ \ S2 <: T2" by fact - have lh_drv_prem: "\ \ T1 <: S1" by fact - hence b5: "T1 closed_in \" by (simp add: subtype_implies_closed) + case (S_All \ X S\<^isub>1 S\<^isub>2 T\<^isub>1 T\<^isub>2) + have fresh_cond: "X\\" by fact + have ih\<^isub>1: "\\. \ \ ok \ \ extends \ \ \ \ T\<^isub>1 <: S\<^isub>1" by fact + have ih\<^isub>2: "\\. \ \ ok \ \ extends ((X,T\<^isub>1)#\) \ \ \ S\<^isub>2 <: T\<^isub>2" by fact + have lh_drv_prem: "\ \ T\<^isub>1 <: S\<^isub>1" by fact + hence closed\<^isub>T\<^isub>1: "T\<^isub>1 closed_in \" by (simp add: subtype_implies_closed) have ok: "\ \ ok" by fact - have extends: "\ extends \" by fact - have "T1 closed_in \" using extends b5 by (simp only: extends_closed) - hence "\ ((X,T1)#\) ok" using fresh ok by force + have ext: "\ extends \" by fact + have "T\<^isub>1 closed_in \" using ext closed\<^isub>T\<^isub>1 by (simp only: extends_closed) + hence "\ ((X,T\<^isub>1)#\) ok" using fresh_cond ok by force moreover - have "((X,T1)#\) extends ((X,T1)#\)" using extends by (force simp add: extends_def) - ultimately have "((X,T1)#\) \ S2 <: T2" using ih2 by simp + have "((X,T\<^isub>1)#\) extends ((X,T\<^isub>1)#\)" using ext by (force simp add: extends_def) + ultimately have "((X,T\<^isub>1)#\) \ S\<^isub>2 <: T\<^isub>2" using ih\<^isub>2 by simp moreover - have "\ \ T1 <: S1" using ok extends ih1 by simp - ultimately show "\ \ \ [X<:S1].S2 <: \ [X<:T1].T2" using ok by (force intro: S_All) + have "\ \ T\<^isub>1 <: S\<^isub>1" using ok ext ih\<^isub>1 by simp + ultimately show "\ \ \ [X<:S\<^isub>1].S\<^isub>2 <: \ [X<:T\<^isub>1].T\<^isub>2" using ok by (force intro: S_All) qed -text {* more automated proof *} +text {* In fact all "non-binding" cases can be solved automatically: *} lemma weakening: assumes a: "\ \ S <: T" - and b: "\ \ ok" - and c: "\ extends \" + and b: "\ \ ok" + and c: "\ extends \" shows "\ \ S <: T" using a b c proof (nominal_induct \ S T avoiding: \ rule: subtype_of_rel_induct) - case (S_Top \ S) thus ?case by (force intro: extends_closed) -next - case (S_Var \ X S T) thus ?case by (force simp add: extends_def) -next - case (S_Refl \ X) thus ?case by (force dest: extends_domain) -next - case S_Arrow thus ?case by force -next - case (S_All \ X S1 S2 T1 T2) - have fresh: "X\\" by fact - have ih1: "\\. \ \ ok \ \ extends \ \ \ \ T1 <: S1" by fact - have ih2: "\\. \ \ ok \ \ extends ((X,T1)#\) \ \ \ S2 <: T2" by fact - have lh_drv_prem: "\ \ T1 <: S1" by fact - hence b5: "T1 closed_in \" by (simp add: subtype_implies_closed) + case (S_All \ X S\<^isub>1 S\<^isub>2 T\<^isub>1 T\<^isub>2) + have fresh_cond: "X\\" by fact + have ih\<^isub>1: "\\. \ \ ok \ \ extends \ \ \ \ T\<^isub>1 <: S\<^isub>1" by fact + have ih\<^isub>2: "\\. \ \ ok \ \ extends ((X,T\<^isub>1)#\) \ \ \ S\<^isub>2 <: T\<^isub>2" by fact + have lh_drv_prem: "\ \ T\<^isub>1 <: S\<^isub>1" by fact + hence closed\<^isub>T\<^isub>1: "T\<^isub>1 closed_in \" by (simp add: subtype_implies_closed) have ok: "\ \ ok" by fact - have extends: "\ extends \" by fact - have "T1 closed_in \" using extends b5 by (simp only: extends_closed) - hence "\ ((X,T1)#\) ok" using fresh ok by force + have ext: "\ extends \" by fact + have "T\<^isub>1 closed_in \" using ext closed\<^isub>T\<^isub>1 by (simp only: extends_closed) + hence "\ ((X,T\<^isub>1)#\) ok" using fresh_cond ok by force moreover - have "((X,T1)#\) extends ((X,T1)#\)" using extends by (force simp add: extends_def) - ultimately have "((X,T1)#\) \ S2 <: T2" using ih2 by simp + have "((X,T\<^isub>1)#\) extends ((X,T\<^isub>1)#\)" using ext by (force simp add: extends_def) + ultimately have "((X,T\<^isub>1)#\) \ S\<^isub>2 <: T\<^isub>2" using ih\<^isub>2 by simp moreover - have "\ \ T1 <: S1" using ok extends ih1 by simp - ultimately show "\ \ \ [X<:S1].S2 <: \ [X<:T1].T2" using ok by (force intro: S_All) -qed + have "\ \ T\<^isub>1 <: S\<^isub>1" using ok ext ih\<^isub>1 by simp + ultimately show "\ \ \ [X<:S\<^isub>1].S\<^isub>2 <: \ [X<:T\<^isub>1].T\<^isub>2" using ok by (force intro: S_All) +qed (blast intro: extends_closed extends_memb dest: extends_domain)+ +text {* our contexts grow from right to left *} lemma transitivity_and_narrowing: shows "\ \ S <: Q \ \ \ Q <: T \ \ \ S <: T" - and "(\@(X,Q)#\) \ M <: N \ \ \ P <: Q \ (\@(X,P)#\) \ M <: N" + and "(\@[(X,Q)]@\) \ M <: N \ \ \ P <: Q \ (\@[(X,P)]@\) \ M <: N" proof (induct Q fixing: \ S T and \ \ X P M N taking: "size_ty" rule: measure_induct_rule) - case (less Q) - note IH1_outer = less[THEN conjunct1, rule_format] - and IH2_outer = less[THEN conjunct2, THEN spec, of _ "[]", simplified, rule_format] + case (less Q) + note IH_trans = prems[THEN conjunct1, rule_format] + note IH_narrow = prems[THEN conjunct2, THEN spec, of _ "[]", simplified, rule_format] + --{* The inner induction for transitivity over @{term "\ \ S <: Q"} *} have transitivity: "\\ S T. \ \ S <: Q \ \ \ Q <: T \ \ \ S <: T" proof - - -- {* We first handle the case where T = Top once and for all; this saves some - repeated argument below (just like on paper :-). We establish a little lemma - that is invoked where needed in each case of the induction. *} + -- {* We first handle the case where T = Top once and for all; this saves some + repeated argument below (just like on paper :-). To do so we establish a little + lemma that is invoked where needed in the induction for transitivity. *} have top_case: "\\ S T' P. \\ \ ok; S closed_in \; P \ \ \ S <: T'; T'=Top \ P\ \ \ \ S <: T'" proof - fix \ S T' P - assume S_Top_prem1: "S closed_in \" - and S_Top_prem2: "\ \ ok" + assume S_Top_prm1: "S closed_in \" + and S_Top_prm2: "\ \ ok" and alternative: "P \ \ \ S <: T'" and "T'=Top \ P" moreover { assume "T'=Top" - hence "\ \ S <: T'" using S_Top_prem1 S_Top_prem2 by (simp add: S_Top) + hence "\ \ S <: T'" using S_Top_prm1 S_Top_prm2 by (simp add: S_Top) } moreover { assume P @@ -719,199 +717,184 @@ ultimately show "\ \ S <: T'" by blast qed - (* Now proceed by induction on the left-hand derivation *) - fix \ S T - assume a: "\ \ S <: Q" - assume b: "\ \ Q <: T" - from a b show "\ \ S <: T" - proof(nominal_induct \ S Q\Q avoiding: \ S T rule: subtype_of_rel_induct) - case (S_Top \1 S1) --{* lh drv.: @{term "\ \ S <: Q \ \1 \ S1 <: Top"} *} - have lh_drv_prem1: "\ \1 ok" by fact - have lh_drv_prem2: "S1 closed_in \1" by fact - have Q_inst: "Top=Q" by fact - have rh_drv: "\1 \ Q <: T" --"rh drv." by fact - hence "T = Top" using Q_inst by (simp add: S_TopE) - thus "\1 \ S1 <: T" using top_case[of "\1" "S1" "False" "T"] lh_drv_prem1 lh_drv_prem2 by blast + --{* Now proceed by the inner induction on the left-hand derivation *} + fix \' S' T + assume a: "\' \ S' <: Q" --{* lh derivation *} + assume b: "\' \ Q <: T" --{* rh derivation *} + from a b show "\' \ S' <: T" + proof(nominal_induct \' S' Q\Q avoiding: \' S' T rule: subtype_of_rel_induct) + case (S_Top \ S) + --{* in this case lh drv is @{term "\ \ S <: Top"} *} + hence rh_drv: "\ \ Top <: T" by simp + hence T_inst: "T = Top" by (simp add: S_TopE) + have lh_drv_prm1: "\ \ ok" by fact + have lh_drv_prm2: "S closed_in \" by fact + from lh_drv_prm1 lh_drv_prm2 have "\ \ S <: Top" by (simp add: subtype_of_rel.S_Top) + thus "\ \ S <: T" using T_inst by simp next - case (S_Var \1 X1 S1 T1) --{* lh drv.: @{term "\ \ S <: Q \ \1 \ TVar(X1) <: S1"} *} - have lh_drv_prem1: "\ \1 ok" by fact - have lh_drv_prem2: "(X1,S1)\set \1" by fact - have IH_inner: "\T. \1 \ Q <: T \ T1=Q \ \1 \ S1 <: T" by fact - have Q_inst: "T1=Q" by fact - have rh_drv: "\1 \ Q <: T" by fact - with IH_inner have "\1 \ S1 <: T" using Q_inst by simp - thus "\1 \ TyVar X1 <: T" using lh_drv_prem1 lh_drv_prem2 by (simp add: subtype_of_rel.S_Var) + case (S_Var \ Y U Q) + --{* in this case lh drv is @{term "\ \ TVar(Y) <: Q"} *} + hence IH_inner: "\ \ U <: T" by simp + have lh_drv_prm1: "\ \ ok" by fact + have lh_drv_prm2: "(Y,U)\set \" by fact + from IH_inner show "\ \ TVar Y <: T" using lh_drv_prm1 lh_drv_prm2 + by (simp add: subtype_of_rel.S_Var) next - case S_Refl --{* @{text S_Refl} case *} - thus ?case by simp + case (S_Refl \ X) + --{* in this case lh drv is @{term "\ \ TVar X <: TVar X"} *} + thus "\ \ TVar X <: T" by simp next - case (S_Arrow \1 S1 S2 T1 T2) --{* lh drv.: @{term "\ \ S <: Q \ \1 \ S1 \ S2 <: T1 \ T2"} *} - have lh_drv_prem1: "\1 \ T1 <: S1" by fact - have lh_drv_prem2: "\1 \ S2 <: T2" by fact - have rh_deriv: "\1 \ Q <: T" by fact - have Q_inst: "T1 \ T2 = Q" by fact - have measure: "size_ty T1 < size_ty Q" "size_ty T2 < size_ty Q " using Q_inst by force+ - have "S1 closed_in \1" and "S2 closed_in \1" - using lh_drv_prem1 lh_drv_prem2 by (simp_all add: subtype_implies_closed) - hence "(S1 \ S2) closed_in \1" by (simp add: closed_in_def ty.supp) + case (S_Arrow \ S1 S2 Q1 Q2) + --{* in this case lh drv is @{term "\ \ S1 \ S2 <: Q1 \ Q2"} *} + hence rh_drv: "\ \ Q1 \ Q2 <: T" by simp + have Q_inst: "Q1 \ Q2 = Q" by fact + hence Q1_less: "size_ty Q1 < size_ty Q" + and Q2_less: "size_ty Q2 < size_ty Q" by auto + have lh_drv_prm1: "\ \ Q1 <: S1" by fact + have lh_drv_prm2: "\ \ S2 <: Q2" by fact + have "S1 closed_in \" and "S2 closed_in \" + using lh_drv_prm1 lh_drv_prm2 by (simp_all add: subtype_implies_closed) + hence "(S1 \ S2) closed_in \" by (simp add: closed_in_def ty.supp) moreover - have "\ \1 ok" using rh_deriv by (rule subtype_implies_ok) + have "\ \ ok" using rh_drv by (rule subtype_implies_ok) moreover - have "T = Top \ (\T3 T4. T= T3 \ T4 \ \1 \ T3 <: T1 \ \1 \ T2 <: T4)" - using rh_deriv Q_inst by (simp add:S_ArrowE_left) + from rh_drv have "T = Top \ (\T1 T2. T = T1 \ T2 \ \ \ T1 <: Q1 \ \ \ Q2 <: T2)" + by (simp add: S_ArrowE_left) moreover - { assume "\T3 T4. T= T3 \ T4 \ \1 \ T3 <: T1 \ \1 \ T2 <: T4" - then obtain T3 T4 - where T_inst: "T= T3 \ T4" - and rh_drv_prem1: "\1 \ T3 <: T1" - and rh_drv_prem2: "\1 \ T2 <: T4" by force - from IH1_outer[of "T1"] have "\1 \ T3 <: S1" using measure rh_drv_prem1 lh_drv_prem1 by blast + { assume "\T1 T2. T = T1 \ T2 \ \ \ T1 <: Q1 \ \ \ Q2 <: T2" + then obtain T1 T2 + where T_inst: "T = T1 \ T2" + and rh_drv_prm1: "\ \ T1 <: Q1" + and rh_drv_prm2: "\ \ Q2 <: T2" by force + from IH_trans[of "Q1"] have "\ \ T1 <: S1" using Q1_less rh_drv_prm1 lh_drv_prm1 by simp moreover - from IH1_outer[of "T2"] have "\1 \ S2 <: T4" using measure rh_drv_prem2 lh_drv_prem2 by blast - ultimately have "\1 \ S1 \ S2 <: T" using T_inst by force + from IH_trans[of "Q2"] have "\ \ S2 <: T2" using Q2_less rh_drv_prm2 lh_drv_prm2 by simp + ultimately have "\ \ S1 \ S2 <: T1 \ T2" by (simp add: subtype_of_rel.S_Arrow) + hence "\ \ S1 \ S2 <: T" using T_inst by simp } - ultimately show "\1 \ S1 \ S2 <: T" using top_case[of "\1" "S1\S2" _ "T'"] by blast + ultimately show "\ \ S1 \ S2 <: T" using top_case by blast next - case (S_All \1 X S1 S2 T1 T2) --{* lh drv.: @{term "\\S<:Q \ \1\\[X<:S1].S2 <: \[X<:T1].T2"} *} - have lh_drv_prem1: "\1 \ T1 <: S1" by fact - have lh_drv_prem2: "((X,T1)#\1) \ S2 <: T2" by fact - have rh_deriv: "\1 \ Q <: T" by fact - have fresh_cond: "X\\1" "X\S1" "X\T1" by fact - have Q_inst: "\[X<:T1].T2 = Q" by fact - have measure: "size_ty T1 < size_ty Q" "size_ty T2 < size_ty Q " using Q_inst by force+ - have "S1 closed_in \1" and "S2 closed_in ((X,T1)#\1)" - using lh_drv_prem1 lh_drv_prem2 by (simp_all add: subtype_implies_closed) - hence "(\[X<:S1].S2) closed_in \1" by (force simp add: closed_in_def ty.supp abs_supp) + case (S_All \ X S1 S2 Q1 Q2) + --{* in this case lh drv is @{term "\\\[X<:S1].S2 <: \[X<:Q1].Q2"} *} + hence rh_drv: "\ \ \[X<:Q1].Q2 <: T" by simp + have lh_drv_prm1: "\ \ Q1 <: S1" by fact + have lh_drv_prm2: "((X,Q1)#\) \ S2 <: Q2" by fact + have fresh_cond: "X\\" "X\Q1" by fact + have Q_inst: "\[X<:Q1].Q2 = Q" by fact + hence Q1_less: "size_ty Q1 < size_ty Q" + and Q2_less: "size_ty Q2 < size_ty Q " by auto + have "S1 closed_in \" and "S2 closed_in ((X,Q1)#\)" + using lh_drv_prm1 lh_drv_prm2 by (simp_all add: subtype_implies_closed) + hence "(\[X<:S1].S2) closed_in \" by (force simp add: closed_in_def ty.supp abs_supp) moreover - have "\ \1 ok" using rh_deriv by (rule subtype_implies_ok) + have "\ \ ok" using rh_drv by (rule subtype_implies_ok) moreover - (* FIX: Maybe T3,T4 could be T1',T2' *) - have "T = Top \ (\T3 T4. T=\[X<:T3].T4 \ \1 \ T3 <: T1 \ ((X,T3)#\1) \ T2 <: T4)" - using rh_deriv fresh_cond Q_inst by (auto dest: S_AllE_left simp add: fresh_prod) + from rh_drv have "T = Top \ (\T1 T2. T = \[X<:T1].T2 \ \ \ T1 <: Q1 \ ((X,T1)#\) \ Q2 <: T2)" + using fresh_cond by (simp add: S_AllE_left) moreover - { assume "\T3 T4. T=\[X<:T3].T4 \ \1 \ T3 <: T1 \ ((X,T3)#\1) \ T2 <: T4" - then obtain T3 T4 - where T_inst: "T= \[X<:T3].T4" - and rh_drv_prem1: "\1 \ T3 <: T1" - and rh_drv_prem2:"((X,T3)#\1) \ T2 <: T4" by force - from IH1_outer[of "T1"] have "\1 \ T3 <: S1" - using lh_drv_prem1 rh_drv_prem1 measure by blast + { assume "\T1 T2. T = \[X<:T1].T2 \ \ \ T1 <: Q1 \ ((X,T1)#\) \ Q2 <: T2" + then obtain T1 T2 + where T_inst: "T = \[X<:T1].T2" + and rh_drv_prm1: "\ \ T1 <: Q1" + and rh_drv_prm2:"((X,T1)#\) \ Q2 <: T2" by force + from IH_trans[of "Q1"] have "\ \ T1 <: S1" + using lh_drv_prm1 rh_drv_prm1 Q1_less by blast moreover - from IH2_outer[of "T1"] have "((X,T3)#\1) \ S2 <: T2" - using measure lh_drv_prem2 rh_drv_prem1 by force - with IH1_outer[of "T2"] have "((X,T3)#\1) \ S2 <: T4" - using measure rh_drv_prem2 by force + from IH_narrow[of "Q1"] have "((X,T1)#\) \ S2 <: Q2" + using Q1_less lh_drv_prm2 rh_drv_prm1 by blast + with IH_trans[of "Q2"] have "((X,T1)#\) \ S2 <: T2" + using Q2_less rh_drv_prm2 by blast moreover - ultimately have "\1 \ \[X<:S1].S2 <: T" - using fresh_cond T_inst by (simp add: fresh_prod subtype_of_rel.S_All) + ultimately have "\ \ \[X<:S1].S2 <: \[X<:T1].T2" + using fresh_cond by (simp add: subtype_of_rel.S_All) + hence "\ \ \[X<:S1].S2 <: T" using T_inst by simp } - ultimately show "\1 \ \[X<:S1].S2 <: T" using Q_inst top_case[of "\1" "\[X<:S1].S2" _ "T'"] - by auto + ultimately show "\ \ \[X<:S1].S2 <: T" using top_case by blast qed qed + --{* The inner induction for narrowing over @{term "(\@[(X,Q)]@\) \ M <: N"} *} have narrowing: - "\\ \ X M N P. (\@(X,Q)#\) \ M <: N \ \ \ P<:Q \ (\@(X,P)#\) \ M <: N" + "\\ \ X M N P. (\@[(X,Q)]@\) \ M <: N \ \ \ P<:Q \ (\@[(X,P)]@\) \ M <: N" proof - - fix \ \ X M N P - assume a: "(\@(X,Q)#\) \ M <: N" - assume b: "\ \ P<:Q" - show "(\@(X,P)#\) \ M <: N" - using a b - proof (nominal_induct \\"\@(X,Q)#\" M N avoiding: \ \ X rule: subtype_of_rel_induct) - case (S_Top \1 S1 \ \2 X) - then have lh_drv_prem1: "\ (\@(X,Q)#\2) ok" - and lh_drv_prem2: "S1 closed_in (\@(X,Q)#\2)" by (simp_all only:) - have rh_drv: "\2 \ P <: Q" by fact - hence "P closed_in \2" by (simp add: subtype_implies_closed) - with lh_drv_prem1 have "\ (\@(X,P)#\2) ok" by (simp only: replace_type) + fix \' \' X M N P + assume a: "(\'@[(X,Q)]@\') \ M <: N" + assume b: "\' \ P<:Q" + from a b show "(\'@[(X,P)]@\') \ M <: N" + proof (nominal_induct \\"\'@[(X,Q)]@\'" M N avoiding: \' \' X rule: subtype_of_rel_induct) + case (S_Top _ S \ \ X) + --{* in this case lh drv is @{term "(\@[(X,Q)]@\) \ S <: Top"} *} + hence lh_drv_prm1: "\ (\@[(X,Q)]@\) ok" + and lh_drv_prm2: "S closed_in (\@[(X,Q)]@\)" by simp_all + have rh_drv: "\ \ P <: Q" by fact + hence "P closed_in \" by (simp add: subtype_implies_closed) + with lh_drv_prm1 have "\ (\@[(X,P)]@\) ok" by (simp add: replace_type) moreover - from lh_drv_prem2 have "S1 closed_in (\@(X,P)#\2)" by (simp add: closed_in_def domain_append) - ultimately show "(\@(X,P)#\2) \ S1 <: Top" by (rule subtype_of_rel.S_Top) + from lh_drv_prm2 have "S closed_in (\@[(X,P)]@\)" by (simp add: closed_in_def domain_append) + ultimately show "(\@[(X,P)]@\) \ S <: Top" by (simp add: subtype_of_rel.S_Top) next - case (S_Var \1 X1 S1 T1 \ \2 X) - then have lh_drv_prem1: "\ (\@(X,Q)#\2) ok" - and lh_drv_prem2: "(X1,S1)\set (\@(X,Q)#\2)" - and lh_drv_prem3: "(\@(X,Q)#\2) \ S1 <: T1" - and IH_inner: "\2 \ P <: Q \ (\@(X,P)#\2) \ S1 <: T1" by (simp_all only:) - have rh_drv: "\2 \ P <: Q" by fact - hence "P closed_in \2" by (simp add: subtype_implies_closed) - hence a3: "\ (\@(X,P)#\2) ok" using lh_drv_prem1 by (simp only: replace_type) - show "(\@(X,P)#\2) \ TyVar X1 <: T1" - proof (cases "X=X1") - case False - have b0: "X\X1" by fact - from lh_drv_prem3 rh_drv IH_inner - have b1: "(\@(X,P)#\2) \ S1 <: T1" by simp - from lh_drv_prem2 b0 have b2: "(X1,S1)\set (\@(X,P)#\2)" by simp - show "(\@(X,P)#\2) \ TyVar X1 <: T1" using a3 b2 b1 by (rule subtype_of_rel.S_Var) - next - case True - have b0: "X=X1" by fact - have a4: "S1=Q" - proof - - have "(X1,Q)\set (\@(X,Q)#\2)" using b0 by simp - with lh_drv_prem1 lh_drv_prem2 show "S1=Q" by (blast intro: uniqueness_of_ctxt) - qed - have a5: "(\@(X,P)#\2) extends \2" by (force simp add: extends_def) - have a6: "(\@(X1,P)#\2) \ P <: Q" using b0 a5 rh_drv a3 by (simp add: weakening) - have a7: "(\@(X1,P)#\2) \ Q <: T1" using b0 IH_inner lh_drv_prem3 rh_drv a4 by simp - have a8: "(\@(X1,P)#\2) \ P <: T1" using a6 a7 transitivity by blast - have a9: "(X1,P)\set (\@(X,P)#\2)" using b0 by simp - show "(\@(X,P)#\2) \ TyVar X1 <: T1" using a3 b0 a8 a9 by force - qed + case (S_Var _ Y S N \ \ X) + --{* in this case lh drv is @{term "(\@[(X,Q)]@\) \ TVar Y <: N"} *} + hence IH_inner: "(\@[(X,P)]@\) \ S <: N" + and lh_drv_prm1: "\ (\@[(X,Q)]@\) ok" + and lh_drv_prm2: "(Y,S)\set (\@[(X,Q)]@\)" by simp_all + have rh_drv: "\ \ P <: Q" by fact + hence "P closed_in \" by (simp add: subtype_implies_closed) + hence cntxt_ok: "\ (\@[(X,P)]@\) ok" using lh_drv_prm1 by (simp add: replace_type) + -- {* we distinguishing the cases @{term "X\Y"} and @{term "X=Y"} (the latter + being the interesting one) *} + { assume "X\Y" + hence "(Y,S)\set (\@[(X,P)]@\)" using lh_drv_prm2 by simp + with IH_inner have "(\@[(X,P)]@\) \ TVar Y <: N" + using cntxt_ok by (simp add: subtype_of_rel.S_Var) + } + moreover + { have memb_XQ: "(X,Q)\set (\@[(X,Q)]@\)" by simp + have memb_XP: "(X,P)\set (\@[(X,P)]@\)" by simp + assume "X=Y" + hence "S=Q" using lh_drv_prm1 lh_drv_prm2 memb_XQ by (simp only: uniqueness_of_ctxt) + hence "(\@[(X,P)]@\) \ Q <: N" using IH_inner by simp + moreover + have "(\@[(X,P)]@\) extends \" by (simp add: extends_def) + hence "(\@[(X,P)]@\) \ P <: Q" using rh_drv cntxt_ok by (simp only: weakening) + ultimately have "(\@[(X,P)]@\) \ P <: N" using transitivity by simp + hence "(\@[(X,P)]@\) \ TVar X <: N" using memb_XP cntxt_ok + by (simp only: subtype_of_rel.S_Var) + } + ultimately show "(\@[(X,P)]@\) \ TVar Y <: N" by blast next - case (S_Refl \1 X1 \ \2 X) - have lh_drv_prem1: "\ \1 ok" by fact - have lh_drv_prem2: "X1 \ domain \1" by fact - have \1_inst: "\1 = \@(X,Q)#\2" by fact - have "\2 \ P <: Q" by fact - hence "P closed_in \2" by (simp add: subtype_implies_closed) - hence a3: "\ (\@(X,P)#\2) ok" using lh_drv_prem1 \1_inst by (simp add: replace_type) - have b0: "X1 \ domain (\@(X,P)#\2)" using lh_drv_prem2 \1_inst by (simp add: domain_append) - show "(\@(X,P)#\2) \ TyVar X1 <: TyVar X1" using a3 b0 by (rule subtype_of_rel.S_Refl) - next - case S_Arrow thus ?case by blast + case (S_Refl _ Y \ \ X) + --{* in this case lh drv is @{term "(\@[(X,Q)]@\) \ TVar Y <: TVar Y"} *} + hence lh_drv_prm1: "\ (\@[(X,Q)]@\) ok" + and lh_drv_prm2: "Y \ domain (\@[(X,Q)]@\)" by simp_all + have "\ \ P <: Q" by fact + hence "P closed_in \" by (simp add: subtype_implies_closed) + with lh_drv_prm1 have "\ (\@[(X,P)]@\) ok" by (simp add: replace_type) + moreover + from lh_drv_prm2 have "Y \ domain (\@[(X,P)]@\)" by (simp add: domain_append) + ultimately show "(\@[(X,P)]@\) \ TVar Y <: TVar Y" by (simp add: subtype_of_rel.S_Refl) next - case (S_All \1 X1 S1 S2 T1 T2 \ \2 X) - have IH_inner1: "\\ \ X. \ \ P <: Q \ \1 = \@(X,Q)#\ \ (\@(X,P)#\) \ T1 <: S1" by fact - have IH_inner2: "\\ \ X. \ \ P <: Q \ (X1,T1)#\1 = \@(X,Q)#\ \ (\@(X,P)#\) \ S2 <: T2" - by fact - have lh_drv_prem1: "\1 \ T1 <: S1" by fact - have lh_drv_prem2: "X1\\1" "X1\S1" "X1\T1" by fact (* check this whether this is the lh_drv_p2 *) - have lh_drv_prem3: "((X1,T1)#\1) \ S2 <: T2" by fact - have \1_inst: "\1 = \@(X,Q)#\2" by fact - have a2: "\2 \ P <: Q" by fact - have b0: "(\@(X,P)#\2) \ T1 <: S1" using \1_inst a2 lh_drv_prem1 IH_inner1 by simp - have b1: "(((X1,T1)#\)@(X,P)#\2) \ S2 <: T2" using \1_inst a2 lh_drv_prem3 IH_inner2 - apply(auto) - apply(drule_tac x="\2" in meta_spec) - apply(drule_tac x="(X1,T1)#\" in meta_spec) - apply(auto) - done - have b3: "X1\(\@(X,P)#\2)" using lh_drv_prem2 \1_inst a2 - by (auto simp add: fresh_prod fresh_list_append fresh_list_cons dest: subtype_implies_fresh) - show "(\@(X,P)#\2) \ \ [X1<:S1].S2 <: \ [X1<:T1].T2" using b0 b3 b1 by force + case (S_Arrow _ Q1 Q2 S1 S2 \ \ X) + --{* in this case lh drv is @{term "(\@[(X,Q)]@\) \ Q1 \ Q2 <: S1 \ S2"} *} + thus "(\@[(X,P)]@\) \ Q1 \ Q2 <: S1 \ S2" by blast + next + case (S_All _ Y S1 S2 T1 T2 \ \ X) + --{* in this case lh drv is @{term "(\@[(X,Q)]@\) \ \[Y<:S1].S2 <: \[Y<:T1].T2"} *} + hence IH_inner1: "(\@[(X,P)]@\) \ T1 <: S1" + and IH_inner2: "((Y,T1)#\@[(X,P)]@\) \ S2 <: T2" + and lh_drv_prm2: "Y\(\@[(X,Q)]@\)" by force+ + have rh_drv: "\ \ P <: Q" by fact + hence "Y\P" using lh_drv_prm2 by (simp only: fresh_list_append subtype_implies_fresh) + hence "Y\(\@[(X,P)]@\)" using lh_drv_prm2 + by (simp add: fresh_list_append fresh_list_cons fresh_prod) + with IH_inner1 IH_inner2 + show "(\@[(X,P)]@\) \ \[Y<:S1].S2 <: \[Y<:T1].T2" by (simp add: subtype_of_rel.S_All) qed qed from transitivity narrowing show ?case by blast qed - -section {* Terms *} -nominal_datatype trm = Var "vrs" - | Lam "\vrs\trm" "ty" - | TAbs "\tyvrs\trm" "ty" - | App "trm" "trm" - | TApp "trm" "ty" - -consts - Lam_syn :: "vrs \ ty \ trm \ trm" ("Lam [_:_]._" [100,100,100] 100) - TAbs_syn :: "tyvrs \ ty \ trm \ trm" ("TAbs [_<:_]._" [100,100,100] 100) -translations - "Lam [a:tys].t" \ "trm.Lam a t tys" - "TAbs [a<:tys].t" \ "trm.TAbs a t tys" end \ No newline at end of file