# HG changeset patch # User urbanc # Date 1155839496 -7200 # Node ID 4d0c337193487fb111895cda5705166245cf8419 # Parent 9a60e315124445fab1fec445731555fc8ed8f828 used the recursion combinator for the height and substitution function diff -r 9a60e3151244 -r 4d0c33719348 src/HOL/Nominal/Examples/Height.thy --- a/src/HOL/Nominal/Examples/Height.thy Thu Aug 17 19:20:43 2006 +0200 +++ b/src/HOL/Nominal/Examples/Height.thy Thu Aug 17 20:31:36 2006 +0200 @@ -3,67 +3,114 @@ (* Simple, but artificial, problem suggested by D. Wang *) theory Height -imports Lam_substs -(* - - inherit the type of alpha-equated lambda-terms, - the iteration combinator for this type and the - definition of capture-avoiding substitution - - (the iteration combinator is not yet derived - automatically in the last stable version of - the nominal package) - - - capture-avoiding substitution is written - - t[x::=t'] - - and is defined such that - - (Var y)[x::=t'] = (if x=y then t' else Var y) - (App t1 t2)[x::=t'] = App (t1[x::=t']) (t2[x::=t']) - y\x \ y\t2 \ (Lam [y].t)[x::=t'] = Lam [y].(t[x::=t']) -*) +imports Nominal begin -text {* definition of the height-function by cases *} +atom_decl name + +nominal_datatype lam = Var "name" + | App "lam" "lam" + | Lam "\name\lam" ("Lam [_]._" [100,100] 100) + +types 'a f1_ty = "name\('a::pt_name)" + 'a f2_ty = "lam\lam\'a\'a\('a::pt_name)" + 'a f3_ty = "name\lam\'a\('a::pt_name)" + +constdefs + rfun :: "'a f1_ty \ 'a f2_ty \ 'a f3_ty \ lam \ ('a::pt_name)" + "rfun f1 f2 f3 t \ (THE r. (t,r) \ lam_rec_set f1 f2 f3)" + +lemma rfun_Var: + assumes f1: "finite ((supp f1)::name set)" + and f2: "finite ((supp f2)::name set)" + and f3: "finite ((supp f3)::name set)" + and fcb: "\a t r. a\f3 \ a\f3 a t r" + shows "rfun f1 f2 f3 (Var a) = (f1 a)" +apply(simp add: rfun_def) +apply(rule trans) +apply(rule the1_equality) +apply(rule lam.rec_unique[where P="\_. True"]) +apply(simp_all add: f1 f2 f3 fcb) +apply(rule lam_rec_set.intros) +done + +lemma rfun_App: + assumes f1: "finite ((supp f1)::name set)" + and f2: "finite ((supp f2)::name set)" + and f3: "finite ((supp f3)::name set)" + and fcb: "\a t r. a\f3 \ a\f3 a t r" + shows "rfun f1 f2 f3 (App t1 t2) = f2 t1 t2 (rfun f1 f2 f3 t1) (rfun f1 f2 f3 t2)" +apply(simp add: rfun_def) +apply(rule trans) +apply(rule the1_equality) +apply(rule lam.rec_unique[where P="\_. True"]) +apply(simp_all add: f1 f2 f3 fcb) +apply(rule lam_rec_set.intros) +apply(rule theI') +apply(rule lam.rec_unique[where P="\_. True"]) +apply(simp_all add: f1 f2 f3 fcb) +apply(rule theI') +apply(rule lam.rec_unique[where P="\_. True"]) +apply(simp_all add: f1 f2 f3 fcb) +done + +lemma rfun_Lam: + assumes f1: "finite ((supp f1)::name set)" + and f2: "finite ((supp f2)::name set)" + and f3: "finite ((supp f3)::name set)" + and fcb: "\a t r. a\f3 \ a\f3 a t r" + and fr: "a\f1" "a\f2" "a\f3" + shows "rfun f1 f2 f3 (Lam [a].t) = f3 a t (rfun f1 f2 f3 t)" +apply(simp add: rfun_def) +apply(rule trans) +apply(rule the1_equality) +apply(rule lam.rec_unique[where P="\_. True"]) +apply(simp_all add: f1 f2 f3 fcb) +apply(rule lam_rec_set.intros) +apply(simp_all add: fr) +apply(rule theI') +apply(rule lam.rec_unique[where P="\_. True"]) +apply(simp_all add: f1 f2 f3 fcb) +done + +text {* definition of the height-function by "structural recursion" ;o) *} + constdefs height_Var :: "name \ int" - "height_Var \ \(a::name). 1" + "height_Var \ \_. 1" - height_App :: "int \ int \ int" - "height_App \ \n1 n2. (max n1 n2)+1" + height_App :: "lam\lam\int\int\int" + "height_App \ \_ _ n1 n2. (max n1 n2)+1" - height_Lam :: "name \ int \ int" - "height_Lam \ \(a::name) n. n+1" + height_Lam :: "name\lam\int\int" + "height_Lam \ \_ _ n. n+1" height :: "lam \ int" - "height \ itfun height_Var height_App height_Lam" + "height \ rfun height_Var height_App height_Lam" text {* show that height is a function *} -lemma supp_height_Lam: - shows "((supp height_Lam)::name set)={}" - apply(simp add: height_Lam_def supp_def perm_fun_def perm_int_def) - done - lemma fin_supp_height: - shows "finite ((supp (height_Var,height_App,height_Lam))::name set)" - by (finite_guess add: height_Var_def height_App_def height_Lam_def perm_int_def fs_name1) + shows "finite ((supp height_Var)::name set)" + and "finite ((supp height_App)::name set)" + and "finite ((supp height_Lam)::name set)" + by (finite_guess add: height_Var_def height_App_def height_Lam_def perm_int_def fs_name1)+ -lemma FCB_height_Lam: - shows "\(a::name). a\height_Lam \ (\n. a\height_Lam a n)" -apply(simp add: height_Lam_def fresh_def supp_def perm_fun_def perm_int_def) +lemma fcb_height_Lam: + assumes fr: "a\height_Lam" + shows "a\height_Lam a t n" +apply(simp add: height_Lam_def perm_int_def fresh_def supp_int) done text {* derive the characteristic equations for height from the iteration combinator *} lemma height_Var: shows "height (Var c) = 1" -apply(simp add: height_def itfun_Var[OF fin_supp_height, OF FCB_height_Lam]) +apply(simp add: height_def rfun_Var[OF fin_supp_height, OF fcb_height_Lam]) apply(simp add: height_Var_def) done lemma height_App: shows "height (App t1 t2) = (max (height t1) (height t2))+1" -apply(simp add: height_def itfun_App[OF fin_supp_height, OF FCB_height_Lam]) +apply(simp add: height_def rfun_App[OF fin_supp_height, OF fcb_height_Lam]) apply(simp add: height_App_def) done @@ -71,15 +118,78 @@ shows "height (Lam [a].t) = (height t)+1" apply(simp add: height_def) apply(rule trans) -apply(rule itfun_Lam[OF fin_supp_height, OF FCB_height_Lam]) -apply(simp add: fresh_def supp_prod supp_height_Lam) -apply(simp add: supp_def height_Var_def height_App_def perm_fun_def perm_int_def) +apply(rule rfun_Lam[OF fin_supp_height, OF fcb_height_Lam], assumption) +apply(fresh_guess add: height_Var_def perm_int_def) +apply(fresh_guess add: height_App_def perm_int_def) +apply(fresh_guess add: height_Lam_def perm_int_def) apply(simp add: height_Lam_def) done text {* add the characteristic equations of height to the simplifier *} declare height_Var[simp] height_App[simp] height_Lam[simp] +text {* define capture-avoiding substitution *} +constdefs + subst_Var :: "name \ lam \ name \ lam" + "subst_Var x t' \ \y. (if y=x then t' else (Var y))" + + subst_App :: "name \ lam \ lam \ lam \ lam \ lam \ lam" + "subst_App x t' \ \_ _ r1 r2. App r1 r2" + + subst_Lam :: "name \ lam \ name \ lam \ lam \ lam" + "subst_Lam x t' \ \a _ r. Lam [a].r" + + subst_lam :: "name \ lam \ lam \ lam" + "subst_lam x t' \ rfun (subst_Var x t') (subst_App x t') (subst_Lam x t')" + +lemma supports_subst_Var: + shows "((supp (x,t))::name set) supports (subst_Var x t)" +apply(supports_simp add: subst_Var_def) +apply(rule impI) +apply(drule pt_bij1[OF pt_name_inst, OF at_name_inst]) +apply(perm_simp) +done + +lemma fin_supp_subst: + shows "finite ((supp (subst_Var x t))::name set)" + and "finite ((supp (subst_App x t))::name set)" + and "finite ((supp (subst_Lam x t))::name set)" +proof - + case goal1 + have f: "finite ((supp (x,t))::name set)" by (simp add: fs_name1) + then have "supp (subst_Var x t) \ ((supp (x,t))::name set)" + using supp_is_subset[OF supports_subst_Var] by simp + then show "finite ((supp (subst_Var x t))::name set)" using f by (simp add: finite_subset) +qed (finite_guess add: subst_App_def subst_Lam_def fs_name1)+ + +lemma fcb_subst_Lam: + assumes fr: "a\(subst_Lam y t')" + shows "a\(subst_Lam y t') a t r" + by (simp add: subst_Lam_def abs_fresh) + +syntax + subst_lam_syn :: "lam \ name \ lam \ lam" ("_[_::=_]" [100,100,100] 100) + +translations + "t1[y::=t2]" \ "subst_lam y t2 t1" + +lemma subst_lam[simp]: + shows "(Var x)[y::=t'] = (if x=y then t' else (Var x))" + and "(App t1 t2)[y::=t'] = App (t1[y::=t']) (t2[y::=t'])" + and "\a\y; a\t'\ \ (Lam [a].t)[y::=t'] = Lam [a].(t[y::=t'])" +apply(unfold subst_lam_def) +apply(simp only: rfun_Var[OF fin_supp_subst, OF fcb_subst_Lam]) +apply(simp only: subst_Var_def) +apply(simp only: rfun_App[OF fin_supp_subst, OF fcb_subst_Lam]) +apply(simp only: subst_App_def) +apply(rule trans) +apply(rule rfun_Lam[OF fin_supp_subst, OF fcb_subst_Lam]) +apply(assumption) +apply(rule supports_fresh, rule supports_subst_Var, simp add: fs_name1, simp add: fresh_def supp_prod) +apply(fresh_guess add: fresh_prod subst_App_def fs_name1) +apply(fresh_guess add: fresh_prod subst_Lam_def fs_name1) +apply(simp add: subst_Lam_def) +done text{* the next lemma is needed in the Var-case of the theorem *} @@ -87,7 +197,6 @@ shows "1 \ (height e)" by (nominal_induct e rule: lam.induct) (simp | arith)+ - text {* unlike the proplem suggested by Wang, the theorem is formulated here entirely by using functions *} @@ -107,7 +216,7 @@ case (App e1 e2) hence ih1: "height (e1[x::=e']) \ (((height e1) - 1) + (height e'))" and ih2: "height (e2[x::=e']) \ (((height e2) - 1) + (height e'))" by simp_all - then show "height ((App e1 e2)[x::=e']) \ height (App e1 e2) - 1 + height e'" by (simp, arith) + then show "height ((App e1 e2)[x::=e']) \ height (App e1 e2) - 1 + height e'" by simp qed end