diff -r 1dd314a00b0c -r 4239a0784e5f Quot/Nominal/LamEx2.thy --- a/Quot/Nominal/LamEx2.thy Mon Feb 01 15:57:37 2010 +0100 +++ b/Quot/Nominal/LamEx2.thy Mon Feb 01 16:05:59 2010 +0100 @@ -1,7 +1,58 @@ theory LamEx -imports Nominal "../QuotMain" "../QuotList" +imports "Nominal2_Atoms" "Nominal2_Eqvt" "Nominal2_Supp" "../QuotMain" "Abs" "../QuotProd" begin + +(* lemmas that should be in Nominal \\must be cleaned *) +lemma in_permute_iff: + shows "(p \ x) \ (p \ X) \ x \ X" +apply(unfold mem_def permute_fun_def)[1] +apply(simp add: permute_bool_def) +done + +lemma fresh_star_permute_iff: + shows "(p \ a) \* (p \ x) \ a \* x" +apply(simp add: fresh_star_def) +apply(auto) +apply(drule_tac x="p \ xa" in bspec) +apply(unfold mem_def permute_fun_def)[1] +apply(simp add: eqvts) +apply(simp add: fresh_permute_iff) +apply(rule_tac ?p1="- p" in fresh_permute_iff[THEN iffD1]) +apply(simp) +apply(drule_tac x="- p \ xa" in bspec) +apply(rule_tac ?p1="p" in in_permute_iff[THEN iffD1]) +apply(simp) +apply(simp) +done + +lemma fresh_plus: + fixes p q::perm + shows "\a \ p; a \ q\ \ a \ (p + q)" +unfolding fresh_def +using supp_plus_perm +apply(auto) +done + +lemma fresh_star_plus: + fixes p q::perm + shows "\a \* p; a \* q\ \ a \* (p + q)" +unfolding fresh_star_def +by (simp add: fresh_plus) + +lemma supp_finite_set: + fixes S::"atom set" + assumes "finite S" + shows "supp S = S" + apply(rule finite_supp_unique) + apply(simp add: supports_def) + apply(auto simp add: permute_set_eq swap_atom)[1] + apply(metis) + apply(rule assms) + apply(auto simp add: permute_set_eq swap_atom)[1] +done + + atom_decl name datatype rlam = @@ -10,57 +61,84 @@ | rLam "name" "rlam" fun - rfv :: "rlam \ name set" + rfv :: "rlam \ atom set" where - rfv_var: "rfv (rVar a) = {a}" + rfv_var: "rfv (rVar a) = {atom a}" | rfv_app: "rfv (rApp t1 t2) = (rfv t1) \ (rfv t2)" -| rfv_lam: "rfv (rLam a t) = (rfv t) - {a}" +| rfv_lam: "rfv (rLam a t) = (rfv t) - {atom a}" -overloading - perm_rlam \ "perm :: 'x prm \ rlam \ rlam" (unchecked) +instantiation rlam :: pt begin -fun - perm_rlam +primrec + permute_rlam where - "perm_rlam pi (rVar a) = rVar (pi \ a)" -| "perm_rlam pi (rApp t1 t2) = rApp (perm_rlam pi t1) (perm_rlam pi t2)" -| "perm_rlam pi (rLam a t) = rLam (pi \ a) (perm_rlam pi t)" + "permute_rlam pi (rVar a) = rVar (pi \ a)" +| "permute_rlam pi (rApp t1 t2) = rApp (permute_rlam pi t1) (permute_rlam pi t2)" +| "permute_rlam pi (rLam a t) = rLam (pi \ a) (permute_rlam pi t)" + +instance +apply default +apply(induct_tac [!] x) +apply(simp_all) +done end -declare perm_rlam.simps[eqvt] +instantiation rlam :: fs +begin -instance rlam::pt_name - apply(default) - apply(induct_tac [!] x rule: rlam.induct) - apply(simp_all add: pt_name2 pt_name3) - done +lemma neg_conj: + "\(P \ Q) \ (\P) \ (\Q)" + by simp + +lemma infinite_Un: + "infinite (S \ T) \ infinite S \ infinite T" + by simp -instance rlam::fs_name - apply(default) - apply(induct_tac [!] x rule: rlam.induct) - apply(simp add: supp_def) - apply(fold supp_def) - apply(simp add: supp_atm) - apply(simp add: supp_def Collect_imp_eq Collect_neg_eq) - apply(simp add: supp_def) - apply(simp add: supp_def Collect_imp_eq Collect_neg_eq[symmetric]) - apply(fold supp_def) - apply(simp add: supp_atm) - done +instance +apply default +apply(induct_tac x) +(* var case *) +apply(simp add: supp_def) +apply(fold supp_def)[1] +apply(simp add: supp_at_base) +(* app case *) +apply(simp only: supp_def) +apply(simp only: permute_rlam.simps) +apply(simp only: rlam.inject) +apply(simp only: neg_conj) +apply(simp only: Collect_disj_eq) +apply(simp only: infinite_Un) +apply(simp only: Collect_disj_eq) +apply(simp) +(* lam case *) +apply(simp only: supp_def) +apply(simp only: permute_rlam.simps) +apply(simp only: rlam.inject) +apply(simp only: neg_conj) +apply(simp only: Collect_disj_eq) +apply(simp only: infinite_Un) +apply(simp only: Collect_disj_eq) +apply(simp) +apply(fold supp_def)[1] +apply(simp add: supp_at_base) +done -declare set_diff_eqvt[eqvt] +end + + +(* for the eqvt proof of the alpha-equivalence *) +declare permute_rlam.simps[eqvt] lemma rfv_eqvt[eqvt]: - fixes pi::"name prm" shows "(pi\rfv t) = rfv (pi\t)" apply(induct t) apply(simp_all) -apply(simp add: perm_set_eq) +apply(simp add: permute_set_eq atom_eqvt) apply(simp add: union_eqvt) -apply(simp add: set_diff_eqvt) -apply(simp add: perm_set_eq) +apply(simp add: Diff_eqvt) +apply(simp add: permute_set_eq atom_eqvt) done inductive @@ -68,35 +146,37 @@ where a1: "a = b \ (rVar a) \ (rVar b)" | a2: "\t1 \ t2; s1 \ s2\ \ rApp t1 s1 \ rApp t2 s2" -| a3: "\pi::name prm. (rfv t - {a} = rfv s - {b} \ (rfv t - {a})\* pi \ (pi \ t) \ s \ (pi \ a) = b) - \ rLam a t \ rLam b s" +| a3: "\pi. (({atom a}, t) \gen alpha rfv pi ({atom b}, s)) \ rLam a t \ rLam b s" - +thm alpha.induct +lemma a3_inverse: + assumes "rLam a t \ rLam b s" + shows "\pi. (({atom a}, t) \gen alpha rfv pi ({atom b}, s))" +using assms +apply(erule_tac alpha.cases) +apply(auto) +done -(* should be automatic with new version of eqvt-machinery *) +text {* should be automatic with new version of eqvt-machinery *} lemma alpha_eqvt: - fixes pi::"name prm" shows "t \ s \ (pi \ t) \ (pi \ s)" apply(induct rule: alpha.induct) apply(simp add: a1) apply(simp add: a2) apply(simp) apply(rule a3) -apply(erule conjE) apply(erule exE) -apply(erule conjE) apply(rule_tac x="pi \ pia" in exI) +apply(simp add: alpha_gen.simps) +apply(erule conjE)+ +apply(rule conjI)+ +apply(rule_tac ?p1="- pi" in permute_eq_iff[THEN iffD1]) +apply(simp add: eqvts atom_eqvt) apply(rule conjI) -apply(rule_tac pi1="rev pi" in perm_bij[THEN iffD1]) -apply(perm_simp add: eqvts) -apply(rule conjI) -apply(rule_tac pi1="rev pi" in pt_fresh_star_bij(1)[OF pt_name_inst at_name_inst, THEN iffD1]) -apply(perm_simp add: eqvts) -apply(rule conjI) -apply(subst perm_compose[symmetric]) -apply(simp) -apply(subst perm_compose[symmetric]) +apply(rule_tac ?p1="- pi" in fresh_star_permute_iff[THEN iffD1]) +apply(simp add: eqvts atom_eqvt) +apply(subst permute_eqvt[symmetric]) apply(simp) done @@ -106,28 +186,44 @@ apply(simp add: a1) apply(simp add: a2) apply(rule a3) -apply(rule_tac x="[]" in exI) -apply(simp_all add: fresh_star_def fresh_list_nil) +apply(rule_tac x="0" in exI) +apply(rule alpha_gen_refl) +apply(assumption) done +lemma fresh_minus_perm: + fixes p::perm + shows "a \ (- p) \ a \ p" + apply(simp add: fresh_def) + apply(simp only: supp_minus_perm) + done + +lemma alpha_gen_atom_sym: + assumes a: "\pi t s. (R t s \ R (pi \ t) (pi \ s))" + shows "\pi. ({atom a}, t) \gen \x1 x2. R x1 x2 \ R x2 x1 f pi ({atom b}, s) \ + \pi. ({atom b}, s) \gen R f pi ({atom a}, t)" + apply(erule exE) + apply(rule_tac x="- pi" in exI) + apply(simp add: alpha_gen.simps) + apply(erule conjE)+ + apply(rule conjI) + apply(simp add: fresh_star_def fresh_minus_perm) + apply(subgoal_tac "R (- pi \ s) ((- pi) \ (pi \ t))") + apply simp + apply(rule a) + apply assumption + done + lemma alpha_sym: shows "t \ s \ s \ t" -apply(induct rule: alpha.induct) -apply(simp add: a1) -apply(simp add: a2) -apply(rule a3) -apply(erule exE) -apply(rule_tac x="rev pi" in exI) -apply(simp) -apply(simp add: fresh_star_def fresh_list_rev) -apply(rule conjI) -apply(erule conjE)+ -apply(rotate_tac 3) -apply(drule_tac pi="rev pi" in alpha_eqvt) -apply(perm_simp) -apply(rule pt_bij2[OF pt_name_inst at_name_inst]) -apply(simp) -done + apply(induct rule: alpha.induct) + apply(simp add: a1) + apply(simp add: a2) + apply(rule a3) + apply(rule alpha_gen_atom_sym) + apply(rule alpha_eqvt) + apply(assumption)+ + done lemma alpha_trans: shows "t1 \ t2 \ t2 \ t3 \ t1 \ t3" @@ -142,42 +238,40 @@ apply(rotate_tac 1) apply(erule alpha.cases) apply(simp_all) +apply(simp add: alpha_gen.simps) apply(erule conjE)+ apply(erule exE)+ apply(erule conjE)+ apply(rule a3) -apply(rule_tac x="pia @ pi" in exI) -apply(simp add: fresh_star_def fresh_list_append) -apply(simp add: pt_name2) -apply(drule_tac x="rev pia \ sa" in spec) +apply(rule_tac x="pia + pi" in exI) +apply(simp add: alpha_gen.simps) +apply(simp add: fresh_star_plus) +apply(drule_tac x="- pia \ sa" in spec) apply(drule mp) -apply(rotate_tac 8) -apply(drule_tac pi="rev pia" in alpha_eqvt) -apply(perm_simp) -apply(rotate_tac 11) +apply(rotate_tac 7) +apply(drule_tac pi="- pia" in alpha_eqvt) +apply(simp) +apply(rotate_tac 9) apply(drule_tac pi="pia" in alpha_eqvt) -apply(perm_simp) +apply(simp) done lemma alpha_equivp: shows "equivp alpha" -apply(rule equivpI) -unfolding reflp_def symp_def transp_def -apply(auto intro: alpha_refl alpha_sym alpha_trans) -done + apply(rule equivpI) + unfolding reflp_def symp_def transp_def + apply(auto intro: alpha_refl alpha_sym alpha_trans) + done lemma alpha_rfv: shows "t \ s \ rfv t = rfv s" -apply(induct rule: alpha.induct) -apply(simp) -apply(simp) -apply(simp) -done + apply(induct rule: alpha.induct) + apply(simp_all add: alpha_gen.simps) + done quotient_type lam = rlam / alpha by (rule alpha_equivp) - quotient_definition "Var :: name \ lam" as @@ -194,48 +288,32 @@ "rLam" quotient_definition - "fv :: lam \ name set" + "fv :: lam \ atom set" as "rfv" -(* definition of overloaded permutation function *) -(* for the lifted type lam *) -overloading - perm_lam \ "perm :: 'x prm \ lam \ lam" (unchecked) -begin - -quotient_definition - "perm_lam :: 'x prm \ lam \ lam" -as - "perm::'x prm \ rlam \ rlam" - -end - lemma perm_rsp[quot_respect]: - "(op = ===> alpha ===> alpha) op \ op \" + "(op = ===> alpha ===> alpha) permute permute" apply(auto) - (* this is propably true if some type conditions are imposed ;o) *) - sorry - -lemma fresh_rsp: - "(op = ===> alpha ===> op =) fresh fresh" - apply(auto) - (* this is probably only true if some type conditions are imposed *) - sorry + apply(rule alpha_eqvt) + apply(simp) + done lemma rVar_rsp[quot_respect]: "(op = ===> alpha) rVar rVar" by (auto intro: a1) -lemma rApp_rsp[quot_respect]: "(alpha ===> alpha ===> alpha) rApp rApp" +lemma rApp_rsp[quot_respect]: + "(alpha ===> alpha ===> alpha) rApp rApp" by (auto intro: a2) -lemma rLam_rsp[quot_respect]: "(op = ===> alpha ===> alpha) rLam rLam" +lemma rLam_rsp[quot_respect]: + "(op = ===> alpha ===> alpha) rLam rLam" apply(auto) apply(rule a3) - apply(rule_tac x="[]" in exI) - unfolding fresh_star_def - apply(simp add: fresh_list_nil) + apply(rule_tac x="0" in exI) + unfolding fresh_star_def + apply(simp add: fresh_star_def fresh_zero_perm alpha_gen.simps) apply(simp add: alpha_rfv) done @@ -244,6 +322,7 @@ apply(simp add: alpha_rfv) done + section {* lifted theorems *} lemma lam_induct: @@ -251,29 +330,43 @@ \lam1 lam2. \P lam1; P lam2\ \ P (App lam1 lam2); \name lam. P lam \ P (Lam name lam)\ \ P lam" - by (lifting rlam.induct) + apply (lifting rlam.induct) + done + +instantiation lam :: pt +begin -lemma perm_lam [simp]: - fixes pi::"'a prm" +quotient_definition + "permute_lam :: perm \ lam \ lam" +as + "permute :: perm \ rlam \ rlam" + +lemma permute_lam [simp]: shows "pi \ Var a = Var (pi \ a)" and "pi \ App t1 t2 = App (pi \ t1) (pi \ t2)" and "pi \ Lam a t = Lam (pi \ a) (pi \ t)" -apply(lifting perm_rlam.simps) +apply(lifting permute_rlam.simps) done -instance lam::pt_name -apply(default) +instance +apply default apply(induct_tac [!] x rule: lam_induct) -apply(simp_all add: pt_name2 pt_name3) +apply(simp_all) done +end + lemma fv_lam [simp]: - shows "fv (Var a) = {a}" + shows "fv (Var a) = {atom a}" and "fv (App t1 t2) = fv t1 \ fv t2" - and "fv (Lam a t) = fv t - {a}" + and "fv (Lam a t) = fv t - {atom a}" apply(lifting rfv_var rfv_app rfv_lam) done +lemma fv_eqvt: + shows "(p \ fv t) = fv (p \ t)" +apply(lifting rfv_eqvt) +done lemma a1: "a = b \ Var a = Var b" @@ -283,32 +376,97 @@ "\x = xa; xb = xc\ \ App x xb = App xa xc" by (lifting a2) -lemma a3: - "\\pi::name prm. (fv t - {a} = fv s - {b} \ (fv t - {a})\* pi \ (pi \ t) = s \ (pi \ a) = b)\ - \ Lam a t = Lam b s" - by (lifting a3) +lemma alpha_gen_rsp_pre: + assumes a5: "\t s. R t s \ R (pi \ t) (pi \ s)" + and a1: "R s1 t1" + and a2: "R s2 t2" + and a3: "\a b c d. R a b \ R c d \ R1 a c = R2 b d" + and a4: "\x y. R x y \ fv1 x = fv2 y" + shows "(a, s1) \gen R1 fv1 pi (b, s2) = (a, t1) \gen R2 fv2 pi (b, t2)" +apply (simp add: alpha_gen.simps) +apply (simp only: a4[symmetric, OF a1] a4[symmetric, OF a2]) +apply auto +apply (subst a3[symmetric]) +apply (rule a5) +apply (rule a1) +apply (rule a2) +apply (assumption) +apply (subst a3) +apply (rule a5) +apply (rule a1) +apply (rule a2) +apply (assumption) +done + +lemma [quot_respect]: "(prod_rel op = alpha ===> + (alpha ===> alpha ===> op =) ===> (alpha ===> op =) ===> op = ===> prod_rel op = alpha ===> op =) + alpha_gen alpha_gen" +apply simp +apply clarify +apply (rule alpha_gen_rsp_pre[of "alpha",OF alpha_eqvt]) +apply auto +done + +lemma pi_rep: "pi \ (rep_lam x) = rep_lam (pi \ x)" +apply (unfold rep_lam_def) +sorry + +lemma [quot_preserve]: "(prod_fun id rep_lam ---> + (abs_lam ---> abs_lam ---> id) ---> (abs_lam ---> id) ---> id ---> (prod_fun id rep_lam) ---> id) + alpha_gen = alpha_gen" +apply (simp add: expand_fun_eq) +apply (simp add: alpha_gen.simps) +apply (simp add: pi_rep) +apply (simp only: Quotient_abs_rep[OF Quotient_lam]) +apply auto +done + +lemma alpha_prs [quot_preserve]: "(rep_lam ---> rep_lam ---> id) alpha = (op =)" +apply (simp add: expand_fun_eq) +sorry + + +lemma a3: + "\pi. ({atom a}, t) \gen (op =) fv pi ({atom b}, s) \ Lam a t = Lam b s" + apply (lifting a3) + done + +lemma a3_inv: + assumes "Lam a t = Lam b s" + shows "\pi. (fv t - {atom a} = fv s - {atom b} \ (fv t - {atom a})\* pi \ (pi \ t) = s)" +using assms +apply(lifting a3_inverse) +done lemma alpha_cases: "\a1 = a2; \a b. \a1 = Var a; a2 = Var b; a = b\ \ P; \x xa xb xc. \a1 = App x xb; a2 = App xa xc; x = xa; xb = xc\ \ P; \t a s b. \a1 = Lam a t; a2 = Lam b s; - \pi::name prm. fv t - {a} = fv s - {b} \ (fv t - {a}) \* pi \ (pi \ t) = s \ pi \ a = b\ \ P\ + \pi. fv t - {atom a} = fv s - {atom b} \ (fv t - {atom a}) \* pi \ (pi \ t) = s\ + \ P\ \ P" by (lifting alpha.cases) +(* not sure whether needed *) lemma alpha_induct: "\qx = qxa; \a b. a = b \ qxb (Var a) (Var b); \x xa xb xc. \x = xa; qxb x xa; xb = xc; qxb xb xc\ \ qxb (App x xb) (App xa xc); \t a s b. - \\pi::name prm. fv t - {a} = fv s - {b} \ - (fv t - {a}) \* pi \ ((pi \ t) = s \ qxb (pi \ t) s) \ pi \ a = b\ \ qxb (Lam a t) (Lam b s)\ + \\pi. fv t - {atom a} = fv s - {atom b} \ + (fv t - {atom a}) \* pi \ ((pi \ t) = s \ qxb (pi \ t) s)\ + \ qxb (Lam a t) (Lam b s)\ \ qxb qx qxa" by (lifting alpha.induct) +(* should they lift automatically *) lemma lam_inject [simp]: shows "(Var a = Var b) = (a = b)" and "(App t1 t2 = App s1 s2) = (t1 = s1 \ t2 = s2)" apply(lifting rlam.inject(1) rlam.inject(2)) +apply(regularize) +prefer 2 +apply(regularize) +prefer 2 apply(auto) apply(drule alpha.cases) apply(simp_all) @@ -321,6 +479,16 @@ apply(simp_all) done +lemma Lam_pseudo_inject: + shows "(Lam a t = Lam b s) = + (\pi. (fv t - {atom a} = fv s - {atom b} \ (fv t - {atom a})\* pi \ (pi \ t) = s))" +apply(rule iffI) +apply(rule a3_inv) +apply(assumption) +apply(rule a3) +apply(assumption) +done + lemma rlam_distinct: shows "\(rVar nam \ rApp rlam1' rlam2')" and "\(rApp rlam1' rlam2' \ rVar nam)" @@ -329,18 +497,18 @@ and "\(rApp rlam1 rlam2 \ rLam nam' rlam')" and "\(rLam nam' rlam' \ rApp rlam1 rlam2)" apply auto -apply(erule alpha.cases) -apply simp_all -apply(erule alpha.cases) -apply simp_all -apply(erule alpha.cases) -apply simp_all -apply(erule alpha.cases) -apply simp_all -apply(erule alpha.cases) -apply simp_all -apply(erule alpha.cases) -apply simp_all +apply (erule alpha.cases) +apply (simp_all only: rlam.distinct) +apply (erule alpha.cases) +apply (simp_all only: rlam.distinct) +apply (erule alpha.cases) +apply (simp_all only: rlam.distinct) +apply (erule alpha.cases) +apply (simp_all only: rlam.distinct) +apply (erule alpha.cases) +apply (simp_all only: rlam.distinct) +apply (erule alpha.cases) +apply (simp_all only: rlam.distinct) done lemma lam_distinct[simp]: @@ -354,49 +522,88 @@ done lemma var_supp1: - shows "(supp (Var a)) = ((supp a)::name set)" - by (simp add: supp_def) + shows "(supp (Var a)) = (supp a)" + apply (simp add: supp_def) + done lemma var_supp: - shows "(supp (Var a)) = {a::name}" - using var_supp1 by (simp add: supp_atm) + shows "(supp (Var a)) = {a:::name}" + using var_supp1 by (simp add: supp_at_base) lemma app_supp: - shows "supp (App t1 t2) = (supp t1) \ ((supp t2)::name set)" -apply(simp only: perm_lam supp_def lam_inject) + shows "supp (App t1 t2) = (supp t1) \ (supp t2)" +apply(simp only: supp_def lam_inject) apply(simp add: Collect_imp_eq Collect_neg_eq) done -lemma lam_supp: - shows "supp (Lam x t) = ((supp ([x].t))::name set)" -apply(simp add: supp_def) -apply(simp add: abs_perm) -sorry +(* supp for lam *) +lemma lam_supp1: + shows "(supp (atom x, t)) supports (Lam x t) " +apply(simp add: supports_def) +apply(fold fresh_def) +apply(simp add: fresh_Pair swap_fresh_fresh) +apply(clarify) +apply(subst swap_at_base_simps(3)) +apply(simp_all add: fresh_atom) +done +lemma lam_fsupp1: + assumes a: "finite (supp t)" + shows "finite (supp (Lam x t))" +apply(rule supports_finite) +apply(rule lam_supp1) +apply(simp add: a supp_Pair supp_atom) +done -instance lam::fs_name +instance lam :: fs apply(default) apply(induct_tac x rule: lam_induct) apply(simp add: var_supp) apply(simp add: app_supp) -apply(simp add: lam_supp abs_supp) +apply(simp add: lam_fsupp1) +done + +lemma supp_fv: + shows "supp t = fv t" +apply(induct t rule: lam_induct) +apply(simp add: var_supp) +apply(simp add: app_supp) +apply(subgoal_tac "supp (Lam name lam) = supp (Abst {atom name} lam)") +apply(simp add: supp_Abst) +apply(simp (no_asm) add: supp_def permute_set_eq atom_eqvt) +apply(simp add: Lam_pseudo_inject) +apply(simp add: abs_eq alpha_gen) +apply(simp add: supp_eqvt[symmetric] fv_eqvt[symmetric]) +done + +lemma lam_supp2: + shows "supp (Lam x t) = supp (Abst {atom x} t)" +apply(simp add: supp_def permute_set_eq atom_eqvt) +apply(simp add: Lam_pseudo_inject) +apply(simp add: abs_eq supp_fv alpha_gen) +done + +lemma lam_supp: + shows "supp (Lam x t) = ((supp t) - {atom x})" +apply(simp add: lam_supp2) +apply(simp add: supp_Abst) done lemma fresh_lam: - "(a \ Lam b t) \ (a = b) \ (a \ b \ a \ t)" + "(atom a \ Lam b t) \ (a = b) \ (a \ b \ atom a \ t)" apply(simp add: fresh_def) -apply(simp add: lam_supp abs_supp) +apply(simp add: lam_supp) apply(auto) done lemma lam_induct_strong: - fixes a::"'a::fs_name" + fixes a::"'a::fs" assumes a1: "\name b. P b (Var name)" and a2: "\lam1 lam2 b. \\c. P c lam1; \c. P c lam2\ \ P b (App lam1 lam2)" - and a3: "\name lam b. \\c. P c lam; name \ b\ \ P b (Lam name lam)" + and a3: "\name lam b. \\c. P c lam; (atom name) \ b\ \ P b (Lam name lam)" shows "P a lam" proof - - have "\(pi::name prm) a. P a (pi \ lam)" + have "\pi a. P a (pi \ lam)" proof (induct lam rule: lam_induct) case (1 name pi) show "P a (pi \ Var name)" @@ -405,8 +612,8 @@ done next case (2 lam1 lam2 pi) - have b1: "\(pi::name prm) a. P a (pi \ lam1)" by fact - have b2: "\(pi::name prm) a. P a (pi \ lam2)" by fact + have b1: "\pi a. P a (pi \ lam1)" by fact + have b2: "\pi a. P a (pi \ lam2)" by fact show "P a (pi \ App lam1 lam2)" apply (simp) apply (rule a2) @@ -415,217 +622,43 @@ done next case (3 name lam pi a) - have b: "\(pi::name prm) a. P a (pi \ lam)" by fact - obtain c::name where fr: "c\(a, pi\name, pi\lam)" - apply(rule exists_fresh[of "(a, pi\name, pi\lam)"]) - apply(simp_all add: fs_name1) - done - from b fr have p: "P a (Lam c (([(c, pi\name)]@pi)\lam))" + have b: "\pi a. P a (pi \ lam)" by fact + obtain c::name where fr: "atom c\(a, pi\name, pi\lam)" + apply(rule obtain_atom) + apply(auto) + sorry + from b fr have p: "P a (Lam c (((c \ (pi \ name)) + pi)\lam))" apply - apply(rule a3) apply(blast) - apply(simp) + apply(simp add: fresh_Pair) done - have eq: "[(c, pi\name)] \ Lam (pi \ name) (pi \ lam) = Lam (pi \ name) (pi \ lam)" - apply(rule perm_fresh_fresh) + have eq: "(atom c \ atom (pi\name)) \ Lam (pi \ name) (pi \ lam) = Lam (pi \ name) (pi \ lam)" + apply(rule swap_fresh_fresh) using fr - apply(simp add: fresh_lam) - apply(simp add: fresh_lam) + apply(simp add: fresh_lam fresh_Pair) + apply(simp add: fresh_lam fresh_Pair) done show "P a (pi \ Lam name lam)" apply (simp) apply(subst eq[symmetric]) using p - apply(simp only: perm_lam pt_name2 swap_simps) + apply(simp only: permute_lam) + apply(simp add: flip_def) done qed - then have "P a (([]::name prm) \ lam)" by blast + then have "P a (0 \ lam)" by blast then show "P a lam" by simp qed lemma var_fresh: fixes a::"name" - shows "(a \ (Var b)) = (a \ b)" + shows "(atom a \ (Var b)) = (atom a \ b)" apply(simp add: fresh_def) apply(simp add: var_supp1) done -(* lemma hom_reg: *) - -lemma rlam_rec_eqvt: - fixes pi::"name prm" - and f1::"name \ ('a::pt_name)" - shows "(pi\rlam_rec f1 f2 f3 t) = rlam_rec (pi\f1) (pi\f2) (pi\f3) (pi\t)" -apply(induct t) -apply(simp_all) -apply(simp add: perm_fun_def) -apply(perm_simp) -apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst]) -back -apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst]) -apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst]) -apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst]) -apply(simp) -apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst]) -back -apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst]) -apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst]) -apply(simp) -done - - -lemma rlam_rec_respects: - assumes f1: "f_var \ Respects (op= ===> op=)" - and f2: "f_app \ Respects (alpha ===> alpha ===> op= ===> op= ===> op=)" - and f3: "f_lam \ Respects (op= ===> alpha ===> op= ===> op=)" - shows "rlam_rec f_var f_app f_lam \ Respects (alpha ===> op =)" -apply(simp add: mem_def) -apply(simp add: Respects_def) -apply(rule allI) -apply(rule allI) -apply(rule impI) -apply(erule alpha.induct) -apply(simp) -apply(simp) -using f2 -apply(simp add: mem_def) -apply(simp add: Respects_def) -using f3[simplified mem_def Respects_def] -apply(simp) -apply(case_tac "a=b") -apply(clarify) -apply(simp) -(* probably true *) -sorry - -function - term1_hom :: "(name \ 'a) \ - (rlam \ rlam \ 'a \ 'a \ 'a) \ - ((name \ rlam) \ (name \ 'a) \ 'a) \ rlam \ 'a" -where - "term1_hom var app abs' (rVar x) = (var x)" -| "term1_hom var app abs' (rApp t u) = - app t u (term1_hom var app abs' t) (term1_hom var app abs' u)" -| "term1_hom var app abs' (rLam x u) = - abs' (\y. [(x, y)] \ u) (\y. term1_hom var app abs' ([(x, y)] \ u))" -apply(pat_completeness) -apply(auto) -done - -lemma pi_size: - fixes pi::"name prm" - and t::"rlam" - shows "size (pi \ t) = size t" -apply(induct t) -apply(auto) -done - -termination term1_hom - apply(relation "measure (\(f1, f2, f3, t). size t)") -apply(auto simp add: pi_size) -done - -lemma lam_exhaust: - "\\name. y = Var name \ P; \rlam1 rlam2. y = App rlam1 rlam2 \ P; \name rlam. y = Lam name rlam \ P\ - \ P" -apply(lifting rlam.exhaust) -done - -(* THIS IS NOT TRUE, but it lets prove the existence of the hom function *) -lemma lam_inject': - "(Lam a x = Lam b y) = ((\c. [(a, c)] \ x) = (\c. [(b, c)] \ y))" -sorry - -function - hom :: "(name \ 'a) \ - (lam \ lam \ 'a \ 'a \ 'a) \ - ((name \ lam) \ (name \ 'a) \ 'a) \ lam \ 'a" -where - "hom f_var f_app f_lam (Var x) = f_var x" -| "hom f_var f_app f_lam (App l r) = f_app l r (hom f_var f_app f_lam l) (hom f_var f_app f_lam r)" -| "hom f_var f_app f_lam (Lam a x) = f_lam (\b. ([(a,b)] \ x)) (\b. hom f_var f_app f_lam ([(a,b)] \ x))" -defer -apply(simp_all add: lam_inject') (* inject, distinct *) -apply(tactic {* Cong_Tac.cong_tac @{thm cong} 1 *}) -apply(rule refl) -apply(rule ext) -apply(tactic {* Cong_Tac.cong_tac @{thm cong} 1 *}) -apply simp_all -apply(erule conjE)+ -apply(rule_tac x="b" in cong) -apply simp_all -apply auto -apply(rule_tac y="b" in lam_exhaust) -apply simp_all -apply auto -apply meson -apply(simp_all add: lam_inject') -apply metis -done - -termination hom - apply - -(* -ML_prf {* Size.size_thms @{theory} "LamEx.lam" *} -*) -sorry - -thm hom.simps - -lemma term1_hom_rsp: - "\(alpha ===> alpha ===> op =) f_app f_app; ((op = ===> alpha) ===> op =) f_lam f_lam\ - \ (alpha ===> op =) (term1_hom f_var f_app f_lam) (term1_hom f_var f_app f_lam)" -apply(simp) -apply(rule allI)+ -apply(rule impI) -apply(erule alpha.induct) -apply(auto)[1] -apply(auto)[1] -apply(simp) -apply(erule conjE)+ -apply(erule exE)+ -apply(erule conjE)+ -apply(clarify) -sorry - -lemma hom: " -\f_var. \f_app \ Respects(alpha ===> alpha ===> op =). -\f_lam \ Respects((op = ===> alpha) ===> op =). -\hom\Respects (alpha ===> op =). - ((\x. hom (rVar x) = f_var x) \ - (\l r. hom (rApp l r) = f_app l r (hom l) (hom r)) \ - (\x a. hom (rLam a x) = f_lam (\b. ([(a,b)]\ x)) (\b. hom ([(a,b)] \ x))))" -apply(rule allI) -apply(rule ballI)+ -apply(rule_tac x="term1_hom f_var f_app f_lam" in bexI) -apply(simp_all) -apply(simp only: in_respects) -apply(rule term1_hom_rsp) -apply(assumption)+ -done - -lemma hom': -"\hom. - ((\x. hom (Var x) = f_var x) \ - (\l r. hom (App l r) = f_app l r (hom l) (hom r)) \ - (\x a. hom (Lam a x) = f_lam (\b. ([(a,b)] \ x)) (\b. hom ([(a,b)] \ x))))" -apply (lifting hom) -done - -(* test test -lemma raw_hom_correct: - assumes f1: "f_var \ Respects (op= ===> op=)" - and f2: "f_app \ Respects (alpha ===> alpha ===> op= ===> op= ===> op=)" - and f3: "f_lam \ Respects ((op= ===> alpha) ===> (op= ===> op=) ===> op=)" - shows "\!hom\Respects (alpha ===> op =). - ((\x. hom (rVar x) = f_var x) \ - (\l r. hom (rApp l r) = f_app l r (hom l) (hom r)) \ - (\x a. hom (rLam a x) = f_lam (\b. ([(a,b)]\ x)) (\b. hom ([(a,b)] \ x))))" -unfolding Bex1_def -apply(rule ex1I) -sorry -*) end