src/HOL/Library/Multiset.thy
changeset 79800 abb5e57c92a7
parent 79575 b21d8401f0ca
child 79971 033f90dc441d
equal deleted inserted replaced
79799:2746dfc9ceae 79800:abb5e57c92a7
   241 proof -
   241 proof -
   242   have "\<exists>x. x \<in># A" by (rule ccontr) (insert assms, auto)
   242   have "\<exists>x. x \<in># A" by (rule ccontr) (insert assms, auto)
   243   with that show ?thesis by blast
   243   with that show ?thesis by blast
   244 qed
   244 qed
   245 
   245 
       
   246 lemma count_gt_imp_in_mset: "count M x > n \<Longrightarrow> x \<in># M"
       
   247   using count_greater_zero_iff by fastforce
       
   248 
   246 
   249 
   247 subsubsection \<open>Union\<close>
   250 subsubsection \<open>Union\<close>
   248 
   251 
   249 lemma count_union [simp]:
   252 lemma count_union [simp]:
   250   "count (M + N) a = count M a + count N a"
   253   "count (M + N) a = count M a + count N a"
   390 abbreviation Min_mset :: "'a::linorder multiset \<Rightarrow> 'a" where
   393 abbreviation Min_mset :: "'a::linorder multiset \<Rightarrow> 'a" where
   391 "Min_mset m \<equiv> Min (set_mset m)"
   394 "Min_mset m \<equiv> Min (set_mset m)"
   392 
   395 
   393 abbreviation Max_mset :: "'a::linorder multiset \<Rightarrow> 'a" where
   396 abbreviation Max_mset :: "'a::linorder multiset \<Rightarrow> 'a" where
   394 "Max_mset m \<equiv> Max (set_mset m)"
   397 "Max_mset m \<equiv> Max (set_mset m)"
       
   398 
       
   399 lemma
       
   400   Min_in_mset: "M \<noteq> {#} \<Longrightarrow> Min_mset M \<in># M" and
       
   401   Max_in_mset: "M \<noteq> {#} \<Longrightarrow> Max_mset M \<in># M"
       
   402   by simp+
   395 
   403 
   396 
   404 
   397 subsubsection \<open>Equality of multisets\<close>
   405 subsubsection \<open>Equality of multisets\<close>
   398 
   406 
   399 lemma single_eq_single [simp]: "{#a#} = {#b#} \<longleftrightarrow> a = b"
   407 lemma single_eq_single [simp]: "{#a#} = {#b#} \<longleftrightarrow> a = b"
   681   then have \<open>a = b\<close>
   689   then have \<open>a = b\<close>
   682     by (auto dest: mset_subset_eq_insertD)
   690     by (auto dest: mset_subset_eq_insertD)
   683   then show "M={#} \<and> a=b"
   691   then show "M={#} \<and> a=b"
   684     using A by (simp add: mset_subset_eq_add_mset_cancel)
   692     using A by (simp add: mset_subset_eq_add_mset_cancel)
   685 qed simp
   693 qed simp
       
   694 
       
   695 lemma nonempty_subseteq_mset_eq_single: "M \<noteq> {#} \<Longrightarrow> M \<subseteq># {#x#} \<Longrightarrow> M = {#x#}"
       
   696   by (cases M) (metis single_is_union subset_mset.less_eqE)
       
   697 
       
   698 lemma nonempty_subseteq_mset_iff_single: "(M \<noteq> {#} \<and> M \<subseteq># {#x#} \<and> P) \<longleftrightarrow> M = {#x#} \<and> P"
       
   699   by (cases M) (metis empty_not_add_mset nonempty_subseteq_mset_eq_single subset_mset.order_refl)
   686 
   700 
   687 
   701 
   688 subsubsection \<open>Intersection and bounded union\<close>
   702 subsubsection \<open>Intersection and bounded union\<close>
   689 
   703 
   690 definition inter_mset :: \<open>'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset\<close>  (infixl \<open>\<inter>#\<close> 70)
   704 definition inter_mset :: \<open>'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset\<close>  (infixl \<open>\<inter>#\<close> 70)
  1372   assumes "M = M'" and "\<And>x. x \<in># M' \<Longrightarrow> f x \<longleftrightarrow> g x"
  1386   assumes "M = M'" and "\<And>x. x \<in># M' \<Longrightarrow> f x \<longleftrightarrow> g x"
  1373   shows "filter_mset f M = filter_mset g M'"
  1387   shows "filter_mset f M = filter_mset g M'"
  1374   unfolding \<open>M = M'\<close>
  1388   unfolding \<open>M = M'\<close>
  1375   using assms by (auto intro: filter_mset_cong0)
  1389   using assms by (auto intro: filter_mset_cong0)
  1376 
  1390 
       
  1391 lemma filter_eq_replicate_mset: "{#y \<in># D. y = x#} = replicate_mset (count D x) x"
       
  1392   by (induct D) (simp add: multiset_eqI)
       
  1393 
  1377 
  1394 
  1378 subsubsection \<open>Size\<close>
  1395 subsubsection \<open>Size\<close>
  1379 
  1396 
  1380 definition wcount where "wcount f M = (\<lambda>x. count M x * Suc (f x))"
  1397 definition wcount where "wcount f M = (\<lambda>x. count M x * Suc (f x))"
  1381 
  1398 
  1477 by (rule size_mset_mono[OF multiset_filter_subset])
  1494 by (rule size_mset_mono[OF multiset_filter_subset])
  1478 
  1495 
  1479 lemma size_Diff_submset:
  1496 lemma size_Diff_submset:
  1480   "M \<subseteq># M' \<Longrightarrow> size (M' - M) = size M' - size(M::'a multiset)"
  1497   "M \<subseteq># M' \<Longrightarrow> size (M' - M) = size M' - size(M::'a multiset)"
  1481 by (metis add_diff_cancel_left' size_union mset_subset_eq_exists_conv)
  1498 by (metis add_diff_cancel_left' size_union mset_subset_eq_exists_conv)
       
  1499 
       
  1500 lemma size_lt_imp_ex_count_lt: "size M < size N \<Longrightarrow> \<exists>x \<in># N. count M x < count N x"
       
  1501   by (metis count_eq_zero_iff leD not_le_imp_less not_less_zero size_mset_mono subseteq_mset_def)
  1482 
  1502 
  1483 
  1503 
  1484 subsection \<open>Induction and case splits\<close>
  1504 subsection \<open>Induction and case splits\<close>
  1485 
  1505 
  1486 theorem multiset_induct [case_names empty add, induct type: multiset]:
  1506 theorem multiset_induct [case_names empty add, induct type: multiset]:
  1640 definition fold_mset :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a multiset \<Rightarrow> 'b"
  1660 definition fold_mset :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a multiset \<Rightarrow> 'b"
  1641 where
  1661 where
  1642   "fold_mset f s M = Finite_Set.fold (\<lambda>x. f x ^^ count M x) s (set_mset M)"
  1662   "fold_mset f s M = Finite_Set.fold (\<lambda>x. f x ^^ count M x) s (set_mset M)"
  1643 
  1663 
  1644 lemma fold_mset_empty [simp]: "fold_mset f s {#} = s"
  1664 lemma fold_mset_empty [simp]: "fold_mset f s {#} = s"
       
  1665   by (simp add: fold_mset_def)
       
  1666 
       
  1667 lemma fold_mset_single [simp]: "fold_mset f s {#x#} = f x s"
  1645   by (simp add: fold_mset_def)
  1668   by (simp add: fold_mset_def)
  1646 
  1669 
  1647 context comp_fun_commute
  1670 context comp_fun_commute
  1648 begin
  1671 begin
  1649 
  1672 
  1672       by (auto intro!: Finite_Set.fold_cong comp_fun_commute_on_funpow)
  1695       by (auto intro!: Finite_Set.fold_cong comp_fun_commute_on_funpow)
  1673     with * show ?thesis by (simp add: fold_mset_def del: count_add_mset) simp
  1696     with * show ?thesis by (simp add: fold_mset_def del: count_add_mset) simp
  1674   qed
  1697   qed
  1675 qed
  1698 qed
  1676 
  1699 
  1677 corollary fold_mset_single: "fold_mset f s {#x#} = f x s"
       
  1678   by simp
       
  1679 
       
  1680 lemma fold_mset_fun_left_comm: "f x (fold_mset f s M) = fold_mset f (f x s) M"
  1700 lemma fold_mset_fun_left_comm: "f x (fold_mset f s M) = fold_mset f (f x s) M"
  1681   by (induct M) (simp_all add: fun_left_comm)
  1701   by (induct M) (simp_all add: fun_left_comm)
  1682 
  1702 
  1683 lemma fold_mset_union [simp]: "fold_mset f s (M + N) = fold_mset f (fold_mset f s M) N"
  1703 lemma fold_mset_union [simp]: "fold_mset f s (M + N) = fold_mset f (fold_mset f s M) N"
  1684   by (induct M) (simp_all add: fold_mset_fun_left_comm)
  1704   by (induct M) (simp_all add: fold_mset_fun_left_comm)
  1846   by (induct M) simp_all
  1866   by (induct M) simp_all
  1847 
  1867 
  1848 lemma image_mset_filter_mset_swap:
  1868 lemma image_mset_filter_mset_swap:
  1849   "image_mset f (filter_mset (\<lambda>x. P (f x)) M) = filter_mset P (image_mset f M)"
  1869   "image_mset f (filter_mset (\<lambda>x. P (f x)) M) = filter_mset P (image_mset f M)"
  1850   by (induction M rule: multiset_induct) simp_all
  1870   by (induction M rule: multiset_induct) simp_all
  1851 
       
  1852 
  1871 
  1853 lemma image_mset_eq_plusD:
  1872 lemma image_mset_eq_plusD:
  1854   "image_mset f A = B + C \<Longrightarrow> \<exists>B' C'. A = B' + C' \<and> B = image_mset f B' \<and> C = image_mset f C'"
  1873   "image_mset f A = B + C \<Longrightarrow> \<exists>B' C'. A = B' + C' \<and> B = image_mset f B' \<and> C = image_mset f C'"
  1855 proof (induction A arbitrary: B C)
  1874 proof (induction A arbitrary: B C)
  1856   case empty
  1875   case empty
  2276     using finite_imageD by blast
  2295     using finite_imageD by blast
  2277   from \<open>infinite A\<close> \<open>infinite (f ` A)\<close> show ?thesis by simp
  2296   from \<open>infinite A\<close> \<open>infinite (f ` A)\<close> show ?thesis by simp
  2278 qed
  2297 qed
  2279 
  2298 
  2280 
  2299 
  2281 subsection \<open>More properties of the replicate and repeat operations\<close>
  2300 subsection \<open>More properties of the replicate, repeat, and image operations\<close>
  2282 
  2301 
  2283 lemma in_replicate_mset[simp]: "x \<in># replicate_mset n y \<longleftrightarrow> n > 0 \<and> x = y"
  2302 lemma in_replicate_mset[simp]: "x \<in># replicate_mset n y \<longleftrightarrow> n > 0 \<and> x = y"
  2284   unfolding replicate_mset_def by (induct n) auto
  2303   unfolding replicate_mset_def by (induct n) auto
  2285 
  2304 
  2286 lemma set_mset_replicate_mset_subset[simp]: "set_mset (replicate_mset n x) = (if n = 0 then {} else {x})"
  2305 lemma set_mset_replicate_mset_subset[simp]: "set_mset (replicate_mset n x) = (if n = 0 then {} else {x})"
  2289 lemma size_replicate_mset[simp]: "size (replicate_mset n M) = n"
  2308 lemma size_replicate_mset[simp]: "size (replicate_mset n M) = n"
  2290   by (induct n, simp_all)
  2309   by (induct n, simp_all)
  2291 
  2310 
  2292 lemma count_le_replicate_mset_subset_eq: "n \<le> count M x \<longleftrightarrow> replicate_mset n x \<subseteq># M"
  2311 lemma count_le_replicate_mset_subset_eq: "n \<le> count M x \<longleftrightarrow> replicate_mset n x \<subseteq># M"
  2293   by (auto simp add: mset_subset_eqI) (metis count_replicate_mset subseteq_mset_def)
  2312   by (auto simp add: mset_subset_eqI) (metis count_replicate_mset subseteq_mset_def)
  2294 
       
  2295 lemma filter_eq_replicate_mset: "{#y \<in># D. y = x#} = replicate_mset (count D x) x"
       
  2296   by (induct D) simp_all
       
  2297 
  2313 
  2298 lemma replicate_count_mset_eq_filter_eq: "replicate (count (mset xs) k) k = filter (HOL.eq k) xs"
  2314 lemma replicate_count_mset_eq_filter_eq: "replicate (count (mset xs) k) k = filter (HOL.eq k) xs"
  2299   by (induct xs) auto
  2315   by (induct xs) auto
  2300 
  2316 
  2301 lemma replicate_mset_eq_empty_iff [simp]: "replicate_mset n a = {#} \<longleftrightarrow> n = 0"
  2317 lemma replicate_mset_eq_empty_iff [simp]: "replicate_mset n a = {#} \<longleftrightarrow> n = 0"
  2352   with assms have "m \<le> n"
  2368   with assms have "m \<le> n"
  2353     by (auto simp add: replicate_mset_msubseteq_iff)
  2369     by (auto simp add: replicate_mset_msubseteq_iff)
  2354   then show thesis using A ..
  2370   then show thesis using A ..
  2355 qed
  2371 qed
  2356 
  2372 
       
  2373 lemma count_image_mset_lt_imp_lt_raw:
       
  2374   assumes
       
  2375     "finite A" and
       
  2376     "A = set_mset M \<union> set_mset N" and
       
  2377     "count (image_mset f M) b < count (image_mset f N) b"
       
  2378   shows "\<exists>x. f x = b \<and> count M x < count N x"
       
  2379   using assms
       
  2380 proof (induct A arbitrary: M N b rule: finite_induct)
       
  2381   case (insert x F)
       
  2382   note fin = this(1) and x_ni_f = this(2) and ih = this(3) and x_f_eq_m_n = this(4) and
       
  2383     cnt_b = this(5)
       
  2384 
       
  2385   let ?Ma = "{#y \<in># M. y \<noteq> x#}"
       
  2386   let ?Mb = "{#y \<in># M. y = x#}"
       
  2387   let ?Na = "{#y \<in># N. y \<noteq> x#}"
       
  2388   let ?Nb = "{#y \<in># N. y = x#}"
       
  2389 
       
  2390   have m_part: "M = ?Mb + ?Ma" and n_part: "N = ?Nb + ?Na"
       
  2391     using multiset_partition by blast+
       
  2392 
       
  2393   have f_eq_ma_na: "F = set_mset ?Ma \<union> set_mset ?Na"
       
  2394     using x_f_eq_m_n x_ni_f by auto
       
  2395 
       
  2396   show ?case
       
  2397   proof (cases "count (image_mset f ?Ma) b < count (image_mset f ?Na) b")
       
  2398     case cnt_ba: True
       
  2399     obtain xa where "f xa = b" and "count ?Ma xa < count ?Na xa"
       
  2400       using ih[OF f_eq_ma_na cnt_ba] by blast
       
  2401     thus ?thesis
       
  2402       by (metis count_filter_mset not_less0)
       
  2403   next
       
  2404     case cnt_ba: False
       
  2405     have fx_eq_b: "f x = b"
       
  2406       using cnt_b cnt_ba
       
  2407       by (subst (asm) m_part, subst (asm) n_part,
       
  2408           auto simp: filter_eq_replicate_mset split: if_splits)
       
  2409     moreover have "count M x < count N x"
       
  2410       using cnt_b cnt_ba
       
  2411       by (subst (asm) m_part, subst (asm) n_part,
       
  2412           auto simp: filter_eq_replicate_mset split: if_splits)
       
  2413     ultimately show ?thesis
       
  2414       by blast
       
  2415   qed
       
  2416 qed auto
       
  2417 
       
  2418 lemma count_image_mset_lt_imp_lt:
       
  2419   assumes cnt_b: "count (image_mset f M) b < count (image_mset f N) b"
       
  2420   shows "\<exists>x. f x = b \<and> count M x < count N x"
       
  2421   by (rule count_image_mset_lt_imp_lt_raw[of "set_mset M \<union> set_mset N", OF _ refl cnt_b]) auto
       
  2422 
       
  2423 lemma count_image_mset_le_imp_lt_raw:
       
  2424   assumes
       
  2425     "finite A" and
       
  2426     "A = set_mset M \<union> set_mset N" and
       
  2427     "count (image_mset f M) (f a) + count N a < count (image_mset f N) (f a) + count M a"
       
  2428   shows "\<exists>b. f b = f a \<and> count M b < count N b"
       
  2429   using assms
       
  2430 proof (induct A arbitrary: M N rule: finite_induct)
       
  2431   case (insert x F)
       
  2432   note fin = this(1) and x_ni_f = this(2) and ih = this(3) and x_f_eq_m_n = this(4) and
       
  2433     cnt_lt = this(5)
       
  2434 
       
  2435   let ?Ma = "{#y \<in># M. y \<noteq> x#}"
       
  2436   let ?Mb = "{#y \<in># M. y = x#}"
       
  2437   let ?Na = "{#y \<in># N. y \<noteq> x#}"
       
  2438   let ?Nb = "{#y \<in># N. y = x#}"
       
  2439 
       
  2440   have m_part: "M = ?Mb + ?Ma" and n_part: "N = ?Nb + ?Na"
       
  2441     using multiset_partition by blast+
       
  2442 
       
  2443   have f_eq_ma_na: "F = set_mset ?Ma \<union> set_mset ?Na"
       
  2444     using x_f_eq_m_n x_ni_f by auto
       
  2445 
       
  2446   show ?case
       
  2447   proof (cases "f x = f a")
       
  2448     case fx_ne_fa: False
       
  2449 
       
  2450     have cnt_fma_fa: "count (image_mset f ?Ma) (f a) = count (image_mset f M) (f a)"
       
  2451       using fx_ne_fa by (subst (2) m_part) (auto simp: filter_eq_replicate_mset)
       
  2452     have cnt_fna_fa: "count (image_mset f ?Na) (f a) = count (image_mset f N) (f a)"
       
  2453       using fx_ne_fa by (subst (2) n_part) (auto simp: filter_eq_replicate_mset)
       
  2454     have cnt_ma_a: "count ?Ma a = count M a"
       
  2455       using fx_ne_fa by (subst (2) m_part) (auto simp: filter_eq_replicate_mset)
       
  2456     have cnt_na_a: "count ?Na a = count N a"
       
  2457       using fx_ne_fa by (subst (2) n_part) (auto simp: filter_eq_replicate_mset)
       
  2458 
       
  2459     obtain b where fb_eq_fa: "f b = f a" and cnt_b: "count ?Ma b < count ?Na b"
       
  2460       using ih[OF f_eq_ma_na] cnt_lt unfolding cnt_fma_fa cnt_fna_fa cnt_ma_a cnt_na_a by blast
       
  2461     have fx_ne_fb: "f x \<noteq> f b"
       
  2462       using fb_eq_fa fx_ne_fa by simp
       
  2463 
       
  2464     have cnt_ma_b: "count ?Ma b = count M b"
       
  2465       using fx_ne_fb by (subst (2) m_part) auto
       
  2466     have cnt_na_b: "count ?Na b = count N b"
       
  2467       using fx_ne_fb by (subst (2) n_part) auto
       
  2468 
       
  2469     show ?thesis
       
  2470       using fb_eq_fa cnt_b unfolding cnt_ma_b cnt_na_b by blast
       
  2471   next
       
  2472     case fx_eq_fa: True
       
  2473     show ?thesis
       
  2474     proof (cases "x = a")
       
  2475       case x_eq_a: True
       
  2476       have "count (image_mset f ?Ma) (f a) + count ?Na a
       
  2477         < count (image_mset f ?Na) (f a) + count ?Ma a"
       
  2478         using cnt_lt x_eq_a by (subst (asm) (1 2) m_part, subst (asm) (1 2) n_part,
       
  2479             auto simp: filter_eq_replicate_mset)
       
  2480       thus ?thesis
       
  2481         using ih[OF f_eq_ma_na] by (metis count_filter_mset nat_neq_iff)
       
  2482     next
       
  2483       case x_ne_a: False
       
  2484       show ?thesis
       
  2485       proof (cases "count M x < count N x")
       
  2486         case True
       
  2487         thus ?thesis
       
  2488           using fx_eq_fa by blast
       
  2489      next
       
  2490         case False
       
  2491         hence cnt_x: "count M x \<ge> count N x"
       
  2492           by fastforce
       
  2493         have "count M x + count (image_mset f ?Ma) (f a) + count ?Na a
       
  2494           < count N x + count (image_mset f ?Na) (f a) + count ?Ma a"
       
  2495           using cnt_lt x_ne_a fx_eq_fa by (subst (asm) (1 2) m_part, subst (asm) (1 2) n_part,
       
  2496             auto simp: filter_eq_replicate_mset)
       
  2497         hence "count (image_mset f ?Ma) (f a) + count ?Na a
       
  2498           < count (image_mset f ?Na) (f a) + count ?Ma a"
       
  2499           using cnt_x by linarith
       
  2500         thus ?thesis
       
  2501           using ih[OF f_eq_ma_na] by (metis count_filter_mset nat_neq_iff)
       
  2502       qed
       
  2503     qed
       
  2504   qed
       
  2505 qed auto
       
  2506 
       
  2507 lemma count_image_mset_le_imp_lt:
       
  2508   assumes
       
  2509     "count (image_mset f M) (f a) \<le> count (image_mset f N) (f a)" and
       
  2510     "count M a > count N a"
       
  2511   shows "\<exists>b. f b = f a \<and> count M b < count N b"
       
  2512   using assms by (auto intro: count_image_mset_le_imp_lt_raw[of "set_mset M \<union> set_mset N"])
       
  2513 
       
  2514 lemma size_filter_unsat_elem:
       
  2515   assumes "x \<in># M" and "\<not> P x"
       
  2516   shows "size {#x \<in># M. P x#} < size M"
       
  2517 proof -
       
  2518   have "size (filter_mset P M) \<noteq> size M"
       
  2519     using assms by (metis add.right_neutral add_diff_cancel_left' count_filter_mset mem_Collect_eq
       
  2520       multiset_partition nonempty_has_size set_mset_def size_union)
       
  2521   then show ?thesis
       
  2522     by (meson leD nat_neq_iff size_filter_mset_lesseq)
       
  2523 qed
       
  2524 
       
  2525 lemma size_filter_ne_elem: "x \<in># M \<Longrightarrow> size {#y \<in># M. y \<noteq> x#} < size M"
       
  2526   by (simp add: size_filter_unsat_elem[of x M "\<lambda>y. y \<noteq> x"])
       
  2527 
       
  2528 lemma size_eq_ex_count_lt:
       
  2529   assumes
       
  2530     sz_m_eq_n: "size M = size N" and
       
  2531     m_eq_n: "M \<noteq> N"
       
  2532   shows "\<exists>x. count M x < count N x"
       
  2533 proof -
       
  2534   obtain x where "count M x \<noteq> count N x"
       
  2535     using m_eq_n by (meson multiset_eqI)
       
  2536   moreover
       
  2537   {
       
  2538     assume "count M x < count N x"
       
  2539     hence ?thesis
       
  2540       by blast
       
  2541   }
       
  2542   moreover
       
  2543   {
       
  2544     assume cnt_x: "count M x > count N x"
       
  2545 
       
  2546     have "size {#y \<in># M. y = x#} + size {#y \<in># M. y \<noteq> x#} =
       
  2547       size {#y \<in># N. y = x#} + size {#y \<in># N. y \<noteq> x#}"
       
  2548       using sz_m_eq_n multiset_partition by (metis size_union)
       
  2549     hence sz_m_minus_x: "size {#y \<in># M. y \<noteq> x#} < size {#y \<in># N. y \<noteq> x#}"
       
  2550       using cnt_x by (simp add: filter_eq_replicate_mset)
       
  2551     then obtain y where "count {#y \<in># M. y \<noteq> x#} y < count {#y \<in># N. y \<noteq> x#} y"
       
  2552       using size_lt_imp_ex_count_lt[OF sz_m_minus_x] by blast
       
  2553     hence "count M y < count N y"
       
  2554       by (metis count_filter_mset less_asym)
       
  2555     hence ?thesis
       
  2556       by blast
       
  2557   }
       
  2558   ultimately show ?thesis
       
  2559     by fastforce
       
  2560 qed
       
  2561 
  2357 
  2562 
  2358 subsection \<open>Big operators\<close>
  2563 subsection \<open>Big operators\<close>
  2359 
  2564 
  2360 locale comm_monoid_mset = comm_monoid
  2565 locale comm_monoid_mset = comm_monoid
  2361 begin
  2566 begin
  2568 lemma Union_mset_empty_conv[simp]: "\<Sum>\<^sub># M = {#} \<longleftrightarrow> (\<forall>i\<in>#M. i = {#})"
  2773 lemma Union_mset_empty_conv[simp]: "\<Sum>\<^sub># M = {#} \<longleftrightarrow> (\<forall>i\<in>#M. i = {#})"
  2569   by (induction M) auto
  2774   by (induction M) auto
  2570 
  2775 
  2571 lemma Union_image_single_mset[simp]: "\<Sum>\<^sub># (image_mset (\<lambda>x. {#x#}) m) = m"
  2776 lemma Union_image_single_mset[simp]: "\<Sum>\<^sub># (image_mset (\<lambda>x. {#x#}) m) = m"
  2572 by(induction m) auto
  2777 by(induction m) auto
  2573 
       
  2574 
  2778 
  2575 context comm_monoid_mult
  2779 context comm_monoid_mult
  2576 begin
  2780 begin
  2577 
  2781 
  2578 sublocale prod_mset: comm_monoid_mset times 1
  2782 sublocale prod_mset: comm_monoid_mset times 1