diff -r fb201e383f1b -r da575186d492 Nominal/Ex/AuxNoFCB.thy --- a/Nominal/Ex/AuxNoFCB.thy Tue Feb 19 05:38:46 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,402 +0,0 @@ -theory Lambda imports "../Nominal2" begin - -atom_decl name - -nominal_datatype lam = - Var "name" -| App "lam" "lam" -| Lam x::"name" l::"lam" binds x in l ("Lam [_]. _" [100, 100] 100) - -nominal_primrec lookup where - "lookup (n :: name) m [] \ (n = m)" -| "lookup n m ((hn, hm) # t) \ - (n, m) = (hn, hm) \ (n \ hn \ m \ hm \ lookup n m t)" - apply (simp add: eqvt_def lookup_graph_def) - apply (rule, perm_simp, rule, rule) - by pat_completeness auto - -termination (eqvt) by lexicographic_order - -nominal_primrec lam2_rec where - "lam2_rec faa fll xs (Var n) (Var m) = lookup n m xs" -| "lam2_rec faa fll xs (Var n) (App l r) = False" -| "lam2_rec faa fll xs (Var n) (Lam [x]. t) = False" -| "lam2_rec faa fll xs (App l r) (Var n) = False" -| "lam2_rec faa fll xs (App l1 r1) (App l2 r2) = faa l1 r1 l2 r2" -| "lam2_rec faa fll xs (App l r) (Lam [x]. t) = False" -| "lam2_rec faa fll xs (Lam [x]. t) (Var n) = False" -| "lam2_rec faa fll xs (Lam [x]. t) (App l1 r1) = False" -| "(atom x \ (xs, Lam [y]. s) \ atom y \ (x, xs, Lam [x]. t) \ - (\x' y' t' s'. atom x' \ (xs, Lam [y']. s') \ atom y' \ (x', xs, Lam [x']. t') \ Lam [x]. t = Lam [x']. t' \ Lam [y]. s = Lam [y']. s' - \ fll x t y s = fll x' t' y' s')) \ - lam2_rec faa fll xs (Lam [x]. t) (Lam [y]. s) = fll x t y s" -| "(atom x \ (xs, Lam [y]. s) \ atom y \ (x, xs, Lam [x]. t) \ - \(\x' y' t' s'. atom x' \ (xs, Lam [y']. s') \ atom y' \ (x', xs, Lam [x']. t') \ Lam [x]. t = Lam [x']. t' \ Lam [y]. s = Lam [y']. s' - \ fll x t y s = fll x' t' y' s')) \ - lam2_rec faa fll xs (Lam [x]. t) (Lam [y]. s) = False" - apply (simp add: eqvt_def lam2_rec_graph_def) - apply (rule, perm_simp, rule, rule) - apply (case_tac x) - apply (rule_tac y="d" and c="(c, e)" in lam.strong_exhaust) - apply (rule_tac y="e" and c="(c, d)" in lam.strong_exhaust) - apply simp_all[3] apply (metis, metis, metis) - apply (rule_tac y="e" and c="(c, d)" in lam.strong_exhaust) - apply simp_all[3] apply (metis, metis, metis) - apply (rule_tac y="e" and c="(name, c, d)" in lam.strong_exhaust) - apply simp_all[2] apply (metis, metis) - unfolding fresh_star_def - apply (thin_tac "\faa fll xs n m. x = (faa, fll, xs, Var n, Var m) \ P") - apply (thin_tac "\faa fll xs n l r. x = (faa, fll, xs, Var n, App l r) \ P") - apply (thin_tac "\faa fll xs n xa t. x = (faa, fll, xs, Var n, Lam [xa]. t) \ P") - apply (thin_tac "\faa fll xs l1 r1 l2 r2. x = (faa, fll, xs, App l1 r1, App l2 r2) \ P") - apply (thin_tac "\faa fll xs l r n. x = (faa, fll, xs, App l r, Var n) \ P") - apply (thin_tac "\faa fll xs l r xa t. x = (faa, fll, xs, App l r, Lam [xa]. t) \ P") - apply (thin_tac "\faa fll xs xa t n. x = (faa, fll, xs, Lam [xa]. t, Var n) \ P") - apply (thin_tac "\faa fll xs xa t l1 r1. x = (faa, fll, xs, Lam [xa]. t, App l1 r1) \ P") - apply (drule_tac x="name" in meta_spec)+ - apply (drule_tac x="c" in meta_spec)+ - apply (drule_tac x="namea" in meta_spec)+ - apply (drule_tac x="lama" in meta_spec) - apply (drule_tac x="lama" in meta_spec) - apply (drule_tac x="lam" in meta_spec)+ - apply (drule_tac x="b" in meta_spec)+ - apply (drule_tac x="a" in meta_spec)+ - apply (case_tac "(\x' y' t' s'. atom x' \ (c, Lam [y']. s') \ - atom y' \ (x', c, Lam [x']. t') \ Lam [name]. lam = Lam [x']. t' \ - Lam [namea]. lama = Lam [y']. s' \ b name lam namea lama = b x' t' y' s')") - apply clarify - apply (simp) - apply (simp only: fresh_Pair_elim) - apply blast - apply (simp_all)[53] - apply clarify - apply metis - apply simp - done - -termination (eqvt) by lexicographic_order - -lemma lam_rec2_cong[fundef_cong]: - "(\s1 s2 s3 s4. l = App s1 s2 \ l2 = App s3 s4 \ faa s1 s2 s3 s4 = faa' s1 s2 s3 s4) \ - (\n t n' t'. l = Lam [n]. t \ l2 = Lam [n']. t' \ fll n t n' t' = fll' n t n' t') \ - lam2_rec faa fll xs l l2 = lam2_rec faa' fll' xs l l2" - apply (rule_tac y="l" and c="(xs, l2)" in lam.strong_exhaust) - apply (rule_tac y="l2" and c="(xs, l)" in lam.strong_exhaust) apply auto[3] - apply (rule_tac y="l2" and c="(xs, l)" in lam.strong_exhaust) apply auto[3] - apply (rule_tac y="l2" and c="(name, xs, l)" in lam.strong_exhaust) - apply auto[2] - apply clarify - apply (case_tac "(\x' y' t' s'. atom x' \ (xs, Lam [y']. s') \ - atom y' \ (x', xs, Lam [x']. t') \ Lam [name]. lam = Lam [x']. t' \ - Lam [namea]. lama = Lam [y']. s' \ fll name lam namea lama = fll x' t' y' s')") - unfolding fresh_star_def - apply (subst lam2_rec.simps) apply simp - apply (subst lam2_rec.simps) apply simp - apply metis - apply (subst lam2_rec.simps(10)) apply (simp add: fresh_star_def) - apply (subst lam2_rec.simps(10)) apply (simp_all add: fresh_star_def) - done - -nominal_primrec aux :: "lam \ lam \ (name \ name) list \ bool" - where -[simp del]: "aux l r xs = lam2_rec - (%t1 t2 t3 t4. (aux t1 t3 xs) \ (aux t2 t4 xs)) - (%x t y s. aux t s ((x, y) # xs)) xs l r" - unfolding eqvt_def aux_graph_def - apply (rule, perm_simp, rule, rule) - by pat_completeness auto - -termination (eqvt) - by (relation "measure (\(l, r, xs). size l + size r)") simp_all - -lemma aux_simps[simp]: - "aux (Var x) (Var y) xs = lookup x y xs" - "aux (App t1 t2) (App s1 s2) xs = (aux t1 s1 xs \ aux t2 s2 xs)" - "aux (Var x) (App t1 t2) xs = False" - "aux (Var x) (Lam [y].t) xs = False" - "aux (App t1 t2) (Var x) xs = False" - "aux (App t1 t2) (Lam [x].t) xs = False" - "aux (Lam [x].t) (Var y) xs = False" - "aux (Lam [x].t) (App t1 t2) xs = False" - "\atom x \ (s, xs); atom y \ (x, t, xs)\ \ aux (Lam [x].t) (Lam [y].s) xs = aux t s ((x, y) # xs)" - apply (subst aux.simps, simp) - apply (subst aux.simps, simp) - apply (subst aux.simps, simp) - apply (subst aux.simps, simp) - apply (subst aux.simps, simp) - apply (subst aux.simps, simp) - apply (subst aux.simps, simp) - apply (subst aux.simps, simp) - apply (subst aux.simps) - apply (subst lam2_rec.simps) - apply (rule, simp add: lam.fresh) - apply (rule, simp add: lam.fresh) - apply (intro allI impI) - apply (rule_tac x="(x, x', y, y', t, t', s, s', xs)" and ?'a="name" in obtain_fresh) - apply (rule_tac x="(a, x, x', y, y', t, t', s, s', xs)" and ?'a="name" in obtain_fresh) - apply (rule_tac s="aux ((atom x \ atom a) \ t) s ((a, y) # xs)" in trans) - apply (rule_tac s="(atom x \ atom a) \ aux t s ((x, y) # xs)" in trans) - apply (rule permute_pure[symmetric]) - apply (simp add: eqvts swap_fresh_fresh) - apply (simp add: lam.fresh fresh_at_base fresh_Pair_elim) - apply (rename_tac b) - apply (rule_tac s="aux ((atom x \ atom a) \ t) ((atom y \ atom b) \ s) ((a, b) # xs)" in trans) - apply (rule_tac s="(atom y \ atom b) \ aux ((atom x \ atom a) \ t) s ((a, y) # xs)" in trans) - apply (rule permute_pure[symmetric]) - apply (simp add: eqvts swap_fresh_fresh) - apply (simp add: lam.fresh fresh_at_base fresh_Pair_elim) - apply (subst permute_eqvt) - apply (simp add: eqvts swap_fresh_fresh) - apply (rule sym) - apply (rule_tac s="aux ((atom x' \ atom a) \ t') s' ((a, y') # xs)" in trans) - apply (rule_tac s="(atom x' \ atom a) \ aux t' s' ((x', y') # xs)" in trans) - apply (rule permute_pure[symmetric]) - apply (simp add: eqvts swap_fresh_fresh) - apply (simp add: lam.fresh fresh_at_base fresh_Pair_elim swap_fresh_fresh) - apply (rule_tac s="aux ((atom x' \ atom a) \ t') ((atom y' \ atom b) \ s') ((a, b) # xs)" in trans) - apply (rule_tac s="(atom y' \ atom b) \ aux ((atom x' \ atom a) \ t') s' ((a, y') # xs)" in trans) - apply (rule permute_pure[symmetric]) - apply (simp add: eqvts swap_fresh_fresh) - apply (simp add: lam.fresh fresh_at_base fresh_Pair_elim swap_fresh_fresh) - apply (subst permute_eqvt) - apply (simp add: eqvts swap_fresh_fresh) - apply (subgoal_tac "(atom x' \ atom a) \ t' = (atom x \ atom a) \ t") - apply (subgoal_tac "(atom y' \ atom b) \ s' = (atom y \ atom b) \ s") - apply simp - apply (subgoal_tac "Lam [y]. s = Lam [b]. ((atom y \ atom b) \ s)") - apply (subgoal_tac "Lam [y']. s' = Lam [b]. ((atom y' \ atom b) \ s')") - apply (auto simp add: fresh_Pair_elim Abs1_eq_iff)[1] - apply (rule sym) - apply (simp add: Abs1_eq_iff fresh_Pair_elim fresh_at_base swap_commute) - apply (rule sym) - apply (simp add: Abs1_eq_iff fresh_Pair_elim fresh_at_base swap_commute) - apply (subgoal_tac "Lam [x]. t = Lam [a]. ((atom x \ atom a) \ t)") - apply (subgoal_tac "Lam [x']. t' = Lam [a]. ((atom x' \ atom a) \ t')") - apply (auto simp add: fresh_Pair_elim Abs1_eq_iff)[1] - apply (rule sym) - apply (simp add: Abs1_eq_iff fresh_Pair_elim fresh_at_base swap_commute) - apply (rule sym) - apply (simp add: Abs1_eq_iff fresh_Pair_elim fresh_at_base swap_commute) - apply (rule refl) - done - -lemma aux_induct: "\\xs n m. P xs (Var n) (Var m); \xs n l r. P xs (Var n) (App l r); - \xs n x t. P xs (Var n) (Lam [x]. t); - \xs l r n. P xs (App l r) (Var n); - (\xs l1 r1 l2 r2. P xs l1 l2 \ P xs r1 r2 \ P xs (App l1 r1) (App l2 r2)); - \xs l r x t. P xs (App l r) (Lam [x]. t); - \xs x t n. P xs (Lam [x]. t) (Var n); - \xs x t l1 r1. P xs (Lam [x]. t) (App l1 r1); - \x xs y s t. - atom x \ (xs, Lam [y]. s) \ - atom y \ (x, xs, Lam [x]. t) \ P ((x, y) # xs) t s \ P xs (Lam [x]. t) (Lam [y]. s)\ -\ P (a :: (name \ name) list) b c" - apply (induction_schema) - apply (rule_tac y="b" and c="(a, c)" in lam.strong_exhaust) - apply (rule_tac y="c" and c="(name, a, b)" in lam.strong_exhaust) - apply simp_all[3] apply (metis) - apply (rule_tac y="c" and c="(name, a, b)" in lam.strong_exhaust) - apply simp_all[3] apply (metis, metis, metis) - apply (rule_tac y="c" and c="(name, a, b)" in lam.strong_exhaust) - apply simp_all[3] apply (metis) - apply (simp add: fresh_star_def) - apply metis - apply lexicographic_order - done - -nominal_primrec swapequal :: "lam \ lam \ (name \ name) list \ bool" where - "swapequal l r [] \ l = r" -| "atom x \ (l, r, hl, hr, t) \ - swapequal l r ((hl, hr) # t) \ swapequal ((hl \ x) \ l) ((hr \ x) \ r) t" - unfolding eqvt_def swapequal_graph_def - apply (rule, perm_simp, rule, rule TrueI) - apply (case_tac x) - apply (case_tac c) - apply metis - apply (case_tac aa) - apply (rename_tac l r lst h t hl hr) - apply (rule_tac x="(l, r, hl, hr, t)" and ?'a="name" in obtain_fresh) - apply simp - apply simp - apply simp - apply clarify - apply (rule_tac s="(x \ xa) \ swapequal_sumC ((hla \ x) \ la, (hra \ x) \ ra, ta)" in trans) - apply (simp only: permute_pure) - apply (simp add: eqvt_at_def fresh_Pair_elim) - apply (simp add: flip_fresh_fresh) - apply (subgoal_tac "(x \ xa) \ (hla \ x) \ la = (hla \ xa) \ la") - apply (subgoal_tac "(x \ xa) \ (hra \ x) \ ra = (hra \ xa) \ ra") - apply simp - apply (subst permute_eqvt) - apply (simp add: flip_fresh_fresh flip_eqvt) - apply (subst permute_eqvt) - apply (simp add: flip_fresh_fresh flip_eqvt) - done - -termination (eqvt) by lexicographic_order - -lemma var_eq_swapequal: "atom ab \ xs \ swapequal (Var ab) (Var ab) xs" - apply (induct xs) - apply simp - apply (case_tac a) - apply (simp add: fresh_Cons) - apply (rule_tac x="(ab, aa, b, xs)" and ?'a="name" in obtain_fresh) - apply (subst swapequal.simps) - apply (simp add: fresh_Pair lam.fresh) - apply (simp add: fresh_Pair_elim) - by (metis flip_at_base_simps(3) fresh_Pair fresh_at_base(2)) - -lemma var_neq_swapequal: - "atom ab \ xs \ ab \ m \ \ swapequal (Var ab) (Var m) xs" - "atom ab \ xs \ ab \ m \ \ swapequal (Var m) (Var ab) xs" - apply (induct xs arbitrary: m) - apply simp_all[2] - apply (case_tac [!] a) - apply (simp_all add: fresh_Cons) - apply (rule_tac [!] x="(ab, aa, b, m, xs)" and ?'a="name" in obtain_fresh) - apply (subst swapequal.simps) - apply (auto simp add: fresh_Pair lam.fresh)[1] - apply (elim conjE) - apply (simp add: fresh_Pair_elim fresh_at_base permute_flip_at) - apply (subst swapequal.simps) - apply (auto simp add: fresh_Pair lam.fresh)[1] - apply (elim conjE) - apply (simp add: fresh_Pair_elim fresh_at_base permute_flip_at) - done - -lemma lookup_swapequal: "lookup n m xs = swapequal (Var n) (Var m) xs" - apply (induct xs arbitrary: m n) - apply simp - apply (case_tac a) - apply (rule_tac x="(n, m, aa, b, xs)" and ?'a="name" in obtain_fresh) - apply simp - apply (subst swapequal.simps) - apply (simp add: fresh_Pair lam.fresh fresh_Nil) - by (metis (hide_lams, mono_tags) flip_at_base_simps(3) flip_at_simps(1) fresh_Pair fresh_at_base(2) lam.perm_simps(1) var_eq_swapequal var_neq_swapequal(1) var_neq_swapequal(2)) - -lemma swapequal_reorder: " - a \ x \ a \ y \ b \ x \ b \ y \ - swapequal t s ((x, y) # (a, b) # xs) = swapequal t s ((a, b) # (x, y) # xs)" - apply (rule_tac x="(a, b, x, y, t, s, xs)" and ?'a="name" in obtain_fresh) - apply (rule_tac x="(a, b, x, y, t, s, xs, aa)" and ?'a="name" in obtain_fresh) - apply (rename_tac f g) - apply (simp add: fresh_Pair_elim fresh_at_base) - apply (subst swapequal.simps) - apply (auto simp add: fresh_Pair fresh_Cons fresh_at_base)[1] - apply (subgoal_tac "(x \ f) \ atom g \ t") - apply (subst swapequal.simps) - apply (simp add: fresh_Pair fresh_Cons fresh_permute_left) - apply rule apply assumption - apply (simp add: flip_at_base_simps fresh_at_base flip_def) - apply (subst swapequal.simps) - apply (simp add: fresh_Pair fresh_Cons fresh_at_base) - apply rule apply (rotate_tac 12) - apply assumption - apply (simp add: fresh_Pair fresh_Cons fresh_at_base) - apply (subst swapequal.simps) - apply (simp add: fresh_Pair fresh_Cons fresh_at_base fresh_permute_left) - apply (subgoal_tac "(a \ g) \ atom f \ t") - apply rule apply assumption - apply (simp add: flip_at_base_simps fresh_at_base flip_def) - apply (simp add: flip_at_base_simps fresh_at_base flip_def) - apply (subgoal_tac "(a \ g) \ (x \ f) \ t = (x \ f) \ (a \ g) \ t") - apply (subgoal_tac "(b \ g) \ (y \ f) \ s = (y \ f) \ (b \ g) \ s") - apply simp - apply (subst permute_eqvt) apply (simp add: flip_eqvt) - apply (subst permute_eqvt) apply (simp add: flip_eqvt) - apply (simp add: flip_at_base_simps fresh_at_base flip_def) - done - -lemma swapequal_lambda: - assumes "distinct xs \ atom x \ xs \ atom y \ xs" - shows "swapequal (Lam [x]. t) (Lam [y]. s) xs = swapequal t s ((x, y) # xs)" - using assms - apply (induct xs arbitrary: t s x y) - apply (rule_tac x="(x, y, t, s)" and ?'a="name" in obtain_fresh) - apply (simp add: fresh_Pair_elim fresh_Nil) - apply (subst swapequal.simps) - apply (simp add: fresh_Pair fresh_Nil) - apply auto[1] - apply simp - apply (subgoal_tac "[[atom x]]lst. t = [[atom a]]lst. ((x \ a) \ t)") - apply (subgoal_tac "[[atom y]]lst. s = [[atom a]]lst. ((y \ a) \ s)") - apply simp - apply (simp add: Abs1_eq_iff) - apply (auto simp add: Abs1_eq_iff flip_def fresh_at_base)[2] - apply (simp add: fresh_permute_left) - apply (simp add: fresh_permute_left) - apply clarify - apply (simp add: fresh_Cons fresh_Pair fresh_at_base) - apply clarify - apply (simp add: swapequal_reorder) - apply (rule_tac x="(x, y, t, s, a, b, xs)" and ?'a="name" in obtain_fresh) - apply (rename_tac f) - apply (subst (2) swapequal.simps) - apply (auto simp add: lam.fresh fresh_Pair fresh_at_base fresh_Cons)[1] - apply (subst swapequal.simps) - apply (auto simp add: lam.fresh fresh_Pair fresh_at_base fresh_Cons)[1] - apply (simp add: flip_def fresh_Pair_elim fresh_at_base) - done - -lemma distinct_swapequal: "\p q. p \ l \ q \ r \ \swapequal l r xs" - apply (induct xs rule:swapequal.induct) - apply auto[1] - apply (simp add: fresh_Pair_elim) - apply (subgoal_tac "\(p\perm) q\perm. p \ (hl \ x) \ l \ q \ (hr \ x) \ r") - apply simp - apply (intro allI) - apply (drule_tac x="p + (hl \ x)" in spec) - apply (drule_tac x="q + (hr \ x)" in spec) - apply simp - done - -lemma swapequal_app: "(swapequal l1 l2 xs \ swapequal r1 r2 xs) = swapequal (App l1 r1) (App l2 r2) xs" - apply (induct xs arbitrary: l1 l2 r1 r2) - apply simp - apply (case_tac a) - apply simp - apply (rule_tac x="(l1, l2, r1, r2, aa, b, xs)" and ?'a="name" in obtain_fresh) - apply (simp add: fresh_Pair_elim) - apply (subst swapequal.simps) apply (auto simp add: fresh_Pair)[1] - apply (subst swapequal.simps) apply (auto simp add: fresh_Pair lam.fresh) - done - -lemma [simp]: "distinct (map fst xs) \ distinct xs" - by (induct xs) auto - -lemma [simp]: - "atom x \ xs \ x \ fst ` set xs" - "atom x \ xs \ x \ snd ` set xs" - apply (induct xs) - apply simp_all - apply (case_tac [!] a) - apply (simp_all add: fresh_Cons fresh_Pair fresh_at_base) - done - -lemma aux_alphaish: - assumes "distinct (map fst xs @ map snd xs)" - shows "aux x y xs \ swapequal x y xs" - using assms - apply (induct xs x y rule: aux_induct) - apply (simp add: lookup_swapequal) - apply (simp, rule distinct_swapequal, simp)+ - apply (simp add: swapequal_app) - apply (simp, rule distinct_swapequal, simp)+ - apply (simp add: fresh_Pair_elim lam.fresh fresh_at_base conjE) - apply (elim conjE) - apply (simp add: fresh_Pair_elim lam.fresh fresh_at_base) - apply (subgoal_tac "x \ fst ` set xs \ - x \ snd ` set xs \ y \ snd ` set xs \ y \ fst ` set xs") - apply (subst swapequal_lambda) - apply auto[2] - apply simp - done - -lemma aux_is_alpha: - "aux x y [] \ (x = y)" - by (simp_all add: supp_Nil aux_alphaish) - -end - - -