# HG changeset patch # User Christian Urban # Date 1287182754 -3600 # Node ID a8f5611dbd6541fbe339db8ef6dcd17b9d7ae935 # Parent c9deccd1247675bd6f39739e1fbba19fa16e612c more cleaning diff -r c9deccd12476 -r a8f5611dbd65 Nominal/FSet.thy --- a/Nominal/FSet.thy Fri Oct 15 17:37:44 2010 +0100 +++ b/Nominal/FSet.thy Fri Oct 15 23:45:54 2010 +0100 @@ -54,13 +54,13 @@ "rsp_fold f \ \u v w. (f u (f v w) = f v (f u w))" primrec - ffold_raw :: "('a \ 'b \ 'b) \ 'b \ 'a list \ 'b" + ffold_list :: "('a \ 'b \ 'b) \ 'b \ 'a list \ 'b" where - "ffold_raw f z [] = z" -| "ffold_raw f z (a # xs) = + "ffold_list f z [] = z" +| "ffold_list f z (a # xs) = (if (rsp_fold f) then - if a \ set xs then ffold_raw f z xs - else f a (ffold_raw f z xs) + if a \ set xs then ffold_list f z xs + else f a (ffold_list f z xs) else z)" @@ -196,14 +196,14 @@ shows "(op = ===> op \ ===> op \) filter filter" by simp -lemma memb_commute_ffold_raw: - "rsp_fold f \ h \ set b \ ffold_raw f z b = f h (ffold_raw f z (removeAll h b))" +lemma memb_commute_ffold_list: + "rsp_fold f \ h \ set b \ ffold_list f z b = f h (ffold_list f z (removeAll h b))" apply (induct b) apply (auto simp add: rsp_fold_def) done -lemma ffold_raw_rsp_pre: - "set a = set b \ ffold_raw f z a = ffold_raw f z b" +lemma ffold_list_rsp_pre: + "set a = set b \ ffold_list f z a = ffold_list f z b" apply (induct a arbitrary: b) apply (simp) apply (simp (no_asm_use)) @@ -212,18 +212,18 @@ apply (rule_tac [!] conjI) apply (rule_tac [!] impI) apply (metis insert_absorb) - apply (metis List.insert_def List.set.simps(2) List.set_insert ffold_raw.simps(2)) - apply (metis Diff_insert_absorb insertI1 memb_commute_ffold_raw set_removeAll) + apply (metis List.insert_def List.set.simps(2) List.set_insert ffold_list.simps(2)) + apply (metis Diff_insert_absorb insertI1 memb_commute_ffold_list set_removeAll) apply(drule_tac x="removeAll a1 b" in meta_spec) apply(auto) apply(drule meta_mp) apply(blast) - by (metis List.set.simps(2) emptyE ffold_raw.simps(2) in_listsp_conv_set listsp.simps mem_def) + by (metis List.set.simps(2) emptyE ffold_list.simps(2) in_listsp_conv_set listsp.simps mem_def) -lemma ffold_raw_rsp [quot_respect]: - shows "(op = ===> op = ===> op \ ===> op =) ffold_raw ffold_raw" +lemma ffold_list_rsp [quot_respect]: + shows "(op = ===> op = ===> op \ ===> op =) ffold_list ffold_list" unfolding fun_rel_def - by(auto intro: ffold_raw_rsp_pre) + by(auto intro: ffold_list_rsp_pre) lemma concat_rsp_pre: assumes a: "list_all2 op \ x x'" @@ -266,6 +266,10 @@ qed + +section {* Quotient definitions for fsets *} + + subsection {* Finite sets are a bounded, distributive lattice with minus *} instantiation fset :: (type) "{bounded_lattice_bot, distrib_lattice, minus}" @@ -366,10 +370,6 @@ end - -section {* Quotient definitions for fsets *} - - quotient_definition "finsert :: 'a \ 'a fset \ 'a fset" is "Cons" @@ -411,7 +411,7 @@ quotient_definition "ffold :: ('a \ 'b \ 'b) \ 'b \ 'a fset \ 'b" - is ffold_raw + is ffold_list quotient_definition "fconcat :: ('a fset) fset \ 'a fset" @@ -422,15 +422,13 @@ is filter -subsection {* Compositional Respectfulness and Preservation *} +section {* Compositional respectfulness and preservation lemmas *} -lemma [quot_respect]: "(list_all2 op \ OOO op \) [] []" +lemma Nil_rsp2 [quot_respect]: + shows "(list_all2 op \ OOO op \) Nil Nil" by (fact compose_list_refl) -lemma [quot_preserve]: "(abs_fset \ map f) [] = abs_fset []" - by simp - -lemma [quot_respect]: +lemma Cons_rsp2 [quot_respect]: shows "(op \ ===> list_all2 op \ OOO op \ ===> list_all2 op \ OOO op \) Cons Cons" apply auto apply (rule_tac b="x # b" in pred_compI) @@ -439,12 +437,16 @@ apply auto done -lemma [quot_preserve]: +lemma map_prs [quot_preserve]: + shows "(abs_fset \ map f) [] = abs_fset []" + by simp + +lemma finsert_rsp [quot_preserve]: "(rep_fset ---> (map rep_fset \ rep_fset) ---> (abs_fset \ map abs_fset)) op # = finsert" by (simp add: fun_eq_iff Quotient_abs_rep[OF Quotient_fset] abs_o_rep[OF Quotient_fset] map_id finsert_def) -lemma [quot_preserve]: +lemma funion_rsp [quot_preserve]: "((map rep_fset \ rep_fset) ---> (map rep_fset \ rep_fset) ---> (abs_fset \ map abs_fset)) op @ = funion" by (simp add: fun_eq_iff Quotient_abs_rep[OF Quotient_fset] abs_o_rep[OF Quotient_fset] map_id sup_fset_def) @@ -487,7 +489,7 @@ done lemma [quot_respect]: - "(list_all2 op \ OOO op \ ===> list_all2 op \ OOO op \ ===> list_all2 op \ OOO op \) op @ op @" + "(list_all2 op \ OOO op \ ===> list_all2 op \ OOO op \ ===> list_all2 op \ OOO op \) append append" proof (intro fun_relI, elim pred_compE) fix x y z w x' z' y' w' :: "'a list list" assume a:"list_all2 op \ x x'" @@ -507,125 +509,6 @@ -section {* Cases *} - - -lemma fset_raw_strong_cases: - obtains "xs = []" - | x ys where "\ memb x ys" and "xs \ x # ys" -proof (induct xs arbitrary: x ys) - case Nil - then show thesis by simp -next - case (Cons a xs) - have a: "\xs = [] \ thesis; \x ys. \\ memb x ys; xs \ x # ys\ \ thesis\ \ thesis" by fact - have b: "\x' ys'. \\ memb x' ys'; a # xs \ x' # ys'\ \ thesis" by fact - have c: "xs = [] \ thesis" using b unfolding memb_def - by (metis in_set_conv_nth less_zeroE list.size(3) list_eq.simps member_set) - have "\x ys. \\ memb x ys; xs \ x # ys\ \ thesis" - proof - - fix x :: 'a - fix ys :: "'a list" - assume d:"\ memb x ys" - assume e:"xs \ x # ys" - show thesis - proof (cases "x = a") - assume h: "x = a" - then have f: "\ memb a ys" using d by simp - have g: "a # xs \ a # ys" using e h by auto - show thesis using b f g by simp - next - assume h: "x \ a" - then have f: "\ memb x (a # ys)" using d unfolding memb_def by auto - have g: "a # xs \ x # (a # ys)" using e h by auto - show thesis using b f g by simp - qed - qed - then show thesis using a c by blast -qed - - -text {* alternate formulation with a different decomposition principle - and a proof of equivalence *} - -inductive - list_eq2 -where - "list_eq2 (a # b # xs) (b # a # xs)" -| "list_eq2 [] []" -| "list_eq2 xs ys \ list_eq2 ys xs" -| "list_eq2 (a # a # xs) (a # xs)" -| "list_eq2 xs ys \ list_eq2 (a # xs) (a # ys)" -| "\list_eq2 xs1 xs2; list_eq2 xs2 xs3\ \ list_eq2 xs1 xs3" - -lemma list_eq2_refl: - shows "list_eq2 xs xs" - by (induct xs) (auto intro: list_eq2.intros) - -lemma cons_delete_list_eq2: - shows "list_eq2 (a # (removeAll a A)) (if memb a A then A else a # A)" - apply (induct A) - apply (simp add: memb_def list_eq2_refl) - apply (case_tac "memb a (aa # A)") - apply (simp_all only: memb_def) - apply (case_tac [!] "a = aa") - apply (simp_all) - apply (case_tac "memb a A") - apply (auto simp add: memb_def)[2] - apply (metis list_eq2.intros(3) list_eq2.intros(4) list_eq2.intros(5) list_eq2.intros(6)) - apply (metis list_eq2.intros(1) list_eq2.intros(5) list_eq2.intros(6)) - apply (auto simp add: list_eq2_refl memb_def) - done - -lemma memb_delete_list_eq2: - assumes a: "memb e r" - shows "list_eq2 (e # removeAll e r) r" - using a cons_delete_list_eq2[of e r] - by simp - -lemma list_eq2_equiv: - "(l \ r) \ (list_eq2 l r)" -proof - show "list_eq2 l r \ l \ r" by (induct rule: list_eq2.induct) auto -next - { - fix n - assume a: "card_list l = n" and b: "l \ r" - have "list_eq2 l r" - using a b - proof (induct n arbitrary: l r) - case 0 - have "card_list l = 0" by fact - then have "\x. \ memb x l" unfolding card_list_def memb_def by auto - then have z: "l = []" unfolding memb_def by auto - then have "r = []" using `l \ r` by simp - then show ?case using z list_eq2_refl by simp - next - case (Suc m) - have b: "l \ r" by fact - have d: "card_list l = Suc m" by fact - then have "\a. memb a l" - apply(simp add: card_list_def memb_def) - apply(drule card_eq_SucD) - apply(blast) - done - then obtain a where e: "memb a l" by auto - then have e': "memb a r" using list_eq.simps[simplified memb_def[symmetric], of l r] b - unfolding memb_def by auto - have f: "card_list (removeAll a l) = m" using e d by (simp add: card_list_def memb_def) - have g: "removeAll a l \ removeAll a r" using removeAll_rsp b by simp - have "list_eq2 (removeAll a l) (removeAll a r)" by (rule Suc.hyps[OF f g]) - then have h: "list_eq2 (a # removeAll a l) (a # removeAll a r)" by (rule list_eq2.intros(5)) - have i: "list_eq2 l (a # removeAll a l)" - by (rule list_eq2.intros(3)[OF memb_delete_list_eq2[OF e]]) - have "list_eq2 l (a # removeAll a r)" by (rule list_eq2.intros(6)[OF i h]) - then show ?case using list_eq2.intros(6)[OF _ memb_delete_list_eq2[OF e']] by simp - qed - } - then show "l \ r \ list_eq2 l r" by blast -qed - - section {* Lifted theorems *} @@ -836,18 +719,10 @@ shows "xs |\| ys = (\x. x |\| xs \ x |\| ys)" by (descending) (auto simp add: sub_list_def memb_def) -(* FIXME: no type ord *) -(* -lemma fsubset_finsert: - shows "(finsert x xs) |\| ys \ x |\| ys \ xs |\| ys" - by (descending) (simp add: sub_list_def memb_def) -*) - lemma fsubseteq_fempty: shows "xs |\| {||} \ xs = {||}" by (descending) (simp add: sub_list_def) -(* also problem with ord *) lemma not_fsubset_fnil: shows "\ xs |\| {||}" by (metis fset_simps(1) fsubset_set not_psubset_empty) @@ -1043,7 +918,7 @@ lemma fin_commute_ffold: "\rsp_fold f; h |\| b\ \ ffold f z b = f h (ffold f z (fdelete h b))" - by (descending) (simp add: memb_def memb_commute_ffold_raw) + by (descending) (simp add: memb_def memb_commute_ffold_list) subsection {* Choice in fsets *} @@ -1057,38 +932,92 @@ by (auto simp add: memb_def Ball_def) -(* FIXME: is that in any way useful *) +section {* Induction and Cases rules for fsets *} + +lemma fset_exhaust [case_names fempty finsert, cases type: fset]: + assumes fempty_case: "S = {||} \ P" + and finsert_case: "\x S'. S = finsert x S' \ P" + shows "P" + using assms by (lifting list.exhaust) +lemma fset_induct [case_names fempty finsert]: + assumes fempty_case: "P {||}" + and finsert_case: "\x S. P S \ P (finsert x S)" + shows "P S" + using assms + by (descending) (blast intro: list.induct) + +lemma fset_induct_stronger [case_names fempty finsert, induct type: fset]: + assumes fempty_case: "P {||}" + and finsert_case: "\x S. \x |\| S; P S\ \ P (finsert x S)" + shows "P S" +proof(induct S rule: fset_induct) + case fempty + show "P {||}" using fempty_case by simp +next + case (finsert x S) + have "P S" by fact + then show "P (finsert x S)" using finsert_case + by (cases "x |\| S") (simp_all) +qed +lemma fcard_induct: + assumes fempty_case: "P {||}" + and fcard_Suc_case: "\S T. Suc (fcard S) = (fcard T) \ P S \ P T" + shows "P S" +proof (induct S) + case fempty + show "P {||}" by (rule fempty_case) +next + case (finsert x S) + have h: "P S" by fact + have "x |\| S" by fact + then have "Suc (fcard S) = fcard (finsert x S)" + using fcard_suc by auto + then show "P (finsert x S)" + using h fcard_Suc_case by simp +qed -section {* Induction and Cases rules for fsets *} +lemma fset_raw_strong_cases: + obtains "xs = []" + | x ys where "\ memb x ys" and "xs \ x # ys" +proof (induct xs arbitrary: x ys) + case Nil + then show thesis by simp +next + case (Cons a xs) + have a: "\xs = [] \ thesis; \x ys. \\ memb x ys; xs \ x # ys\ \ thesis\ \ thesis" by fact + have b: "\x' ys'. \\ memb x' ys'; a # xs \ x' # ys'\ \ thesis" by fact + have c: "xs = [] \ thesis" using b unfolding memb_def + by (metis in_set_conv_nth less_zeroE list.size(3) list_eq.simps member_set) + have "\x ys. \\ memb x ys; xs \ x # ys\ \ thesis" + proof - + fix x :: 'a + fix ys :: "'a list" + assume d:"\ memb x ys" + assume e:"xs \ x # ys" + show thesis + proof (cases "x = a") + assume h: "x = a" + then have f: "\ memb a ys" using d by simp + have g: "a # xs \ a # ys" using e h by auto + show thesis using b f g by simp + next + assume h: "x \ a" + then have f: "\ memb x (a # ys)" using d unfolding memb_def by auto + have g: "a # xs \ x # (a # ys)" using e h by auto + show thesis using b f g by simp + qed + qed + then show thesis using a c by blast +qed + lemma fset_strong_cases: obtains "xs = {||}" | x ys where "x |\| ys" and "xs = finsert x ys" by (lifting fset_raw_strong_cases) -lemma fset_exhaust[case_names fempty finsert, cases type: fset]: - shows "\S = {||} \ P; \x S'. S = finsert x S' \ P\ \ P" - by (lifting list.exhaust) - -lemma fset_induct_weak[case_names fempty finsert]: - shows "\P {||}; \x S. P S \ P (finsert x S)\ \ P S" - by (lifting list.induct) - -lemma fset_induct[case_names fempty finsert, induct type: fset]: - assumes prem1: "P {||}" - and prem2: "\x S. \x |\| S; P S\ \ P (finsert x S)" - shows "P S" -proof(induct S rule: fset_induct_weak) - case fempty - show "P {||}" by (rule prem1) -next - case (finsert x S) - have asm: "P S" by fact - show "P (finsert x S)" - by (cases "x |\| S") (simp_all add: asm prem2) -qed lemma fset_induct2: "P {||} {||} \ @@ -1097,24 +1026,140 @@ (\x xs y ys. \P xs ys; x |\| xs; y |\| ys\ \ P (finsert x xs) (finsert y ys)) \ P xsa ysa" apply (induct xsa arbitrary: ysa) - apply (induct_tac x rule: fset_induct) + apply (induct_tac x rule: fset_induct_stronger) apply simp_all - apply (induct_tac xa rule: fset_induct) + apply (induct_tac xa rule: fset_induct_stronger) apply simp_all done -lemma fset_fcard_induct: - assumes a: "P {||}" - and b: "\xs ys. Suc (fcard xs) = (fcard ys) \ P xs \ P ys" - shows "P zs" -proof (induct zs) - show "P {||}" by (rule a) + + +subsection {* alternate formulation with a different decomposition principle + and a proof of equivalence *} + +inductive + list_eq2 ("_ \2 _") +where + "(a # b # xs) \2 (b # a # xs)" +| "[] \2 []" +| "xs \2 ys \ ys \2 xs" +| "(a # a # xs) \2 (a # xs)" +| "xs \2 ys \ (a # xs) \2 (a # ys)" +| "\xs1 \2 xs2; xs2 \2 xs3\ \ xs1 \2 xs3" + +lemma list_eq2_refl: + shows "xs \2 xs" + by (induct xs) (auto intro: list_eq2.intros) + +lemma list_eq2_set: + assumes a: "xs \2 ys" + shows "set xs = set ys" +using a by (induct) (auto) + +lemma list_eq2_card: + assumes a: "xs \2 ys" + shows "card_list xs = card_list ys" +using a +apply(induct) +apply(auto simp add: card_list_def) +apply(metis insert_commute) +apply(metis list_eq2_set) +done + +lemma list_eq2_equiv1: + assumes a: "xs \2 ys" + shows "xs \ ys" +using a by (induct) (auto) + + +lemma cons_delete_list_eq2: + shows "(a # (removeAll a A)) \2 (if memb a A then A else a # A)" + apply (induct A) + apply (simp add: memb_def list_eq2_refl) + apply (case_tac "memb a (aa # A)") + apply (simp_all only: memb_def) + apply (case_tac [!] "a = aa") + apply (simp_all) + apply (case_tac "memb a A") + apply (auto simp add: memb_def)[2] + apply (metis list_eq2.intros(3) list_eq2.intros(4) list_eq2.intros(5) list_eq2.intros(6)) + apply (metis list_eq2.intros(1) list_eq2.intros(5) list_eq2.intros(6)) + apply (auto simp add: list_eq2_refl memb_def) + done + +lemma memb_delete_list_eq2: + assumes a: "memb e r" + shows "(e # removeAll e r) \2 r" + using a cons_delete_list_eq2[of e r] + by simp + +(* +lemma list_eq2_equiv2: + assumes a: "xs \ ys" + shows "xs \2 ys" +using a +apply(induct xs arbitrary: ys taking: "card o set" rule: measure_induct) +apply(simp) +apply(case_tac x) +apply(simp) +apply(auto intro: list_eq2.intros)[1] +apply(simp) +apply(case_tac "a \ set list") +apply(simp add: insert_absorb) +apply(drule_tac x="removeAll a ys" in spec) +apply(drule mp) +apply(simp) +apply(subgoal_tac "0 < card (set ys)") +apply(simp) +apply(metis length_pos_if_in_set length_remdups_card_conv set_remdups) +apply(simp) +apply(clarify) +apply(drule_tac x="removeAll a list" in spec) +apply(drule mp) +apply(simp) +oops +*) + +lemma list_eq2_equiv: + "(l \ r) \ (list_eq2 l r)" +proof + show "list_eq2 l r \ l \ r" by (induct rule: list_eq2.induct) auto next - fix x :: 'a and zs :: "'a fset" - assume h: "P zs" - assume "x |\| zs" - then have H1: "Suc (fcard zs) = fcard (finsert x zs)" using fcard_suc by auto - then show "P (finsert x zs)" using b h by simp + { + fix n + assume a: "card_list l = n" and b: "l \ r" + have "l \2 r" + using a b + proof (induct n arbitrary: l r) + case 0 + have "card_list l = 0" by fact + then have "\x. \ memb x l" unfolding card_list_def memb_def by auto + then have z: "l = []" unfolding memb_def by auto + then have "r = []" using `l \ r` by simp + then show ?case using z list_eq2_refl by simp + next + case (Suc m) + have b: "l \ r" by fact + have d: "card_list l = Suc m" by fact + then have "\a. memb a l" + apply(simp add: card_list_def memb_def) + apply(drule card_eq_SucD) + apply(blast) + done + then obtain a where e: "memb a l" by auto + then have e': "memb a r" using list_eq.simps[simplified memb_def[symmetric], of l r] b + unfolding memb_def by auto + have f: "card_list (removeAll a l) = m" using e d by (simp add: card_list_def memb_def) + have g: "removeAll a l \ removeAll a r" using removeAll_rsp b by simp + have "list_eq2 (removeAll a l) (removeAll a r)" by (rule Suc.hyps[OF f g]) + then have h: "list_eq2 (a # removeAll a l) (a # removeAll a r)" by (rule list_eq2.intros(5)) + have i: "list_eq2 l (a # removeAll a l)" + by (rule list_eq2.intros(3)[OF memb_delete_list_eq2[OF e]]) + have "list_eq2 l (a # removeAll a r)" by (rule list_eq2.intros(6)[OF i h]) + then show ?case using list_eq2.intros(6)[OF _ memb_delete_list_eq2[OF e']] by simp + qed + } + then show "l \ r \ list_eq2 l r" by blast qed @@ -1144,14 +1189,6 @@ by (lifting list_eq2.induct[simplified list_eq2_equiv[symmetric]]) - -section {* lemmas transferred from Finite_Set theory *} - -text {* finiteness for finite sets holds *} - - - - lemma list_all2_refl: assumes q: "equivp R" shows "(list_all2 R) r r" @@ -1231,5 +1268,6 @@ no_notation list_eq (infix "\" 50) +and list_eq2 (infix "\2" 50) end