diff -r 734f23ad5d8f -r 3f36e2165e51 src/HOL/Nominal/Examples/Lam_substs.thy --- a/src/HOL/Nominal/Examples/Lam_substs.thy Mon Nov 28 00:25:43 2005 +0100 +++ b/src/HOL/Nominal/Examples/Lam_substs.thy Mon Nov 28 05:03:00 2005 +0100 @@ -1,43 +1,48 @@ +(* $Id$ *) theory lam_substs imports "../nominal" begin +text {* Contains all the reasoning infrastructure for the + lambda-calculus that the nominal datatype package + does not yet provide. *} + atom_decl name nominal_datatype lam = Var "name" | App "lam" "lam" | Lam "\name\lam" ("Lam [_]._" [100,100] 100) -section {* strong induction principles for lam *} +section {* Strong induction principles for lam *} lemma lam_induct_aux: fixes P :: "lam \ 'a \ bool" - and f :: "'a \ name set" - assumes fs: "\x. finite (f x)" + and f :: "'a \ 'a" + assumes fs: "\x. finite ((supp (f x))::name set)" and h1: "\x a. P (Var a) x" and h2: "\x t1 t2. (\z. P t1 z) \ (\z. P t2 z) \ P (App t1 t2) x" - and h3: "\x a t. a\f x \ (\z. P t z) \ P (Lam [a].t) x" + and h3: "\x a t. a\f x \ (\z. P t z) \ P (Lam [a].t) x" shows "\(pi::name prm) x. P (pi\t) x" proof (induct rule: lam.induct_weak) case (Lam a t) - assume i1: "\(pi::name prm) x. P (pi\t) x" - show ?case + have ih: "\(pi::name prm) x. P (pi\t) x" by fact + show "\(pi::name prm) x. P (pi\(Lam [a].t)) x" proof (intro strip, simp add: abs_perm) fix x::"'a" and pi::"name prm" - have f: "\c::name. c\(f x,pi\a,pi\t)" - by (rule at_exists_fresh[OF at_name_inst], simp add: supp_prod fs_name1 - at_fin_set_supp[OF at_name_inst, OF fs] fs) + have "\c::name. c\(f x,pi\a,pi\t)" + by (rule at_exists_fresh[OF at_name_inst], simp add: supp_prod fs_name1 fs) then obtain c::"name" where f1: "c\(pi\a)" and f2: "c\(f x)" and f3: "c\(pi\t)" - by (force simp add: fresh_prod at_fresh[OF at_name_inst]) - have g: "Lam [c].([(c,pi\a)]\(pi\t)) = Lam [(pi\a)].(pi\t)" using f1 f3 + by (force simp add: fresh_prod fresh_atm) + have "Lam [c].([(c,pi\a)]\(pi\t)) = Lam [(pi\a)].(pi\t)" using f1 f3 by (simp add: lam.inject alpha) - from i1 have "\x. P (([(c,pi\a)]@pi)\t) x" by force - hence i1b: "\x. P ([(c,pi\a)]\(pi\t)) x" by (simp add: pt_name2[symmetric]) - with h3 f2 have "P (Lam [c].([(c,pi\a)]\(pi\t))) x" + moreover + from ih have "\x. P (([(c,pi\a)]@pi)\t) x" by force + hence "\x. P ([(c,pi\a)]\(pi\t)) x" by (simp add: pt_name2[symmetric]) + hence "P (Lam [c].([(c,pi\a)]\(pi\t))) x" using h3 f2 by (auto simp add: fresh_def at_fin_set_supp[OF at_name_inst, OF fs]) - with g show "P (Lam [(pi\a)].(pi\t)) x" by simp + ultimately show "P (Lam [(pi\a)].(pi\t)) x" by simp qed qed (auto intro: h1 h2) @@ -45,11 +50,11 @@ fixes P :: "lam \ 'a \ bool" and x :: "'a" and t :: "lam" - and f :: "'a \ name set" - assumes fs: "\x. finite (f x)" + and f :: "'a \ 'a" + assumes fs: "\x. finite ((supp (f x))::name set)" and h1: "\x a. P (Var a) x" and h2: "\x t1 t2. (\z. P t1 z)\(\z. P t2 z)\P (App t1 t2) x" - and h3: "\x a t. a\f x \ (\z. P t z)\ P (Lam [a].t) x" + and h3: "\x a t. a\f x \ (\z. P t z)\ P (Lam [a].t) x" shows "P t x" proof - from fs h1 h2 h3 have "\(pi::name prm) x. P (pi\t) x" by (rule lam_induct_aux, auto) @@ -65,7 +70,7 @@ and h2: "\x t1 t2. (\z. P t1 z)\(\z. P t2 z)\P (App t1 t2) x" and h3: "\x a t. a\x \ (\z. P t z)\ P (Lam [a].t) x" shows "P t x" -by (rule lam_induct'[of "\x. ((supp x)::name set)" "P"], +by (rule lam_induct'[of "\x. x" "P"], simp_all add: fs_name1 fresh_def[symmetric], auto intro: h1 h2 h3) types 'a f1_ty = "name\('a::pt_name)" @@ -197,24 +202,6 @@ ultimately show ?thesis by (rule supports_finite) qed -(* -types 'a recT = "'a f1_ty \ 'a f2_ty \ 'a f3_ty \ ((lam\name prm\('a::pt_name)) set)" - -consts - rec :: "('a::pt_name) recT" - -inductive "rec f1 f2 f3" -intros -r1: "(Var a,pi,f1 (pi\a))\rec f1 f2 f3" -r2: "\finite ((supp y1)::name set);(t1,pi,y1)\rec f1 f2 f3; - finite ((supp y2)::name set);(t2,pi,y2)\rec f1 f2 f3\ - \ (App t1 t2,pi,f2 y1 y2)\rec f1 f2 f3" -r3: "\finite ((supp y)::name set);\a'. ((t,pi@[(a,a')],y)\rec f1 f2 f3)\ - \ (Lam [a].t,pi,fresh_fun (\a'. f3 a' y))\rec f1 f2 f3" - -*) - -(* types 'a recT = "'a f1_ty \ 'a f2_ty \ 'a f3_ty \ (lam\(name prm \ ('a::pt_name))) set" consts @@ -227,37 +214,6 @@ finite ((supp y2)::name set);(t2,y2)\rec f1 f2 f3\ \ (App t1 t2,\pi. f2 (y1 pi) (y2 pi))\rec f1 f2 f3" r3: "\finite ((supp y)::name set);(t,y)\rec f1 f2 f3\ - \ (Lam [a].t,fresh_fun (\a' pi. f3 a' (y (pi@[(a,a')]))))\rec f1 f2 f3" -*) - -term lam_Rep.Var -term lam_Rep.Lam - -consts nthe :: "'a nOption \ 'a" -primrec - "nthe (nSome x) = x" - -types 'a recT = "'a f1_ty \ 'a f2_ty \ 'a f3_ty \ (lam\(name prm \ ('a::pt_name))) set" - -(* -consts fn :: "'a f1_ty \ 'a f2_ty \ 'a f3_ty \ lam_Rep \ ('a::pt_name)" - -primrec -"fn f1 f2 f3 (lam_Rep.Var a) = f1 a" -"fn f1 f2 f3 (lam_Rep.App t1 t2) = f2 (fn f1 f2 f3 t1) (fn f1 f2 f3 t2)" -"fn f1 f2 f3 (lam_Rep.Lam f) = fresh_fun (\a'. f3 a' (fn f1 f2 f3 (fn' (f a'))))" -*) - -consts - rec :: "('a::pt_name) recT" - -inductive "rec f1 f2 f3" -intros -r1: "(Var a,\pi. f1 (pi\a))\rec f1 f2 f3" -r2: "\finite ((supp y1)::name set);(t1,y1)\rec f1 f2 f3; - finite ((supp y2)::name set);(t2,y2)\rec f1 f2 f3\ - \ (App t1 t2,\pi. f2 (y1 pi) (y2 pi))\rec f1 f2 f3" -r3: "\finite ((supp y)::name set);(t,y)\rec f1 f2 f3\ \ (Lam [a].t,\pi. fresh_fun (\a'. f3 a' (y (pi@[(a,a')]))))\rec f1 f2 f3" constdefs @@ -969,7 +925,7 @@ and a3: "\a t. a\(f1,f2,f3) \ fun (Lam [a].t) = f3 a (fun t)" shows "fun t = rfun f1 f2 f3 t" (*apply(nominal_induct t rule: lam_induct')*) -apply (rule lam_induct'[of "\_. ((supp (f1,f2,f3))::name set)" "\t _. fun t = rfun f1 f2 f3 t"]) +apply (rule lam_induct'[of "\_. (f1,f2,f3)" "\t _. fun t = rfun f1 f2 f3 t"]) (* finite support *) apply(rule f) (* VAR *) @@ -977,7 +933,6 @@ (* APP *) apply(simp add: a2 rfun_App[OF f, OF c, symmetric]) (* LAM *) -apply(fold fresh_def) apply(simp add: a3 rfun_Lam[OF f, OF c, symmetric]) done @@ -1084,14 +1039,13 @@ assumes f: "finite ((supp (f1,f2,f3))::name set)" and c: "(\(a::name). a\f3 \ (\(y::'a::pt_name) t. a\f3 t a y))" shows "fst (rfun_gen' f1 f2 f3 t) = t" -apply (rule lam_induct'[of "\_. ((supp (f1,f2,f3))::name set)" "\t _. fst (rfun_gen' f1 f2 f3 t) = t"]) +apply(rule lam_induct'[of "\_. (f1,f2,f3)" "\t _. fst (rfun_gen' f1 f2 f3 t) = t"]) apply(simp add: f) apply(unfold rfun_gen'_def) apply(simp only: rfun_Var[OF fsupp'[OF f],OF fcb'[OF f, OF c]]) apply(simp) apply(simp only: rfun_App[OF fsupp'[OF f],OF fcb'[OF f, OF c]]) apply(simp) -apply(fold fresh_def) apply(auto) apply(rule trans) apply(rule_tac f="fst" in arg_cong) @@ -1211,6 +1165,8 @@ apply(simp add: rfun_gen_def) done +(* FIXME: this should be automatically proved in nominal_atoms *) + instance nat :: pt_name apply(intro_classes) apply(simp_all add: perm_nat_def) @@ -1431,7 +1387,6 @@ (* parallel substitution *) - consts "domain" :: "(name\lam) list \ (name list)" primrec