961 by (metis image_mset_cong split_cong) |
961 by (metis image_mset_cong split_cong) |
962 |
962 |
963 |
963 |
964 subsection \<open>Further conversions\<close> |
964 subsection \<open>Further conversions\<close> |
965 |
965 |
966 primrec multiset_of :: "'a list \<Rightarrow> 'a multiset" where |
966 primrec mset :: "'a list \<Rightarrow> 'a multiset" where |
967 "multiset_of [] = {#}" | |
967 "mset [] = {#}" | |
968 "multiset_of (a # x) = multiset_of x + {# a #}" |
968 "mset (a # x) = mset x + {# a #}" |
969 |
969 |
970 lemma in_multiset_in_set: |
970 lemma in_multiset_in_set: |
971 "x \<in># multiset_of xs \<longleftrightarrow> x \<in> set xs" |
971 "x \<in># mset xs \<longleftrightarrow> x \<in> set xs" |
972 by (induct xs) simp_all |
972 by (induct xs) simp_all |
973 |
973 |
974 lemma count_multiset_of: |
974 lemma count_mset: |
975 "count (multiset_of xs) x = length (filter (\<lambda>y. x = y) xs)" |
975 "count (mset xs) x = length (filter (\<lambda>y. x = y) xs)" |
976 by (induct xs) simp_all |
976 by (induct xs) simp_all |
977 |
977 |
978 lemma multiset_of_zero_iff[simp]: "(multiset_of x = {#}) = (x = [])" |
978 lemma mset_zero_iff[simp]: "(mset x = {#}) = (x = [])" |
979 by (induct x) auto |
979 by (induct x) auto |
980 |
980 |
981 lemma multiset_of_zero_iff_right[simp]: "({#} = multiset_of x) = (x = [])" |
981 lemma mset_zero_iff_right[simp]: "({#} = mset x) = (x = [])" |
982 by (induct x) auto |
982 by (induct x) auto |
983 |
983 |
984 lemma set_mset_multiset_of[simp]: "set_mset (multiset_of x) = set x" |
984 lemma set_mset_mset[simp]: "set_mset (mset x) = set x" |
985 by (induct x) auto |
985 by (induct x) auto |
986 |
986 |
987 lemma mem_set_multiset_eq: "x \<in> set xs = (x :# multiset_of xs)" |
987 lemma mem_set_multiset_eq: "x \<in> set xs = (x :# mset xs)" |
988 by (induct xs) auto |
988 by (induct xs) auto |
989 |
989 |
990 lemma size_multiset_of [simp]: "size (multiset_of xs) = length xs" |
990 lemma size_mset [simp]: "size (mset xs) = length xs" |
991 by (induct xs) simp_all |
991 by (induct xs) simp_all |
992 |
992 |
993 lemma multiset_of_append [simp]: |
993 lemma mset_append [simp]: |
994 "multiset_of (xs @ ys) = multiset_of xs + multiset_of ys" |
994 "mset (xs @ ys) = mset xs + mset ys" |
995 by (induct xs arbitrary: ys) (auto simp: ac_simps) |
995 by (induct xs arbitrary: ys) (auto simp: ac_simps) |
996 |
996 |
997 lemma multiset_of_filter: |
997 lemma mset_filter: |
998 "multiset_of (filter P xs) = {#x :# multiset_of xs. P x #}" |
998 "mset (filter P xs) = {#x :# mset xs. P x #}" |
999 by (induct xs) simp_all |
999 by (induct xs) simp_all |
1000 |
1000 |
1001 lemma multiset_of_rev [simp]: |
1001 lemma mset_rev [simp]: |
1002 "multiset_of (rev xs) = multiset_of xs" |
1002 "mset (rev xs) = mset xs" |
1003 by (induct xs) simp_all |
1003 by (induct xs) simp_all |
1004 |
1004 |
1005 lemma surj_multiset_of: "surj multiset_of" |
1005 lemma surj_mset: "surj mset" |
1006 apply (unfold surj_def) |
1006 apply (unfold surj_def) |
1007 apply (rule allI) |
1007 apply (rule allI) |
1008 apply (rule_tac M = y in multiset_induct) |
1008 apply (rule_tac M = y in multiset_induct) |
1009 apply auto |
1009 apply auto |
1010 apply (rule_tac x = "x # xa" in exI) |
1010 apply (rule_tac x = "x # xa" in exI) |
1011 apply auto |
1011 apply auto |
1012 done |
1012 done |
1013 |
1013 |
1014 lemma set_count_greater_0: "set x = {a. count (multiset_of x) a > 0}" |
1014 lemma set_count_greater_0: "set x = {a. count (mset x) a > 0}" |
1015 by (induct x) auto |
1015 by (induct x) auto |
1016 |
1016 |
1017 lemma distinct_count_atmost_1: |
1017 lemma distinct_count_atmost_1: |
1018 "distinct x = (! a. count (multiset_of x) a = (if a \<in> set x then 1 else 0))" |
1018 "distinct x = (! a. count (mset x) a = (if a \<in> set x then 1 else 0))" |
1019 apply (induct x, simp, rule iffI, simp_all) |
1019 apply (induct x, simp, rule iffI, simp_all) |
1020 apply (rename_tac a b) |
1020 apply (rename_tac a b) |
1021 apply (rule conjI) |
1021 apply (rule conjI) |
1022 apply (simp_all add: set_mset_multiset_of [THEN sym] del: set_mset_multiset_of) |
1022 apply (simp_all add: set_mset_mset [THEN sym] del: set_mset_mset) |
1023 apply (erule_tac x = a in allE, simp, clarify) |
1023 apply (erule_tac x = a in allE, simp, clarify) |
1024 apply (erule_tac x = aa in allE, simp) |
1024 apply (erule_tac x = aa in allE, simp) |
1025 done |
1025 done |
1026 |
1026 |
1027 lemma multiset_of_eq_setD: |
1027 lemma mset_eq_setD: |
1028 "multiset_of xs = multiset_of ys \<Longrightarrow> set xs = set ys" |
1028 "mset xs = mset ys \<Longrightarrow> set xs = set ys" |
1029 by (rule) (auto simp add:multiset_eq_iff set_count_greater_0) |
1029 by (rule) (auto simp add:multiset_eq_iff set_count_greater_0) |
1030 |
1030 |
1031 lemma set_eq_iff_multiset_of_eq_distinct: |
1031 lemma set_eq_iff_mset_eq_distinct: |
1032 "distinct x \<Longrightarrow> distinct y \<Longrightarrow> |
1032 "distinct x \<Longrightarrow> distinct y \<Longrightarrow> |
1033 (set x = set y) = (multiset_of x = multiset_of y)" |
1033 (set x = set y) = (mset x = mset y)" |
1034 by (auto simp: multiset_eq_iff distinct_count_atmost_1) |
1034 by (auto simp: multiset_eq_iff distinct_count_atmost_1) |
1035 |
1035 |
1036 lemma set_eq_iff_multiset_of_remdups_eq: |
1036 lemma set_eq_iff_mset_remdups_eq: |
1037 "(set x = set y) = (multiset_of (remdups x) = multiset_of (remdups y))" |
1037 "(set x = set y) = (mset (remdups x) = mset (remdups y))" |
1038 apply (rule iffI) |
1038 apply (rule iffI) |
1039 apply (simp add: set_eq_iff_multiset_of_eq_distinct[THEN iffD1]) |
1039 apply (simp add: set_eq_iff_mset_eq_distinct[THEN iffD1]) |
1040 apply (drule distinct_remdups [THEN distinct_remdups |
1040 apply (drule distinct_remdups [THEN distinct_remdups |
1041 [THEN set_eq_iff_multiset_of_eq_distinct [THEN iffD2]]]) |
1041 [THEN set_eq_iff_mset_eq_distinct [THEN iffD2]]]) |
1042 apply simp |
1042 apply simp |
1043 done |
1043 done |
1044 |
1044 |
1045 lemma multiset_of_compl_union [simp]: |
1045 lemma mset_compl_union [simp]: |
1046 "multiset_of [x\<leftarrow>xs. P x] + multiset_of [x\<leftarrow>xs. \<not>P x] = multiset_of xs" |
1046 "mset [x\<leftarrow>xs. P x] + mset [x\<leftarrow>xs. \<not>P x] = mset xs" |
1047 by (induct xs) (auto simp: ac_simps) |
1047 by (induct xs) (auto simp: ac_simps) |
1048 |
1048 |
1049 lemma nth_mem_multiset_of: "i < length ls \<Longrightarrow> (ls ! i) :# multiset_of ls" |
1049 lemma nth_mem_mset: "i < length ls \<Longrightarrow> (ls ! i) :# mset ls" |
1050 apply (induct ls arbitrary: i) |
1050 apply (induct ls arbitrary: i) |
1051 apply simp |
1051 apply simp |
1052 apply (case_tac i) |
1052 apply (case_tac i) |
1053 apply auto |
1053 apply auto |
1054 done |
1054 done |
1055 |
1055 |
1056 lemma multiset_of_remove1[simp]: |
1056 lemma mset_remove1[simp]: |
1057 "multiset_of (remove1 a xs) = multiset_of xs - {#a#}" |
1057 "mset (remove1 a xs) = mset xs - {#a#}" |
1058 by (induct xs) (auto simp add: multiset_eq_iff) |
1058 by (induct xs) (auto simp add: multiset_eq_iff) |
1059 |
1059 |
1060 lemma multiset_of_eq_length: |
1060 lemma mset_eq_length: |
1061 assumes "multiset_of xs = multiset_of ys" |
1061 assumes "mset xs = mset ys" |
1062 shows "length xs = length ys" |
1062 shows "length xs = length ys" |
1063 using assms by (metis size_multiset_of) |
1063 using assms by (metis size_mset) |
1064 |
1064 |
1065 lemma multiset_of_eq_length_filter: |
1065 lemma mset_eq_length_filter: |
1066 assumes "multiset_of xs = multiset_of ys" |
1066 assumes "mset xs = mset ys" |
1067 shows "length (filter (\<lambda>x. z = x) xs) = length (filter (\<lambda>y. z = y) ys)" |
1067 shows "length (filter (\<lambda>x. z = x) xs) = length (filter (\<lambda>y. z = y) ys)" |
1068 using assms by (metis count_multiset_of) |
1068 using assms by (metis count_mset) |
1069 |
1069 |
1070 lemma fold_multiset_equiv: |
1070 lemma fold_multiset_equiv: |
1071 assumes f: "\<And>x y. x \<in> set xs \<Longrightarrow> y \<in> set xs \<Longrightarrow> f x \<circ> f y = f y \<circ> f x" |
1071 assumes f: "\<And>x y. x \<in> set xs \<Longrightarrow> y \<in> set xs \<Longrightarrow> f x \<circ> f y = f y \<circ> f x" |
1072 and equiv: "multiset_of xs = multiset_of ys" |
1072 and equiv: "mset xs = mset ys" |
1073 shows "List.fold f xs = List.fold f ys" |
1073 shows "List.fold f xs = List.fold f ys" |
1074 using f equiv [symmetric] |
1074 using f equiv [symmetric] |
1075 proof (induct xs arbitrary: ys) |
1075 proof (induct xs arbitrary: ys) |
1076 case Nil then show ?case by simp |
1076 case Nil then show ?case by simp |
1077 next |
1077 next |
1078 case (Cons x xs) |
1078 case (Cons x xs) |
1079 then have *: "set ys = set (x # xs)" by (blast dest: multiset_of_eq_setD) |
1079 then have *: "set ys = set (x # xs)" by (blast dest: mset_eq_setD) |
1080 have "\<And>x y. x \<in> set ys \<Longrightarrow> y \<in> set ys \<Longrightarrow> f x \<circ> f y = f y \<circ> f x" |
1080 have "\<And>x y. x \<in> set ys \<Longrightarrow> y \<in> set ys \<Longrightarrow> f x \<circ> f y = f y \<circ> f x" |
1081 by (rule Cons.prems(1)) (simp_all add: *) |
1081 by (rule Cons.prems(1)) (simp_all add: *) |
1082 moreover from * have "x \<in> set ys" by simp |
1082 moreover from * have "x \<in> set ys" by simp |
1083 ultimately have "List.fold f ys = List.fold f (remove1 x ys) \<circ> f x" by (fact fold_remove1_split) |
1083 ultimately have "List.fold f ys = List.fold f (remove1 x ys) \<circ> f x" by (fact fold_remove1_split) |
1084 moreover from Cons.prems have "List.fold f xs = List.fold f (remove1 x ys)" by (auto intro: Cons.hyps) |
1084 moreover from Cons.prems have "List.fold f xs = List.fold f (remove1 x ys)" by (auto intro: Cons.hyps) |
1085 ultimately show ?case by simp |
1085 ultimately show ?case by simp |
1086 qed |
1086 qed |
1087 |
1087 |
1088 lemma multiset_of_insort [simp]: |
1088 lemma mset_insort [simp]: |
1089 "multiset_of (insort x xs) = multiset_of xs + {#x#}" |
1089 "mset (insort x xs) = mset xs + {#x#}" |
1090 by (induct xs) (simp_all add: ac_simps) |
1090 by (induct xs) (simp_all add: ac_simps) |
1091 |
1091 |
1092 lemma multiset_of_map: |
1092 lemma mset_map: |
1093 "multiset_of (map f xs) = image_mset f (multiset_of xs)" |
1093 "mset (map f xs) = image_mset f (mset xs)" |
1094 by (induct xs) simp_all |
1094 by (induct xs) simp_all |
1095 |
1095 |
1096 definition mset_set :: "'a set \<Rightarrow> 'a multiset" |
1096 definition mset_set :: "'a set \<Rightarrow> 'a multiset" |
1097 where |
1097 where |
1098 "mset_set = folding.F (\<lambda>x M. {#x#} + M) {#}" |
1098 "mset_set = folding.F (\<lambda>x M. {#x#} + M) {#}" |
2069 \<close> |
2069 \<close> |
2070 |
2070 |
2071 |
2071 |
2072 subsection \<open>Naive implementation using lists\<close> |
2072 subsection \<open>Naive implementation using lists\<close> |
2073 |
2073 |
2074 code_datatype multiset_of |
2074 code_datatype mset |
2075 |
2075 |
2076 lemma [code]: |
2076 lemma [code]: |
2077 "{#} = multiset_of []" |
2077 "{#} = mset []" |
2078 by simp |
2078 by simp |
2079 |
2079 |
2080 lemma [code]: |
2080 lemma [code]: |
2081 "{#x#} = multiset_of [x]" |
2081 "{#x#} = mset [x]" |
2082 by simp |
2082 by simp |
2083 |
2083 |
2084 lemma union_code [code]: |
2084 lemma union_code [code]: |
2085 "multiset_of xs + multiset_of ys = multiset_of (xs @ ys)" |
2085 "mset xs + mset ys = mset (xs @ ys)" |
2086 by simp |
2086 by simp |
2087 |
2087 |
2088 lemma [code]: |
2088 lemma [code]: |
2089 "image_mset f (multiset_of xs) = multiset_of (map f xs)" |
2089 "image_mset f (mset xs) = mset (map f xs)" |
2090 by (simp add: multiset_of_map) |
2090 by (simp add: mset_map) |
2091 |
2091 |
2092 lemma [code]: |
2092 lemma [code]: |
2093 "filter_mset f (multiset_of xs) = multiset_of (filter f xs)" |
2093 "filter_mset f (mset xs) = mset (filter f xs)" |
2094 by (simp add: multiset_of_filter) |
2094 by (simp add: mset_filter) |
2095 |
2095 |
2096 lemma [code]: |
2096 lemma [code]: |
2097 "multiset_of xs - multiset_of ys = multiset_of (fold remove1 ys xs)" |
2097 "mset xs - mset ys = mset (fold remove1 ys xs)" |
2098 by (rule sym, induct ys arbitrary: xs) (simp_all add: diff_add diff_right_commute) |
2098 by (rule sym, induct ys arbitrary: xs) (simp_all add: diff_add diff_right_commute) |
2099 |
2099 |
2100 lemma [code]: |
2100 lemma [code]: |
2101 "multiset_of xs #\<inter> multiset_of ys = |
2101 "mset xs #\<inter> mset ys = |
2102 multiset_of (snd (fold (\<lambda>x (ys, zs). |
2102 mset (snd (fold (\<lambda>x (ys, zs). |
2103 if x \<in> set ys then (remove1 x ys, x # zs) else (ys, zs)) xs (ys, [])))" |
2103 if x \<in> set ys then (remove1 x ys, x # zs) else (ys, zs)) xs (ys, [])))" |
2104 proof - |
2104 proof - |
2105 have "\<And>zs. multiset_of (snd (fold (\<lambda>x (ys, zs). |
2105 have "\<And>zs. mset (snd (fold (\<lambda>x (ys, zs). |
2106 if x \<in> set ys then (remove1 x ys, x # zs) else (ys, zs)) xs (ys, zs))) = |
2106 if x \<in> set ys then (remove1 x ys, x # zs) else (ys, zs)) xs (ys, zs))) = |
2107 (multiset_of xs #\<inter> multiset_of ys) + multiset_of zs" |
2107 (mset xs #\<inter> mset ys) + mset zs" |
2108 by (induct xs arbitrary: ys) |
2108 by (induct xs arbitrary: ys) |
2109 (auto simp add: mem_set_multiset_eq inter_add_right1 inter_add_right2 ac_simps) |
2109 (auto simp add: mem_set_multiset_eq inter_add_right1 inter_add_right2 ac_simps) |
2110 then show ?thesis by simp |
2110 then show ?thesis by simp |
2111 qed |
2111 qed |
2112 |
2112 |
2113 lemma [code]: |
2113 lemma [code]: |
2114 "multiset_of xs #\<union> multiset_of ys = |
2114 "mset xs #\<union> mset ys = |
2115 multiset_of (split append (fold (\<lambda>x (ys, zs). (remove1 x ys, x # zs)) xs (ys, [])))" |
2115 mset (split append (fold (\<lambda>x (ys, zs). (remove1 x ys, x # zs)) xs (ys, [])))" |
2116 proof - |
2116 proof - |
2117 have "\<And>zs. multiset_of (split append (fold (\<lambda>x (ys, zs). (remove1 x ys, x # zs)) xs (ys, zs))) = |
2117 have "\<And>zs. mset (split append (fold (\<lambda>x (ys, zs). (remove1 x ys, x # zs)) xs (ys, zs))) = |
2118 (multiset_of xs #\<union> multiset_of ys) + multiset_of zs" |
2118 (mset xs #\<union> mset ys) + mset zs" |
2119 by (induct xs arbitrary: ys) (simp_all add: multiset_eq_iff) |
2119 by (induct xs arbitrary: ys) (simp_all add: multiset_eq_iff) |
2120 then show ?thesis by simp |
2120 then show ?thesis by simp |
2121 qed |
2121 qed |
2122 |
2122 |
2123 declare in_multiset_in_set [code_unfold] |
2123 declare in_multiset_in_set [code_unfold] |
2124 |
2124 |
2125 lemma [code]: |
2125 lemma [code]: |
2126 "count (multiset_of xs) x = fold (\<lambda>y. if x = y then Suc else id) xs 0" |
2126 "count (mset xs) x = fold (\<lambda>y. if x = y then Suc else id) xs 0" |
2127 proof - |
2127 proof - |
2128 have "\<And>n. fold (\<lambda>y. if x = y then Suc else id) xs n = count (multiset_of xs) x + n" |
2128 have "\<And>n. fold (\<lambda>y. if x = y then Suc else id) xs n = count (mset xs) x + n" |
2129 by (induct xs) simp_all |
2129 by (induct xs) simp_all |
2130 then show ?thesis by simp |
2130 then show ?thesis by simp |
2131 qed |
2131 qed |
2132 |
2132 |
2133 declare set_mset_multiset_of [code] |
2133 declare set_mset_mset [code] |
2134 |
2134 |
2135 declare sorted_list_of_multiset_multiset_of [code] |
2135 declare sorted_list_of_multiset_mset [code] |
2136 |
2136 |
2137 lemma [code]: -- \<open>not very efficient, but representation-ignorant!\<close> |
2137 lemma [code]: -- \<open>not very efficient, but representation-ignorant!\<close> |
2138 "mset_set A = multiset_of (sorted_list_of_set A)" |
2138 "mset_set A = mset (sorted_list_of_set A)" |
2139 apply (cases "finite A") |
2139 apply (cases "finite A") |
2140 apply simp_all |
2140 apply simp_all |
2141 apply (induct A rule: finite_induct) |
2141 apply (induct A rule: finite_induct) |
2142 apply (simp_all add: add.commute) |
2142 apply (simp_all add: add.commute) |
2143 done |
2143 done |
2144 |
2144 |
2145 declare size_multiset_of [code] |
2145 declare size_mset [code] |
2146 |
2146 |
2147 fun ms_lesseq_impl :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool option" where |
2147 fun ms_lesseq_impl :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool option" where |
2148 "ms_lesseq_impl [] ys = Some (ys \<noteq> [])" |
2148 "ms_lesseq_impl [] ys = Some (ys \<noteq> [])" |
2149 | "ms_lesseq_impl (Cons x xs) ys = (case List.extract (op = x) ys of |
2149 | "ms_lesseq_impl (Cons x xs) ys = (case List.extract (op = x) ys of |
2150 None \<Rightarrow> None |
2150 None \<Rightarrow> None |
2151 | Some (ys1,_,ys2) \<Rightarrow> ms_lesseq_impl xs (ys1 @ ys2))" |
2151 | Some (ys1,_,ys2) \<Rightarrow> ms_lesseq_impl xs (ys1 @ ys2))" |
2152 |
2152 |
2153 lemma ms_lesseq_impl: "(ms_lesseq_impl xs ys = None \<longleftrightarrow> \<not> multiset_of xs \<le># multiset_of ys) \<and> |
2153 lemma ms_lesseq_impl: "(ms_lesseq_impl xs ys = None \<longleftrightarrow> \<not> mset xs \<le># mset ys) \<and> |
2154 (ms_lesseq_impl xs ys = Some True \<longleftrightarrow> multiset_of xs <# multiset_of ys) \<and> |
2154 (ms_lesseq_impl xs ys = Some True \<longleftrightarrow> mset xs <# mset ys) \<and> |
2155 (ms_lesseq_impl xs ys = Some False \<longrightarrow> multiset_of xs = multiset_of ys)" |
2155 (ms_lesseq_impl xs ys = Some False \<longrightarrow> mset xs = mset ys)" |
2156 proof (induct xs arbitrary: ys) |
2156 proof (induct xs arbitrary: ys) |
2157 case (Nil ys) |
2157 case (Nil ys) |
2158 show ?case by (auto simp: mset_less_empty_nonempty) |
2158 show ?case by (auto simp: mset_less_empty_nonempty) |
2159 next |
2159 next |
2160 case (Cons x xs ys) |
2160 case (Cons x xs ys) |
2161 show ?case |
2161 show ?case |
2162 proof (cases "List.extract (op = x) ys") |
2162 proof (cases "List.extract (op = x) ys") |
2163 case None |
2163 case None |
2164 hence x: "x \<notin> set ys" by (simp add: extract_None_iff) |
2164 hence x: "x \<notin> set ys" by (simp add: extract_None_iff) |
2165 { |
2165 { |
2166 assume "multiset_of (x # xs) \<le># multiset_of ys" |
2166 assume "mset (x # xs) \<le># mset ys" |
2167 from set_mset_mono[OF this] x have False by simp |
2167 from set_mset_mono[OF this] x have False by simp |
2168 } note nle = this |
2168 } note nle = this |
2169 moreover |
2169 moreover |
2170 { |
2170 { |
2171 assume "multiset_of (x # xs) <# multiset_of ys" |
2171 assume "mset (x # xs) <# mset ys" |
2172 hence "multiset_of (x # xs) \<le># multiset_of ys" by auto |
2172 hence "mset (x # xs) \<le># mset ys" by auto |
2173 from nle[OF this] have False . |
2173 from nle[OF this] have False . |
2174 } |
2174 } |
2175 ultimately show ?thesis using None by auto |
2175 ultimately show ?thesis using None by auto |
2176 next |
2176 next |
2177 case (Some res) |
2177 case (Some res) |
2178 obtain ys1 y ys2 where res: "res = (ys1,y,ys2)" by (cases res, auto) |
2178 obtain ys1 y ys2 where res: "res = (ys1,y,ys2)" by (cases res, auto) |
2179 note Some = Some[unfolded res] |
2179 note Some = Some[unfolded res] |
2180 from extract_SomeE[OF Some] have "ys = ys1 @ x # ys2" by simp |
2180 from extract_SomeE[OF Some] have "ys = ys1 @ x # ys2" by simp |
2181 hence id: "multiset_of ys = multiset_of (ys1 @ ys2) + {#x#}" |
2181 hence id: "mset ys = mset (ys1 @ ys2) + {#x#}" |
2182 by (auto simp: ac_simps) |
2182 by (auto simp: ac_simps) |
2183 show ?thesis unfolding ms_lesseq_impl.simps |
2183 show ?thesis unfolding ms_lesseq_impl.simps |
2184 unfolding Some option.simps split |
2184 unfolding Some option.simps split |
2185 unfolding id |
2185 unfolding id |
2186 using Cons[of "ys1 @ ys2"] |
2186 using Cons[of "ys1 @ ys2"] |
2187 unfolding subset_mset_def subseteq_mset_def by auto |
2187 unfolding subset_mset_def subseteq_mset_def by auto |
2188 qed |
2188 qed |
2189 qed |
2189 qed |
2190 |
2190 |
2191 lemma [code]: "multiset_of xs \<le># multiset_of ys \<longleftrightarrow> ms_lesseq_impl xs ys \<noteq> None" |
2191 lemma [code]: "mset xs \<le># mset ys \<longleftrightarrow> ms_lesseq_impl xs ys \<noteq> None" |
2192 using ms_lesseq_impl[of xs ys] by (cases "ms_lesseq_impl xs ys", auto) |
2192 using ms_lesseq_impl[of xs ys] by (cases "ms_lesseq_impl xs ys", auto) |
2193 |
2193 |
2194 lemma [code]: "multiset_of xs <# multiset_of ys \<longleftrightarrow> ms_lesseq_impl xs ys = Some True" |
2194 lemma [code]: "mset xs <# mset ys \<longleftrightarrow> ms_lesseq_impl xs ys = Some True" |
2195 using ms_lesseq_impl[of xs ys] by (cases "ms_lesseq_impl xs ys", auto) |
2195 using ms_lesseq_impl[of xs ys] by (cases "ms_lesseq_impl xs ys", auto) |
2196 |
2196 |
2197 instantiation multiset :: (equal) equal |
2197 instantiation multiset :: (equal) equal |
2198 begin |
2198 begin |
2199 |
2199 |
2200 definition |
2200 definition |
2201 [code del]: "HOL.equal A (B :: 'a multiset) \<longleftrightarrow> A = B" |
2201 [code del]: "HOL.equal A (B :: 'a multiset) \<longleftrightarrow> A = B" |
2202 lemma [code]: "HOL.equal (multiset_of xs) (multiset_of ys) \<longleftrightarrow> ms_lesseq_impl xs ys = Some False" |
2202 lemma [code]: "HOL.equal (mset xs) (mset ys) \<longleftrightarrow> ms_lesseq_impl xs ys = Some False" |
2203 unfolding equal_multiset_def |
2203 unfolding equal_multiset_def |
2204 using ms_lesseq_impl[of xs ys] by (cases "ms_lesseq_impl xs ys", auto) |
2204 using ms_lesseq_impl[of xs ys] by (cases "ms_lesseq_impl xs ys", auto) |
2205 |
2205 |
2206 instance |
2206 instance |
2207 by default (simp add: equal_multiset_def) |
2207 by default (simp add: equal_multiset_def) |
2208 end |
2208 end |
2209 |
2209 |
2210 lemma [code]: |
2210 lemma [code]: |
2211 "msetsum (multiset_of xs) = listsum xs" |
2211 "msetsum (mset xs) = listsum xs" |
2212 by (induct xs) (simp_all add: add.commute) |
2212 by (induct xs) (simp_all add: add.commute) |
2213 |
2213 |
2214 lemma [code]: |
2214 lemma [code]: |
2215 "msetprod (multiset_of xs) = fold times xs 1" |
2215 "msetprod (mset xs) = fold times xs 1" |
2216 proof - |
2216 proof - |
2217 have "\<And>x. fold times xs x = msetprod (multiset_of xs) * x" |
2217 have "\<And>x. fold times xs x = msetprod (mset xs) * x" |
2218 by (induct xs) (simp_all add: mult.assoc) |
2218 by (induct xs) (simp_all add: mult.assoc) |
2219 then show ?thesis by simp |
2219 then show ?thesis by simp |
2220 qed |
2220 qed |
2221 |
2221 |
2222 text \<open> |
2222 text \<open> |
2286 case False |
2286 case False |
2287 then obtain k where k: "j = Suc k" |
2287 then obtain k where k: "j = Suc k" |
2288 by (case_tac j) simp |
2288 by (case_tac j) simp |
2289 hence "k \<le> length xs" |
2289 hence "k \<le> length xs" |
2290 using Cons.prems by auto |
2290 using Cons.prems by auto |
2291 hence "multiset_of (zip (take k xs @ x # drop k xs) (take k ys @ y # drop k ys)) = |
2291 hence "mset (zip (take k xs @ x # drop k xs) (take k ys @ y # drop k ys)) = |
2292 multiset_of (zip xs ys) + {#(x, y)#}" |
2292 mset (zip xs ys) + {#(x, y)#}" |
2293 by (rule Cons.hyps(2)) |
2293 by (rule Cons.hyps(2)) |
2294 thus ?thesis |
2294 thus ?thesis |
2295 unfolding k by (auto simp: add.commute union_lcomm) |
2295 unfolding k by (auto simp: add.commute union_lcomm) |
2296 qed |
2296 qed |
2297 qed |
2297 qed |
2298 |
2298 |
2299 lemma ex_multiset_of_zip_left: |
2299 lemma ex_mset_zip_left: |
2300 assumes "length xs = length ys" "multiset_of xs' = multiset_of xs" |
2300 assumes "length xs = length ys" "mset xs' = mset xs" |
2301 shows "\<exists>ys'. length ys' = length xs' \<and> multiset_of (zip xs' ys') = multiset_of (zip xs ys)" |
2301 shows "\<exists>ys'. length ys' = length xs' \<and> mset (zip xs' ys') = mset (zip xs ys)" |
2302 using assms |
2302 using assms |
2303 proof (induct xs ys arbitrary: xs' rule: list_induct2) |
2303 proof (induct xs ys arbitrary: xs' rule: list_induct2) |
2304 case Nil |
2304 case Nil |
2305 thus ?case |
2305 thus ?case |
2306 by auto |
2306 by auto |
2307 next |
2307 next |
2308 case (Cons x xs y ys xs') |
2308 case (Cons x xs y ys xs') |
2309 obtain j where j_len: "j < length xs'" and nth_j: "xs' ! j = x" |
2309 obtain j where j_len: "j < length xs'" and nth_j: "xs' ! j = x" |
2310 by (metis Cons.prems in_set_conv_nth list.set_intros(1) multiset_of_eq_setD) |
2310 by (metis Cons.prems in_set_conv_nth list.set_intros(1) mset_eq_setD) |
2311 |
2311 |
2312 def xsa \<equiv> "take j xs' @ drop (Suc j) xs'" |
2312 def xsa \<equiv> "take j xs' @ drop (Suc j) xs'" |
2313 have "multiset_of xs' = {#x#} + multiset_of xsa" |
2313 have "mset xs' = {#x#} + mset xsa" |
2314 unfolding xsa_def using j_len nth_j |
2314 unfolding xsa_def using j_len nth_j |
2315 by (metis (no_types) ab_semigroup_add_class.add_ac(1) append_take_drop_id Cons_nth_drop_Suc |
2315 by (metis (no_types) ab_semigroup_add_class.add_ac(1) append_take_drop_id Cons_nth_drop_Suc |
2316 multiset_of.simps(2) union_code add.commute) |
2316 mset.simps(2) union_code add.commute) |
2317 hence ms_x: "multiset_of xsa = multiset_of xs" |
2317 hence ms_x: "mset xsa = mset xs" |
2318 by (metis Cons.prems add.commute add_right_imp_eq multiset_of.simps(2)) |
2318 by (metis Cons.prems add.commute add_right_imp_eq mset.simps(2)) |
2319 then obtain ysa where |
2319 then obtain ysa where |
2320 len_a: "length ysa = length xsa" and ms_a: "multiset_of (zip xsa ysa) = multiset_of (zip xs ys)" |
2320 len_a: "length ysa = length xsa" and ms_a: "mset (zip xsa ysa) = mset (zip xs ys)" |
2321 using Cons.hyps(2) by blast |
2321 using Cons.hyps(2) by blast |
2322 |
2322 |
2323 def ys' \<equiv> "take j ysa @ y # drop j ysa" |
2323 def ys' \<equiv> "take j ysa @ y # drop j ysa" |
2324 have xs': "xs' = take j xsa @ x # drop j xsa" |
2324 have xs': "xs' = take j xsa @ x # drop j xsa" |
2325 using ms_x j_len nth_j Cons.prems xsa_def |
2325 using ms_x j_len nth_j Cons.prems xsa_def |
2326 by (metis append_eq_append_conv append_take_drop_id diff_Suc_Suc Cons_nth_drop_Suc length_Cons |
2326 by (metis append_eq_append_conv append_take_drop_id diff_Suc_Suc Cons_nth_drop_Suc length_Cons |
2327 length_drop size_multiset_of) |
2327 length_drop size_mset) |
2328 have j_len': "j \<le> length xsa" |
2328 have j_len': "j \<le> length xsa" |
2329 using j_len xs' xsa_def |
2329 using j_len xs' xsa_def |
2330 by (metis add_Suc_right append_take_drop_id length_Cons length_append less_eq_Suc_le not_less) |
2330 by (metis add_Suc_right append_take_drop_id length_Cons length_append less_eq_Suc_le not_less) |
2331 have "length ys' = length xs'" |
2331 have "length ys' = length xs'" |
2332 unfolding ys'_def using Cons.prems len_a ms_x |
2332 unfolding ys'_def using Cons.prems len_a ms_x |
2333 by (metis add_Suc_right append_take_drop_id length_Cons length_append multiset_of_eq_length) |
2333 by (metis add_Suc_right append_take_drop_id length_Cons length_append mset_eq_length) |
2334 moreover have "multiset_of (zip xs' ys') = multiset_of (zip (x # xs) (y # ys))" |
2334 moreover have "mset (zip xs' ys') = mset (zip (x # xs) (y # ys))" |
2335 unfolding xs' ys'_def |
2335 unfolding xs' ys'_def |
2336 by (rule trans[OF multiset_of_zip_take_Cons_drop_twice]) |
2336 by (rule trans[OF mset_zip_take_Cons_drop_twice]) |
2337 (auto simp: len_a ms_a j_len' add.commute) |
2337 (auto simp: len_a ms_a j_len' add.commute) |
2338 ultimately show ?case |
2338 ultimately show ?case |
2339 by blast |
2339 by blast |
2340 qed |
2340 qed |
2341 |
2341 |
2342 lemma list_all2_reorder_left_invariance: |
2342 lemma list_all2_reorder_left_invariance: |
2343 assumes rel: "list_all2 R xs ys" and ms_x: "multiset_of xs' = multiset_of xs" |
2343 assumes rel: "list_all2 R xs ys" and ms_x: "mset xs' = mset xs" |
2344 shows "\<exists>ys'. list_all2 R xs' ys' \<and> multiset_of ys' = multiset_of ys" |
2344 shows "\<exists>ys'. list_all2 R xs' ys' \<and> mset ys' = mset ys" |
2345 proof - |
2345 proof - |
2346 have len: "length xs = length ys" |
2346 have len: "length xs = length ys" |
2347 using rel list_all2_conv_all_nth by auto |
2347 using rel list_all2_conv_all_nth by auto |
2348 obtain ys' where |
2348 obtain ys' where |
2349 len': "length xs' = length ys'" and ms_xy: "multiset_of (zip xs' ys') = multiset_of (zip xs ys)" |
2349 len': "length xs' = length ys'" and ms_xy: "mset (zip xs' ys') = mset (zip xs ys)" |
2350 using len ms_x by (metis ex_multiset_of_zip_left) |
2350 using len ms_x by (metis ex_mset_zip_left) |
2351 have "list_all2 R xs' ys'" |
2351 have "list_all2 R xs' ys'" |
2352 using assms(1) len' ms_xy unfolding list_all2_iff by (blast dest: multiset_of_eq_setD) |
2352 using assms(1) len' ms_xy unfolding list_all2_iff by (blast dest: mset_eq_setD) |
2353 moreover have "multiset_of ys' = multiset_of ys" |
2353 moreover have "mset ys' = mset ys" |
2354 using len len' ms_xy map_snd_zip multiset_of_map by metis |
2354 using len len' ms_xy map_snd_zip mset_map by metis |
2355 ultimately show ?thesis |
2355 ultimately show ?thesis |
2356 by blast |
2356 by blast |
2357 qed |
2357 qed |
2358 |
2358 |
2359 lemma ex_multiset_of: "\<exists>xs. multiset_of xs = X" |
2359 lemma ex_mset: "\<exists>xs. mset xs = X" |
2360 by (induct X) (simp, metis multiset_of.simps(2)) |
2360 by (induct X) (simp, metis mset.simps(2)) |
2361 |
2361 |
2362 bnf "'a multiset" |
2362 bnf "'a multiset" |
2363 map: image_mset |
2363 map: image_mset |
2364 sets: set_mset |
2364 sets: set_mset |
2365 bd: natLeq |
2365 bd: natLeq |