theory Lec16 imports Nominal begin atom_decl name nominal_datatype lam = Var "name" | App "lam" "lam" | Lam "\name\lam" ("Lam [_]._") consts subst :: "lam \ name \ lam \ lam" ("_[_::=_]" [100,100] 100) nominal_primrec "(Var x)[y::=s] = (if x=y then s else (Var x))" "(App t\<^isub>1 t\<^isub>2)[y::=s] = App (t\<^isub>1[y::=s]) (t\<^isub>2[y::=s])" "x\(y,s) \ (Lam [x].t)[y::=s] = Lam [x].(t[y::=s])" apply(finite_guess)+ apply(rule TrueI)+ apply(simp add: abs_fresh) apply(fresh_guess)+ done datatype ctx = Hole ("\") | CAppL "ctx" "lam" | CAppR "lam" "ctx" fun filling :: "ctx \ lam \ lam" ("_\_\") where "\\t\ = t" | "(CAppL E t')\t\ = App (E\t\) t'" | "(CAppR t' E)\t\ = App t' (E\t\)" inductive val :: "lam\bool" where v_Lam[intro]: "val (Lam [x].e)" inductive machine :: "lam\ctx list\lam\ctx list\bool" ("<_,_> \ <_,_>") where m1[intro]: " \ e2)#Es>" | m2[intro]: "val v \ e2)#Es> \ )#Es>" | m3[intro]: "val v \ )#Es> \ " inductive "machine_star" :: "lam\ctx list\lam\ctx list\bool" ("<_,_> \* <_,_>") where ms1[intro]: " \* " | ms2[intro]: "\ \ ; \* \ \ \* " lemma ms3[intro,trans]: assumes a: " \* " " \* " shows " \* " using a by (induct) (auto) lemma ms4[intro]: assumes a: " \ " shows " \* " using a by (rule ms2) (rule ms1) inductive eval :: "lam\lam\bool" ("_ \ _") where eval_lam[intro]: "Lam [x].t \ Lam [x].t" | eval_app[intro]: "\t1\ Lam [x].t; t2\ t2'; t[x::=t2']\ t'\ \ App t1 t2 \ t'" lemma eval_app_elim: assumes a: "App t1 t2 \ t'" shows "\x t t2'. t1\ Lam [x].t \ t2\ t2' \ t[x::=t2']\ t'" using a by (cases) (auto simp add: lam.inject) lemma eval_to: assumes a: "t \ t'" shows "val t'" using a by (induct) (auto) lemma eval_val: assumes a: "val t" shows "t \ t" using a by (induct) (auto) theorem assumes a: "t \ t'" shows " \* " using a apply(induct arbitrary: Es) apply(metis eval_to m1 ms1 m2 ms2 m3 ms3 ms4 v_Lam)+ done fun ctx_compose :: "ctx \ ctx \ ctx" ("_ \ _") where "\ \ E' = E'" | "(CAppL E t') \ E' = CAppL (E \ E') t'" | "(CAppR t' E) \ E' = CAppR t' (E \ E')" lemma ctx_compose: shows "(E1 \ E2)\t\ = E1\E2\t\\" by (induct E1 rule: ctx.induct) (auto) fun ctx_composes :: "ctx list \ ctx" ("_\") where "[]\ = \" | "(E#Es)\ = (Es\) \ E" inductive cbv :: "lam\lam\bool" ("_ \cbv _") where cbv1[intro]: "val v \ App (Lam [x].t) v \cbv t[x::=v]" | cbv2[intro]: "t \cbv t' \ App t t2 \cbv App t' t2" | cbv3[intro]: "t \cbv t' \ App t2 t \cbv App t2 t'" inductive "cbv_star" :: "lam\lam\bool" (" _ \cbv* _") where cbvs1[intro]: "e \cbv* e" | cbvs2[intro]: "e \cbv e' \ e \cbv* e'" | cbvs3[intro,trans]: "\e1\cbv* e2; e2 \cbv* e3\ \ e1 \cbv* e3" lemma cbv_in_ctx: assumes a: "t \cbv t'" shows "E\t\ \cbv E\t'\" using a by (induct E) (auto) lemma machine_implies_cbv_star: assumes a: " \ " shows "(Es\)\e\ \cbv* (Es'\)\e'\" using a by (induct) (auto simp add: ctx_compose intro: cbv_in_ctx) lemma cbv_eval: assumes a: "t1 \cbv t2" "t2 \ t3" shows "t1 \ t3" using a by (induct arbitrary: t3) (auto dest!: eval_app_elim intro: eval_val) lemma cbv_star_eval: assumes a: "t1 \cbv* t2" "t2 \ t3" shows "t1 \ t3" using a by (induct) (auto simp add: cbv_eval) lemma machine_implies_eval: assumes a: " \ " and b: "(Es'\)\t2\ \ t3" shows "(Es\)\t1\ \ t3" proof - from a have "(Es\)\t1\ \cbv* (Es'\)\t2\" by (rule machine_implies_cbv_star) moreover have "(Es'\)\t2\ \ t3" by fact ultimately show "(Es\)\t1\ \ t3" by (rule cbv_star_eval) qed lemma machine_star_implies_eval: assumes a: " \* " "val t2" shows "(Es\)\t1\ \ t2" using a by (induct t1 Es t2 Es'\"[]::ctx list") (auto simp add: eval_val machine_implies_eval) theorem assumes a: " \* " "val t2" shows "t1 \ t2" using a by (auto dest: machine_star_implies_eval) end