theory Lec16 imports Nominal begin atom_decl name nominal_datatype lam = Var "name" | App "lam" "lam" | Lam "\name\lam" ("Lam [_]._") | I "nat" | D "lam" "lam" ("_ -- _") | P "lam" "lam" ("_ ++ _") | TR | FA | IF "lam" "lam" "lam" | Fix "\name\lam" ("Fix [_]._") | ZE "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])" "(I n)[y::=s] = I n" "(t\<^isub>1 -- t\<^isub>2)[y::=s] = (t\<^isub>1[y::=s]) -- (t\<^isub>2[y::=s])" "(t\<^isub>1 ++ t\<^isub>2)[y::=s] = (t\<^isub>1[y::=s]) ++ (t\<^isub>2[y::=s])" "x\(y,s) \ (Fix [x].t)[y::=s] = Fix [x].(t[y::=s])" "TR[y::=s] = TR" "FA[y::=s] = FA" "(IF t1 t2 t3)[y::=s] = IF (t1[y::=s]) (t2[y::=s]) (t3[y::=s])" "(ZE t)[y::=s] = ZE (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" | CDiffL "ctx" "lam" | CDiffR "lam" "ctx" | CPlusL "ctx" "lam" | CPlusR "lam" "ctx" | CIf "ctx" "lam" "lam" | CZe "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\)" | "(CDiffL E t')\t\ = (E\t\) -- t'" | "(CDiffR t' E)\t\ = t' -- (E\t\)" | "(CPlusL E t')\t\ = P (E\t\) t'" | "(CPlusR t' E)\t\ = P t' (E\t\)" | "(CIf E t1 t2)\t\ = IF (E\t\) t1 t2" | "(CZe E)\t\ = ZE (E\t\)" inductive val :: "lam\bool" where v_Lam[intro]: "val (Lam [x].e)" | v_Int[intro]: "val (I n)" | v_false[intro]: "val FA" | v_true[intro]: "val TR" 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> \ " | m4[intro]: " \ e2)#Es>" | m5[intro]: " e2)#Es> \ )#Es>" | m6[intro]: ")#Es> \ " | m4'[intro]:" \ e2)#Es>" | m5'[intro]:" e2)#Es> \ )#Es>" | m6'[intro]:")#Es> \ " | m7[intro]: " \ e2 e3)#Es>" | m8[intro]: " e1 e2)#Es> \ " | m9[intro]: " e1 e2)#Es> \ " | mA[intro]: " \ " | mB[intro]: " \ )#Es>" | mC[intro]: ")#Es> \ " | mD[intro]: "0 < n \ )#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_int[intro]: "I n \ I n" | eval_diff[intro]: "\t1 \ (I n1); t2 \ (I n2)\ \ t1 -- t2 \ I (n1 - n2)" | eval_plus[intro]: "\t1 \ (I n1); t2 \ (I n2)\ \ t1 ++ t2 \ I (n1 + n2)" | 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'" | eval_fix[intro]: "t[x::= Fix [x].t] \ t' \ Fix [x].t \ t'" | eval_if1[intro]: "\t1 \ TR; t2 \ t'\ \ IF t1 t2 t3 \ t'" | eval_if2[intro]: "\t1 \ FA; t3 \ t'\ \ IF t1 t2 t3 \ t'" | eval_true[intro]: "TR \ TR" | eval_false[intro]:"FA \ FA" | eval_ze1[intro]: "t \ I 0 \ ZE t \ TR" | eval_ze2[intro]: "\t \ I n; 0 < n\ \ ZE t \ FA" 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_if_elim: assumes a: "IF t1 t2 t3 \ t'" shows "(t1 \ TR \ t2 \ t') \ (t1 \ FA \ t3 \ t')" using a apply(cases) apply(auto simp add: lam.inject) done lemma eval_ze_elim: assumes a: "ZE t \ t'" shows "(t \ I 0 \ t' = TR) \ (\n. t \ I n \ 0 < n \ t' = FA)" using a apply(cases) apply(auto simp add: lam.inject) done lemma eval_plus_elim: assumes a: "P t1 t2 \ t'" shows "\n1 n2. t1\ (I n1) \ t2\ (I n2) \ t' = I (n1 + n2)" using a by (cases) (auto simp add: lam.inject) lemma eval_diff_elim: assumes a: "t1 -- t2 \ t'" shows "\n1 n2. t1\ (I n1) \ t2\ (I n2) \ t' = I (n1 - n2)" using a by (cases) (auto simp add: lam.inject) lemma eval_int_elim: assumes a: "(I n) \ t" shows "t = I n" using a by (cases) (auto simp add: lam.inject) lemma eval_TR_elim: assumes a: "TR \ t" shows "t = TR" using a by (cases) (auto) lemma eval_FA_elim: assumes a: "FA \ t" shows "t = FA" using a by (cases) (auto) 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 m4 m5 m6 m4' m5' m6' m7 m8 m9 mA mB mC mD 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')" | "(CDiffL E t') \ E' = CDiffL (E \ E') t'" | "(CDiffR t' E) \ E' = CDiffR t' (E \ E')" | "(CPlusL E t') \ E' = CPlusL (E \ E') t'" | "(CPlusR t' E) \ E' = CPlusR t' (E \ E')" | "(CIf E t1 t2) \ E' = CIf (E \ E') t1 t2" | "(CZe E) \ E' = CZe (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'" | cbv4[intro]: "t \cbv t' \ t -- t2 \cbv t' -- t2" | cbv5[intro]: "t \cbv t' \ t2 -- t \cbv t2 -- t'" | cbv6[intro]: "(I n1) -- (I n2) \cbv I (n1 - n2)" | cbv4'[intro]: "t \cbv t' \ t ++ t2 \cbv t' ++ t2" | cbv5'[intro]: "t \cbv t' \ t2 ++ t \cbv t2 ++ t'" | cbv6'[intro]:"(I n1) ++ (I n2) \cbv I (n1 + n2)" | cbv7[intro]: "t \cbv t' \ IF t t1 t2 \cbv IF t' t1 t2" | cbv8[intro]: "IF TR t1 t2 \cbv t1" | cbv9[intro]: "IF FA t1 t2 \cbv t2" | cbvA[intro]: "Fix [x].t \cbv t[x::=Fix [x].t]" | cbvB[intro]: "t \cbv t' \ ZE t \cbv ZE t'" | cbvC[intro]: "ZE (I 0) \cbv TR" | cbvD[intro]: "0 < n \ ZE (I n) \cbv FA" 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 apply(induct) apply(auto simp add: ctx_compose intro: cbv_in_ctx) done lemma cbv_eval: assumes a: "t1 \cbv t2" "t2 \ t3" shows "t1 \ t3" using a apply(induct arbitrary: t3) apply(auto dest!: eval_app_elim eval_ze_elim eval_diff_elim eval_int_elim eval_if_elim eval_plus_elim eval_FA_elim eval_TR_elim intro: eval_val) done 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) text {* example *} lemma forget: assumes asm: "y\t" shows "t[y::=s] = t" using asm by (nominal_induct t avoiding: y s rule: lam.strong_induct) (auto simp add: abs_fresh fresh_atm) lemma forget2: shows "(Lam [y].t)[y::=s] = (Lam [y].t)" apply(rule forget) apply(simp add: abs_fresh) done consts x::"name" f::"name" abbreviation MY :: "lam" where "MY \ Fix [f].Lam [x].(IF (ZE (Var x)) (I 0) ((Var x) ++ (App (Var f) ((Var x) -- I 1))))" lemma aux: assumes a: "t \ t'" "t' = t''" shows "t \ t''" using a by simp lemma assumes a: "x\f" shows "App MY (I 1) \ (I 1)" using a apply(auto) apply(rule eval_app) apply(rule eval_fix) apply(auto simp add: abs_fresh fresh_atm fresh_nat forget2) apply(rule eval_if2) apply(rule eval_ze2) apply(auto)[2] apply(rule aux) apply(rule eval_plus) apply(auto)[1] apply(rule eval_app) apply(rule eval_fix) apply(auto simp add: abs_fresh fresh_atm fresh_nat) apply(rule eval_if1) apply(rule eval_ze1) apply(auto simp add: nat_number) done lemma assumes a: "x\f" shows " \* " using a apply(auto) apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule mA) apply(auto simp add: abs_fresh fresh_atm fresh_nat forget2) apply(rule ms2) apply(rule machine.intros) apply(rule val.intros) apply(rule ms2) apply(rule machine.intros) apply(rule val.intros) apply(auto simp add: abs_fresh fresh_atm fresh_nat forget2) apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule machine.intros) apply(auto)[1] apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule mA) apply(auto simp add: abs_fresh fresh_atm fresh_nat forget2) apply(rule ms2) apply(rule machine.intros) apply(auto)[1] apply(rule ms2) apply(rule m4) apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule machine.intros) apply(auto)[1] apply(auto simp add: abs_fresh fresh_atm fresh_nat forget2) apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule machine.intros) apply(rule ms2) apply(rule machine.intros) apply(simp add: nat_number) apply(rule ms1) done lemma assumes a: "x\f" shows "App MY (I 2) \ (I 3)" using a apply(auto) apply(rule eval_app) apply(rule eval_fix) apply(auto simp add: abs_fresh fresh_atm fresh_nat forget2) apply(rule eval_if2) apply(rule eval_ze2) apply(auto simp add: nat_number)[2] apply(rule aux) apply(rule eval_plus) apply(auto)[1] apply(rule eval_app) apply(rule eval_fix) apply(auto simp add: abs_fresh fresh_atm fresh_nat) apply(rule eval_if2) apply(rule eval_ze2) apply(auto simp add: nat_number) apply(rule aux) apply(rule eval_plus) apply(auto)[1] apply(rule eval_app) apply(rule eval_fix) apply(auto simp add: abs_fresh fresh_atm fresh_nat forget2) apply(rule eval_if1) apply(rule eval_ze1) apply(auto simp add: nat_number) done end