diff -r a6f3e1b08494 -r b6873d123f9b Attic/Quot/Examples/LamEx.thy --- a/Attic/Quot/Examples/LamEx.thy Sat May 12 21:05:59 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,619 +0,0 @@ -theory LamEx -imports Nominal "../Quotient" "../Quotient_List" -begin - -atom_decl name - -datatype rlam = - rVar "name" -| rApp "rlam" "rlam" -| rLam "name" "rlam" - -fun - rfv :: "rlam \ name set" -where - rfv_var: "rfv (rVar a) = {a}" -| rfv_app: "rfv (rApp t1 t2) = (rfv t1) \ (rfv t2)" -| rfv_lam: "rfv (rLam a t) = (rfv t) - {a}" - -overloading - perm_rlam \ "perm :: 'x prm \ rlam \ rlam" (unchecked) -begin - -fun - perm_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)" - -end - -declare perm_rlam.simps[eqvt] - -instance rlam::pt_name - apply(default) - apply(induct_tac [!] x rule: rlam.induct) - apply(simp_all add: pt_name2 pt_name3) - done - -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 - -declare set_diff_eqvt[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: union_eqvt) - apply(simp add: set_diff_eqvt) - apply(simp add: perm_set_eq) - done - -inductive - alpha :: "rlam \ rlam \ bool" ("_ \ _" [100, 100] 100) -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" - - -(* 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(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(simp) - done - -lemma alpha_refl: - shows "t \ t" - apply(induct t rule: rlam.induct) - 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) - 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 - -lemma alpha_trans: - shows "t1 \ t2 \ t2 \ t3 \ t1 \ t3" - apply(induct arbitrary: t3 rule: alpha.induct) - apply(erule alpha.cases) - apply(simp_all) - apply(simp add: a1) - apply(rotate_tac 4) - apply(erule alpha.cases) - apply(simp_all) - apply(simp add: a2) - apply(rotate_tac 1) - apply(erule alpha.cases) - apply(simp_all) - 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(drule mp) - apply(rotate_tac 8) - apply(drule_tac pi="rev pia" in alpha_eqvt) - apply(perm_simp) - apply(rotate_tac 11) - apply(drule_tac pi="pia" in alpha_eqvt) - apply(perm_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 - -lemma alpha_rfv: - shows "t \ s \ rfv t = rfv s" - apply(induct rule: alpha.induct) - apply(simp) - apply(simp) - apply(simp) - done - -quotient_type lam = rlam / alpha - by (rule alpha_equivp) - - -quotient_definition - "Var :: name \ lam" -is - "rVar" - -quotient_definition - "App :: lam \ lam \ lam" -is - "rApp" - -quotient_definition - "Lam :: name \ lam \ lam" -is - "rLam" - -quotient_definition - "fv :: lam \ name set" -is - "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" -is - "perm::'x prm \ rlam \ rlam" - -end - -lemma perm_rsp[quot_respect]: - "(op = ===> alpha ===> alpha) op \ (op \ :: (name \ name) list \ rlam \ rlam)" - apply auto - apply(erule alpha_eqvt) - done - -lemma rVar_rsp[quot_respect]: - "(op = ===> alpha) rVar rVar" - by (auto intro: a1) - -lemma rApp_rsp[quot_respect]: "(alpha ===> alpha ===> alpha) rApp rApp" - by (auto intro: a2) - -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(simp add: alpha_rfv) - done - -lemma rfv_rsp[quot_respect]: - "(alpha ===> op =) rfv rfv" - apply(simp add: alpha_rfv) - done - -section {* lifted theorems *} - -lemma lam_induct: - "\\name. P (Var name); - \lam1 lam2. \P lam1; P lam2\ \ P (App lam1 lam2); - \name lam. P lam \ P (Lam name lam)\ - \ P lam" - by (lifting rlam.induct) - -lemma perm_lam [simp]: - fixes pi::"name prm" - 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)" - by (lifting perm_rlam.simps[where 'a="name"]) - -instance lam::pt_name - apply(default) - apply(induct_tac [!] x rule: lam_induct) - apply(simp_all add: pt_name2 pt_name3) - done - -lemma fv_lam [simp]: - shows "fv (Var a) = {a}" - and "fv (App t1 t2) = fv t1 \ fv t2" - and "fv (Lam a t) = fv t - {a}" - by(lifting rfv_var rfv_app rfv_lam) - -lemma a1: - "a = b \ Var a = Var b" - by (lifting a1) - -lemma a2: - "\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_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\ - \ P" - by (lifting alpha.cases) - -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)\ - \ qxb qx qxa" - by (lifting alpha.induct) - -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(auto) - apply(drule alpha.cases) - apply(simp_all) - apply(simp add: alpha.a1) - apply(drule alpha.cases) - apply(simp_all) - apply(drule alpha.cases) - apply(simp_all) - apply(rule alpha.a2) - apply(simp_all) - done - -lemma rlam_distinct: - shows "\(rVar nam \ rApp rlam1' rlam2')" - and "\(rApp rlam1' rlam2' \ rVar nam)" - and "\(rVar nam \ rLam nam' rlam')" - and "\(rLam nam' rlam' \ rVar nam)" - 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 - done - -lemma lam_distinct[simp]: - shows "Var nam \ App lam1' lam2'" - and "App lam1' lam2' \ Var nam" - and "Var nam \ Lam nam' lam'" - and "Lam nam' lam' \ Var nam" - and "App lam1 lam2 \ Lam nam' lam'" - and "Lam nam' lam' \ App lam1 lam2" - by(lifting rlam_distinct(1) rlam_distinct(2) rlam_distinct(3) rlam_distinct(4) rlam_distinct(5) rlam_distinct(6)) - -lemma var_supp1: - shows "(supp (Var a)) = ((supp a)::name set)" - by (simp add: supp_def) - -lemma var_supp: - shows "(supp (Var a)) = {a::name}" - using var_supp1 by (simp add: supp_atm) - -lemma app_supp: - shows "supp (App t1 t2) = (supp t1) \ ((supp t2)::name set)" - apply(simp only: perm_lam 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 - -instance lam::fs_name - 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) - done - -lemma fresh_lam: - "(a \ Lam b t) \ (a = b) \ (a \ b \ a \ t)" - apply(simp add: fresh_def) - apply(simp add: lam_supp abs_supp) - apply(auto) - done - -lemma lam_induct_strong: - fixes a::"'a::fs_name" - 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)" - shows "P a lam" -proof - - have "\(pi::name prm) a. P a (pi \ lam)" - proof (induct lam rule: lam_induct) - case (1 name pi) - show "P a (pi \ Var name)" - apply (simp) - apply (rule a1) - 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 - show "P a (pi \ App lam1 lam2)" - apply (simp) - apply (rule a2) - apply (rule b1) - apply (rule b2) - 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))" - apply - - apply(rule a3) - apply(blast) - apply(simp) - done - have eq: "[(c, pi\name)] \ Lam (pi \ name) (pi \ lam) = Lam (pi \ name) (pi \ lam)" - apply(rule perm_fresh_fresh) - using fr - apply(simp add: fresh_lam) - apply(simp add: fresh_lam) - 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) - done - qed - then have "P a (([]::name prm) \ lam)" by blast - then show "P a lam" by simp -qed - - -lemma var_fresh: - fixes a::"name" - shows "(a \ (Var b)) = (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 -