diff -r 9fb315392493 -r 8732ff59068b Nominal/Ex/Lambda.thy --- a/Nominal/Ex/Lambda.thy Wed May 26 15:34:54 2010 +0200 +++ b/Nominal/Ex/Lambda.thy Wed May 26 15:37:56 2010 +0200 @@ -1,5 +1,5 @@ theory Lambda -imports "../NewParser" +imports "../NewParser" Quotient_Option begin atom_decl name @@ -456,10 +456,10 @@ fun prove_strong_ind (pred_name, avoids) ctxt = Proof.theorem NONE (K I) [] ctxt -local structure P = OuterParse and K = OuterKeyword in +local structure P = Parse and K = Keyword in val _ = - OuterSyntax.local_theory_to_proof "nominal_inductive" + Outer_Syntax.local_theory_to_proof "nominal_inductive" "proves strong induction theorem for inductive predicate involving nominal datatypes" K.thy_goal (P.xname -- (Scan.optional (P.$$$ "avoids" |-- P.enum1 "|" (P.name -- (P.$$$ ":" |-- P.and_list1 P.term))) []) >> prove_strong_ind) @@ -474,113 +474,283 @@ (* Substitution *) -definition new where - "new s = (THE x. \a \ s. atom x \ a)" - -lemma size_no_change: "size (p \ (t :: lam_raw)) = size t" - by (induct t) simp_all +primrec match_Var_raw where + "match_Var_raw (Var_raw x) = Some x" +| "match_Var_raw (App_raw x y) = None" +| "match_Var_raw (Lam_raw n t) = None" -function - subst_raw :: "lam_raw \ name \ lam_raw \ lam_raw" -where - "subst_raw (Var_raw x) y s = (if x=y then s else (Var_raw x))" -| "subst_raw (App_raw l r) y s = App_raw (subst_raw l y s) (subst_raw r y s)" -| "subst_raw (Lam_raw x t) y s = - Lam_raw (new ({atom y} \ fv_lam_raw s \ fv_lam_raw t - {atom x})) - (subst_raw ((x \ (new ({atom y} \ fv_lam_raw s \ fv_lam_raw t - {atom x}))) \ t) y s)" -by (pat_completeness, auto) -termination - apply (relation "measure (\(t, y, s). (size t))") - apply (auto simp add: size_no_change) +quotient_definition + "match_Var :: lam \ name option" +is match_Var_raw + +lemma [quot_respect]: "(alpha_lam_raw ===> op =) match_Var_raw match_Var_raw" + apply rule + apply (induct_tac a b rule: alpha_lam_raw.induct) + apply simp_all done -lemma fv_subst[simp]: "fv_lam_raw (subst_raw t y s) = - (if (atom y \ fv_lam_raw t) then fv_lam_raw s \ (fv_lam_raw t - {atom y}) else fv_lam_raw t)" - apply (induct t arbitrary: s) - apply (auto simp add: supp_at_base)[1] - apply (auto simp add: supp_at_base)[1] - apply (simp only: fv_lam_raw.simps) - apply simp - apply (rule conjI) +lemmas match_Var_simps = match_Var_raw.simps[quot_lifted] + +primrec match_App_raw where + "match_App_raw (Var_raw x) = None" +| "match_App_raw (App_raw x y) = Some (x, y)" +| "match_App_raw (Lam_raw n t) = None" + +quotient_definition + "match_App :: lam \ (lam \ lam) option" +is match_App_raw + +lemma [quot_respect]: + "(alpha_lam_raw ===> option_rel (prod_rel alpha_lam_raw alpha_lam_raw)) match_App_raw match_App_raw" + apply (intro fun_relI) + apply (induct_tac a b rule: alpha_lam_raw.induct) + apply simp_all + done + +lemmas match_App_simps = match_App_raw.simps[quot_lifted] + +definition new where + "new (s :: 'a :: fs) = (THE x. \a \ supp s. atom x \ a)" + +definition + "match_Lam (S :: 'a :: fs) t = (if (\n s. (t = Lam n s)) then + (let z = new (S, t) in Some (z, THE s. t = Lam z s)) else None)" + +lemma lam_half_inj: "(Lam z s = Lam z sa) = (s = sa)" + apply auto + apply (simp only: lam.eq_iff alphas) apply clarify - sorry - -thm supp_at_base -lemma new_eqvt[eqvt]: "p \ (new s) = new (p \ s)" + apply (simp add: eqvts) sorry -lemma subst_var_raw_eqvt[eqvt]: "p \ (subst_raw t y s) = subst_raw (p \ t) (p \ y) (p \ s)" - apply (induct t arbitrary: p y s) - apply simp_all - apply(perm_simp) - apply simp - sorry +lemma match_Lam_simps: + "match_Lam S (Var n) = None" + "match_Lam S (App l r) = None" + "z = new (S, (Lam z s)) \ match_Lam S (Lam z s) = Some (z, s)" + apply (simp_all add: match_Lam_def) + apply (simp add: lam_half_inj) + apply auto + done -lemma subst_id: "alpha_lam_raw (subst_raw x d (Var_raw d)) x" - apply (induct x arbitrary: d) - apply (simp_all add: alpha_lam_raw.intros) - apply (rule alpha_lam_raw.intros) - apply (rule_tac x="(name \ new (insert (atom d) (supp d)))" in exI) - apply (simp add: alphas) - oops +(* +lemma match_Lam_simps2: + "atom n \ ((S :: 'a :: fs), Lam n s) \ match_Lam S (Lam n s) = Some (n, s)" + apply (rule_tac t="Lam n s" + and s="Lam (new (S, (Lam n s))) ((n \ (new (S, (Lam n s)))) \ s)" in subst) + defer + apply (subst match_Lam_simps(3)) + defer + apply simp +*) + +(*primrec match_Lam_raw where + "match_Lam_raw (S :: atom set) (Var_raw x) = None" +| "match_Lam_raw S (App_raw x y) = None" +| "match_Lam_raw S (Lam_raw n t) = (let z = new (S \ (fv_lam_raw t - {atom n})) in Some (z, (n \ z) \ t))" quotient_definition - subst ("_ [ _ ::= _ ]" [100,100,100] 100) -where - "subst :: lam \ name \ lam \ lam" is "subst_raw" - -lemmas fv_rsp = quot_respect(10)[simplified] + "match_Lam :: (atom set) \ lam \ (name \ lam) option" +is match_Lam_raw -lemma subst_rsp_pre1: - assumes a: "alpha_lam_raw a b" - shows "alpha_lam_raw (subst_raw a y c) (subst_raw b y c)" - using a - apply (induct a b arbitrary: c y rule: alpha_lam_raw.induct) - apply (simp add: equivp_reflp[OF lam_equivp]) - apply (simp add: alpha_lam_raw.intros) - apply (simp only: alphas) - apply clarify - apply (simp only: subst_raw.simps) +lemma swap_fresh: + assumes a: "fv_lam_raw t \* p" + shows "alpha_lam_raw (p \ t) t" + using a apply (induct t) + apply (simp add: supp_at_base fresh_star_def) apply (rule alpha_lam_raw.intros) - apply (simp only: alphas) - sorry - -lemma subst_rsp_pre2: - assumes a: "alpha_lam_raw a b" - shows "alpha_lam_raw (subst_raw c y a) (subst_raw c y b)" - using a - apply (induct c arbitrary: a b y) - apply (simp add: equivp_reflp[OF lam_equivp]) - apply (simp add: alpha_lam_raw.intros) + apply (metis Rep_name_inverse atom_eqvt atom_name_def fresh_perm) + apply (simp) + apply (simp only: fresh_star_union) + apply clarify + apply (rule alpha_lam_raw.intros) + apply simp + apply simp apply simp apply (rule alpha_lam_raw.intros) sorry lemma [quot_respect]: - "(alpha_lam_raw ===> op = ===> alpha_lam_raw ===> alpha_lam_raw) subst_raw subst_raw" - proof (intro fun_relI, simp) - fix a b c d :: lam_raw - fix y :: name - assume a: "alpha_lam_raw a b" - assume b: "alpha_lam_raw c d" - have c: "alpha_lam_raw (subst_raw a y c) (subst_raw b y c)" using subst_rsp_pre1 a by simp - then have d: "alpha_lam_raw (subst_raw b y c) (subst_raw b y d)" using subst_rsp_pre2 b by simp - show "alpha_lam_raw (subst_raw a y c) (subst_raw b y d)" - using c d equivp_transp[OF lam_equivp] by blast + "(op = ===> alpha_lam_raw ===> option_rel (prod_rel op = alpha_lam_raw)) match_Lam_raw match_Lam_raw" + proof (intro fun_relI, clarify) + fix S t s + assume a: "alpha_lam_raw t s" + show "option_rel (prod_rel op = alpha_lam_raw) (match_Lam_raw S t) (match_Lam_raw S s)" + using a proof (induct t s rule: alpha_lam_raw.induct) + case goal1 show ?case by simp + next + case goal2 show ?case by simp + next + case (goal3 x t y s) + then obtain p where "({atom x}, t) \gen (\x1 x2. alpha_lam_raw x1 x2 \ + option_rel (prod_rel op = alpha_lam_raw) (match_Lam_raw S x1) + (match_Lam_raw S x2)) fv_lam_raw p ({atom y}, s)" .. + then have + c: "fv_lam_raw t - {atom x} = fv_lam_raw s - {atom y}" and + d: "(fv_lam_raw t - {atom x}) \* p" and + e: "alpha_lam_raw (p \ t) s" and + f: "option_rel (prod_rel op = alpha_lam_raw) (match_Lam_raw S (p \ t)) (match_Lam_raw S s)" and + g: "p \ {atom x} = {atom y}" unfolding alphas(1) by - (elim conjE, assumption)+ + let ?z = "new (S \ (fv_lam_raw t - {atom x}))" + have h: "?z = new (S \ (fv_lam_raw s - {atom y}))" using c by simp + show ?case + unfolding match_Lam_raw.simps Let_def option_rel.simps prod_rel.simps split_conv + proof + show "?z = new (S \ (fv_lam_raw s - {atom y}))" by (fact h) + next + have "atom y \ p" sorry + have "fv_lam_raw t \* ((x \ y) \ p)" sorry + then have "alpha_lam_raw (((x \ y) \ p) \ t) t" using swap_fresh by auto + then have "alpha_lam_raw (p \ t) ((x \ y) \ t)" sorry + have "alpha_lam_raw t ((x \ y) \ s)" sorry + then have "alpha_lam_raw ((x \ ?z) \ t) ((y \ ?z) \ s)" using eqvts(15) sorry + then show "alpha_lam_raw ((x \ new (S \ (fv_lam_raw t - {atom x}))) \ t) + ((y \ new (S \ (fv_lam_raw s - {atom y}))) \ s)" unfolding h . + qed + qed qed -lemma simp3: - "x \ y \ atom x \ fv_lam_raw s \ alpha_lam_raw (subst_raw (Lam_raw x t) y s) (Lam_raw x (subst_raw t y s))" - apply simp - apply (rule alpha_lam_raw.intros) - apply (rule_tac x ="(x \ (new (insert (atom y) (fv_lam_raw s \ fv_lam_raw t) - - {atom x})))" in exI) - apply (simp only: alphas) - apply simp +lemmas match_Lam_simps = match_Lam_raw.simps[quot_lifted] +*) + +lemma app_some: "match_App x = Some (a, b) \ x = App a b" +by (induct x rule: lam.induct) (simp_all add: match_App_simps) + +lemma lam_some: "match_Lam S x = Some (z, s) \ x = Lam z s \ atom z \ S" + apply (induct x rule: lam.induct) + apply (simp_all add: match_Lam_simps) + apply (thin_tac "match_Lam S lam = Some (z, s) \ lam = Lam z s \ atom z \ S") + apply (simp add: match_Lam_def) + apply (subgoal_tac "\n s. Lam name lam = Lam n s") + prefer 2 + apply auto[1] + apply (simp add: Let_def) + apply (thin_tac "\n s. Lam name lam = Lam n s") + apply clarify + apply (rule conjI) + apply (rule_tac t="THE s. Lam name lam = Lam (new (S, Lam name lam)) s" and + s="(name \ (new (S, Lam name lam))) \ lam" in subst) + defer + apply (simp add: lam.eq_iff) + apply (rule_tac x="(name \ (new (S, Lam name lam)))" in exI) + apply (simp add: alphas) + apply (simp add: eqvts) + apply (rule conjI) sorry -lemmas subst_simps = subst_raw.simps(1-2)[quot_lifted,no_vars] - simp3[quot_lifted,simplified lam.supp,simplified fresh_def[symmetric], no_vars] +function subst where +"subst v s t = ( + case match_Var t of Some n \ if n = v then s else Var n | None \ + case match_App t of Some (l, r) \ App (subst v s l) (subst v s r) | None \ + case match_Lam (v,s) t of Some (n, t) \ Lam n (subst v s t) | None \ undefined)" +by pat_completeness auto + +termination apply (relation "measure (\(_, _, t). size t)") + apply auto[1] + apply (case_tac a) apply simp + apply (frule lam_some) apply simp + apply (case_tac a) apply simp + apply (frule app_some) apply simp + apply (case_tac a) apply simp + apply (frule app_some) apply simp +done + +lemmas lam_exhaust = lam_raw.exhaust[quot_lifted] + +lemma subst_eqvt: + "p \ (subst v s t) = subst (p \ v) (p \ s) (p \ t)" + proof (induct v s t rule: subst.induct) + case (1 v s t) + show ?case proof (cases t rule: lam_exhaust) + fix n + assume "t = Var n" + then show ?thesis by (simp add: match_Var_simps) + next + fix l r + assume "t = App l r" + then show ?thesis + apply (simp only:) + apply (subst subst.simps) + apply (subst match_Var_simps) + apply (simp only: option.cases) + apply (subst match_App_simps) + apply (simp only: option.cases) + apply (simp only: prod.cases) + apply (simp only: lam.perm) + apply (subst (3) subst.simps) + apply (subst match_Var_simps) + apply (simp only: option.cases) + apply (subst match_App_simps) + apply (simp only: option.cases) + apply (simp only: prod.cases) + apply (subst 1(2)[of "(l, r)" "l" "r"]) + apply (simp add: match_Var_simps) + apply (simp add: match_App_simps) + apply (rule refl) + apply (subst 1(3)[of "(l, r)" "l" "r"]) + apply (simp add: match_Var_simps) + apply (simp add: match_App_simps) + apply (rule refl) + apply (rule refl) + done + next + fix n t' + assume "t = Lam n t'" + then show ?thesis + apply (simp only: ) + apply (simp only: lam.perm) + apply (subst subst.simps) + apply (subst match_Var_simps) + apply (simp only: option.cases) + apply (subst match_App_simps) + apply (simp only: option.cases) + apply (rule_tac t="Lam n t'" and s="Lam (new ((v, s), Lam n t')) ((n \ new ((v, s), Lam n t')) \ t')" in subst) + defer + apply (subst match_Lam_simps) + defer + apply (simp only: option.cases) + apply (simp only: prod.cases) + apply (subst (2) subst.simps) + apply (subst match_Var_simps) + apply (simp only: option.cases) + apply (subst match_App_simps) + apply (simp only: option.cases) + apply (rule_tac t="Lam (p \ n) (p \ t')" and s="Lam (new ((p \ v, p \ s), Lam (p \ n) (p \ t'))) (((p \ n) \ new ((p \ v, p \ s), Lam (p \ n) (p \ t'))) \ t')" in subst) + defer + apply (subst match_Lam_simps) + defer + apply (simp only: option.cases) + apply (simp only: prod.cases) + apply (simp only: lam.perm) + thm 1(1) + sorry + qed + qed + +lemma subst_proper_eqs: + "subst y s (Var x) = (if x = y then s else (Var x))" + "subst y s (App l r) = App (subst y s l) (subst y s r)" + "atom x \ (t, s) \ subst y s (Lam x t) = Lam x (subst y s t)" + apply (subst subst.simps) + apply (simp only: match_Var_simps) + apply (simp only: option.simps) + apply (subst subst.simps) + apply (simp only: match_App_simps) + apply (simp only: option.simps) + apply (simp only: prod.simps) + apply (simp only: match_Var_simps) + apply (simp only: option.simps) + apply (subst subst.simps) + apply (simp only: match_Var_simps) + apply (simp only: option.simps) + apply (simp only: match_App_simps) + apply (simp only: option.simps) + apply (rule_tac t="Lam x t" and s="Lam (new ((y, s), Lam x t)) ((x \ new ((y, s), Lam x t)) \ t)" in subst) + defer + apply (subst match_Lam_simps) + defer + apply (simp only: option.simps) + apply (simp only: prod.simps) + sorry end