theory STLC imports Main begin datatype ty = IntT | BoolT | ArrowT ty ty (infixr "\" 200) datatype const = IntC int | BoolC bool datatype opr = Succ | Prev | IsZero types name = nat datatype stmt = SLet name expr stmt | SRet expr | SCall name expr expr stmt | STailCall expr expr and expr = Var name | Const const | PrimApp opr expr | Lam nat ty stmt datatype val = VConst const | Closure nat ty stmt "(nat \ val) list" 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 "Operational Semantics" types env = "(nat \ val) list" types stack = "(stmt \ env) list" types state = "stmt \ env \ 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 eval :: "expr \ env \ val option" where "eval (Var x) \ = lookup x \" | "eval (Const c) \ = return (VConst c)" | "eval (PrimApp f e) \ = (v := eval e \; delta f v)" | "eval (Lam x T s) \ = return (Closure x T s \)" fun step :: "state \ state option" where "step (SLet x e s, \, k) = (v := eval e \; return (s, (x,v)#\ , k))" | "step (SRet e, \, (SCall x e1 e2 s, \')#k) = (v := eval e \; return (s, (x,v)#\', k))" | "step (SCall x e1 e2 s, \, k) = (v1 := eval e1 \; v2 := eval e2 \; case v1 of Closure y T s' \' \ return (s', (y,v2)#\', (SCall x e1 e2 s,\)#k) | _ \ error)" | "step (STailCall e1 e2, \, k) = (v1 := eval e1 \; v2 := eval e2 \; case v1 of Closure y T s' \' \ return (s', (y,v2)#\', k) | _ \ error)" | "step s = None" datatype result = Fun | Con const | Error | TimeOut primrec observe :: "val \ result" where "observe (VConst c) = Con c" | "observe (Closure x T s \) = Fun" 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,[],[])" types ty_env = "(name \ ty) 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 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 "lookup x \ = Some A \ \ \\<^isub>e Var x : A" | "\ \\<^isub>e Const c : typeof c" | "\ typeof_opr f = A \ B; \ \\<^isub>e e : A \ \ \ \\<^isub>e PrimApp f e : B" | "\ (x,A)#\ \\<^isub>s s : B \ \ \ \\<^isub>e Lam x A s : (A \ B)" | "\ \ \\<^isub>e e : A; (x,A)#\ \\<^isub>s s : B \ \ \ \\<^isub>s SLet x e s : B" | "\ \ \\<^isub>e e : A \ \ \ \\<^isub>s SRet e : A" | "\ \ \\<^isub>e e1 : A \ B; \ \\<^isub>e e2 : A; (x,B)#\ \\<^isub>s s : C \ \ \ \\<^isub>s SCall x e1 e2 s : C" | "\ \ \\<^isub>e e1 : A \ B; \ \\<^isub>e e2 : A \ \ \ \\<^isub>s STailCall e1 e2 : B" thm wt_expr_wt_stmt.induct inductive wt_val :: "val \ ty \ bool" and wt_env :: "ty_env \ env \ bool" ("_ \ _" [60,60] 59) where wt_vc[intro!]: "typeof c = A \ wt_val (VConst c) A" | wt_cl[intro!]: "\ \ \ E; (x,A)#\ \\<^isub>s s : B \ \ wt_val (Closure x A s E) (A \ B)" | wt_nil[intro!]: "[] \ []" | wt_cons[intro!]: "\ wt_val v A; \ \ E \ \ ((x,A)#\) \ ((x,v)#E)" inductive wt_stack :: "stack \ ty \ ty \ bool" ("_ : _ \ _") where nil_stack[intro!]: "[] : A \ A" | cons_stack[intro!]: "\ \ \ \; (x,A)#\ \\<^isub>s s : B; k : B \ C \ \ (SCall x e1 e2 s,\)#k : A \ C" inductive wt_state :: "state \ ty \ bool" where wts[intro!]: "\ \ \ \; \ \\<^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 (Con c) T = (typeof c = T)" | "wt_result Error T = False" lemma delta_safe: assumes wtop: "typeof_opr f = A \ B" and wtv: "wt_val v A" shows "\ v'. delta f v = Some v' \ wt_val v' B" sorry lemma lookup_safe: assumes wtg: "\ \ \" and l: "lookup x \ = Some A" shows "\ v. lookup x \ = Some v \ wt_val v A" sorry lemma eval_safe: assumes wte: "\ \\<^isub>e e : A" and wtg: "\ \ \" shows "\ v. eval e \ = Some v \ wt_val v A" sorry lemma step_safe: assumes wtsA: "wt_state s A" shows "final s \ (\ s'. step s = Some s' \ wt_state s' A)" sorry lemma steps_safe: assumes wtsA: "wt_state s A" shows "steps n s = TimeOut \ (\ r. steps n s = r \ wt_result r A)" using wtsA apply (induct n s rule: steps.induct) theorem type_safety: assumes wts: "[] \\<^isub>s s : A" shows "\ r. run s = r \ (r = TimeOut \ wt_result r A)" proof - from wts have 1: "wt_state (s,[],[]) A" by auto let ?n = "1000000" and ?s = "(s,[],[])" from 1 have 2: "steps ?n ?s = TimeOut \ (\ r. steps ?n ?s = r \ wt_result r A)" by (rule steps_safe) moreover { assume "steps ?n ?s = TimeOut" with 2 have "\ r. run s = r \ (r = TimeOut \ wt_result r A)" by (auto simp: run_def) } moreover { assume 3: "\ r. steps ?n ?s = r \ wt_result r A" from 3 obtain r where 4: "steps ?n ?s = r" and 5: "wt_result r A" by blast from 4 have 6: "run s = r" by (simp add: run_def) from 6 5 have "\ r. run s = r \ (r = TimeOut \ wt_result r A)" by blast } ultimately show ?thesis by blast qed end