diff -r 6471e252f14e -r 78fdc6b36a1c Nominal/Ex/Lambda.thy --- a/Nominal/Ex/Lambda.thy Fri Apr 09 09:02:54 2010 -0700 +++ b/Nominal/Ex/Lambda.thy Fri Apr 09 21:51:01 2010 +0200 @@ -4,12 +4,14 @@ atom_decl name -nominal_datatype lm = - Vr "name" -| Ap "lm" "lm" -| Lm x::"name" l::"lm" bind x in l +nominal_datatype lam = + Var "name" +| App "lam" "lam" +| Lam x::"name" l::"lam" bind x in l -lemmas supp_fn' = lm.fv[simplified lm.supp] +lemmas supp_fn' = lam.fv[simplified lam.supp] + +section {* Strong Induction Principles*} (* Old way of establishing strong induction @@ -17,31 +19,31 @@ *) lemma fixes c::"'a::fs" - assumes a1: "\name c. P c (Vr name)" - and a2: "\lm1 lm2 c. \\d. P d lm1; \d. P d lm2\ \ P c (Ap lm1 lm2)" - and a3: "\name lm c. \atom name \ c; \d. P d lm\ \ P c (Lm name lm)" - shows "P c lm" + assumes a1: "\name c. P c (Var name)" + and a2: "\lam1 lam2 c. \\d. P d lam1; \d. P d lam2\ \ P c (App lam1 lam2)" + and a3: "\name lam c. \atom name \ c; \d. P d lam\ \ P c (Lam name lam)" + shows "P c lam" proof - - have "\p. P c (p \ lm)" - apply(induct lm arbitrary: c rule: lm.induct) - apply(simp only: lm.perm) + have "\p. P c (p \ lam)" + apply(induct lam arbitrary: c rule: lam.induct) + apply(simp only: lam.perm) apply(rule a1) - apply(simp only: lm.perm) + apply(simp only: lam.perm) apply(rule a2) apply(assumption) apply(assumption) - apply(subgoal_tac "\new::name. (atom new) \ (c, Lm (p \ name) (p \ lm))") + apply(subgoal_tac "\new::name. (atom new) \ (c, Lam (p \ name) (p \ lam))") defer apply(simp add: fresh_def) - apply(rule_tac X="supp (c, Lm (p \ name) (p \ lm))" in obtain_at_base) + apply(rule_tac X="supp (c, Lam (p \ name) (p \ lam))" in obtain_at_base) apply(simp add: supp_Pair finite_supp) apply(blast) apply(erule exE) - apply(rule_tac t="p \ Lm name lm" and - s="(((p \ name) \ new) + p) \ Lm name lm" in subst) - apply(simp del: lm.perm) - apply(subst lm.perm) - apply(subst (2) lm.perm) + apply(rule_tac t="p \ Lam name lam" and + s="(((p \ name) \ new) + p) \ Lam name lam" in subst) + apply(simp del: lam.perm) + apply(subst lam.perm) + apply(subst (2) lam.perm) apply(rule flip_fresh_fresh) apply(simp add: fresh_def) apply(simp only: supp_fn') @@ -53,8 +55,8 @@ apply(drule_tac x="((p \ name) \ new) + p" in meta_spec) apply(simp) done - then have "P c (0 \ lm)" by blast - then show "P c lm" by simp + then have "P c (0 \ lam)" by blast + then show "P c lam" by simp qed (* @@ -63,25 +65,25 @@ *) lemma fixes c::"'a::fs" - assumes a1: "\name c. P c (Vr name)" - and a2: "\lm1 lm2 c. \\d. P d lm1; \d. P d lm2\ \ P c (Ap lm1 lm2)" - and a3: "\name lm c. \atom name \ c; \d. P d lm\ \ P c (Lm name lm)" - shows "P c lm" + assumes a1: "\name c. P c (Var name)" + and a2: "\lam1 lam2 c. \\d. P d lam1; \d. P d lam2\ \ P c (App lam1 lam2)" + and a3: "\name lam c. \atom name \ c; \d. P d lam\ \ P c (Lam name lam)" + shows "P c lam" proof - - have "\p. P c (p \ lm)" - apply(induct lm arbitrary: c rule: lm.induct) - apply(simp only: lm.perm) + have "\p. P c (p \ lam)" + apply(induct lam arbitrary: c rule: lam.induct) + apply(simp only: lam.perm) apply(rule a1) - apply(simp only: lm.perm) + apply(simp only: lam.perm) apply(rule a2) apply(assumption) apply(assumption) - apply(subgoal_tac "\q. (q \ {p \ atom name}) \* c \ supp (p \ Lm name lm) \* q") + apply(subgoal_tac "\q. (q \ {p \ atom name}) \* c \ supp (p \ Lam name lam) \* q") apply(erule exE) - apply(rule_tac t="p \ Lm name lm" and - s="q \ p \ Lm name lm" in subst) + apply(rule_tac t="p \ Lam name lam" and + s="q \ p \ Lam name lam" in subst) defer - apply(simp add: lm.perm) + apply(simp add: lam.perm) apply(rule a3) apply(simp add: eqvts fresh_star_def) apply(drule_tac x="q + p" in meta_spec) @@ -90,15 +92,172 @@ apply(simp add: finite_supp) apply(simp add: finite_supp) apply(simp add: finite_supp) - apply(simp only: lm.perm atom_eqvt) + apply(simp only: lam.perm atom_eqvt) apply(simp add: fresh_star_def fresh_def supp_fn') apply(rule supp_perm_eq) apply(simp) done - then have "P c (0 \ lm)" by blast - then show "P c lm" by simp + then have "P c (0 \ lam)" by blast + then show "P c lam" by simp qed +section {* size function *} + +lemma size_eqvt_raw: + fixes t::"lam_raw" + shows "size (pi \ t) = size t" + apply (induct rule: lam_raw.inducts) + apply simp_all + done + +instantiation lam :: size +begin + +quotient_definition + "size_lam :: lam \ nat" +is + "size :: lam_raw \ nat" + +lemma size_rsp: + "alpha_lam_raw x y \ size x = size y" + apply (induct rule: alpha_lam_raw.inducts) + apply (simp_all only: lam_raw.size) + apply (simp_all only: alphas) + apply clarify + apply (simp_all only: size_eqvt_raw) + done + +lemma [quot_respect]: + "(alpha_lam_raw ===> op =) size size" + by (simp_all add: size_rsp) + +lemma [quot_preserve]: + "(rep_lam ---> id) size = size" + by (simp_all add: size_lam_def) + +instance + by default + +end + +lemmas size_lam[simp] = + lam_raw.size(4)[quot_lifted] + lam_raw.size(5)[quot_lifted] + lam_raw.size(6)[quot_lifted] + +(* is this needed? *) +lemma [measure_function]: + "is_measure (size::lam\nat)" + by (rule is_measure_trivial) + +section {* Matching *} + +definition + MATCH :: "('c::pt \ (bool * 'a::pt * 'b::pt)) \ 'b \ 'a \ 'b" +where + "MATCH M d x \ if (\!r. \q. M q = (True, x, r)) then (THE r. \q. M q = (True, x, r)) else d" + +(* +lemma MATCH_eqvt: + shows "p \ (MATCH M d x) = MATCH (p \ M) (p \ d) (p \ x)" +unfolding MATCH_def +apply(perm_simp the_eqvt) +apply (tactic {* Nominal_Permeq.eqvt_tac @{context} 1 *}) +apply(simp) +thm eqvts_raw +apply(subst if_eqvt) +apply(subst ex1_eqvt) +apply(subst permute_fun_def) +apply(subst ex_eqvt) +apply(subst permute_fun_def) +apply(subst eq_eqvt) +apply(subst permute_fun_app_eq[where f="M"]) +apply(simp only: permute_minus_cancel) +apply(subst permute_prod.simps) +apply(subst permute_prod.simps) +apply(simp only: permute_minus_cancel) +apply(simp only: permute_bool_def) +apply(simp) +apply(subst ex1_eqvt) +apply(subst permute_fun_def) +apply(subst ex_eqvt) +apply(subst permute_fun_def) +apply(subst eq_eqvt) + +apply(simp only: eqvts) +apply(simp) +apply(subgoal_tac "(p \ (\!r. \q. M q = (True, x, r))) = (\!r. \q. (p \ M) q = (True, p \ x, r))") +apply(drule sym) +apply(simp) +apply(rule impI) +apply(simp add: perm_bool) +apply(rule trans) +apply(rule pt_the_eqvt[OF pta at]) +apply(assumption) +apply(simp add: pt_ex_eqvt[OF pt at]) +apply(simp add: pt_eq_eqvt[OF ptb at]) +apply(rule cheat) +apply(rule trans) +apply(rule pt_ex1_eqvt) +apply(rule pta) +apply(rule at) +apply(simp add: pt_ex_eqvt[OF pt at]) +apply(simp add: pt_eq_eqvt[OF ptb at]) +apply(subst pt_pi_rev[OF pta at]) +apply(subst pt_fun_app_eq[OF pt at]) +apply(subst pt_pi_rev[OF pt at]) +apply(simp) +done + +lemma MATCH_cng: + assumes a: "M1 = M2" "d1 = d2" + shows "MATCH M1 d1 x = MATCH M2 d2 x" +using a by simp + +lemma MATCH_eq: + assumes a: "t = l x" "G x" "\x'. t = l x' \ G x' \ r x' = r x" + shows "MATCH (\x. (G x, l x, r x)) d t = r x" +using a +unfolding MATCH_def +apply(subst if_P) +apply(rule_tac a="r x" in ex1I) +apply(rule_tac x="x" in exI) +apply(blast) +apply(erule exE) +apply(drule_tac x="q" in meta_spec) +apply(auto)[1] +apply(rule the_equality) +apply(blast) +apply(erule exE) +apply(drule_tac x="q" in meta_spec) +apply(auto)[1] +done + +lemma MATCH_eq2: + assumes a: "t = l x1 x2" "G x1 x2" "\x1' x2'. t = l x1' x2' \ G x1' x2' \ r x1' x2' = r x1 x2" + shows "MATCH (\(x1,x2). (G x1 x2, l x1 x2, r x1 x2)) d t = r x1 x2" +sorry + +lemma MATCH_neq: + assumes a: "\x. t = l x \ G x \ False" + shows "MATCH (\x. (G x, l x, r x)) d t = d" +using a +unfolding MATCH_def +apply(subst if_not_P) +apply(blast) +apply(rule refl) +done + +lemma MATCH_neq2: + assumes a: "\x1 x2. t = l x1 x2 \ G x1 x2 \ False" + shows "MATCH (\(x1,x2). (G x1 x2, l x1 x2, r x1 x2)) d t = d" +using a +unfolding MATCH_def +apply(subst if_not_P) +apply(auto) +done +*) + end