theory SystemF imports Main begin section "Option Monad" definition option_bind :: "['a option, 'a => 'b option] => 'b option" where "option_bind m f = (case m of None => None | Some r => f r)" declare option_bind_def[simp] syntax "_option_bind" :: "[pttrns,'a option,'b] => 'c" ("(_ := _;//_)" 0) translations "P := E; F" == "CONST option_bind E (%P. F)" definition return :: "'a \ 'a option" where "return x \ Some x" declare return_def[simp] definition error :: "'a option" where "error \ None" declare error_def[simp] section "Syntax" type_synonym name = nat datatype ty = IntT | BoolT | ArrowT ty ty (infixr "\" 200) | AllT ty | BVar nat | FVar name datatype const = IntC int | BoolC bool datatype opr = Succ | Prev | IsZero datatype stmt = SLet name expr stmt | SRet expr | SCall name expr expr stmt | SInst name expr ty stmt and expr = Var name | Const const | PrimApp opr expr | Lam name stmt ty | TyAbs name stmt ty datatype val = VConst const | Boxed const name | Closure nat stmt "(name \ val) list" "(name \ ty) list" ty ty | TAbs name stmt "(name \ val) list" "(name \ ty) list" ty ty section "Operational Semantics" type_synonym env = "(name \ val) list" type_synonym tymap = "(name \ ty) list" type_synonym stack = "(name \ ty \ ty \ stmt \ env \ tymap) list" type_synonym state = "stmt \ env \ tymap \ stack" fun lookup :: "'a \ ('a \ 'b) list \ 'b option" where "lookup x [] = None" | "lookup x ((y,v)#bs) = (if x = y then Some v else lookup x bs)" fun delta :: "opr \ val \ val option" where "delta Succ (VConst (IntC n)) = Some (VConst (IntC (n + 1)))" | "delta Prev (VConst (IntC n)) = Some (VConst (IntC (n - 1)))" | "delta IsZero (VConst (IntC n)) = Some (VConst (BoolC (n = 0)))" | "delta f v = None" fun cast :: "val \ ty \ ty \ val" where castcf:"cast (VConst c) A (FVar \) = Boxed c \" | castc: "cast (VConst c) A B = VConst c" | castbf: "cast (Boxed c \) A (FVar \) = Boxed c \" | castb: "cast (Boxed c \) A B = VConst c" | castf: "cast (Closure x s \ \ A B) B' C = (Closure x s \ \ A C)" | casta: "cast (TAbs \ s \ \ A B) B' C = (TAbs \ s \ \ A C)" fun eval :: "expr \ env \ tymap \ val option" where evalv: "eval (Var x) \ \ = lookup x \" | evalc: "eval (Const c) \ \ = return (VConst c)" | evalp: "eval (PrimApp f e) \ \ = (v := eval e \ \; delta f v)" | evall: "eval (Lam x s A) \ \ = return (Closure x s \ \ A A)" | evalt: "eval (TyAbs x s A) \ \ = return (TAbs x s \ \ A A)" primrec shift :: "nat \ ty \ ty" where "shift c IntT = IntT" | "shift c BoolT = BoolT" | "shift c (ArrowT T1 T2) = ArrowT (shift c T1) (shift c T2)" | "shift c (AllT T1) = AllT (shift (Suc c) T1)" | "shift c (BVar k) = (if k < c then BVar k else BVar (Suc k))" | "shift c (FVar x) = FVar x" primrec bsub :: "nat \ ty \ ty \ ty" where "bsub j S IntT = IntT" | "bsub j S BoolT = BoolT" | "bsub j S (ArrowT T1 T2) = ArrowT (bsub j S T1) (bsub j S T2)" | "bsub j S (AllT T1) = AllT (bsub (Suc j) (shift 0 S) T1)" | "bsub j S (BVar k) = (if k = j then S else BVar k)" | "bsub j S (FVar x) = FVar x" abbreviation ty_bsub :: "ty \ ty \ ty" ("[_]_" [65,65] 64) where "[T1]T2 \ bsub 0 T1 T2" text{* parallel type subsitution *} primrec psub :: "tymap \ ty \ ty" where "psub \ IntT = IntT" | "psub \ BoolT = BoolT" | "psub \ (ArrowT T1 T2) = ArrowT (psub \ T1) (psub \ T2)" | "psub \ (AllT T) = AllT (psub \ T)" | "psub \ (BVar k) = BVar k" | "psub \ (FVar x) = (case lookup x \ of None \ FVar x | Some T \ T)" fun step :: "state \ state option" where "step (SLet x e s, \, \, k) = (v := eval e \ \; return (s, (x,v)#\, \, k))" | "step (SRet e, \, \, (x, S, T, s, \', \')#k) = (v := eval e \ \; return (s, (x,cast v S T)#\', \', k))" | "step (SCall x e1 e2 s, \, \, k) = (v1 := eval e1 \ \; v2 := eval e2 \ \; case v1 of Closure y s' \' \' (S1\S2) (T1\T2) \ return (s', (y,cast v2 T1 S1)#\', \', (x, S2, T2, s, \, \)#k) | _ \ error)" | "step (SInst x e1 T s, \, \, k) = (v1 := eval e1 \ \; case v1 of TAbs y s' \' \' (AllT S) (AllT T') \ return (s', \', (y,psub \ T)#\', (x, [FVar y]S, [T]T', s, \, \)#k) | _ \ error)" | "step s = None" datatype result = Fun | Poly | Con const | Error | TimeOut primrec observe :: "val \ result" where "observe (VConst c) = Con c" | "observe (Closure x s \ \ S T) = Fun" | "observe (TAbs x s \ \ S T) = Poly" definition final :: "state \ bool" where "final s \ (case s of (SRet e, \, \, []) \ True | _ \ False)" declare final_def[simp] fun steps :: "nat \ state \ result" where "steps 0 s = TimeOut" | "steps (Suc n) (SRet e, \, \, []) = (case eval e \ \ of None \ Error | Some v \ observe v)" | "steps (Suc n) s = (case step s of None \ Error | Some s' \ steps n s')" definition run :: "stmt \ result" where "run s \ steps 1000000 (s,[],[],[])" section "Type System" primrec close :: "name \ nat \ ty \ ty" where "close x k IntT = IntT" | "close x k BoolT = BoolT" | "close x k (ArrowT T1 T2) = ArrowT (close x k T1) (close x k T2)" | "close x k (AllT T1) = AllT (close x (Suc k) T1)" | "close x k (BVar j) = BVar j" | "close x k (FVar y) = (if x = y then BVar k else FVar y)" datatype bind = EVar ty | TVar type_synonym ty_env = "(name \ bind) list" primrec typeof :: "const \ ty" where "typeof (IntC n) = IntT" | "typeof (BoolC b) = BoolT" primrec typeof_opr :: "opr \ ty" where "typeof_opr Succ = (IntT \ IntT)" | "typeof_opr Prev = (IntT \ IntT)" | "typeof_opr IsZero = (IntT \ BoolT)" inductive wf_ty :: "ty_env \ nat \ ty \ bool" ("_;_ \ _ wf" [60,60,60] 59) where wfint[intro!]: "\;n \ IntT wf" | wfbool[intro!]: "\;n \ BoolT wf" | wffun[intro!]: "\ \;n \ T1 wf; \;n \ T2 wf \ \ \;n \ (T1 \ T2) wf" | wfall[intro!]: "\;Suc n \ T wf \ \;n \ (AllT T) wf" | wfbvar[intro!]: "k < n \ \;n \ (BVar k) wf" | wffvar1[intro!]: "lookup x \ = Some TVar \ \;n \ (FVar x) wf" abbreviation wfty :: "ty_env \ ty \ bool" ("_ \ _" [60,60] 59) where "\ \ T \ \;0 \ T wf" definition dom :: "('a \ 'b) list \ 'a set" where "dom f \ set (map fst f)" declare dom_def[simp] inductive wf_env :: "ty_env \ bool" where wf_nil[intro!]: "wf_env []" | wf_cons1[intro!]: "\ x \ dom \; \ \ T; wf_env \ \ \ wf_env ((x,EVar T)#\)" | wf_cons2[intro!]: "\ x \ dom \; wf_env \ \ \ wf_env ((x,TVar)#\)" inductive wt_expr :: "ty_env \ expr \ ty \ bool" ("_ \\<^isub>e _ : _" [60,60,60] 59) and wt_stmt :: "ty_env \ stmt \ ty \ bool" ("_ \\<^isub>s _ : _" [60,60,60] 59) where wtvar[intro!]: "lookup x \ = Some (EVar A) \ \ \\<^isub>e Var x : A" | wtconst[intro!]: "\ \\<^isub>e Const c : typeof c" | wtpapp[intro!]: "\ typeof_opr f = A \ B; \ \\<^isub>e e : A \ \ \ \\<^isub>e PrimApp f e : B" | wtlam[intro!]: "\ (x,EVar A)#\ \\<^isub>s s : B; x \ dom \; \ \ A \ \ \ \\<^isub>e Lam x s (A\B) : (A \ B)" | wtpoly[intro!]: "\ (\,TVar)#\ \\<^isub>s s : A; \ \ dom \ \ \ \ \\<^isub>e TyAbs \ s (AllT (close \ 0 A)) : AllT (close \ 0 A)" | wtlet[intro!]: "\ \ \\<^isub>e e : A; x \ dom \; (x,EVar A)#\ \\<^isub>s s : B \ \ \ \\<^isub>s SLet x e s : B" | wtret[intro!]: "\ \ \\<^isub>e e : A \ \ \ \\<^isub>s SRet e : A" | wtcall[intro!]: "\ \ \\<^isub>e e1 : A \ B; \ \\<^isub>e e2 : A; x \ dom \; (x, EVar B)#\ \\<^isub>s s : C \ \ \ \\<^isub>s SCall x e1 e2 s : C" | wtinst[intro!]: "\ \ \\<^isub>e e : AllT A; \ \ B; x \ dom \; (x,EVar ([B]A))#\ \\<^isub>s s : C\ \ \ \\<^isub>s SInst x e B s : C" inductive wt_val :: "tymap \ val \ ty \ bool" ("_ \\<^isub>v _ : _" [60,60,60] 59) and wt_env :: "ty_env \ tymap \ env \ bool" ("_;_ \ _" [60,60,60] 59) where wt_vc[intro!]: "typeof c = A \ \' \\<^isub>v (VConst c) : A" | wt_box[intro!]: "psub \' (FVar \) = (typeof c) \ \' \\<^isub>v (Boxed c \) : (FVar \)" | wt_cl[intro!]: "\ wf_env \; \;\ \ (\::env); x \ dom \; \ \ A\<^isub>1; psub \ (A\<^isub>1\A\<^isub>2) = psub \' B; (x,EVar A\<^isub>1)#\ \\<^isub>s s : A\<^isub>2 \ \ \' \\<^isub>v (Closure x s \ \ (A\<^isub>1\A\<^isub>2) B) : B" | wt_tabs[intro!]: "\ wf_env \; \;\ \ \; \ \ dom \; psub \ (AllT (close \ 0 A)) = psub \' B; (\,TVar)#\ \\<^isub>s s : A \ \ \' \\<^isub>v (TAbs \ s \ \ (AllT (close \ 0 A)) B) : B" | wt_nil[intro!]: "[];[] \ []" | wt_cons[intro!]: "\ x \ dom \; \ \\<^isub>v v : A; \ \ A; \;\ \ (\::env) \ \ ((x,EVar A)#\);\ \ ((x,v)#\)" | wt_cons2[intro!]: "\ \ \ dom \; [] \ T; \;\ \ (\::env) \ \ ((\,TVar)#\);((\,T)#\) \ \" inductive wt_stack :: "tymap \ stack \ ty \ ty \ bool" ("_ \ _ : _ \ _") where nil_stack[intro!]: "\ \ [] : A \ A" | cons_stack[intro!]: "\ wf_env \; \; \ \ \; psub \' A = psub \ B; (x,EVar B)#\ \\<^isub>s s : C; \ \ B; x \ dom \; \ \ k : C \ D \ \ \' \ (x, A, B, s, \, \)#k : A \ D" inductive wt_state :: "state \ ty \ bool" where wts[intro!]: "\ wf_env \; \;\ \ \; \ \\<^isub>s s : A; \ \ k : A \ B \ \ wt_state (s, \, \, k) B" fun wt_result :: "result \ ty \ bool" where "wt_result Fun (A \ B) = True" | "wt_result Poly (AllT A) = True" | "wt_result (Con c) A = (typeof c = A)" | "wt_result Error A = False" section "Type Safety" inductive_cases bool_int[elim!]: "\ \\<^isub>v (VConst (BoolC b)) : IntT" and int_any[elim!]: "\ \\<^isub>v (VConst (IntC n)) : A" and intval_inv[elim!]: "\ \\<^isub>v v : IntT" and boolval_inv[elim!]: "\ \\<^isub>v v : BoolT" and bvarval_inv[elim!]: "\ \\<^isub>v v : (BVar k)" and fvarval_inv[elim!]: "\ \\<^isub>v v : (FVar x)" and const_any[elim!]: "\ \\<^isub>v (VConst c) : A" and bool_any[elim!]: "\ \\<^isub>v (VConst (BoolC b)) : A" and clos_any[elim!]: "\ \\<^isub>v (Closure x s \ \' S T) : A" and clos_int[elim!]: "\ \\<^isub>v (Closure x s \ \' S T) : IntT" and clos_bool[elim!]: "\ \\<^isub>v (Closure x s \ \' S T) : BoolT" and tabs_any[elim!]: "\ \\<^isub>v (TAbs x e \ \' S T) : A " and const_fun[elim!]: "\ \\<^isub>v (VConst c) : (A \ B)" and clos_fun[elim!]: "\ \\<^isub>v (Closure x s \ \' S T) : (A \ B)" and funval_inv[elim!]: "\ \\<^isub>v v : (A \ B)" and boxed_inv[elim!]: "\ \\<^isub>v Boxed c n : T" subsection "Lemmas Regarding Lookup" (* lemma lookup_dom_iff: shows "(\ v. lookup x F = Some v) = (x \ dom F)" apply (induct F) apply simp apply force done *) lemma lookup_dom: assumes l: "lookup x F = Some v" shows "x \ dom F" using l apply (induct F) apply simp apply force done (* lemma dom_lookup: assumes x: "x \ dom F" shows "\ v. lookup x F = Some v" using x apply (induct F) apply simp apply (case_tac a) apply (case_tac "x = aa") apply simp apply simp done *) lemma not_dom_lookup: assumes x: "x \ dom F" shows "lookup x F = None" using x apply (induct F) apply simp apply force done (* lemma lookup_none_dom: assumes x: "lookup x F = None" shows "x \ dom F" using x apply (induct F arbitrary: x) apply simp apply simp apply (case_tac a) apply simp apply (case_tac "x = aa") apply auto done *) subsection "Lemmas Regarding Well-Formed Types" lemma wf_ty_weaken_cons: fixes T::ty assumes wft: "\; n \ T wf" and xg: "x \ dom \" shows "(x,b)#\;n \ T wf" using wft xg apply (induct T) apply force apply force apply force apply force apply force apply clarify using lookup_dom apply force done lemma wf_ty_weaken_ty: fixes T::ty assumes wft: "\; n \ T wf" and g: "\ = []" shows "\';n \ T wf" using wft g apply (induct T) apply auto done lemma wf_ty_weaken_n: fixes T::ty assumes wft: "\; n \ T wf" and nm: "n \ m" shows "\;m \ T wf" using wft nm apply (induct T arbitrary: m) apply auto done lemma wf_ty_weaken: fixes T::ty assumes wft: "[] \ T" shows "\;n \ T wf" using wft wf_ty_weaken_n wf_ty_weaken_ty apply fast done lemma wf_env_strengthen: fixes B::ty assumes wfe: "\'; n \ B wf" and g: "\' = (x,EVar A)#\" shows "\;n \ B wf" using wfe g apply (induct arbitrary: x A rule: wf_ty.induct) apply force apply force apply force apply force apply force apply simp apply (case_tac "x = xa") apply auto done lemma close_wf: fixes S::ty assumes wts: "\';n \ S wf" and kn: "k < n" and g: "\'=(x,TVar)#\" shows "\;n \ (close x k S) wf" using wts kn g apply (induct arbitrary: k rule: wf_ty.induct) apply auto done inductive_cases wf_fun_inv[elim!]: "\; n \ (A \ B) wf" and wf_all_inv[elim!]: "\; n \ (AllT A) wf" and wf_bvar_inv[elim!]: "\; n \ (BVar k) wf" and wf_fvar_inv[elim!]: "\; n \ (FVar x) wf" lemma wf_shift: fixes n::nat assumes wf: "\;n \ T wf" shows "\; Suc n \ (shift c T) wf" using wf apply (induct arbitrary: c rule: wf_ty.induct) apply auto done lemma wf_bsub: fixes \::ty_env and A::ty and n::nat assumes 1:"\;m \ A wf" and 2: "\;n \ T wf" and 3: "m = Suc n" shows "\;n \ (bsub n T A) wf" using 1 2 3 apply (induct arbitrary: n T rule: wf_ty.induct) apply auto apply (frule_tac n=na and c=0 in wf_shift) apply simp done lemma bsub_close_id: fixes n::nat and T::ty assumes wft: "\;n \ T wf" shows "bsub n (FVar x) (close x n T) = T" using wft apply (induct rule: wf_ty.induct) by auto subsection "Lemmas Regarding Well-Formed Environments" inductive_cases wf_env_inv[elim!]: "wf_env ((a,b)#\)" lemma lookup_wf[rule_format]: assumes wf: "wf_env \" shows "\ x T. lookup x \ = Some (EVar T) \ \ \ T" using wf apply (induct rule: wf_env.induct) apply simp apply clarsimp apply (case_tac "xa = x") apply simp using wf_ty_weaken_cons apply force apply clarsimp apply (erule_tac x=xa in allE) apply (erule_tac x=Ta in allE) apply simp using wf_ty_weaken_cons apply force apply clarsimp apply (case_tac "xa = x") apply simp using wf_ty_weaken_cons apply force done lemma wte_wts_wft: "(\ \\<^isub>e e : T \ wf_env \ \ \ \ T) \ (\ \\<^isub>s s : T \ wf_env \ \ \ \ T)" apply (induct rule: wt_expr_wt_stmt.induct) using lookup_wf apply blast apply (case_tac c) apply force apply force apply (case_tac f) apply force apply force apply force apply clarsimp apply (erule impE) apply force apply (rule_tac \=\ and B=B and n=0 in wf_env_strengthen) apply blast apply blast apply clarsimp apply (erule impE) apply force using close_wf wf_ty_weaken_n apply fast apply clarsimp apply (erule impE) apply force using wf_env_strengthen apply fast apply force apply clarsimp apply (erule impE) apply (rule wf_cons1) apply simp apply blast apply simp using wf_env_strengthen apply fast apply clarsimp apply (erule impE) apply (rule wf_cons1) apply simp using wf_bsub apply force apply simp using wf_env_strengthen apply fast done subsection "Lemmas Regarding Well-Typed Values and Environments" lemma lookup_wft_aux: "(\ \\<^isub>v v : T \ True) \ (\;\ \ \ \ (\ x T. lookup x \ = Some T \ [] \ T))" apply (induct rule: wt_val_wt_env.induct) apply auto done lemma wtenv_lookup_wft: "\ \;\ \ \; lookup x \ = Some T \ \ [] \ T" using lookup_wft_aux apply auto done lemma wtenv_lookup_iff_aux: "(\ \\<^isub>v v : T \ True) \ (\;\ \ \ \ (\ x. (lookup x \ = Some TVar) = (\ T. lookup x \ = Some T)))" apply (induct rule: wt_val_wt_env.induct) apply force apply force apply force apply force apply simp apply clarify apply (erule_tac x=xa in allE) apply simp apply (case_tac "xa=x") apply simp using not_dom_lookup apply force apply simp apply clarify apply simp done lemma wtenv_lookup_iff: "\;\ \ \ \ (lookup x \ = Some TVar) = (\ T. lookup x \ = Some T)" using wtenv_lookup_iff_aux apply auto done lemma wft_swap_env: fixes \::env assumes 1: "\; \ \ \" and 2: "\'; \ \ \" and 3: "\ \ T" shows "\' \ T" using 3 2 1 apply (induct arbitrary: \' \ rule: wf_ty.induct) using wtenv_lookup_iff apply auto done lemma wt_cast: assumes wtv: "\ \\<^isub>v v : S" and st: "psub \ S = psub \' T" and wft: "\ \ T" shows "\' \\<^isub>v (cast v S T) : T" using st wtv wft apply (cases v) (* v= VConst const *) apply simp apply (case_tac T) apply clarsimp apply (case_tac const) apply simp apply simp apply clarsimp apply (case_tac const) apply simp apply simp apply clarsimp apply (case_tac const) apply simp apply simp apply clarsimp apply (case_tac const) apply simp apply simp apply clarsimp apply simp apply (rule wt_box) apply (case_tac "lookup nat \'") apply simp apply clarify apply (case_tac const) apply simp apply simp apply simp apply clarify apply (case_tac const) apply simp apply simp (* v = Boxed const nat *) apply simp apply (case_tac T) apply clarsimp apply clarsimp apply clarsimp apply (case_tac "lookup nat \") apply clarsimp apply clarsimp apply (case_tac const) apply simp apply simp apply clarsimp apply (case_tac "lookup nat \") apply clarsimp apply clarsimp apply (case_tac const) apply simp apply simp apply clarsimp apply clarsimp (* v = Closure ... *) apply simp apply (erule clos_any) apply clarsimp apply (rule wt_cl) apply simp apply simp apply simp apply simp using wte_wts_wft apply force apply simp (* v = TAbs ... *) apply simp apply (erule tabs_any) apply clarsimp apply (rule wt_tabs) apply auto done lemma psub_cons_weaken: fixes \::env assumes wft: "\ \ T" and gs: "\; \ \ \" and xg: "x \ dom \" shows "psub \ T = psub ((x,T')#\) T" using wft gs xg apply (induct rule: wf_ty.induct) apply force apply force apply force apply force apply force apply simp apply (case_tac "xa = x") apply simp apply (case_tac "lookup x \") using wtenv_lookup_iff apply force using not_dom_lookup apply force apply auto done lemma weaken_env_val: "(\ \\<^isub>v v : T' \ (\ T \ \ x. [] \ T \ \ \ T' \ \; \ \ \ \ x \ dom \ \ (x,T)#\ \\<^isub>v v : T')) \ (\;\ \ \ \ (\ T x. [] \ T \ x \ dom \ \ (x, TVar) # \;(x, T) # \ \ \))" (is "(\ \\<^isub>v v : T' \ ?P \ v T') \ (\;\ \ \ \ ?Q \ \ \)") proof (induct rule: wt_val_wt_env.induct) fix c A \' assume "typeof c = A" thus "?P \' (VConst c) A" apply force done next fix \' x' c assume "psub \' (FVar x') = typeof c" thus "?P \' (Boxed c x') (FVar x')" apply auto apply (case_tac "lookup x' \'") apply auto apply (case_tac c) apply auto using not_dom_lookup apply force done next fix \ and \::tymap and \::env and x A1 A2 \' B s assume wfg: "wf_env \" and wfE: "\;\ \ \" and IH: "?Q \ \ \" and xpg: "x \ dom \" and wfs1: "\ \ A1" and ps12: "psub \ (A1 \ A2) = psub \' B" and wts: "(x,EVar A1)#\ \\<^isub>s s : A2" show "?P \' (Closure x s \ \ (A1 \ A2) B) B" apply (rule allI)+ apply (rule impI)+ apply (rule wt_cl) prefer 6 using wts apply assumption using wfg apply assumption using wfE apply simp using xpg apply simp using wfs1 apply simp proof - fix T' \' and \'::env and x'' assume wftp: "[] \ T'" and gpt: "\' \ B" and gps: "\' ; \' \ \'" and xgp: "x'' \ dom \'" from gpt gps xgp have "psub \' B = psub ((x'', T') # \') B" apply (rule psub_cons_weaken) done thus "psub \ (A1 \ A2) = psub ((x'', T') # \') B" using ps12 apply simp done qed next fix \ and \::tymap and \::env and xa S \' T s assume wfg: "wf_env \" and wtr: "\;\ \ \" and IH: "?Q \ \ \" and xag: "xa \ dom \" and psx: "psub \ (AllT (close xa 0 S)) = psub \' T" and wts: "(xa, TVar) # \ \\<^isub>s s : S" show "?P \' (TAbs xa s \ \ (AllT (close xa 0 S)) T) T" apply (rule allI)+ apply (rule impI)+ apply (rule wt_tabs) prefer 5 using wts apply assumption using wfg apply assumption prefer 2 using xag apply assumption using wtr apply assumption proof - fix Ta \' and \'::env and x' assume wfta: "[] \ Ta" and wft: "\' \ T" and gsp: "\';\' \ \'" and xgp: "x' \ dom \'" from wft gsp xgp have "psub \' T = psub ((x', Ta) # \') T" apply (rule psub_cons_weaken) done with psx show " psub \ (AllT (close xa 0 S)) = psub ((x', Ta) # \') T" by simp qed next fix \ show "?Q [] [] []" apply auto done next fix x \ \ v A and E::env assume xg: "x \ dom \" and wtv: "\ \\<^isub>v v : A" and IH1: "?P \ v A" and wfa: "\ \ A" and wtE: "\;\ \ E" and IH2: "?Q \ \ E" show "?Q ((x,EVar A)#\) \ ((x,v)#E)" apply (rule allI)+ apply (rule impI)+ apply (rule wt_cons2) apply simp apply simp apply (rule wt_cons) using xg apply assumption using wtv apply simp using wfa apply assumption using wtE apply assumption done next fix x \ T \ and E::env assume xg: "x \ dom \" and wft: "[] \ T" and wtE: "\;\ \ E" and IH: "?Q \ \ E" show "?Q ((x,TVar)#\) ((x,T)#\) E" apply (rule allI)+ apply (rule impI)+ apply (rule wt_cons2) apply simp using wft apply simp using IH apply simp apply (erule_tac x=T in allE) apply (erule impE) using wft apply assumption apply (erule_tac x=x in allE) apply (erule impE) using xg apply simp apply simp done qed lemma weaken_wtval: "\ \ \\<^isub>v v : T'; [] \ T; \ \ T'; \; \ \ \; x \ dom \ \ \ (x,T)#\ \\<^isub>v v : T'" using weaken_env_val apply simp apply blast done lemma weaken_wtenv: fixes \::env assumes wtr: "\;\ \ \" and wft: "[] \ T" and xg: "x \ dom \" shows "(x, TVar) # \;(x, T) # \ \ \" using weaken_env_val wtr wft xg apply simp done lemma lookup_safe: fixes \::env assumes wtg: "\;\ \ \" and wfg: "wf_env \" and l: "lookup x \ = Some (EVar A)" shows "\ v. lookup x \ = Some v \ \ \\<^isub>v v : A \ \ \ A" using wtg wfg l apply (induct \) apply force apply force apply force apply force apply force apply (case_tac "x = xa") apply simp apply (rule wf_ty_weaken_cons) apply simp apply (erule wf_env_inv) apply simp apply blast apply simp apply (erule wf_env_inv) apply simp apply (erule exE) apply simp apply (rule wf_ty_weaken_cons) apply simp apply simp apply simp apply clarsimp apply (case_tac "x = \") apply simp apply simp apply (erule wf_env_inv) apply simp apply simp apply (erule exE) apply simp apply (rule conjI) apply (rule weaken_wtval) apply simp apply simp apply force apply force apply force apply (rule wf_ty_weaken_cons) apply simp apply simp done subsection "Lemmas Regarding the Dynamic Semantics" lemma delta_safe: fixes A::ty assumes wtop: "typeof_opr f = A \ B" and wtv: "\ \\<^isub>v v : A" shows "\ v'. delta f v = Some v' \ \ \\<^isub>v v' : B" using wtop wtv apply (case_tac f) apply (case_tac v) apply auto apply (case_tac const) apply auto apply (case_tac v) apply auto apply (case_tac c) apply auto apply (case_tac c) apply auto apply (case_tac c) apply auto apply (case_tac c) apply auto apply (case_tac c) apply auto done inductive_cases wtv[elim!]: "\ \\<^isub>e Var x : A" and wtc[elim!]: "\ \\<^isub>e Const c : A" and wti[elim!]: "\ \\<^isub>e Const (IntC n) : A" and wtb[elim!]: "\ \\<^isub>e Const (BoolC b) : A" and wtp[elim!]: "\ \\<^isub>e PrimApp f e : A" and wtlam_inv[elim!]: "\ \\<^isub>e Lam x s T : A" and wtabs[elim!]: "\ \\<^isub>e TyAbs x s T : A" and wtlet_inv[elim!]: "\ \\<^isub>s SLet x e s : A" and wtret_inv[elim!]: "\ \\<^isub>s SRet e : A" and wtcall_inv[elim!]: "\ \\<^isub>s SCall x e1 e2 s : A" and wtinst_inv[elim!]: "\ \\<^isub>s SInst x e T s : A" lemma eval_safe: fixes \::"ty_env" and \::env assumes wte: "\ \\<^isub>e e : A" and wfg: "wf_env \" and wtg: "\; \ \ \" shows "\ v. eval e \ \ = Some v \ \ \\<^isub>v v : A" using wte wfg wtg proof (induct e \ \ arbitrary: A rule: eval.induct) fix x \ \ A assume wte: "\ \\<^isub>e Var x : A" and wfg: "wf_env \" and wtr: "\;\ \ \" from wte have lx: "lookup x \ = Some (EVar A)" by blast from wtr wfg lx obtain v where lv: "lookup x \ = Some v" and wtv: "\ \\<^isub>v v : A" using lookup_safe apply blast done from lv wtv show "\v. eval (Var x) \ \ = Some v \ \ \\<^isub>v v : A" by simp next fix c \ \ A assume wte: "\ \\<^isub>e Const c : A" and wfg: "wf_env \" and wtr: "\;\ \ \" from wte have "typeof c = A" by blast hence "\ \\<^isub>v VConst c : A" by blast thus "\v. eval (Const c) \ \ = Some v \ \ \\<^isub>v v : A" by simp next fix f e \ \ A assume IH: "\A. \\ \\<^isub>e e : A; wf_env \; \;\ \ \ \ \ \v. eval e \ \ = Some v \ \ \\<^isub>v v : A" and wtp: "\ \\<^isub>e PrimApp f e : A" and wfg: "wf_env \" and wtr: "\;\ \ \" from wtp obtain T where tf: "typeof_opr f = T \ A" and wte: "\ \\<^isub>e e : T" apply blast done from wte wfg wtr IH obtain v where ev: "eval e \ \ = Some v" and wtv: "\ \\<^isub>v v : T" apply blast done from tf wtv obtain v' where d: "delta f v = Some v'" and wtvp: "\ \\<^isub>v v' : A" using delta_safe apply blast done from ev d wtvp show "\v. eval (PrimApp f e) \ \ = Some v \ \ \\<^isub>v v : A" by simp next fix x s T \ \ A assume wtl: "\ \\<^isub>e Lam x s T : A" and wfg: "wf_env \" and wtr: "\;\ \ \" let ?V = "Closure x s \ \ T T" from wtl obtain T1 T2 where a: "A=T1\T2" and wts: "(x,EVar T1)#\ \\<^isub>s s : T2" and xg: "x \ dom \" and wft1: "\ \ T1" and t: "T=T1\T2" apply auto done from wfg wft1 xg have wtg2: "wf_env ((x,EVar T1)#\)" by auto from wts wtg2 have "((x,EVar T1)#\) \ T2" using wte_wts_wft by auto hence wft2: "\ \ T2" using wf_env_strengthen apply auto done from wfg wtr xg wts t a wft1 wft2 have "\ \\<^isub>v ?V : A" apply simp apply (rule wt_cl) apply auto done thus "\v. eval (Lam x s T) \ \ = Some v \ \ \\<^isub>v v : A" apply simp done next fix x s T \ \ A assume wtp: "\ \\<^isub>e TyAbs x s T : A" and wfg: "wf_env \" and wtr: "\;\ \ \" from wtp obtain S where a: "A = AllT (close x 0 S)" and wts: "(x,TVar)#\ \\<^isub>s s : S" and xg: "x \ dom \" and t: "T = AllT (close x 0 S)" apply (rule wtabs) apply simp done let ?V = "TAbs x s \ \ T T" from wfg xg have wfg2: "wf_env ((x,TVar)#\)" apply auto done from wts wfg2 have "(x,TVar)#\ \ S" using wte_wts_wft apply auto done hence "(x,TVar)#\;Suc 0 \ S wf" using wf_ty_weaken_n apply fast done hence "\;Suc 0 \ (close x 0 S) wf" using close_wf apply fast done hence wfa: "\ \ AllT (close x 0 S)" apply blast done from wfg wtr xg wts a t wfa have "\ \\<^isub>v ?V : A" apply simp apply (rule wt_tabs) apply simp+ done thus "\v. eval (TyAbs x s T) \ \ = Some v \ \ \\<^isub>v v : A" by simp qed inductive_cases wts_inv[elim!]: "wt_state s A" inductive_cases wtk_cons_inv[elim!]: "\ \ (x, T1, T2, s, \, \')#k : A \ C" inductive_cases polyval_inv[elim!]: "\ \\<^isub>v v : AllT T" lemma tymap_psub_wf: fixes n::nat and T::ty and \::env assumes wfpt: "[];n \ (psub \ T) wf" and gs: "\; \ \ \" shows "\;n \ T wf" using wfpt gs apply (induct T arbitrary: n) apply auto apply (case_tac "lookup nat \") apply auto using wtenv_lookup_iff apply auto done lemma psub_tymap_wf: fixes T::ty and \::env assumes wft: "\ \ T" and gs: "\; \ \ \" shows "[] \ psub \ T" using wft gs apply (induct rule: wf_ty.induct) apply force apply force apply force apply force apply force apply simp apply (case_tac "lookup x \") apply simp using wtenv_lookup_iff apply force apply simp apply (frule wtenv_lookup_wft) apply simp apply (rule wf_ty_weaken_n) apply simp apply simp done lemma psub_wf: fixes n::nat and S::ty and \::env and \'::env assumes wfa2: "\;n \ S wf" and gs: "\; \ \ \" and gs2: "\'; \' \ \'" and at: "psub \ S = psub \' T" shows "\';n \ T wf" using wfa2 gs gs2 at apply (induct arbitrary: \ T \' \' rule: wf_ty.induct) apply simp apply (case_tac T) apply simp apply blast apply simp apply simp apply simp apply simp apply simp apply (case_tac "lookup nat \'") apply simp apply simp apply clarify using wtenv_lookup_iff apply simp apply simp apply (case_tac T) apply simp apply blast apply simp apply simp apply simp apply simp apply (case_tac "lookup nat \'") apply simp apply simp apply clarify using wtenv_lookup_iff apply simp apply simp apply (case_tac T) apply simp apply simp apply simp apply force apply simp apply simp apply simp apply (case_tac "lookup nat \'") apply simp apply simp apply clarify using wtenv_lookup_iff apply force apply simp apply (case_tac Ta) apply simp apply simp apply simp apply force apply simp apply simp apply (case_tac "lookup nat \'") apply simp apply simp apply clarify using wtenv_lookup_iff apply force apply simp apply (case_tac T) apply simp apply simp apply simp apply simp apply simp apply blast apply simp apply (case_tac "lookup nat \'") apply simp apply simp apply clarify using wtenv_lookup_iff apply force apply simp apply (case_tac "lookup x \") apply simp using wtenv_lookup_iff apply force apply simp apply (subgoal_tac "[] \ psub \' T") prefer 2 apply (frule wtenv_lookup_wft) apply simp apply clarify apply (rule tymap_psub_wf) apply (rule wf_ty_weaken_n) apply blast apply simp apply simp done lemma shift_id: assumes wft: "\;k \ T wf" and kn: "k \ n" shows "T = shift n T" using wft kn apply (induct T arbitrary: n) apply auto done lemma bsub_id: assumes wft: "\;k \ T wf" and kn: "k \ n" shows "T = bsub n S T" using wft kn apply (induct T arbitrary: n S) apply force apply force apply force apply force apply force apply force done lemma psub_shift: fixes \::env and T::ty assumes wtr: "\;\ \ \" and wft: "\';k \ T wf" shows "psub \ (shift n T) = shift n (psub \ T)" using wtr wft apply (induct T arbitrary: n k) apply simp apply simp apply force apply force apply simp apply simp apply (case_tac "lookup nat \") apply auto apply (frule wtenv_lookup_wft) apply simp apply (rule shift_id) apply blast apply simp done lemma psub_bsub: fixes \::env and n::nat assumes wtr: "\;\ \ \" and wft: "\'; n \ T wf" shows "psub \ (bsub n T B) = bsub n (psub \ T) (psub \ B)" using wtr wft apply (induct B arbitrary: n T) apply simp apply simp apply force prefer 2 apply simp proof - fix B n T assume IH: "\n T. \\;\ \ \; \';n \ T wf\ \ psub \ (bsub n T B) = bsub n (psub \ T) (psub \ B)" and wtr: "\;\ \ \" and wft: "\';n \ T wf" show "psub \ (bsub n T (AllT B)) = bsub n (psub \ T) (psub \ (AllT B))" proof simp from wft have wfst: "\'; Suc n \ (shift 0 T) wf" using wf_shift[of \' n T] apply simp done from wtr wfst IH have "psub \ (bsub (Suc n) (shift 0 T) B) = bsub (Suc n) (psub \ (shift 0 T)) (psub \ B)" apply simp done also from wtr wft have "... = bsub (Suc n) (shift 0 (psub \ T)) (psub \ B)" using psub_shift[of \ \ \ \' n T 0] apply simp done finally show "psub \ (bsub (Suc n) (shift 0 T) B) = bsub (Suc n) (shift 0 (psub \ T)) (psub \ B)" by simp qed next fix k n T assume wtr: "\;\ \ \" and wft: "\';n \ T wf" show "psub \ (bsub n T (FVar k)) = bsub n (psub \ T) (psub \ (FVar k))" apply simp apply (case_tac "lookup k \") apply simp apply simp using wtr apply (frule wtenv_lookup_wft) using wtr bsub_id apply simp done qed lemma close_id: assumes wft: "\;k \ T wf" and xg: "x \ dom \" shows "T = close x n T" using wft xg apply (induct arbitrary: n rule: wf_ty.induct) apply simp apply simp apply simp apply simp apply simp apply simp apply (subgoal_tac "x \ dom \") apply (frule not_dom_lookup) apply auto done lemma psub_close: assumes xg: "x \ dom \" and wtr: "\;\ \ \" shows "psub \ (close x k T) = close x k (psub \ T)" using xg wtr apply (induct T arbitrary: k) apply simp apply simp apply force apply simp apply simp apply simp apply (case_tac "x = nat") apply simp apply (case_tac "lookup nat \") apply simp apply simp apply (subgoal_tac "nat \ dom \") apply (frule not_dom_lookup) apply (frule wtenv_lookup_iff) apply simp apply force apply simp apply simp apply (case_tac "lookup nat \") apply simp apply simp apply (subgoal_tac "x \ dom \") apply (frule not_dom_lookup) apply (frule wtenv_lookup_iff) apply simp apply (rule close_id) apply (rule wtenv_lookup_wft) apply assumption apply simp apply simp apply simp done lemma bsub_close_psub: assumes wft: "\;n \ T wf" and wfs: "[] \ S" shows "bsub n S (close x n T) = psub [(x,S)] T" using wft wfs apply (induct T arbitrary: S) apply simp apply simp apply simp apply simp apply (subgoal_tac "shift 0 S = S") apply simp using shift_id apply force apply simp apply simp done lemma wf_psub: assumes wft: "\;n \ T wf" and wtr: "\';\ \ \" shows "\;n \ psub \ T wf" using wft wtr apply (induct T) apply force apply force apply force apply force apply force apply simp apply (case_tac "lookup x \") apply simp apply clarify apply simp apply (frule wtenv_lookup_wft) apply simp apply (rule wf_ty_weaken_ty) apply (rule wf_ty_weaken_n) apply simp apply simp apply simp done lemma psub_id: assumes wft: "\;n \ T wf" and g: "\ = []" shows "psub \ T = T" using wft g apply (induct T) apply auto done lemma psub_cons: assumes yg: "y \ dom \" and wtr: "\;\ \ \" shows "psub [(y, T)] (psub \ S) = psub ((y, T) # \) S" using yg wtr apply (induct S) apply simp apply simp apply simp apply simp apply simp apply (frule not_dom_lookup) apply (frule_tac x=y in wtenv_lookup_iff) apply simp apply (case_tac "nat = y") apply simp apply simp apply (case_tac "lookup nat \") apply simp apply simp apply (frule wtenv_lookup_wft) apply simp apply (rule psub_id) apply simp apply simp done lemma psub_close_ext: fixes \'::env assumes 1: "psub \' (close y 0 S') = psub \ B" and 2: "(y,TVar)#\' \ S'" and 3: "\;Suc 0 \ B wf" and 4: "y \ dom \'" and gr: "\; \ \ \" and gr2: "\'; \' \ \'" and wft: "\ \ T" shows "psub ((y, psub \ T) # \') S' = psub \ ([T]B)" proof - from 2 gr2 have 5: "(y,TVar)#\' \ psub \' S'" apply (rule wf_psub) done from wft gr have 6: "[] \ psub \ T" apply (rule psub_tymap_wf) done from gr wft have "psub \ ([T]B) = [psub \ T]psub \ B" using psub_bsub[of \ \ \ \ 0 T B] apply simp done also have "... = [psub \ T]psub \' (close y 0 S')" using 1 apply simp done also from 4 gr2 have "... = [psub \ T]close y 0 (psub \' S')" using psub_close apply simp done also from 5 6 have "... = psub [(y,psub \ T)] (psub \' S')" using bsub_close_psub[of "(y,TVar)#\'" 0 "psub \' S'" "psub \ T" y] apply simp done also from 4 gr2 have "... = psub ((y, psub \ T) # \') S'" apply (rule psub_cons) done finally show ?thesis by simp qed lemma step_safe: assumes wtsA: "wt_state s A" shows "final s \ (\ s'. step s = Some s' \ wt_state s' A)" using wtsA proof (rule wts_inv) fix \::ty_env and \ and \::env and st A' k assume st: "s = (st, \, \, k)" and wfg: "wf_env \" and gr: "\;\ \ \" and wtst: "\ \\<^isub>s st : A'" and wt_k: "\ \ k : A' \ A" from wfg wtst have wfap: "\ \ A'" using wte_wts_wft apply auto done show ?thesis proof (cases st) case (SLet x e s2) from wtst SLet obtain B where wte: "\ \\<^isub>e e : B" and xg: "x \ dom \" and wts2: "(x,EVar B)#\ \\<^isub>s s2 : A'" by auto from wte wfg gr obtain v where v: "eval e \ \ = Some v" and wtv: "\ \\<^isub>v v : B" using eval_safe by blast from wte wfg have wfb: "\ \ B" using wte_wts_wft apply auto done from xg wtv wfb gr have gr2: "(x,EVar B)#\; \ \ (x,v)#\" by (rule wt_cons) from v SLet xg st wfg gr2 wts2 wt_k wtv wfb show ?thesis apply clarsimp apply (rule wts) apply auto done next case (SRet e) show ?thesis proof (cases k) assume k: "k = []" from SRet st k have "final s" by simp thus ?thesis by blast next fix f k' assume k: "k = f#k'" from wtst SRet have wte: "\ \\<^isub>e e : A'" by blast from wte wfg gr obtain v where v: "eval e \ \ = Some v" and wtv: "\ \\<^isub>v v : A'" using eval_safe by blast obtain x S T s' \' \' where f: "f = (x,S,T,s',\',\')" apply (case_tac f) apply blast done from wt_k f k have wt_k2: "\ \ (x,S,T,s',\',\')#k' : A' \ A" by simp from wt_k2 show ?thesis proof fix \' C assume wfgp: "wf_env \'" and wtr: "\';\' \ \'" and at: "psub \ A' = psub \' T" and wtsp: "(x,EVar T)#\' \\<^isub>s s' : C" and xg: "x \ fst ` set \'" and wtkp: "\' \ k' : C \ A" and s: "S = A'" from wfap gr wtr at have wft: "\' \ T" by (rule psub_wf) from wft wfgp xg have 1: "wf_env ((x, EVar T) # \')" by auto have 2: "(x, EVar T) # \';\' \ (x, cast v S T) # \'" proof (rule wt_cons) show "\' \\<^isub>v cast v S T : T" apply (rule wt_cast) using wtv s apply simp using at s apply simp using wft apply simp done next from wft show "\' \ T" . next from wtr show "\';\' \ \'" . next from xg show "x \ dom \'" by simp qed from st SRet k f v 1 2 show ?thesis apply simp apply (rule wts) prefer 4 using wtkp apply assumption prefer 3 using wtsp apply assumption apply assumption+ done qed qed next case (SCall x e1 e2 s2) from wtst SCall obtain B::ty and C where wte1: "\ \\<^isub>e e1 : B \ C" and wte2: "\ \\<^isub>e e2 : B" and xg: "x \ dom \" and wts2: "(x,EVar C)#\ \\<^isub>s s2 : A'" by auto from wte1 wfg have wfbc: "\ \ B \ C" using wte_wts_wft apply auto done from wte1 wfg gr obtain v1 where v1: "eval e1 \ \ = Some v1" and wtv1: "\ \\<^isub>v v1 : B \ C" using eval_safe[of \ e1 "B\C" \ \] apply simp apply (erule exE) apply simp done from wte2 wfg gr obtain v2 where v2: "eval e2 \ \ = Some v2" and wtv2: "\ \\<^isub>v v2 : B" using eval_safe by blast from wtv1 show ?thesis proof fix c assume "typeof c = B \ C" thus ?thesis apply (case_tac c) apply auto done next fix \ \' \ x S sa assume "AllT (psub \' (close x 0 S)) = psub \ (B \ C)" thus ?thesis apply simp done next fix \'::ty_env and \' and \'::env and y and A1::ty and A2::ty and s' assume v1cl: "v1 = Closure y s' \' \' (A1 \ A2) (B \ C)" and wfg2: "wf_env \'" and gr2: "\';\' \ \'" and yg: "y \ fst ` set \'" and wfs12: "\' \ A1" and sbc: "psub \' A1 \ psub \' A2 = psub \ (B \ C)" and wtsp: "(y, EVar A1)#\' \\<^isub>s s' : A2" from st SCall v1 v2 v1cl show ?thesis apply simp apply (rule wts) prefer 3 using wtsp apply assumption apply (rule wf_cons1) using yg apply simp using wfs12 apply assumption using wfg2 apply assumption proof - show "\' \ (x, A2, C, s2, \, \) # k : A2 \ A" apply (rule cons_stack) using wfg apply assumption using gr apply assumption using sbc apply force using wts2 apply blast using wfbc apply blast using xg apply simp using wt_k apply simp done next show "(y, EVar A1) # \';\' \ (y, cast v2 B A1) # \'" proof (rule wt_cons) from sbc have bs1: "psub \ B = psub \' A1" by auto from wtv2 bs1 wfs12 show "\' \\<^isub>v cast v2 B A1 : A1" by (rule wt_cast) next from wfs12 show "\' \ A1" . next from gr2 show "\'; \' \ \'" . next from yg show "y \ dom \'" by simp qed qed qed next case (SInst x e T s1) from wtst SInst obtain B::ty where wte1: "\ \\<^isub>e e : AllT B" and wft: "\ \ T" and xg: "x \ dom \" and wts1: "(x,EVar ([T]B))#\ \\<^isub>s s1 : A'" by auto from wte1 wfg gr obtain v1 where ev1: "eval e \ \ = Some v1" and wtv1: "\ \\<^isub>v v1 : AllT B" using eval_safe[of \ e "AllT B" \ \] apply simp apply (erule exE) apply auto done from wtv1 show ?thesis proof (rule polyval_inv) fix c assume "v1 = VConst c" and "typeof c = AllT B" thus ?thesis apply (case_tac c) apply force apply force done next fix \ \' E x S1 S2 sa assume "v1 = Closure x sa E \' (S1 \ S2) (AllT B)" and "psub \' S1 \ psub \' S2 = psub \ (AllT B)" thus ?thesis apply simp done next fix \' \' and \'::env and y S' s' assume v1: "v1 = TAbs y s' \' \' (AllT (close y 0 S')) (AllT B)" and wfgp: "wf_env \'" and gr2: "\'; \' \ \'" and ygp: "y \ fst ` set \'" and allsb: "AllT (psub \' (close y 0 S')) = psub \ (AllT B)" and wtsp: "(y,TVar)#\' \\<^isub>s s' : S'" let ?T = "psub \ T" let ?S = "(y,?T)#\'" and ?G = "(y,TVar)#\'" from wfgp ygp have wfgp2: "wf_env ?G" apply auto done from wft gr have wft2: "[] \ psub \ T" using psub_tymap_wf by blast from st SInst ev1 v1 wtsp show ?thesis apply simp apply (rule wts) prefer 3 apply assumption using wfgp2 apply assumption proof - from gr2 wft2 ygp show "?G; ?S \ \'" using weaken_wtenv apply auto done next from wtsp wfgp2 have wfsp: "?G \ S'" using wte_wts_wft apply simp done from wfsp have csp: "[FVar y]close y 0 S' = S'" using bsub_close_id apply simp done from wte1 wfg have wfb: "\ \ AllT B" using wte_wts_wft apply auto done from allsb wfsp wfb ygp gr gr2 wft have 1: "psub ((y, psub \ T) # \') S' = psub \ ([T]B)" apply simp apply (rule psub_close_ext) apply simp apply simp apply clarify apply simp apply simp apply simp apply simp apply simp done from wfb wft have 2: "\ \ [T]B" using wf_bsub[of \ "Suc 0" B 0 T] apply clarsimp done from csp wts1 wfg show "?S \ (x,[FVar y]close y 0 S', ty_bsub T B, s1, \, \)#k : S' \ A" apply simp apply (rule cons_stack) prefer 4 apply assumption apply assumption using gr apply assumption using allsb apply simp using 1 apply assumption using 2 apply assumption using xg apply assumption using wt_k apply assumption done qed qed qed qed end