diff -r a0c7290a4e27 -r 27cdc0a3a763 Nominal/FSet.thy --- a/Nominal/FSet.thy Wed Apr 21 12:25:52 2010 +0200 +++ b/Nominal/FSet.thy Mon Apr 26 10:01:13 2010 +0200 @@ -71,6 +71,85 @@ else f a (ffold_raw f z A) else z)" +text {* Composition Quotient *} + +lemma list_rel_refl: + shows "(list_rel op \) r r" + by (rule list_rel_refl) (metis equivp_def fset_equivp) + +lemma compose_list_refl: + shows "(list_rel op \ OOO op \) r r" +proof + show c: "list_rel op \ r r" by (rule list_rel_refl) + have d: "r \ r" by (rule equivp_reflp[OF fset_equivp]) + show b: "(op \ OO list_rel op \) r r" by (rule pred_compI) (rule d, rule c) +qed + +lemma Quotient_fset_list: + shows "Quotient (list_rel op \) (map abs_fset) (map rep_fset)" + by (fact list_quotient[OF Quotient_fset]) + +lemma set_in_eq: "(\e. ((e \ A) \ (e \ B))) \ A = B" + by (rule eq_reflection) auto + +lemma map_rel_cong: "b \ ba \ map f b \ map f ba" + unfolding list_eq.simps + by (simp only: set_map set_in_eq) + +lemma quotient_compose_list[quot_thm]: + shows "Quotient ((list_rel op \) OOO (op \)) + (abs_fset \ (map abs_fset)) ((map rep_fset) \ rep_fset)" + unfolding Quotient_def comp_def +proof (intro conjI allI) + fix a r s + show "abs_fset (map abs_fset (map rep_fset (rep_fset a))) = a" + by (simp add: abs_o_rep[OF Quotient_fset] Quotient_abs_rep[OF Quotient_fset] map_id) + have b: "list_rel op \ (map rep_fset (rep_fset a)) (map rep_fset (rep_fset a))" + by (rule list_rel_refl) + have c: "(op \ OO list_rel op \) (map rep_fset (rep_fset a)) (map rep_fset (rep_fset a))" + by (rule, rule equivp_reflp[OF fset_equivp]) (rule b) + show "(list_rel op \ OOO op \) (map rep_fset (rep_fset a)) (map rep_fset (rep_fset a))" + by (rule, rule list_rel_refl) (rule c) + show "(list_rel op \ OOO op \) r s = ((list_rel op \ OOO op \) r r \ + (list_rel op \ OOO op \) s s \ abs_fset (map abs_fset r) = abs_fset (map abs_fset s))" + proof (intro iffI conjI) + show "(list_rel op \ OOO op \) r r" by (rule compose_list_refl) + show "(list_rel op \ OOO op \) s s" by (rule compose_list_refl) + next + assume a: "(list_rel op \ OOO op \) r s" + then have b: "map abs_fset r \ map abs_fset s" proof (elim pred_compE) + fix b ba + assume c: "list_rel op \ r b" + assume d: "b \ ba" + assume e: "list_rel op \ ba s" + have f: "map abs_fset r = map abs_fset b" + using Quotient_rel[OF Quotient_fset_list] c by blast + have "map abs_fset ba = map abs_fset s" + using Quotient_rel[OF Quotient_fset_list] e by blast + then have g: "map abs_fset s = map abs_fset ba" by simp + then show "map abs_fset r \ map abs_fset s" using d f map_rel_cong by simp + qed + then show "abs_fset (map abs_fset r) = abs_fset (map abs_fset s)" + using Quotient_rel[OF Quotient_fset] by blast + next + assume a: "(list_rel op \ OOO op \) r r \ (list_rel op \ OOO op \) s s + \ abs_fset (map abs_fset r) = abs_fset (map abs_fset s)" + then have s: "(list_rel op \ OOO op \) s s" by simp + have d: "map abs_fset r \ map abs_fset s" + by (subst Quotient_rel[OF Quotient_fset]) (simp add: a) + have b: "map rep_fset (map abs_fset r) \ map rep_fset (map abs_fset s)" + by (rule map_rel_cong[OF d]) + have y: "list_rel op \ (map rep_fset (map abs_fset s)) s" + by (fact rep_abs_rsp_left[OF Quotient_fset_list, OF list_rel_refl[of s]]) + have c: "(op \ OO list_rel op \) (map rep_fset (map abs_fset r)) s" + by (rule pred_compI) (rule b, rule y) + have z: "list_rel op \ r (map rep_fset (map abs_fset r))" + by (fact rep_abs_rsp[OF Quotient_fset_list, OF list_rel_refl[of r]]) + then show "(list_rel op \ OOO op \) r s" + using a c pred_compI by simp + qed +qed + text {* Respectfullness *} lemma [quot_respect]: @@ -178,7 +257,7 @@ apply (induct b) apply (simp_all add: not_memb_nil) apply (auto) - apply (simp_all add: memb_delete_raw not_memb_delete_raw_ident rsp_fold_def memb_cons_iff) + apply (simp_all add: memb_delete_raw not_memb_delete_raw_ident rsp_fold_def memb_cons_iff) done lemma ffold_raw_rsp_pre: @@ -217,6 +296,44 @@ "(op = ===> op = ===> op \ ===> op =) ffold_raw ffold_raw" by (simp add: memb_def[symmetric] ffold_raw_rsp_pre) +lemma concat_rsp_pre: + assumes a: "list_rel op \ x x'" + and b: "x' \ y'" + and c: "list_rel op \ y' y" + and d: "\x\set x. xa \ set x" + shows "\x\set y. xa \ set x" +proof - + obtain xb where e: "xb \ set x" and f: "xa \ set xb" using d by auto + have "\y. y \ set x' \ xb \ y" by (rule list_rel_find_element[OF e a]) + then obtain ya where h: "ya \ set x'" and i: "xb \ ya" by auto + have j: "ya \ set y'" using b h by simp + have "\yb. yb \ set y \ ya \ yb" by (rule list_rel_find_element[OF j c]) + then show ?thesis using f i by auto +qed + +lemma [quot_respect]: + shows "(list_rel op \ OOO op \ ===> op \) concat concat" +proof (rule fun_relI, elim pred_compE) + fix a b ba bb + assume a: "list_rel op \ a ba" + assume b: "ba \ bb" + assume c: "list_rel op \ bb b" + have "\x. (\xa\set a. x \ set xa) = (\xa\set b. x \ set xa)" proof + fix x + show "(\xa\set a. x \ set xa) = (\xa\set b. x \ set xa)" proof + assume d: "\xa\set a. x \ set xa" + show "\xa\set b. x \ set xa" by (rule concat_rsp_pre[OF a b c d]) + next + assume e: "\xa\set b. x \ set xa" + have a': "list_rel op \ ba a" by (rule list_rel_symp[OF list_eq_equivp, OF a]) + have b': "bb \ ba" by (rule equivp_symp[OF list_eq_equivp, OF b]) + have c': "list_rel op \ b bb" by (rule list_rel_symp[OF list_eq_equivp, OF c]) + show "\xa\set a. x \ set xa" by (rule concat_rsp_pre[OF c' b' a' e]) + qed + qed + then show "concat a \ concat b" by simp +qed + text {* Distributive lattice with bot *} lemma sub_list_not_eq: @@ -375,11 +492,124 @@ "fin :: 'a \ 'a fset \ bool" is "memb" abbreviation - fnotin :: "'a \ 'a fset \ bool" ("_ |\| _" [50, 51] 50) + fnotin :: "'a \ 'a fset \ bool" (infix "|\|" 50) where "x |\| S \ \ (x |\| S)" -section {* Augmenting an fset -- @{const finsert} *} +section {* Other constants on the Quotient Type *} + +quotient_definition + "fcard :: 'a fset \ nat" +is + "fcard_raw" + +quotient_definition + "fmap :: ('a \ 'b) \ 'a fset \ 'b fset" +is + "map" + +quotient_definition + "fdelete :: 'a fset \ 'a \ 'a fset" + is "delete_raw" + +quotient_definition + "fset_to_set :: 'a fset \ 'a set" + is "set" + +quotient_definition + "ffold :: ('a \ 'b \ 'b) \ 'b \ 'a fset \ 'b" + is "ffold_raw" + +quotient_definition + "fconcat :: ('a fset) fset \ 'a fset" +is + "concat" + +text {* Compositional Respectfullness and Preservation *} + +lemma [quot_respect]: "(list_rel op \ OOO op \) [] []" + by (fact compose_list_refl) + +lemma [quot_preserve]: "(abs_fset \ map f) [] = abs_fset []" + by simp + +lemma [quot_respect]: + "(op \ ===> list_rel op \ OOO op \ ===> list_rel op \ OOO op \) op # op #" + apply auto + apply (simp add: set_in_eq) + apply (rule_tac b="x # b" in pred_compI) + apply auto + apply (rule_tac b="x # ba" in pred_compI) + apply auto + done + +lemma [quot_preserve]: + "(rep_fset ---> (map rep_fset \ rep_fset) ---> (abs_fset \ map abs_fset)) op # = finsert" + by (simp add: expand_fun_eq Quotient_abs_rep[OF Quotient_fset] + abs_o_rep[OF Quotient_fset] map_id finsert_def) + +lemma [quot_preserve]: + "((map rep_fset \ rep_fset) ---> (map rep_fset \ rep_fset) ---> (abs_fset \ map abs_fset)) op @ = funion" + by (simp add: expand_fun_eq Quotient_abs_rep[OF Quotient_fset] + abs_o_rep[OF Quotient_fset] map_id sup_fset_def) + +lemma list_rel_app_l: + assumes a: "reflp R" + and b: "list_rel R l r" + shows "list_rel R (z @ l) (z @ r)" + by (induct z) (simp_all add: b rev_iffD1[OF a meta_eq_to_obj_eq[OF reflp_def]]) + +lemma append_rsp2_pre0: + assumes a:"list_rel op \ x x'" + shows "list_rel op \ (x @ z) (x' @ z)" + using a apply (induct x x' rule: list_induct2') + by simp_all (rule list_rel_refl) + +lemma append_rsp2_pre1: + assumes a:"list_rel op \ x x'" + shows "list_rel op \ (z @ x) (z @ x')" + using a apply (induct x x' arbitrary: z rule: list_induct2') + apply (rule list_rel_refl) + apply (simp_all del: list_eq.simps) + apply (rule list_rel_app_l) + apply (simp_all add: reflp_def) + done + +lemma append_rsp2_pre: + assumes a:"list_rel op \ x x'" + and b: "list_rel op \ z z'" + shows "list_rel op \ (x @ z) (x' @ z')" + apply (rule list_rel_transp[OF fset_equivp]) + apply (rule append_rsp2_pre0) + apply (rule a) + using b apply (induct z z' rule: list_induct2') + apply (simp_all only: append_Nil2) + apply (rule list_rel_refl) + apply simp_all + apply (rule append_rsp2_pre1) + apply simp + done + +lemma [quot_respect]: + "(list_rel op \ OOO op \ ===> list_rel op \ OOO op \ ===> list_rel op \ OOO op \) op @ op @" +proof (intro fun_relI, elim pred_compE) + fix x y z w x' z' y' w' :: "'a list list" + assume a:"list_rel op \ x x'" + and b: "x' \ y'" + and c: "list_rel op \ y' y" + assume aa: "list_rel op \ z z'" + and bb: "z' \ w'" + and cc: "list_rel op \ w' w" + have a': "list_rel op \ (x @ z) (x' @ z')" using a aa append_rsp2_pre by auto + have b': "x' @ z' \ y' @ w'" using b bb by simp + have c': "list_rel op \ (y' @ w') (y @ w)" using c cc append_rsp2_pre by auto + have d': "(op \ OO list_rel op \) (x' @ z') (y @ w)" + by (rule pred_compI) (rule b', rule c') + show "(list_rel op \ OOO op \) (x @ z) (y @ w)" + by (rule pred_compI) (rule a', rule d') +qed + +text {* Raw theorems. Finsert, memb, singleron, sub_list *} lemma nil_not_cons: shows "\ ([] \ x # xs)" @@ -398,30 +628,20 @@ shows "memb x xs \ memb x (y # xs)" by (simp add: memb_def) -section {* Singletons *} - lemma singleton_list_eq: shows "[x] \ [y] \ x = y" by (simp add: id_simps) auto -section {* sub_list *} - lemma sub_list_cons: "sub_list (x # xs) ys = (memb x ys \ sub_list xs ys)" by (auto simp add: memb_def sub_list_def) -section {* Cardinality of finite sets *} - -quotient_definition - "fcard :: 'a fset \ nat" -is - "fcard_raw" +text {* Cardinality of finite sets *} lemma fcard_raw_0: shows "fcard_raw xs = 0 \ xs \ []" by (induct xs) (auto simp add: memb_def) - lemma fcard_raw_not_memb: shows "\ memb x xs \ fcard_raw (x # xs) = Suc (fcard_raw xs)" by auto @@ -432,7 +652,7 @@ using a by (induct xs) (auto simp add: memb_def split: if_splits) -lemma singleton_fcard_1: +lemma singleton_fcard_1: shows "set xs = {x} \ fcard_raw xs = 1" by (induct xs) (auto simp add: memb_def subset_insert) @@ -451,11 +671,7 @@ assumes a: "fcard_raw A = Suc n" shows "\a. memb a A" using a - apply (induct A) - apply simp - apply (rule_tac x="a" in exI) - apply (simp add: memb_def) - done + by (induct A) (auto simp add: memb_def) lemma memb_card_not_0: assumes a: "memb a A" @@ -466,12 +682,7 @@ then show ?thesis using fcard_raw_0[of A] by simp qed -section {* fmap *} - -quotient_definition - "fmap :: ('a \ 'b) \ 'a fset \ 'b fset" -is - "map" +text {* fmap *} lemma map_append: "map f (xs @ ys) \ (map f xs) @ (map f ys)" @@ -526,28 +737,10 @@ "fcard_raw (delete_raw xs y) = (if memb y xs then fcard_raw xs - 1 else fcard_raw xs)" by (simp add: fdelete_raw_filter fcard_raw_delete_one) - - - - lemma finter_raw_empty: "finter_raw l [] = []" by (induct l) (simp_all add: not_memb_nil) -section {* Constants on the Quotient Type *} - -quotient_definition - "fdelete :: 'a fset \ 'a \ 'a fset" - is "delete_raw" - -quotient_definition - "fset_to_set :: 'a fset \ 'a set" - is "set" - -quotient_definition - "ffold :: ('a \ 'b \ 'b) \ 'b \ 'a fset \ 'b" - is "ffold_raw" - lemma set_cong: shows "(set x = set y) = (x \ y)" by auto @@ -556,12 +749,6 @@ "inj f \ (map f l \ map f m) = (l \ m)" by (simp add: expand_set_eq[symmetric] inj_image_eq_iff) -quotient_definition - "fconcat :: ('a fset) fset \ 'a fset" -is - "concat" - - text {* alternate formulation with a different decomposition principle and a proof of equivalence *} @@ -604,42 +791,44 @@ "xs \ ys \ delete_raw xs x \ delete_raw ys x" by (simp add: memb_def[symmetric] memb_delete_raw) -lemma list_eq2_equiv_aux: - assumes a: "fcard_raw l = n" - and b: "l \ r" - shows "list_eq2 l r" -using a b -proof (induct n arbitrary: l r) - case 0 - have "fcard_raw l = 0" by fact - then have "\x. \ memb x l" using memb_card_not_0[of _ l] by auto - then have z: "l = []" using no_memb_nil 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: "fcard_raw l = Suc m" by fact - have "\a. memb a l" by (rule fcard_raw_suc_memb[OF d]) - 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 by auto - have f: "fcard_raw (delete_raw l a) = m" using fcard_raw_delete[of l a] e d by simp - have g: "delete_raw l a \ delete_raw r a" using delete_raw_rsp[OF b] by simp - have g': "list_eq2 (delete_raw l a) (delete_raw r a)" by (rule Suc.hyps[OF f g]) - have h: "list_eq2 (a # delete_raw l a) (a # delete_raw r a)" by (rule list_eq2.intros(5)[OF g']) - have i: "list_eq2 l (a # delete_raw l a)" by (rule list_eq2.intros(3)[OF memb_delete_list_eq2[OF e]]) - have "list_eq2 l (a # delete_raw r a)" 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 - 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 - show "l \ r \ list_eq2 l r" using list_eq2_equiv_aux by blast +next + { + fix n + assume a: "fcard_raw l = n" and b: "l \ r" + have "list_eq2 l r" + using a b + proof (induct n arbitrary: l r) + case 0 + have "fcard_raw l = 0" by fact + then have "\x. \ memb x l" using memb_card_not_0[of _ l] by auto + then have z: "l = []" using no_memb_nil 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: "fcard_raw l = Suc m" by fact + have "\a. memb a l" by (rule fcard_raw_suc_memb[OF d]) + 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 by auto + have f: "fcard_raw (delete_raw l a) = m" using fcard_raw_delete[of l a] e d by simp + have g: "delete_raw l a \ delete_raw r a" using delete_raw_rsp[OF b] by simp + have g': "list_eq2 (delete_raw l a) (delete_raw r a)" by (rule Suc.hyps[OF f g]) + have h: "list_eq2 (a # delete_raw l a) (a # delete_raw r a)" by (rule list_eq2.intros(5)[OF g']) + have i: "list_eq2 l (a # delete_raw l a)" + by (rule list_eq2.intros(3)[OF memb_delete_list_eq2[OF e]]) + have "list_eq2 l (a # delete_raw r a)" 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 part *} +text {* Lifted theorems *} lemma not_fin_fnil: "x |\| {||}" by (lifting not_memb_nil) @@ -742,10 +931,6 @@ shows "S |\| {||} = S" by (lifting append_Nil2) -thm sup.commute[where 'a="'a fset"] - -thm sup.assoc[where 'a="'a fset"] - lemma singleton_union_left: "{|a|} |\| S = finsert a S" by simp @@ -779,15 +964,7 @@ case (finsert x S) have asm: "P S" by fact show "P (finsert x S)" - proof(cases "x |\| S") - case True - have "x |\| S" by fact - then show "P (finsert x S)" using asm by simp - next - case False - have "x |\| S" by fact - then show "P (finsert x S)" using prem2 asm by simp - qed + by (cases "x |\| S") (simp_all add: asm prem2) qed lemma fset_induct2: @@ -876,7 +1053,8 @@ "(finsert x xs |\| ys) = (x |\| ys \ xs |\| ys)" by (lifting sub_list_cons) -thm sub_list_def[simplified memb_def[symmetric], quot_lifted, no_vars] +lemma "xs |\| ys \ \x. x |\| xs \ x |\| ys" + by (lifting sub_list_def[simplified memb_def[symmetric]]) lemma fsubset_fin: "xs |\| ys = (\x. x |\| xs \ x |\| ys)" by (rule meta_eq_to_obj_eq) @@ -911,6 +1089,19 @@ using assms by (lifting list_eq2.induct[simplified list_eq2_equiv[symmetric]]) +text {* concat *} + +lemma fconcat_empty: + shows "fconcat {||} = {||}" + by (lifting concat.simps(1)) + +lemma fconcat_insert: + shows "fconcat (finsert x S) = x |\| fconcat S" + by (lifting concat.simps(2)) + +lemma "fconcat (xs |\| ys) = fconcat xs |\| fconcat ys" + by (lifting concat_append) + ML {* fun dest_fsetT (Type ("FSet.fset", [T])) = T | dest_fsetT T = raise TYPE ("dest_fsetT: fset type expected", [T], []);