# HG changeset patch # User urbanc # Date 1136400819 -3600 # Node ID a636846a02c754925019ad25c25c144ae690f091 # Parent 8d98b7711e473a3fb8fb9ce5f6fa039899a12b5a added more documentation; will now try out a modification of the ok-predicate diff -r 8d98b7711e47 -r a636846a02c7 src/HOL/Nominal/Examples/Fsub.thy --- a/src/HOL/Nominal/Examples/Fsub.thy Wed Jan 04 19:22:53 2006 +0100 +++ b/src/HOL/Nominal/Examples/Fsub.thy Wed Jan 04 19:53:39 2006 +0100 @@ -1,50 +1,83 @@ (* $Id$ *) +(*<*) theory fsub imports "../nominal" begin +(*>*) -text {* Authors: Christian Urban, - Benjamin Pierce, - Steve Zdancewic. - Stephanie Weihrich and - Dimitrios Vytiniotis; +text{* Authors: Christian Urban, + Benjamin Pierce, + Steve Zdancewic, + Stephanie Weihrich and + Dimitrios Vytiniotis, - with help from Stefan Berghofer and Markus Wenzel. - *} - + with great help from Stefan Berghofer and Markus Wenzel. *} section {* Atom Types, Types and Terms *} +text {* The main point of this solution is to use names everywhere (be they bound, + binding or free). There are two kinds of names corresponding to type-variables and + to term-variables in System \FSUB. These two kinds of names are represented in + the nominal datatype package as atom-types @{text "tyvrs"} and @{text "vrs"}: *} + atom_decl tyvrs vrs +text{* There are numerous facts that come with this declaration: for example that + there are infinitely many elements in @{text "tyvrs"} and @{text "vrs"}. *} + +text{* The constructors for types and terms in System \FSUB{} contain abstractions + over type-variables and term-variables. The nominal datatype-package uses + @{text "\\\\"} to indicate where abstractions occur. *} + nominal_datatype ty = - TVar "tyvrs" + Tvar "tyvrs" | Top - | Arrow "ty" "ty" ("_ \ _" [900,900] 900) - | TAll "\tyvrs\ty" "ty" + | Arrow "ty" "ty" ("_ \ _" [100,100] 100) + | Forall "\tyvrs\ty" "ty" nominal_datatype trm = Var "vrs" - | Lam "\vrs\trm" "ty" - | TAbs "\tyvrs\trm" "ty" + | Lam "\vrs\trm" "ty" + | Tabs "\tyvrs\trm" "ty" | App "trm" "trm" - | TApp "trm" "ty" + | Tapp "trm" "ty" + +text {* To be polite to the eye, some more familiar notation is introduced. + Because of the change in the order of the argument, one needs to use + translation rules, instead of syntax annotations at the term-constructors + like for @{term "Arrow"}. *} 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) + Forall_syn :: "tyvrs \ ty \ ty \ ty" ("\[_<:_]._" [100,100,100] 100) + 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" - "Lam [a:tys].t" \ "trm.Lam a t tys" - "TAbs [a<:tys].t" \ "trm.TAbs a t tys" + "\[X<:T\<^isub>1].T\<^isub>2" \ "ty.Forall X T\<^isub>2 T\<^isub>1" + "Lam [x:T].t" \ "trm.Lam x t T" + "Tabs [X<:T].t" \ "trm.Tabs X t T" -subsection {* Typing contexts and Their Domains *} +text {* Note that the nominal-datatype declarations for @{typ "ty"} and @{typ "trm"} + do \emph{not} define "classical" constructor-based datatypes, but rather define + $\alpha$-equivalence classes. Indeed we can show that $\alpha$-equivalent @{typ "ty"}s + and @{typ "trm"}s are equal: *} + +lemma alpha_illustration: + shows "\[X<:T].(Tvar X) = \[Y<:T].(Tvar Y)" + and "Lam [x:T].(Var x) = Lam [y:T].(Var y)" + by (simp_all add: ty.inject trm.inject alpha calc_atm fresh_atm) + +section {* Typing Contexts *} types ty_context = "(tyvrs\ty) list" +text {* Typing contexts are represented as lists "growing" on the left, + in contrast to the POPLmark-paper. *} + +text {* In order to state valitity-conditions for typing-context, the notion of + a domain of a typing-context is handy. *} + consts "domain" :: "ty_context \ tyvrs set" primrec @@ -57,7 +90,6 @@ by (induct \, auto simp add: perm_set_def) lemma finite_domain: - fixes \::"ty_context" shows "finite (domain \)" by (induct \, auto) @@ -75,45 +107,17 @@ shows "domain (\@\) = ((domain \) \ (domain \))" by (induct \, auto) -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 (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" -sorry - -consts subst_ty :: "ty \ tyvrs \ ty \ ty" - -lemma subst_ty[simp]: - 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))" - and "\X\Y; X\T\ \ subst_ty (\[X<:T1].T2) Y T = (\[X<:(subst_ty T1 Y T)].(subst_ty T2 Y T))" -sorry - - -consts subst_ctxt :: "ty_context \ tyvrs \ ty \ ty_context" -primrec -"subst_ctxt [] Y T = []" -"subst_ctxt (XT#Xs) Y T = (fst XT, subst_ty (snd XT) Y T)#(subst_ctxt Xs Y T)" - -subsection {* valid contexts *} +text {* Not all lists of type @{typ "ty_context"} are well-formed. One condition + requires that in @{term "(X,S)#\"} all free variables of @{term "S"} must be + in @{term "domain \"}, that is @{term "S"} must be closed in @{term "\"}. *} constdefs "closed_in" :: "ty \ ty_context \ bool" ("_ closed'_in _" [100,100] 100) "S closed_in \ \ (supp S)\(domain \)" lemma closed_in_def2: - shows "(S closed_in \) = ((supp S)\((supp (domain \)):: tyvrs set))" -apply(simp add: closed_in_def) -apply(simp add: at_fin_set_supp[OF at_tyvrs_inst, OF finite_domain]) + shows "(S closed_in \) = ((supp S)\((supp (domain \))::tyvrs set))" +apply(simp add: closed_in_def at_fin_set_supp[OF at_tyvrs_inst, OF finite_domain]) done lemma closed_in_eqvt: @@ -136,8 +140,9 @@ "\ \ ok" \ "\ \ valid_rel" inductive valid_rel intros -v1[intro]: "\ [] ok" -v2[intro]: "\\ \ ok; X\\; T closed_in \\ \ \ ((X,T)#\) ok" +v_nil[intro]: "\ [] ok" +v_cons[intro]: "\\ \ ok; X\\; T closed_in \\ \ \ ((X,T)#\) ok" + lemma valid_eqvt: fixes pi::"tyvrs prm" @@ -145,21 +150,18 @@ shows "\ (pi\\) ok" using a proof (induct) - case v1 - show ?case by force + case v_nil + show "\ (pi\[]) ok" by (simp add: valid_rel.v_nil) next - case (v2 T X \) - have a1: "\ (pi \ \) ok" by fact - have a2: "X\\" by fact - have a3: "T closed_in \" by fact - show ?case - proof (simp, rule valid_rel.v2) - show "\ (pi \ \) ok" using a1 by simp - next - 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 + case (v_cons T X \) + have "\ (pi \ \) ok" by fact + moreover + have "X\\" by fact + hence "(pi\X)\(pi\\)" by (simp add: fresh_eqvt) + moreover + have "T closed_in \" by fact + hence "(pi\T) closed_in (pi\\)" by (rule closed_in_eqvt) + ultimately show "\ (pi\((X,T)#\)) ok" by (simp add: valid_rel.v_cons) qed lemma validE: @@ -202,7 +204,7 @@ 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(auto dest!: validE intro!: v_cons simp add: fresh_list_append fresh_list_cons fresh_prod) apply(drule validE_append) apply(drule validE) apply(drule_tac S="S" in closed_in_fresh) @@ -216,10 +218,7 @@ fixes \::"ty_context" 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 + using a by (induct \, auto dest: validE simp add: fresh_list_cons fresh_prod fresh_atm) lemma uniqueness_of_ctxt: fixes \::"ty_context" @@ -227,26 +226,56 @@ and b: "(X,T)\set \" and c: "(X,S)\set \" shows "T=S" -using a b c -apply (induct \) -apply (auto dest!: validE fresh_implies_not_member) -done + using a b c by (induct \, auto dest: validE fresh_implies_not_member) + +subsection {* Size Functions and Capture-Avoiding Substitutiuon for Types *} + +text {* In the current version of the nominal datatype + package even simple functions (such as size of types and capture-avoiding + substitution) can only be defined manually via some sophisticated proof + constructions. Therefore we sill just assume them here. *} + +consts size_ty :: "ty \ nat" + +lemma size_ty[simp]: + shows "size_ty (Tvar X) = 1" + and "size_ty (Top) = 1" + and "\size_ty t\<^isub>1 = m ; size_ty t\<^isub>2 = n\ \ size_ty (t\<^isub>1 \ t\<^isub>2) = m + n + 1" + and "\size_ty t\<^isub>1 = m ; size_ty t\<^isub>2 = n\ \ size_ty (\[a<:t\<^isub>1].t\<^isub>2) = m + n + 1" +sorry + +consts subst_ty :: "ty \ tyvrs \ ty \ ty" ("_[_:=_]\<^isub>t\<^isub>y" [100,100,100] 100) + +lemma subst_ty[simp]: + shows "(Tvar X)[Y:=T]\<^isub>t\<^isub>y = (if X=Y then T else (Tvar X))" + and "(Top)[Y:=T]\<^isub>t\<^isub>y = Top" + and "(T\<^isub>1 \ T\<^isub>2)[Y:=T]\<^isub>t\<^isub>y = (T\<^isub>1[Y:=T]\<^isub>t\<^isub>y) \ (T\<^isub>2[Y:=T]\<^isub>t\<^isub>y)" + and "X\(Y,T) \ (\[X<:T\<^isub>1].T\<^isub>2)[Y:=T]\<^isub>t\<^isub>y = (\[X<:(T\<^isub>1[Y:=T]\<^isub>t\<^isub>y)].(T\<^isub>2[Y:=T]\<^isub>t\<^isub>y))" + and "\X\Y; X\T\ \ (\[X<:T\<^isub>1].T\<^isub>2)[Y:=T]\<^isub>t\<^isub>y = (\[X<:(T\<^isub>1[Y:=T]\<^isub>t\<^isub>y)].(T\<^isub>2[Y:=T]\<^isub>t\<^isub>y))" +sorry + +consts subst_ctxt :: "ty_context \ tyvrs \ ty \ ty_context" ("_[_:=_]\<^isub>t\<^isub>y\<^isub>c" [100,100,100] 100) +primrec +"([])[Y:=T]\<^isub>t\<^isub>y\<^isub>c= []" +"(XT#\)[Y:=T]\<^isub>t\<^isub>y\<^isub>c = (fst XT,(snd XT)[Y:=T]\<^isub>t\<^isub>y)#(\[Y:=T]\<^isub>t\<^isub>y\<^isub>c)" -section {* Subtyping *} +section {* Subtyping-Relation *} consts - subtype_of_rel :: "(ty_context \ ty \ ty) set" - subtype_of_sym :: "ty_context \ ty \ ty \ bool" ("_ \ _ <: _" [100,100,100] 100) + subtype_of :: "(ty_context \ ty \ ty) set" +syntax + subtype_of_syn :: "ty_context \ ty \ ty \ bool" ("_ \ _ <: _" [100,100,100] 100) + translations - "\ \ S <: T" \ "(\,S,T) \ subtype_of_rel" -inductive subtype_of_rel + "\ \ S <: T" \ "(\,S,T) \ subtype_of" +inductive subtype_of intros S_Top[intro]: "\\ \ ok; S closed_in \\ \ \ \ S <: Top" -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" +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]: "\\ \ T\<^isub>1 <: S\<^isub>1; \ \ S\<^isub>2 <: T\<^isub>2\ \ \ \ (S\<^isub>1 \ S\<^isub>2) <: (T\<^isub>1 \ T\<^isub>2)" +S_All[intro]: "\\ \ T\<^isub>1 <: S\<^isub>1; X\\; ((X,T\<^isub>1)#\) \ S\<^isub>2 <: T\<^isub>2\ + \ \ \ \[X<:S\<^isub>1].S\<^isub>2 <: \[X<:T\<^isub>1].T\<^isub>2" lemma subtype_implies_closed: assumes a: "\ \ S <: T" @@ -262,14 +291,13 @@ case (S_Var S T X \) have "(X,S)\set \" by fact hence "X \ domain \" by (rule domain_inclusion) - hence "(TVar X) closed_in \" by (simp add: closed_in_def ty.supp supp_atm) + 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 "(TVar X) closed_in \ \ T closed_in \" by simp + ultimately show "(Tvar X) closed_in \ \ T closed_in \" by simp qed (auto simp add: closed_in_def ty.supp supp_atm abs_supp) - lemma subtype_implies_ok: fixes X::"tyvrs" assumes a1: "\ \ S <: T" @@ -311,26 +339,25 @@ lemma subtype_eqvt: fixes pi::"tyvrs prm" shows "\ \ S <: T \ (pi\\) \ (pi\S) <: (pi\T)" -apply(erule subtype_of_rel.induct) +apply(erule subtype_of.induct) apply(force intro: valid_eqvt closed_in_eqvt) apply(force intro: closed_in_eqvt valid_eqvt silly_eqvt1) apply(force intro: valid_eqvt silly_eqvt2) apply(force) -apply(force intro!: S_All simp add: fresh_prod pt_fresh_bij1[OF pt_tyvrs_inst, OF at_tyvrs_inst]) +apply(force intro!: S_All simp add: fresh_prod fresh_eqvt) done -lemma subtype_of_rel_induct[consumes 1, case_names S_Top S_Var S_Refl S_Arrow S_All]: +lemma subtype_of_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 \ (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. - X\x \ X\(\,S1,T1) \ \ \ T1 <: S1 \ (\z. P z \ T1 S1) \ ((X,T1)#\) \ S2 <: T2 - \ (\z. P z ((X,T1)#\) S2 T2) \ P x \ (\ [X<:S1].S2) (\ [X<:T1].T2)" + 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: "\\ S\<^isub>1 S\<^isub>2 T\<^isub>1 T\<^isub>2 x. \ \ T\<^isub>1 <: S\<^isub>1 \ (\z. P z \ T\<^isub>1 S\<^isub>1) \ \ \ S\<^isub>2 <: T\<^isub>2 \ + (\z. P z \ S\<^isub>2 T\<^isub>2) \ P x \ (S\<^isub>1 \ S\<^isub>2) (T\<^isub>1 \ T\<^isub>2)" + and a5: "\\ X S\<^isub>1 S\<^isub>2 T\<^isub>1 T\<^isub>2 x. X\x \ X\(\,S\<^isub>1,T\<^isub>1) \ \ \ T\<^isub>1 <: S\<^isub>1 \ (\z. P z \ T\<^isub>1 S\<^isub>1) + \ ((X,T\<^isub>1)#\) \ S\<^isub>2 <: T\<^isub>2 \ (\z. P z ((X,T\<^isub>1)#\) S\<^isub>2 T\<^isub>2) \ P x \ (\[X<:S\<^isub>1].S\<^isub>2) (\[X<:T\<^isub>1].T\<^isub>2)" shows "P x \ S T" proof - from a have "\(pi::tyvrs prm) (x::'a::fs_tyvrs). P x (pi\\) (pi\S) (pi\T)" @@ -339,29 +366,29 @@ 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 - have b2: "(X,S) \ set \" by fact - have b3: "\ \ S <: T" by fact - have b4: "\(pi::tyvrs prm) x. P x (pi\\) (pi\S) (pi\T)" by fact - from b1 have "\ (pi\\) ok" by (rule valid_eqvt) + have "\ \ ok" by fact + hence "\ (pi\\) ok" by (rule valid_eqvt) + moreover + have "(X,S) \ set \" by fact + hence "pi\(X,S)\pi\(set \)" by (rule pt_set_bij2[OF pt_tyvrs_inst, OF at_tyvrs_inst]) + hence "(pi\X,pi\S)\set (pi\\)" by (simp add: pt_list_set_pi[OF pt_tyvrs_inst]) moreover - from b2 have "pi\(X,S)\pi\(set \)" by (rule pt_set_bij2[OF pt_tyvrs_inst, OF at_tyvrs_inst]) - hence "(pi\X,pi\S)\set (pi\\)" by (simp add: pt_list_set_pi[OF pt_tyvrs_inst]) - moreover - from b3 have "(pi\\) \ (pi\S) <: (pi\T)" by (rule subtype_eqvt) - moreover - from b4 have "\x. P x (pi\\) (pi\S) (pi\T)" by simp + have "\ \ S <: T" by fact + hence "(pi\\) \ (pi\S) <: (pi\T)" by (rule subtype_eqvt) + moreover + have "\(pi::tyvrs prm) x. P x (pi\\) (pi\S) (pi\T)" by fact + hence "\x. P x (pi\\) (pi\S) (pi\T)" by simp ultimately - show "P x (pi\\) (pi\(TVar 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 - have b2: "X \ domain \" by fact - from b1 have "\ (pi\\) ok" by (rule valid_eqvt) + have "\ \ ok" by fact + hence "\ (pi\\) ok" by (rule valid_eqvt) moreover - from b2 have "(pi\X)\pi\domain \" by (rule pt_set_bij2[OF pt_tyvrs_inst, OF at_tyvrs_inst]) + have "X \ domain \" by fact + hence "(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\(TVar X)) (pi\(TVar 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 (auto intro: a4 subtype_eqvt) next @@ -370,9 +397,8 @@ have b2: "\(pi::tyvrs prm) x. P x (pi\\) (pi\T1) (pi\S1)" by fact 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" "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 b3: "X\\" by fact + have b3': "X\T1" "X\S1" using b1 b3 by (simp_all add: subtype_implies_fresh) 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) then obtain C::"tyvrs" where f1: "C\(pi\X)" and f2: "C\(pi\S1)" and f3: "C\(pi\T1)" @@ -389,12 +415,12 @@ with f6 have f6a: "?pi'\\=pi\\" by (simp only: pt_tyvrs2 pt_fresh_fresh[OF pt_tyvrs_inst, OF at_tyvrs_inst]) hence f6': "C\(?pi'\\)" using f6 by simp - from b3 have "(pi\X)\(pi\S1)" + from b3' have "(pi\X)\(pi\S1)" by (simp add: fresh_prod pt_fresh_bij[OF pt_tyvrs_inst, OF at_tyvrs_inst]) with f2 have f2a: "?pi'\S1=pi\S1" by (simp only: pt_tyvrs2 pt_fresh_fresh[OF pt_tyvrs_inst, OF at_tyvrs_inst]) hence f2': "C\(?pi'\S1)" using f2 by simp - from b3 have "(pi\X)\(pi\T1)" + from b3' have "(pi\X)\(pi\T1)" by (simp add: fresh_prod pt_fresh_bij[OF pt_tyvrs_inst, OF at_tyvrs_inst]) with f3 have f3a: "?pi'\T1=pi\T1" by (simp only: pt_tyvrs2 pt_fresh_fresh[OF pt_tyvrs_inst, OF at_tyvrs_inst]) @@ -405,13 +431,13 @@ hence e2: "((C,?pi'\T1)#(?pi'\\)) \ (?pi'\S2) <: (?pi'\T2)" using f1 by (simp only: pt_tyvrs2 calc_atm, simp) have fnew: "C\(?pi'\\,?pi'\S1,?pi'\T1)" using f6' f2' f3' by (simp add: fresh_prod) - have main: "P x (?pi'\\) (\ [C<:(?pi'\S1)].(?pi'\S2)) (\ [C<:(?pi'\T1)].(?pi'\T2))" + have main: "P x (?pi'\\) (\[C<:(?pi'\S1)].(?pi'\S2)) (\[C<:(?pi'\T1)].(?pi'\T2))" using f7 fnew e1 c1 e2 c2 by (rule a5) - have alpha1: "(\ [C<:(?pi'\S1)].(?pi'\S2)) = (pi\(\ [X<:S1].S2))" + have alpha1: "(\[C<:(?pi'\S1)].(?pi'\S2)) = (pi\(\[X<:S1].S2))" using f1 f4 f2a[symmetric] by (simp add: ty.inject alpha pt_tyvrs2[symmetric]) - have alpha2: "(\ [C<:(?pi'\T1)].(?pi'\T2)) = (pi\(\ [X<:T1].T2))" + have alpha2: "(\[C<:(?pi'\T1)].(?pi'\T2)) = (pi\(\[X<:T1].T2))" using f1 f5 f3a[symmetric] by (simp add: ty.inject alpha pt_tyvrs2[symmetric]) - show "P x (pi\\) (pi\(\ [X<:S1].S2)) (pi\(\ [X<:T1].T2))" + show "P x (pi\\) (pi\(\[X<:S1].S2)) (pi\(\[X<:T1].T2))" using alpha1 alpha2 f6a main by simp qed hence "P x (([]::tyvrs prm)\\) (([]::tyvrs prm)\S) (([]::tyvrs prm)\T)" by blast @@ -426,7 +452,7 @@ shows "\ \ T <: T" using a b proof(nominal_induct T avoiding: \ rule: ty.induct_unsafe) - case (TAll X T\<^isub>1 T\<^isub>2) + case (Forall 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 @@ -439,7 +465,7 @@ moreover 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) + by (simp add: subtype_of.S_All) qed (auto simp add: closed_in_def ty.supp supp_atm) lemma subtype_reflexivity: @@ -449,7 +475,9 @@ 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 instantiation cannot be found automatically. *} + --{* Too bad that this instantiation cannot be found automatically by + auto; blast cannot be used since the simplification rule + @{text "closed_in_def"} needs to be applied. *} apply(drule_tac x="(tyvrs, ty2)#\" in meta_spec) apply(force simp add: closed_in_def) done @@ -471,7 +499,7 @@ apply(frule subtype_implies_ok) apply(ind_cases "\ \ \[X<:S1].S2 <: T") apply(auto simp add: ty.inject alpha) - apply(rule_tac x="[(X,Xa)]\T2" in exI) + apply(rule_tac x="[(X,Xa)]\T\<^isub>2" in exI) (* term *) apply(rule conjI) apply(rule sym) @@ -482,7 +510,7 @@ (* 1st conjunct *) apply(rule conjI) apply(simp add: pt_fresh_left[OF pt_tyvrs_inst, OF at_tyvrs_inst] calc_atm) - apply(drule_tac \="((Xa,T1)#\)" in subtype_implies_closed)+ + apply(drule_tac \="((Xa,T\<^isub>1)#\)" in subtype_implies_closed)+ apply(simp add: closed_in_def) apply(simp add: domain_fresh[of "\" "X", symmetric]) apply(simp add: fresh_def) @@ -552,8 +580,8 @@ shows "\ (\@(X,Q)#\) ok \ \ \ P <: Q \ ((subst_ctxt \ X P)@\) \ (subst_ty S X P) <: (subst_ty T X P)" using a0 - thm subtype_of_rel_induct - apply(rule subtype_of_rel_induct[of "\@(X,Q)#\" "S" "T" _ "P"]) + thm subtype_of_induct + apply(rule subtype_of_induct[of "\@(X,Q)#\" "S" "T" _ "P"]) apply(auto) apply(rule S_Top) defer @@ -569,7 +597,7 @@ defer -apply (nominal_induct \ X Q \ S T rule: subtype_of_rel_induct) +apply (nominal_induct \ X Q \ S T rule: subtype_of_induct) *) section {* Weakening *} @@ -606,7 +634,7 @@ and c: "\ extends \" shows "\ \ S <: T" using a b c -proof (nominal_induct \ S T avoiding: \ rule: subtype_of_rel_induct) +proof (nominal_induct \ S T avoiding: \ rule: subtype_of_induct) case (S_Top \ S) have lh_drv_prem: "S closed_in \" by fact have "\ \ ok" by fact @@ -623,7 +651,7 @@ 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 "\ \ TVar 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 @@ -631,7 +659,7 @@ moreover have "\ extends \" by fact hence "X \ domain \" using lh_drv_prem by (force dest: extends_domain) - ultimately show "\ \ TVar X <: TVar X" by force + ultimately show "\ \ Tvar X <: Tvar X" by force next 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 @@ -650,7 +678,7 @@ ultimately have "((X,T\<^isub>1)#\) \ S\<^isub>2 <: T\<^isub>2" using ih\<^isub>2 by simp moreover 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) + 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 {* In fact all "non-binding" cases can be solved automatically: *} @@ -661,7 +689,7 @@ and c: "\ extends \" shows "\ \ S <: T" using a b c -proof (nominal_induct \ S T avoiding: \ rule: subtype_of_rel_induct) +proof (nominal_induct \ S T avoiding: \ rule: subtype_of_induct) 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 @@ -677,7 +705,7 @@ ultimately have "((X,T\<^isub>1)#\) \ S\<^isub>2 <: T\<^isub>2" using ih\<^isub>2 by simp moreover 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) + 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 *} @@ -722,27 +750,27 @@ 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) + proof(nominal_induct \' S' Q\Q avoiding: \' S' T rule: subtype_of_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) + from lh_drv_prm1 lh_drv_prm2 have "\ \ S <: Top" by (simp add: subtype_of.S_Top) thus "\ \ S <: T" using T_inst by simp next case (S_Var \ Y U Q) - --{* in this case lh drv is @{term "\ \ TVar(Y) <: 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) + from IH_inner show "\ \ Tvar Y <: T" using lh_drv_prm1 lh_drv_prm2 + by (simp add: subtype_of.S_Var) next case (S_Refl \ X) - --{* in this case lh drv is @{term "\ \ TVar X <: TVar X"} *} - thus "\ \ TVar X <: T" by simp + --{* in this case lh drv is @{term "\ \ Tvar X <: Tvar X"} *} + thus "\ \ Tvar X <: T" by simp next case (S_Arrow \ S1 S2 Q1 Q2) --{* in this case lh drv is @{term "\ \ S1 \ S2 <: Q1 \ Q2"} *} @@ -769,7 +797,7 @@ from IH_trans[of "Q1"] have "\ \ T1 <: S1" using Q1_less rh_drv_prm1 lh_drv_prm1 by simp moreover 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) + ultimately have "\ \ S1 \ S2 <: T1 \ T2" by (simp add: subtype_of.S_Arrow) hence "\ \ S1 \ S2 <: T" using T_inst by simp } ultimately show "\ \ S1 \ S2 <: T" using top_case by blast @@ -806,7 +834,7 @@ using Q2_less rh_drv_prm2 by blast moreover ultimately have "\ \ \[X<:S1].S2 <: \[X<:T1].T2" - using fresh_cond by (simp add: subtype_of_rel.S_All) + using fresh_cond by (simp add: subtype_of.S_All) hence "\ \ \[X<:S1].S2 <: T" using T_inst by simp } ultimately show "\ \ \[X<:S1].S2 <: T" using top_case by blast @@ -821,7 +849,7 @@ 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) + proof (nominal_induct \\"\'@[(X,Q)]@\'" M N avoiding: \' \' X rule: subtype_of_induct) case (S_Top _ S \ \ X) --{* in this case lh drv is @{term "(\@[(X,Q)]@\) \ S <: Top"} *} hence lh_drv_prm1: "\ (\@[(X,Q)]@\) ok" @@ -831,10 +859,10 @@ with lh_drv_prm1 have "\ (\@[(X,P)]@\) ok" by (simp add: replace_type) moreover 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) + ultimately show "(\@[(X,P)]@\) \ S <: Top" by (simp add: subtype_of.S_Top) next case (S_Var _ Y S N \ \ X) - --{* in this case lh drv is @{term "(\@[(X,Q)]@\) \ TVar Y <: N"} *} + --{* 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 @@ -845,8 +873,8 @@ 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) + with IH_inner have "(\@[(X,P)]@\) \ Tvar Y <: N" + using cntxt_ok by (simp add: subtype_of.S_Var) } moreover { have memb_XQ: "(X,Q)\set (\@[(X,Q)]@\)" by simp @@ -858,13 +886,13 @@ 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) + hence "(\@[(X,P)]@\) \ Tvar X <: N" using memb_XP cntxt_ok + by (simp only: subtype_of.S_Var) } - ultimately show "(\@[(X,P)]@\) \ TVar Y <: N" by blast + ultimately show "(\@[(X,P)]@\) \ Tvar Y <: N" by blast next case (S_Refl _ Y \ \ X) - --{* in this case lh drv is @{term "(\@[(X,Q)]@\) \ TVar Y <: TVar Y"} *} + --{* 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 @@ -872,7 +900,7 @@ 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) + ultimately show "(\@[(X,P)]@\) \ Tvar Y <: Tvar Y" by (simp add: subtype_of.S_Refl) next case (S_Arrow _ Q1 Q2 S1 S2 \ \ X) --{* in this case lh drv is @{term "(\@[(X,Q)]@\) \ Q1 \ Q2 <: S1 \ S2"} *} @@ -888,7 +916,7 @@ 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) + show "(\@[(X,P)]@\) \ \[Y<:S1].S2 <: \[Y<:T1].T2" by (simp add: subtype_of.S_All) qed qed from transitivity narrowing show ?case by blast