# HG changeset patch # User Cezary Kaliszyk # Date 1274431447 -7200 # Node ID e838f7d90f811c565c26e2de4260a29349c71059 # Parent 95aac598a5269f309b8b0283edd5bbf47e5c4aa5 Function experiments diff -r 95aac598a526 -r e838f7d90f81 Nominal/Ex/Lambda.thy --- a/Nominal/Ex/Lambda.thy Mon May 17 17:54:07 2010 +0100 +++ b/Nominal/Ex/Lambda.thy Fri May 21 10:44:07 2010 +0200 @@ -1,5 +1,5 @@ theory Lambda -imports "../NewParser" +imports "../NewParser" Quotient_Option begin atom_decl name @@ -472,6 +472,321 @@ nominal_inductive typing *) +(* Substitution *) + +definition new where + "new s = (THE x. \a \ s. atom x \ a)" + +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" + +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 + +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] + +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 + "match_Lam :: (atom set) \ lam \ (name \ lam) option" +is match_Lam_raw + +lemma [quot_respect]: + "(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" sorry + 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 + +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 (simp add: Let_def) + apply (erule conjE) + apply (thin_tac "match_Lam S lam = Some (z, s) \ lam = Lam z s \ atom z \ S") + apply (rule conjI) + apply (simp add: lam.eq_iff) + apply (rule_tac x="(name \ z)" in exI) + apply (simp add: alphas) + apply (simp add: eqvts) + apply (simp only: lam.fv(3)[symmetric]) + apply (subgoal_tac "Lam name lam = Lam z s") + apply (simp del: lam.fv) + prefer 3 + apply (thin_tac "(name \ new (S \ (fv_lam lam - {atom name}))) \ lam = s") + apply (simp only: new_def) + apply (subgoal_tac "\a \ S. atom z \ a") + apply (simp only: fresh_def) + + thm new_def + apply simp + + +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 (supp (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] +defer +apply (case_tac a) apply simp +apply (frule app_some) apply simp +apply (case_tac a) apply simp +apply (frule app_some) apply simp +apply (case_tac a) apply simp +apply (frule lam_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 (subst match_Lam_simps) + apply (simp only: Let_def) + 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 (subst match_Lam_simps) + apply (simp only: Let_def) + apply (simp only: option.cases) + apply (simp only: prod.cases) + apply (simp only: lam.perm) + apply (simp only: lam.eq_iff) + sorry + qed + qed + +lemma size_no_change: "size (p \ (t :: lam_raw)) = size t" + by (induct t) simp_all + +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) + 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) + apply clarify + oops + +lemma new_eqvt[eqvt]: "p \ (new s) = new (p \ s)" + oops + +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) + oops + +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 + +quotient_definition + subst2 ("_ [ _ ::= _ ]" [100,100,100] 100) +where + "subst2 :: lam \ name \ lam \ lam" is "subst_raw" + +lemmas fv_rsp = quot_respect(10)[simplified] + +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) + 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 simp + apply (rule alpha_lam_raw.intros) + apply (rule_tac x="((new (insert (atom y) (fv_lam_raw a \ fv_lam_raw c) - + {atom name}))\(new (insert (atom y) (fv_lam_raw b \ fv_lam_raw c) - + {atom name})))" in exI) + apply (simp only: alphas) + apply (tactic {* split_conj_tac 1 *}) + prefer 3 + 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 + 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) + 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] + + +thm subst_raw.simps(3)[quot_lifted,no_vars] end