src/HOL/Library/Multiset.thy
changeset 63908 ca41b6670904
parent 63882 018998c00003
child 63919 9aed2da07200
child 63921 0a5184877cb7
equal deleted inserted replaced
63907:36bac3d245d9 63908:ca41b6670904
   872 subsubsection \<open>Subset is an order\<close>
   872 subsubsection \<open>Subset is an order\<close>
   873 
   873 
   874 interpretation subset_mset: order "op \<le>#" "op <#" by unfold_locales auto
   874 interpretation subset_mset: order "op \<le>#" "op <#" by unfold_locales auto
   875 
   875 
   876 
   876 
   877 subsubsection \<open>Simprocs\<close>
   877 subsection \<open>Replicate and repeat operations\<close>
       
   878 
       
   879 definition replicate_mset :: "nat \<Rightarrow> 'a \<Rightarrow> 'a multiset" where
       
   880   "replicate_mset n x = (add_mset x ^^ n) {#}"
       
   881 
       
   882 lemma replicate_mset_0[simp]: "replicate_mset 0 x = {#}"
       
   883   unfolding replicate_mset_def by simp
       
   884 
       
   885 lemma replicate_mset_Suc [simp]: "replicate_mset (Suc n) x = add_mset x (replicate_mset n x)"
       
   886   unfolding replicate_mset_def by (induct n) (auto intro: add.commute)
       
   887 
       
   888 lemma count_replicate_mset[simp]: "count (replicate_mset n x) y = (if y = x then n else 0)"
       
   889   unfolding replicate_mset_def by (induct n) auto
   878 
   890 
   879 fun repeat_mset :: "nat \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset" where
   891 fun repeat_mset :: "nat \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset" where
   880   "repeat_mset 0 _ = {#}" |
   892   "repeat_mset 0 _ = {#}" |
   881   "repeat_mset (Suc n) A = A + repeat_mset n A"
   893   "repeat_mset (Suc n) A = A + repeat_mset n A"
   882 
   894 
   887   by (auto simp: multiset_eq_iff left_diff_distrib')
   899   by (auto simp: multiset_eq_iff left_diff_distrib')
   888 
   900 
   889 lemma left_diff_repeat_mset_distrib': \<open>repeat_mset (i - j) u = repeat_mset i u - repeat_mset j u\<close>
   901 lemma left_diff_repeat_mset_distrib': \<open>repeat_mset (i - j) u = repeat_mset i u - repeat_mset j u\<close>
   890   by (auto simp: multiset_eq_iff left_diff_distrib')
   902   by (auto simp: multiset_eq_iff left_diff_distrib')
   891 
   903 
       
   904 lemma left_add_mult_distrib_mset:
       
   905   "repeat_mset i u + (repeat_mset j u + k) = repeat_mset (i+j) u + k"
       
   906   by (auto simp: multiset_eq_iff add_mult_distrib)
       
   907 
       
   908 lemma repeat_mset_distrib:
       
   909   "repeat_mset (m + n) A = repeat_mset m A + repeat_mset n A"
       
   910   by (auto simp: multiset_eq_iff Nat.add_mult_distrib)
       
   911 
       
   912 lemma repeat_mset_distrib2[simp]:
       
   913   "repeat_mset n (A + B) = repeat_mset n A + repeat_mset n B"
       
   914   by (auto simp: multiset_eq_iff add_mult_distrib2)
       
   915 
       
   916 lemma repeat_mset_replicate_mset[simp]:
       
   917   "repeat_mset n {#a#} = replicate_mset n a"
       
   918   by (auto simp: multiset_eq_iff)
       
   919 
       
   920 lemma repeat_mset_distrib_add_mset[simp]:
       
   921   "repeat_mset n (add_mset a A) = replicate_mset n a + repeat_mset n A"
       
   922   by (auto simp: multiset_eq_iff)
       
   923 
       
   924 lemma repeat_mset_empty[simp]: "repeat_mset n {#} = {#}"
       
   925   by (induction n) simp_all
       
   926 
       
   927 
       
   928 subsubsection \<open>Simprocs\<close>
       
   929 
   892 lemma mset_diff_add_eq1:
   930 lemma mset_diff_add_eq1:
   893   "j \<le> (i::nat) \<Longrightarrow> ((repeat_mset i u + m) - (repeat_mset j u + n)) = ((repeat_mset (i-j) u + m) - n)"
   931   "j \<le> (i::nat) \<Longrightarrow> ((repeat_mset i u + m) - (repeat_mset j u + n)) = ((repeat_mset (i-j) u + m) - n)"
   894   by (auto simp: multiset_eq_iff nat_diff_add_eq1)
   932   by (auto simp: multiset_eq_iff nat_diff_add_eq1)
   895 
   933 
   896 lemma mset_diff_add_eq2:
   934 lemma mset_diff_add_eq2:
   919 
   957 
   920 lemma mset_subset_add_iff2:
   958 lemma mset_subset_add_iff2:
   921   "i \<le> (j::nat) \<Longrightarrow> (repeat_mset i u + m \<subset># repeat_mset j u + n) = (m \<subset># repeat_mset (j-i) u + n)"
   959   "i \<le> (j::nat) \<Longrightarrow> (repeat_mset i u + m \<subset># repeat_mset j u + n) = (m \<subset># repeat_mset (j-i) u + n)"
   922   unfolding subset_mset_def by (simp add: mset_eq_add_iff2 mset_subseteq_add_iff2)
   960   unfolding subset_mset_def by (simp add: mset_eq_add_iff2 mset_subseteq_add_iff2)
   923 
   961 
   924 lemma left_add_mult_distrib_mset:
       
   925   "repeat_mset i u + (repeat_mset j u + k) = repeat_mset (i+j) u + k"
       
   926   by (auto simp: multiset_eq_iff add_mult_distrib)
       
   927 
       
   928 lemma repeat_mset_cancel1: "repeat_mset a A = repeat_mset a B \<longleftrightarrow> A = B \<or> a = 0"
       
   929   by (auto simp: multiset_eq_iff)
       
   930 
       
   931 lemma repeat_mset_cancel2: "repeat_mset a A = repeat_mset b A \<longleftrightarrow> a = b \<or> A = {#}"
       
   932   by (auto simp: multiset_eq_iff)
       
   933 
       
   934 lemma repeat_mset_distrib [simp]:
       
   935   "repeat_mset n (A + B) = repeat_mset n A + repeat_mset n B"
       
   936   by (auto simp: multiset_eq_iff add_mult_distrib2)
       
   937 
       
   938 ML_file "multiset_simprocs_util.ML"
   962 ML_file "multiset_simprocs_util.ML"
   939 ML_file "multiset_simprocs.ML"
   963 ML_file "multiset_simprocs.ML"
   940 
   964 
   941 simproc_setup mseteq_cancel_numerals
   965 simproc_setup mseteq_cancel_numerals
   942   ("(l::'a multiset) + m = n" | "(l::'a multiset) = m + n" |
   966   ("(l::'a multiset) + m = n" | "(l::'a multiset) = m + n" |
   943    "add_mset a m = n" | "m = add_mset a n") =
   967    "add_mset a m = n" | "m = add_mset a n" |
       
   968    "replicate_mset p a = n" | "m = replicate_mset p a" |
       
   969    "repeat_mset p m = n" | "m = repeat_mset p m") =
   944   \<open>fn phi => Multiset_Simprocs.eq_cancel_msets\<close>
   970   \<open>fn phi => Multiset_Simprocs.eq_cancel_msets\<close>
   945 
   971 
   946 simproc_setup msetless_cancel_numerals
   972 simproc_setup msetless_cancel_numerals
   947   ("(l::'a multiset) + m \<subset># n" | "(l::'a multiset) \<subset># m + n" |
   973   ("(l::'a multiset) + m \<subset># n" | "(l::'a multiset) \<subset># m + n" |
   948    "add_mset a m \<subset># n" | "m \<subset># add_mset a n") =
   974    "add_mset a m \<subset># n" | "m \<subset># add_mset a n" |
       
   975    "replicate_mset p r \<subset># n" | "m \<subset># replicate_mset p r" |
       
   976    "repeat_mset p m \<subset># n" | "m \<subset># repeat_mset p m") =
   949   \<open>fn phi => Multiset_Simprocs.subset_cancel_msets\<close>
   977   \<open>fn phi => Multiset_Simprocs.subset_cancel_msets\<close>
   950 
   978 
   951 simproc_setup msetle_cancel_numerals
   979 simproc_setup msetle_cancel_numerals
   952   ("(l::'a multiset) + m \<subseteq># n" | "(l::'a multiset) \<subseteq># m + n" |
   980   ("(l::'a multiset) + m \<subseteq># n" | "(l::'a multiset) \<subseteq># m + n" |
   953    "add_mset a m \<subseteq># n" | "m \<subseteq># add_mset a n") =
   981    "add_mset a m \<subseteq># n" | "m \<subseteq># add_mset a n" |
       
   982    "replicate_mset p r \<subseteq># n" | "m \<subseteq># replicate_mset p r" |
       
   983    "repeat_mset p m \<subseteq># n" | "m \<subseteq># repeat_mset p m") =
   954   \<open>fn phi => Multiset_Simprocs.subseteq_cancel_msets\<close>
   984   \<open>fn phi => Multiset_Simprocs.subseteq_cancel_msets\<close>
   955 
   985 
   956 simproc_setup msetdiff_cancel_numerals
   986 simproc_setup msetdiff_cancel_numerals
   957   ("((l::'a multiset) + m) - n" | "(l::'a multiset) - (m + n)" |
   987   ("((l::'a multiset) + m) - n" | "(l::'a multiset) - (m + n)" |
   958    "add_mset a m - n" | "m - add_mset a n") =
   988    "add_mset a m - n" | "m - add_mset a n" |
       
   989    "replicate_mset p r - n" | "m - replicate_mset p r" |
       
   990    "repeat_mset p m - n" | "m - repeat_mset p m") =
   959   \<open>fn phi => Multiset_Simprocs.diff_cancel_msets\<close>
   991   \<open>fn phi => Multiset_Simprocs.diff_cancel_msets\<close>
   960 
   992 
   961 
   993 
   962 subsubsection \<open>Conditionally complete lattice\<close>
   994 subsubsection \<open>Conditionally complete lattice\<close>
   963 
   995 
  1956   also from Cons.prems have "\<dots> = mset (map snd xs)" by (intro Cons.IH) simp_all
  1988   also from Cons.prems have "\<dots> = mset (map snd xs)" by (intro Cons.IH) simp_all
  1957   finally show ?case by simp
  1989   finally show ?case by simp
  1958 qed simp_all
  1990 qed simp_all
  1959 
  1991 
  1960 
  1992 
  1961 subsection \<open>Replicate operation\<close>
  1993 subsection \<open>More properties of the replicate and repeat operations\<close>
  1962 
       
  1963 definition replicate_mset :: "nat \<Rightarrow> 'a \<Rightarrow> 'a multiset" where
       
  1964   "replicate_mset n x = (add_mset x ^^ n) {#}"
       
  1965 
       
  1966 lemma replicate_mset_0[simp]: "replicate_mset 0 x = {#}"
       
  1967   unfolding replicate_mset_def by simp
       
  1968 
       
  1969 lemma replicate_mset_Suc [simp]: "replicate_mset (Suc n) x = add_mset x (replicate_mset n x)"
       
  1970   unfolding replicate_mset_def by (induct n) (auto intro: add.commute)
       
  1971 
  1994 
  1972 lemma in_replicate_mset[simp]: "x \<in># replicate_mset n y \<longleftrightarrow> n > 0 \<and> x = y"
  1995 lemma in_replicate_mset[simp]: "x \<in># replicate_mset n y \<longleftrightarrow> n > 0 \<and> x = y"
  1973   unfolding replicate_mset_def by (induct n) auto
       
  1974 
       
  1975 lemma count_replicate_mset[simp]: "count (replicate_mset n x) y = (if y = x then n else 0)"
       
  1976   unfolding replicate_mset_def by (induct n) auto
  1996   unfolding replicate_mset_def by (induct n) auto
  1977 
  1997 
  1978 lemma set_mset_replicate_mset_subset[simp]: "set_mset (replicate_mset n x) = (if n = 0 then {} else {x})"
  1998 lemma set_mset_replicate_mset_subset[simp]: "set_mset (replicate_mset n x) = (if n = 0 then {} else {x})"
  1979   by (auto split: if_splits)
  1999   by (auto split: if_splits)
  1980 
  2000 
  1998 lemma replicate_mset_eq_iff:
  2018 lemma replicate_mset_eq_iff:
  1999   "replicate_mset m a = replicate_mset n b \<longleftrightarrow>
  2019   "replicate_mset m a = replicate_mset n b \<longleftrightarrow>
  2000     m = 0 \<and> n = 0 \<or> m = n \<and> a = b"
  2020     m = 0 \<and> n = 0 \<or> m = n \<and> a = b"
  2001   by (auto simp add: multiset_eq_iff)
  2021   by (auto simp add: multiset_eq_iff)
  2002 
  2022 
  2003 lemma repeat_mset_replicate_mset[simp]:
  2023 lemma repeat_mset_cancel1: "repeat_mset a A = repeat_mset a B \<longleftrightarrow> A = B \<or> a = 0"
  2004   "repeat_mset n {#a#} = replicate_mset n a"
       
  2005   by (auto simp: multiset_eq_iff)
  2024   by (auto simp: multiset_eq_iff)
  2006 
  2025 
  2007 lemma repeat_mset_distrib_add_mset[simp]:
  2026 lemma repeat_mset_cancel2: "repeat_mset a A = repeat_mset b A \<longleftrightarrow> a = b \<or> A = {#}"
  2008   "repeat_mset n (add_mset a A) = replicate_mset n a + repeat_mset n A"
       
  2009   by (auto simp: multiset_eq_iff)
  2027   by (auto simp: multiset_eq_iff)
  2010 
  2028 
  2011 
  2029 
  2012 subsection \<open>Big operators\<close>
  2030 subsection \<open>Big operators\<close>
  2013 
  2031