merged
authorbulwahn
Fri Jan 22 15:26:29 2010 +0100 (2010-01-22)
changeset 34958dcd0fa5cc6d3
parent 34957 3b1957113753
parent 34947 e1b8f2736404
child 34961 e8cdef6d47c0
merged
src/HOL/IsaMakefile
     1.1 --- a/NEWS	Fri Jan 22 11:42:28 2010 +0100
     1.2 +++ b/NEWS	Fri Jan 22 15:26:29 2010 +0100
     1.3 @@ -12,6 +12,15 @@
     1.4  
     1.5  *** HOL ***
     1.6  
     1.7 +* Various old-style primrec specifications in the HOL theories have been
     1.8 +replaced by new-style primrec, especially in theory List.  The corresponding
     1.9 +constants now have authentic syntax.  INCOMPATIBILITY.
    1.10 +
    1.11 +* Reorganized theory Multiset.thy: less duplication, less historical
    1.12 +organization of sections, conversion from associations lists to
    1.13 +multisets, rudimentary code generation.  Use insert_DiffM2 [symmetric]
    1.14 +instead of elem_imp_eq_diff_union, if needed.  INCOMPATIBILITY.
    1.15 +
    1.16  * Reorganized theory Sum_Type.thy; Inl and Inr now have
    1.17  authentic syntax.  INCOMPATIBILITY.
    1.18  
     2.1 --- a/src/HOL/Code_Numeral.thy	Fri Jan 22 11:42:28 2010 +0100
     2.2 +++ b/src/HOL/Code_Numeral.thy	Fri Jan 22 15:26:29 2010 +0100
     2.3 @@ -296,15 +296,14 @@
     2.4  
     2.5  setup {*
     2.6    fold (Numeral.add_code @{const_name number_code_numeral_inst.number_of_code_numeral}
     2.7 -    false false Code_Printer.str) ["SML", "Haskell"]
     2.8 +    false Code_Printer.literal_naive_numeral) ["SML", "Haskell"]
     2.9    #> Numeral.add_code @{const_name number_code_numeral_inst.number_of_code_numeral}
    2.10 -    false true Code_Printer.str "OCaml"
    2.11 +    false Code_Printer.literal_numeral "OCaml"
    2.12    #> Numeral.add_code @{const_name number_code_numeral_inst.number_of_code_numeral}
    2.13 -    false false Code_Printer.str "Scala"
    2.14 +    false Code_Printer.literal_naive_numeral "Scala"
    2.15  *}
    2.16  
    2.17  code_reserved SML Int int
    2.18 -code_reserved OCaml Big_int
    2.19  code_reserved Scala Int
    2.20  
    2.21  code_const "op + \<Colon> code_numeral \<Rightarrow> code_numeral \<Rightarrow> code_numeral"
     3.1 --- a/src/HOL/IsaMakefile	Fri Jan 22 11:42:28 2010 +0100
     3.2 +++ b/src/HOL/IsaMakefile	Fri Jan 22 15:26:29 2010 +0100
     3.3 @@ -109,6 +109,7 @@
     3.4    $(SRC)/Tools/Code/code_ml.ML \
     3.5    $(SRC)/Tools/Code/code_preproc.ML \
     3.6    $(SRC)/Tools/Code/code_printer.ML \
     3.7 +  $(SRC)/Tools/Code/code_scala.ML \
     3.8    $(SRC)/Tools/Code/code_target.ML \
     3.9    $(SRC)/Tools/Code/code_thingol.ML \
    3.10    $(SRC)/Tools/Code_Generator.thy \
     4.1 --- a/src/HOL/Library/Code_Integer.thy	Fri Jan 22 11:42:28 2010 +0100
     4.2 +++ b/src/HOL/Library/Code_Integer.thy	Fri Jan 22 15:26:29 2010 +0100
     4.3 @@ -25,9 +25,9 @@
     4.4  
     4.5  setup {*
     4.6    fold (Numeral.add_code @{const_name number_int_inst.number_of_int}
     4.7 -    true true Code_Printer.str) ["SML", "OCaml", "Haskell", "Scala"]
     4.8 +    true Code_Printer.literal_numeral) ["SML", "OCaml", "Haskell", "Scala"]
     4.9    #> Numeral.add_code @{const_name number_int_inst.number_of_int}
    4.10 -    true true (fn s => (Pretty.block o map Code_Printer.str) ["BigInt", s]) "Scala"
    4.11 +    true Code_Printer.literal_numeral "Scala"
    4.12  *}
    4.13  
    4.14  code_const "Int.Pls" and "Int.Min" and "Int.Bit0" and "Int.Bit1"
    4.15 @@ -88,7 +88,7 @@
    4.16  code_const pdivmod
    4.17    (SML "IntInf.divMod/ (IntInf.abs _,/ IntInf.abs _)")
    4.18    (OCaml "Big'_int.quomod'_big'_int/ (Big'_int.abs'_big'_int _)/ (Big'_int.abs'_big'_int _)")
    4.19 -  (Haskell "divMod/ (abs _)/ (abs _))")
    4.20 +  (Haskell "divMod/ (abs _)/ (abs _)")
    4.21    (Scala "!(_.abs '/% _.abs)")
    4.22  
    4.23  code_const "eq_class.eq \<Colon> int \<Rightarrow> int \<Rightarrow> bool"
    4.24 @@ -113,10 +113,7 @@
    4.25    (SML "IntInf.fromInt")
    4.26    (OCaml "_")
    4.27    (Haskell "toEnum")
    4.28 -  (Scala "!BigInt(_)")
    4.29 -
    4.30 -code_reserved SML IntInf
    4.31 -code_reserved Scala BigInt
    4.32 +  (Scala "!BigInt((_))")
    4.33  
    4.34  text {* Evaluation *}
    4.35  
     5.1 --- a/src/HOL/Library/Efficient_Nat.thy	Fri Jan 22 11:42:28 2010 +0100
     5.2 +++ b/src/HOL/Library/Efficient_Nat.thy	Fri Jan 22 15:26:29 2010 +0100
     5.3 @@ -287,6 +287,8 @@
     5.4  code_reserved Haskell Nat
     5.5  
     5.6  code_include Scala "Nat" {*
     5.7 +import scala.Math
     5.8 +
     5.9  object Nat {
    5.10  
    5.11    def apply(numeral: BigInt): Nat = new Nat(numeral max 0)
    5.12 @@ -309,7 +311,9 @@
    5.13    def equals(that: Nat): Boolean = this.value == that.value
    5.14  
    5.15    def as_BigInt: BigInt = this.value
    5.16 -  def as_Int: Int = this.value
    5.17 +  def as_Int: Int = if (this.value >= Math.MAX_INT && this.value <= Math.MAX_INT)
    5.18 +      this.value.intValue
    5.19 +    else error("Int value too big:" + this.value.toString)
    5.20  
    5.21    def +(that: Nat): Nat = new Nat(this.value + that.value)
    5.22    def -(that: Nat): Nat = Nat(this.value + that.value)
    5.23 @@ -348,9 +352,9 @@
    5.24  
    5.25  setup {*
    5.26    fold (Numeral.add_code @{const_name number_nat_inst.number_of_nat}
    5.27 -    false true Code_Printer.str) ["SML", "OCaml", "Haskell"]
    5.28 +    false Code_Printer.literal_positive_numeral) ["SML", "OCaml", "Haskell"]
    5.29    #> Numeral.add_code @{const_name number_nat_inst.number_of_nat}
    5.30 -    false true (fn s => (Pretty.block o map Code_Printer.str) ["Nat.Nat", s]) "Scala"
    5.31 +    false Code_Printer.literal_positive_numeral "Scala"
    5.32  *}
    5.33  
    5.34  text {*
     6.1 --- a/src/HOL/Library/Multiset.thy	Fri Jan 22 11:42:28 2010 +0100
     6.2 +++ b/src/HOL/Library/Multiset.thy	Fri Jan 22 15:26:29 2010 +0100
     6.3 @@ -2,34 +2,21 @@
     6.4      Author:     Tobias Nipkow, Markus Wenzel, Lawrence C Paulson, Norbert Voelker
     6.5  *)
     6.6  
     6.7 -header {* Multisets *}
     6.8 +header {* (Finite) multisets *}
     6.9  
    6.10  theory Multiset
    6.11 -imports List Main
    6.12 +imports Main
    6.13  begin
    6.14  
    6.15  subsection {* The type of multisets *}
    6.16  
    6.17 -typedef 'a multiset = "{f::'a => nat. finite {x . f x > 0}}"
    6.18 +typedef 'a multiset = "{f :: 'a => nat. finite {x. f x > 0}}"
    6.19 +  morphisms count Abs_multiset
    6.20  proof
    6.21    show "(\<lambda>x. 0::nat) \<in> ?multiset" by simp
    6.22  qed
    6.23  
    6.24 -lemmas multiset_typedef [simp] =
    6.25 -    Abs_multiset_inverse Rep_multiset_inverse Rep_multiset
    6.26 -  and [simp] = Rep_multiset_inject [symmetric]
    6.27 -
    6.28 -definition Mempty :: "'a multiset"  ("{#}") where
    6.29 -  [code del]: "{#} = Abs_multiset (\<lambda>a. 0)"
    6.30 -
    6.31 -definition single :: "'a => 'a multiset" where
    6.32 -  [code del]: "single a = Abs_multiset (\<lambda>b. if b = a then 1 else 0)"
    6.33 -
    6.34 -definition count :: "'a multiset => 'a => nat" where
    6.35 -  "count = Rep_multiset"
    6.36 -
    6.37 -definition MCollect :: "'a multiset => ('a => bool) => 'a multiset" where
    6.38 -  "MCollect M P = Abs_multiset (\<lambda>x. if P x then Rep_multiset M x else 0)"
    6.39 +lemmas multiset_typedef = Abs_multiset_inverse count_inverse count
    6.40  
    6.41  abbreviation Melem :: "'a => 'a multiset => bool"  ("(_/ :# _)" [50, 51] 50) where
    6.42    "a :# M == 0 < count M a"
    6.43 @@ -37,142 +24,456 @@
    6.44  notation (xsymbols)
    6.45    Melem (infix "\<in>#" 50)
    6.46  
    6.47 +lemma multiset_eq_conv_count_eq:
    6.48 +  "M = N \<longleftrightarrow> (\<forall>a. count M a = count N a)"
    6.49 +  by (simp only: count_inject [symmetric] expand_fun_eq)
    6.50 +
    6.51 +lemma multi_count_ext:
    6.52 +  "(\<And>x. count A x = count B x) \<Longrightarrow> A = B"
    6.53 +  using multiset_eq_conv_count_eq by auto
    6.54 +
    6.55 +text {*
    6.56 + \medskip Preservation of the representing set @{term multiset}.
    6.57 +*}
    6.58 +
    6.59 +lemma const0_in_multiset:
    6.60 +  "(\<lambda>a. 0) \<in> multiset"
    6.61 +  by (simp add: multiset_def)
    6.62 +
    6.63 +lemma only1_in_multiset:
    6.64 +  "(\<lambda>b. if b = a then n else 0) \<in> multiset"
    6.65 +  by (simp add: multiset_def)
    6.66 +
    6.67 +lemma union_preserves_multiset:
    6.68 +  "M \<in> multiset \<Longrightarrow> N \<in> multiset \<Longrightarrow> (\<lambda>a. M a + N a) \<in> multiset"
    6.69 +  by (simp add: multiset_def)
    6.70 +
    6.71 +lemma diff_preserves_multiset:
    6.72 +  assumes "M \<in> multiset"
    6.73 +  shows "(\<lambda>a. M a - N a) \<in> multiset"
    6.74 +proof -
    6.75 +  have "{x. N x < M x} \<subseteq> {x. 0 < M x}"
    6.76 +    by auto
    6.77 +  with assms show ?thesis
    6.78 +    by (auto simp add: multiset_def intro: finite_subset)
    6.79 +qed
    6.80 +
    6.81 +lemma MCollect_preserves_multiset:
    6.82 +  assumes "M \<in> multiset"
    6.83 +  shows "(\<lambda>x. if P x then M x else 0) \<in> multiset"
    6.84 +proof -
    6.85 +  have "{x. (P x \<longrightarrow> 0 < M x) \<and> P x} \<subseteq> {x. 0 < M x}"
    6.86 +    by auto
    6.87 +  with assms show ?thesis
    6.88 +    by (auto simp add: multiset_def intro: finite_subset)
    6.89 +qed
    6.90 +
    6.91 +lemmas in_multiset = const0_in_multiset only1_in_multiset
    6.92 +  union_preserves_multiset diff_preserves_multiset MCollect_preserves_multiset
    6.93 +
    6.94 +
    6.95 +subsection {* Representing multisets *}
    6.96 +
    6.97 +text {* Multiset comprehension *}
    6.98 +
    6.99 +definition MCollect :: "'a multiset => ('a => bool) => 'a multiset" where
   6.100 +  "MCollect M P = Abs_multiset (\<lambda>x. if P x then count M x else 0)"
   6.101 +
   6.102  syntax
   6.103    "_MCollect" :: "pttrn => 'a multiset => bool => 'a multiset"    ("(1{# _ :# _./ _#})")
   6.104  translations
   6.105    "{#x :# M. P#}" == "CONST MCollect M (\<lambda>x. P)"
   6.106  
   6.107 -definition set_of :: "'a multiset => 'a set" where
   6.108 -  "set_of M = {x. x :# M}"
   6.109  
   6.110 -instantiation multiset :: (type) "{plus, minus, zero, size}" 
   6.111 +text {* Multiset enumeration *}
   6.112 +
   6.113 +instantiation multiset :: (type) "{zero, plus}"
   6.114  begin
   6.115  
   6.116 -definition union_def [code del]:
   6.117 -  "M + N = Abs_multiset (\<lambda>a. Rep_multiset M a + Rep_multiset N a)"
   6.118 -
   6.119 -definition diff_def [code del]:
   6.120 -  "M - N = Abs_multiset (\<lambda>a. Rep_multiset M a - Rep_multiset N a)"
   6.121 +definition Mempty_def:
   6.122 +  "0 = Abs_multiset (\<lambda>a. 0)"
   6.123  
   6.124 -definition Zero_multiset_def [simp]:
   6.125 -  "0 = {#}"
   6.126 +abbreviation Mempty :: "'a multiset" ("{#}") where
   6.127 +  "Mempty \<equiv> 0"
   6.128  
   6.129 -definition size_def:
   6.130 -  "size M = setsum (count M) (set_of M)"
   6.131 +definition union_def:
   6.132 +  "M + N = Abs_multiset (\<lambda>a. count M a + count N a)"
   6.133  
   6.134  instance ..
   6.135  
   6.136  end
   6.137  
   6.138 -definition
   6.139 -  multiset_inter :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset"  (infixl "#\<inter>" 70) where
   6.140 -  "multiset_inter A B = A - (A - B)"
   6.141 +definition single :: "'a => 'a multiset" where
   6.142 +  "single a = Abs_multiset (\<lambda>b. if b = a then 1 else 0)"
   6.143  
   6.144 -text {* Multiset Enumeration *}
   6.145  syntax
   6.146    "_multiset" :: "args => 'a multiset"    ("{#(_)#}")
   6.147  translations
   6.148    "{#x, xs#}" == "{#x#} + {#xs#}"
   6.149    "{#x#}" == "CONST single x"
   6.150  
   6.151 -
   6.152 -text {*
   6.153 - \medskip Preservation of the representing set @{term multiset}.
   6.154 -*}
   6.155 +lemma count_empty [simp]: "count {#} a = 0"
   6.156 +  by (simp add: Mempty_def in_multiset multiset_typedef)
   6.157  
   6.158 -lemma const0_in_multiset: "(\<lambda>a. 0) \<in> multiset"
   6.159 -by (simp add: multiset_def)
   6.160 -
   6.161 -lemma only1_in_multiset: "(\<lambda>b. if b = a then 1 else 0) \<in> multiset"
   6.162 -by (simp add: multiset_def)
   6.163 -
   6.164 -lemma union_preserves_multiset:
   6.165 -  "M \<in> multiset ==> N \<in> multiset ==> (\<lambda>a. M a + N a) \<in> multiset"
   6.166 -by (simp add: multiset_def)
   6.167 +lemma count_single [simp]: "count {#b#} a = (if b = a then 1 else 0)"
   6.168 +  by (simp add: single_def in_multiset multiset_typedef)
   6.169  
   6.170  
   6.171 -lemma diff_preserves_multiset:
   6.172 -  "M \<in> multiset ==> (\<lambda>a. M a - N a) \<in> multiset"
   6.173 -apply (simp add: multiset_def)
   6.174 -apply (rule finite_subset)
   6.175 - apply auto
   6.176 -done
   6.177 -
   6.178 -lemma MCollect_preserves_multiset:
   6.179 -  "M \<in> multiset ==> (\<lambda>x. if P x then M x else 0) \<in> multiset"
   6.180 -apply (simp add: multiset_def)
   6.181 -apply (rule finite_subset, auto)
   6.182 -done
   6.183 -
   6.184 -lemmas in_multiset = const0_in_multiset only1_in_multiset
   6.185 -  union_preserves_multiset diff_preserves_multiset MCollect_preserves_multiset
   6.186 -
   6.187 -
   6.188 -subsection {* Algebraic properties *}
   6.189 +subsection {* Basic operations *}
   6.190  
   6.191  subsubsection {* Union *}
   6.192  
   6.193 -lemma union_empty [simp]: "M + {#} = M \<and> {#} + M = M"
   6.194 -by (simp add: union_def Mempty_def in_multiset)
   6.195 -
   6.196 -lemma union_commute: "M + N = N + (M::'a multiset)"
   6.197 -by (simp add: union_def add_ac in_multiset)
   6.198 -
   6.199 -lemma union_assoc: "(M + N) + K = M + (N + (K::'a multiset))"
   6.200 -by (simp add: union_def add_ac in_multiset)
   6.201 +lemma count_union [simp]: "count (M + N) a = count M a + count N a"
   6.202 +  by (simp add: union_def in_multiset multiset_typedef)
   6.203  
   6.204 -lemma union_lcomm: "M + (N + K) = N + (M + (K::'a multiset))"
   6.205 -proof -
   6.206 -  have "M + (N + K) = (N + K) + M" by (rule union_commute)
   6.207 -  also have "\<dots> = N + (K + M)" by (rule union_assoc)
   6.208 -  also have "K + M = M + K" by (rule union_commute)
   6.209 -  finally show ?thesis .
   6.210 -qed
   6.211 -
   6.212 -lemmas union_ac = union_assoc union_commute union_lcomm
   6.213 -
   6.214 -instance multiset :: (type) comm_monoid_add
   6.215 -proof
   6.216 -  fix a b c :: "'a multiset"
   6.217 -  show "(a + b) + c = a + (b + c)" by (rule union_assoc)
   6.218 -  show "a + b = b + a" by (rule union_commute)
   6.219 -  show "0 + a = a" by simp
   6.220 -qed
   6.221 +instance multiset :: (type) cancel_comm_monoid_add proof
   6.222 +qed (simp_all add: multiset_eq_conv_count_eq)
   6.223  
   6.224  
   6.225  subsubsection {* Difference *}
   6.226  
   6.227 +instantiation multiset :: (type) minus
   6.228 +begin
   6.229 +
   6.230 +definition diff_def:
   6.231 +  "M - N = Abs_multiset (\<lambda>a. count M a - count N a)"
   6.232 +
   6.233 +instance ..
   6.234 +
   6.235 +end
   6.236 +
   6.237 +lemma count_diff [simp]: "count (M - N) a = count M a - count N a"
   6.238 +  by (simp add: diff_def in_multiset multiset_typedef)
   6.239 +
   6.240  lemma diff_empty [simp]: "M - {#} = M \<and> {#} - M = {#}"
   6.241 -by (simp add: Mempty_def diff_def in_multiset)
   6.242 +  by (simp add: Mempty_def diff_def in_multiset multiset_typedef)
   6.243  
   6.244  lemma diff_union_inverse2 [simp]: "M + {#a#} - {#a#} = M"
   6.245 -by (simp add: union_def diff_def in_multiset)
   6.246 +  by (rule multi_count_ext)
   6.247 +    (auto simp del: count_single simp add: union_def diff_def in_multiset multiset_typedef)
   6.248  
   6.249  lemma diff_cancel: "A - A = {#}"
   6.250 -by (simp add: diff_def Mempty_def)
   6.251 +  by (rule multi_count_ext) simp
   6.252 +
   6.253 +lemma insert_DiffM:
   6.254 +  "x \<in># M \<Longrightarrow> {#x#} + (M - {#x#}) = M"
   6.255 +  by (clarsimp simp: multiset_eq_conv_count_eq)
   6.256 +
   6.257 +lemma insert_DiffM2 [simp]:
   6.258 +  "x \<in># M \<Longrightarrow> M - {#x#} + {#x#} = M"
   6.259 +  by (clarsimp simp: multiset_eq_conv_count_eq)
   6.260 +
   6.261 +lemma diff_right_commute:
   6.262 +  "(M::'a multiset) - N - Q = M - Q - N"
   6.263 +  by (auto simp add: multiset_eq_conv_count_eq)
   6.264 +
   6.265 +lemma diff_union_swap:
   6.266 +  "a \<noteq> b \<Longrightarrow> M - {#a#} + {#b#} = M + {#b#} - {#a#}"
   6.267 +  by (auto simp add: multiset_eq_conv_count_eq)
   6.268 +
   6.269 +lemma diff_union_single_conv:
   6.270 +  "a \<in># J \<Longrightarrow> I + J - {#a#} = I + (J - {#a#})"
   6.271 +  by (simp add: multiset_eq_conv_count_eq)
   6.272  
   6.273  
   6.274 -subsubsection {* Count of elements *}
   6.275 +subsubsection {* Intersection *}
   6.276 +
   6.277 +definition multiset_inter :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset" (infixl "#\<inter>" 70) where
   6.278 +  "multiset_inter A B = A - (A - B)"
   6.279 +
   6.280 +lemma multiset_inter_count:
   6.281 +  "count (A #\<inter> B) x = min (count A x) (count B x)"
   6.282 +  by (simp add: multiset_inter_def multiset_typedef)
   6.283  
   6.284 -lemma count_empty [simp]: "count {#} a = 0"
   6.285 -by (simp add: count_def Mempty_def in_multiset)
   6.286 +lemma multiset_inter_commute: "A #\<inter> B = B #\<inter> A"
   6.287 +  by (rule multi_count_ext) (simp add: multiset_inter_count)
   6.288 +
   6.289 +lemma multiset_inter_assoc: "A #\<inter> (B #\<inter> C) = A #\<inter> B #\<inter> C"
   6.290 +  by (rule multi_count_ext) (simp add: multiset_inter_count)
   6.291 +
   6.292 +lemma multiset_inter_left_commute: "A #\<inter> (B #\<inter> C) = B #\<inter> (A #\<inter> C)"
   6.293 +  by (rule multi_count_ext) (simp add: multiset_inter_count)
   6.294  
   6.295 -lemma count_single [simp]: "count {#b#} a = (if b = a then 1 else 0)"
   6.296 -by (simp add: count_def single_def in_multiset)
   6.297 +lemmas multiset_inter_ac =
   6.298 +  multiset_inter_commute
   6.299 +  multiset_inter_assoc
   6.300 +  multiset_inter_left_commute
   6.301 +
   6.302 +lemma multiset_inter_single: "a \<noteq> b \<Longrightarrow> {#a#} #\<inter> {#b#} = {#}"
   6.303 +  by (rule multi_count_ext) (auto simp add: multiset_inter_count)
   6.304  
   6.305 -lemma count_union [simp]: "count (M + N) a = count M a + count N a"
   6.306 -by (simp add: count_def union_def in_multiset)
   6.307 +lemma multiset_union_diff_commute:
   6.308 +  assumes "B #\<inter> C = {#}"
   6.309 +  shows "A + B - C = A - C + B"
   6.310 +proof (rule multi_count_ext)
   6.311 +  fix x
   6.312 +  from assms have "min (count B x) (count C x) = 0"
   6.313 +    by (auto simp add: multiset_inter_count multiset_eq_conv_count_eq)
   6.314 +  then have "count B x = 0 \<or> count C x = 0"
   6.315 +    by auto
   6.316 +  then show "count (A + B - C) x = count (A - C + B) x"
   6.317 +    by auto
   6.318 +qed
   6.319  
   6.320 -lemma count_diff [simp]: "count (M - N) a = count M a - count N a"
   6.321 -by (simp add: count_def diff_def in_multiset)
   6.322 +
   6.323 +subsubsection {* Comprehension (filter) *}
   6.324  
   6.325  lemma count_MCollect [simp]:
   6.326    "count {# x:#M. P x #} a = (if P a then count M a else 0)"
   6.327 -by (simp add: count_def MCollect_def in_multiset)
   6.328 +  by (simp add: MCollect_def in_multiset multiset_typedef)
   6.329 +
   6.330 +lemma MCollect_empty [simp]: "MCollect {#} P = {#}"
   6.331 +  by (rule multi_count_ext) simp
   6.332 +
   6.333 +lemma MCollect_single [simp]:
   6.334 +  "MCollect {#x#} P = (if P x then {#x#} else {#})"
   6.335 +  by (rule multi_count_ext) simp
   6.336 +
   6.337 +lemma MCollect_union [simp]:
   6.338 +  "MCollect (M + N) f = MCollect M f + MCollect N f"
   6.339 +  by (rule multi_count_ext) simp
   6.340 +
   6.341 +
   6.342 +subsubsection {* Equality of multisets *}
   6.343 +
   6.344 +lemma single_not_empty [simp]: "{#a#} \<noteq> {#} \<and> {#} \<noteq> {#a#}"
   6.345 +  by (simp add: multiset_eq_conv_count_eq)
   6.346 +
   6.347 +lemma single_eq_single [simp]: "{#a#} = {#b#} \<longleftrightarrow> a = b"
   6.348 +  by (auto simp add: multiset_eq_conv_count_eq)
   6.349 +
   6.350 +lemma union_eq_empty [iff]: "M + N = {#} \<longleftrightarrow> M = {#} \<and> N = {#}"
   6.351 +  by (auto simp add: multiset_eq_conv_count_eq)
   6.352 +
   6.353 +lemma empty_eq_union [iff]: "{#} = M + N \<longleftrightarrow> M = {#} \<and> N = {#}"
   6.354 +  by (auto simp add: multiset_eq_conv_count_eq)
   6.355 +
   6.356 +lemma multi_self_add_other_not_self [simp]: "M = M + {#x#} \<longleftrightarrow> False"
   6.357 +  by (auto simp add: multiset_eq_conv_count_eq)
   6.358 +
   6.359 +lemma diff_single_trivial:
   6.360 +  "\<not> x \<in># M \<Longrightarrow> M - {#x#} = M"
   6.361 +  by (auto simp add: multiset_eq_conv_count_eq)
   6.362 +
   6.363 +lemma diff_single_eq_union:
   6.364 +  "x \<in># M \<Longrightarrow> M - {#x#} = N \<longleftrightarrow> M = N + {#x#}"
   6.365 +  by auto
   6.366 +
   6.367 +lemma union_single_eq_diff:
   6.368 +  "M + {#x#} = N \<Longrightarrow> M = N - {#x#}"
   6.369 +  by (auto dest: sym)
   6.370 +
   6.371 +lemma union_single_eq_member:
   6.372 +  "M + {#x#} = N \<Longrightarrow> x \<in># N"
   6.373 +  by auto
   6.374 +
   6.375 +lemma union_is_single:
   6.376 +  "M + N = {#a#} \<longleftrightarrow> M = {#a#} \<and> N={#} \<or> M = {#} \<and> N = {#a#}" (is "?lhs = ?rhs")
   6.377 +proof
   6.378 +  assume ?rhs then show ?lhs by auto
   6.379 +next
   6.380 +  assume ?lhs
   6.381 +  then have "\<And>b. count (M + N) b = (if b = a then 1 else 0)" by auto
   6.382 +  then have *: "\<And>b. count M b + count N b = (if b = a then 1 else 0)" by auto
   6.383 +  then have "count M a + count N a = 1" by auto
   6.384 +  then have **: "count M a = 1 \<and> count N a = 0 \<or> count M a = 0 \<and> count N a = 1"
   6.385 +    by auto
   6.386 +  from * have "\<And>b. b \<noteq> a \<Longrightarrow> count M b + count N b = 0" by auto
   6.387 +  then have ***: "\<And>b. b \<noteq> a \<Longrightarrow> count M b = 0 \<and> count N b = 0" by auto
   6.388 +  from ** and *** have
   6.389 +    "(\<forall>b. count M b = (if b = a then 1 else 0) \<and> count N b = 0) \<or>
   6.390 +      (\<forall>b. count M b = 0 \<and> count N b = (if b = a then 1 else 0))"
   6.391 +    by auto
   6.392 +  then have
   6.393 +    "(\<forall>b. count M b = (if b = a then 1 else 0)) \<and> (\<forall>b. count N b = 0) \<or>
   6.394 +      (\<forall>b. count M b = 0) \<and> (\<forall>b. count N b = (if b = a then 1 else 0))"
   6.395 +    by auto
   6.396 +  then show ?rhs by (auto simp add: multiset_eq_conv_count_eq)
   6.397 +qed
   6.398 +
   6.399 +lemma single_is_union:
   6.400 +  "{#a#} = M + N \<longleftrightarrow> {#a#} = M \<and> N = {#} \<or> M = {#} \<and> {#a#} = N"
   6.401 +  by (auto simp add: eq_commute [of "{#a#}" "M + N"] union_is_single)
   6.402 +
   6.403 +lemma add_eq_conv_diff:
   6.404 +  "M + {#a#} = N + {#b#} \<longleftrightarrow> M = N \<and> a = b \<or> M = N - {#a#} + {#b#} \<and> N = M - {#b#} + {#a#}"  (is "?lhs = ?rhs")
   6.405 +proof
   6.406 +  assume ?rhs then show ?lhs
   6.407 +  by (auto simp add: add_assoc add_commute [of "{#b#}"])
   6.408 +    (drule sym, simp add: add_assoc [symmetric])
   6.409 +next
   6.410 +  assume ?lhs
   6.411 +  show ?rhs
   6.412 +  proof (cases "a = b")
   6.413 +    case True with `?lhs` show ?thesis by simp
   6.414 +  next
   6.415 +    case False
   6.416 +    from `?lhs` have "a \<in># N + {#b#}" by (rule union_single_eq_member)
   6.417 +    with False have "a \<in># N" by auto
   6.418 +    moreover from `?lhs` have "M = N + {#b#} - {#a#}" by (rule union_single_eq_diff)
   6.419 +    moreover note False
   6.420 +    ultimately show ?thesis by (auto simp add: diff_right_commute [of _ "{#a#}"] diff_union_swap)
   6.421 +  qed
   6.422 +qed
   6.423 +
   6.424 +lemma insert_noteq_member: 
   6.425 +  assumes BC: "B + {#b#} = C + {#c#}"
   6.426 +   and bnotc: "b \<noteq> c"
   6.427 +  shows "c \<in># B"
   6.428 +proof -
   6.429 +  have "c \<in># C + {#c#}" by simp
   6.430 +  have nc: "\<not> c \<in># {#b#}" using bnotc by simp
   6.431 +  then have "c \<in># B + {#b#}" using BC by simp
   6.432 +  then show "c \<in># B" using nc by simp
   6.433 +qed
   6.434 +
   6.435 +lemma add_eq_conv_ex:
   6.436 +  "(M + {#a#} = N + {#b#}) =
   6.437 +    (M = N \<and> a = b \<or> (\<exists>K. M = K + {#b#} \<and> N = K + {#a#}))"
   6.438 +  by (auto simp add: add_eq_conv_diff)
   6.439 +
   6.440 +
   6.441 +subsubsection {* Pointwise ordering induced by count *}
   6.442 +
   6.443 +definition mset_le :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool"  (infix "\<le>#" 50) where
   6.444 +  "A \<le># B \<longleftrightarrow> (\<forall>a. count A a \<le> count B a)"
   6.445 +
   6.446 +definition mset_less :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool"  (infix "<#" 50) where
   6.447 +  "A <# B \<longleftrightarrow> A \<le># B \<and> A \<noteq> B"
   6.448 +
   6.449 +notation mset_le  (infix "\<subseteq>#" 50)
   6.450 +notation mset_less  (infix "\<subset>#" 50)
   6.451 +
   6.452 +lemma mset_less_eqI:
   6.453 +  "(\<And>x. count A x \<le> count B x) \<Longrightarrow> A \<subseteq># B"
   6.454 +  by (simp add: mset_le_def)
   6.455 +
   6.456 +lemma mset_le_refl[simp]: "A \<le># A"
   6.457 +unfolding mset_le_def by auto
   6.458 +
   6.459 +lemma mset_le_trans: "A \<le># B \<Longrightarrow> B \<le># C \<Longrightarrow> A \<le># C"
   6.460 +unfolding mset_le_def by (fast intro: order_trans)
   6.461 +
   6.462 +lemma mset_le_antisym: "A \<le># B \<Longrightarrow> B \<le># A \<Longrightarrow> A = B"
   6.463 +apply (unfold mset_le_def)
   6.464 +apply (rule multiset_eq_conv_count_eq [THEN iffD2])
   6.465 +apply (blast intro: order_antisym)
   6.466 +done
   6.467 +
   6.468 +lemma mset_le_exists_conv: "(A \<le># B) = (\<exists>C. B = A + C)"
   6.469 +apply (unfold mset_le_def, rule iffI, rule_tac x = "B - A" in exI)
   6.470 +apply (auto intro: multiset_eq_conv_count_eq [THEN iffD2])
   6.471 +done
   6.472 +
   6.473 +lemma mset_le_mono_add_right_cancel[simp]: "(A + C \<le># B + C) = (A \<le># B)"
   6.474 +unfolding mset_le_def by auto
   6.475 +
   6.476 +lemma mset_le_mono_add_left_cancel[simp]: "(C + A \<le># C + B) = (A \<le># B)"
   6.477 +unfolding mset_le_def by auto
   6.478 +
   6.479 +lemma mset_le_mono_add: "\<lbrakk> A \<le># B; C \<le># D \<rbrakk> \<Longrightarrow> A + C \<le># B + D"
   6.480 +apply (unfold mset_le_def)
   6.481 +apply auto
   6.482 +apply (erule_tac x = a in allE)+
   6.483 +apply auto
   6.484 +done
   6.485 +
   6.486 +lemma mset_le_add_left[simp]: "A \<le># A + B"
   6.487 +unfolding mset_le_def by auto
   6.488 +
   6.489 +lemma mset_le_add_right[simp]: "B \<le># A + B"
   6.490 +unfolding mset_le_def by auto
   6.491 +
   6.492 +lemma mset_le_single: "a :# B \<Longrightarrow> {#a#} \<le># B"
   6.493 +by (simp add: mset_le_def)
   6.494 +
   6.495 +lemma multiset_diff_union_assoc: "C \<le># B \<Longrightarrow> A + B - C = A + (B - C)"
   6.496 +by (simp add: multiset_eq_conv_count_eq mset_le_def)
   6.497 +
   6.498 +lemma mset_le_multiset_union_diff_commute:
   6.499 +assumes "B \<le># A"
   6.500 +shows "A - B + C = A + C - B"
   6.501 +proof -
   6.502 +  from mset_le_exists_conv [of "B" "A"] assms have "\<exists>D. A = B + D" ..
   6.503 +  from this obtain D where "A = B + D" ..
   6.504 +  then show ?thesis
   6.505 +    apply simp
   6.506 +    apply (subst add_commute)
   6.507 +    apply (subst multiset_diff_union_assoc)
   6.508 +    apply simp
   6.509 +    apply (simp add: diff_cancel)
   6.510 +    apply (subst add_assoc)
   6.511 +    apply (subst add_commute [of "B" _])
   6.512 +    apply (subst multiset_diff_union_assoc)
   6.513 +    apply simp
   6.514 +    apply (simp add: diff_cancel)
   6.515 +    done
   6.516 +qed
   6.517 +
   6.518 +interpretation mset_order: order "op \<le>#" "op <#"
   6.519 +proof qed (auto intro: order.intro mset_le_refl mset_le_antisym
   6.520 +  mset_le_trans simp: mset_less_def)
   6.521 +
   6.522 +interpretation mset_order_cancel_semigroup:
   6.523 +  pordered_cancel_ab_semigroup_add "op +" "op \<le>#" "op <#"
   6.524 +proof qed (erule mset_le_mono_add [OF mset_le_refl])
   6.525 +
   6.526 +interpretation mset_order_semigroup_cancel:
   6.527 +  pordered_ab_semigroup_add_imp_le "op +" "op \<le>#" "op <#"
   6.528 +proof qed simp
   6.529 +
   6.530 +lemma mset_lessD: "A \<subset># B \<Longrightarrow> x \<in># A \<Longrightarrow> x \<in># B"
   6.531 +apply (clarsimp simp: mset_le_def mset_less_def)
   6.532 +apply (erule_tac x=x in allE)
   6.533 +apply auto
   6.534 +done
   6.535 +
   6.536 +lemma mset_leD: "A \<subseteq># B \<Longrightarrow> x \<in># A \<Longrightarrow> x \<in># B"
   6.537 +apply (clarsimp simp: mset_le_def mset_less_def)
   6.538 +apply (erule_tac x = x in allE)
   6.539 +apply auto
   6.540 +done
   6.541 +  
   6.542 +lemma mset_less_insertD: "(A + {#x#} \<subset># B) \<Longrightarrow> (x \<in># B \<and> A \<subset># B)"
   6.543 +apply (rule conjI)
   6.544 + apply (simp add: mset_lessD)
   6.545 +apply (clarsimp simp: mset_le_def mset_less_def)
   6.546 +apply safe
   6.547 + apply (erule_tac x = a in allE)
   6.548 + apply (auto split: split_if_asm)
   6.549 +done
   6.550 +
   6.551 +lemma mset_le_insertD: "(A + {#x#} \<subseteq># B) \<Longrightarrow> (x \<in># B \<and> A \<subseteq># B)"
   6.552 +apply (rule conjI)
   6.553 + apply (simp add: mset_leD)
   6.554 +apply (force simp: mset_le_def mset_less_def split: split_if_asm)
   6.555 +done
   6.556 +
   6.557 +lemma mset_less_of_empty[simp]: "A \<subset># {#} \<longleftrightarrow> False"
   6.558 +  by (auto simp add: mset_less_def mset_le_def multiset_eq_conv_count_eq)
   6.559 +
   6.560 +lemma multi_psub_of_add_self[simp]: "A \<subset># A + {#x#}"
   6.561 +by (auto simp: mset_le_def mset_less_def)
   6.562 +
   6.563 +lemma multi_psub_self[simp]: "A \<subset># A = False"
   6.564 +by (auto simp: mset_le_def mset_less_def)
   6.565 +
   6.566 +lemma mset_less_add_bothsides:
   6.567 +  "T + {#x#} \<subset># S + {#x#} \<Longrightarrow> T \<subset># S"
   6.568 +by (auto simp: mset_le_def mset_less_def)
   6.569 +
   6.570 +lemma mset_less_empty_nonempty: "({#} \<subset># S) = (S \<noteq> {#})"
   6.571 +by (auto simp: mset_le_def mset_less_def)
   6.572 +
   6.573 +lemma mset_less_diff_self: "c \<in># B \<Longrightarrow> B - {#c#} \<subset># B"
   6.574 +  by (auto simp: mset_le_def mset_less_def multiset_eq_conv_count_eq)
   6.575  
   6.576  
   6.577  subsubsection {* Set of elements *}
   6.578  
   6.579 +definition set_of :: "'a multiset => 'a set" where
   6.580 +  "set_of M = {x. x :# M}"
   6.581 +
   6.582  lemma set_of_empty [simp]: "set_of {#} = {}"
   6.583  by (simp add: set_of_def)
   6.584  
   6.585 @@ -183,7 +484,7 @@
   6.586  by (auto simp add: set_of_def)
   6.587  
   6.588  lemma set_of_eq_empty_iff [simp]: "(set_of M = {}) = (M = {#})"
   6.589 -by (auto simp: set_of_def Mempty_def in_multiset count_def expand_fun_eq [where f="Rep_multiset M"])
   6.590 +by (auto simp add: set_of_def multiset_eq_conv_count_eq)
   6.591  
   6.592  lemma mem_set_of_iff [simp]: "(x \<in> set_of M) = (x :# M)"
   6.593  by (auto simp add: set_of_def)
   6.594 @@ -191,18 +492,28 @@
   6.595  lemma set_of_MCollect [simp]: "set_of {# x:#M. P x #} = set_of M \<inter> {x. P x}"
   6.596  by (auto simp add: set_of_def)
   6.597  
   6.598 +lemma finite_set_of [iff]: "finite (set_of M)"
   6.599 +  using count [of M] by (simp add: multiset_def set_of_def)
   6.600 +
   6.601  
   6.602  subsubsection {* Size *}
   6.603  
   6.604 +instantiation multiset :: (type) size
   6.605 +begin
   6.606 +
   6.607 +definition size_def:
   6.608 +  "size M = setsum (count M) (set_of M)"
   6.609 +
   6.610 +instance ..
   6.611 +
   6.612 +end
   6.613 +
   6.614  lemma size_empty [simp]: "size {#} = 0"
   6.615  by (simp add: size_def)
   6.616  
   6.617  lemma size_single [simp]: "size {#b#} = 1"
   6.618  by (simp add: size_def)
   6.619  
   6.620 -lemma finite_set_of [iff]: "finite (set_of M)"
   6.621 -using Rep_multiset [of M] by (simp add: multiset_def set_of_def count_def)
   6.622 -
   6.623  lemma setsum_count_Int:
   6.624    "finite A ==> setsum (count N) (A \<inter> set_of N) = setsum (count N) A"
   6.625  apply (induct rule: finite_induct)
   6.626 @@ -221,9 +532,7 @@
   6.627  done
   6.628  
   6.629  lemma size_eq_0_iff_empty [iff]: "(size M = 0) = (M = {#})"
   6.630 -apply (unfold size_def Mempty_def count_def, auto simp: in_multiset)
   6.631 -apply (simp add: set_of_def count_def in_multiset expand_fun_eq)
   6.632 -done
   6.633 +by (auto simp add: size_def multiset_eq_conv_count_eq)
   6.634  
   6.635  lemma nonempty_has_size: "(S \<noteq> {#}) = (0 < size S)"
   6.636  by (metis gr0I gr_implies_not0 size_empty size_eq_0_iff_empty)
   6.637 @@ -234,149 +543,16 @@
   6.638  apply auto
   6.639  done
   6.640  
   6.641 -
   6.642 -subsubsection {* Equality of multisets *}
   6.643 -
   6.644 -lemma multiset_eq_conv_count_eq: "(M = N) = (\<forall>a. count M a = count N a)"
   6.645 -by (simp add: count_def expand_fun_eq)
   6.646 -
   6.647 -lemma single_not_empty [simp]: "{#a#} \<noteq> {#} \<and> {#} \<noteq> {#a#}"
   6.648 -by (simp add: single_def Mempty_def in_multiset expand_fun_eq)
   6.649 -
   6.650 -lemma single_eq_single [simp]: "({#a#} = {#b#}) = (a = b)"
   6.651 -by (auto simp add: single_def in_multiset expand_fun_eq)
   6.652 -
   6.653 -lemma union_eq_empty [iff]: "(M + N = {#}) = (M = {#} \<and> N = {#})"
   6.654 -by (auto simp add: union_def Mempty_def in_multiset expand_fun_eq)
   6.655 -
   6.656 -lemma empty_eq_union [iff]: "({#} = M + N) = (M = {#} \<and> N = {#})"
   6.657 -by (auto simp add: union_def Mempty_def in_multiset expand_fun_eq)
   6.658 -
   6.659 -lemma union_right_cancel [simp]: "(M + K = N + K) = (M = (N::'a multiset))"
   6.660 -by (simp add: union_def in_multiset expand_fun_eq)
   6.661 -
   6.662 -lemma union_left_cancel [simp]: "(K + M = K + N) = (M = (N::'a multiset))"
   6.663 -by (simp add: union_def in_multiset expand_fun_eq)
   6.664 -
   6.665 -lemma union_is_single:
   6.666 -  "(M + N = {#a#}) = (M = {#a#} \<and> N={#} \<or> M = {#} \<and> N = {#a#})"
   6.667 -apply (simp add: Mempty_def single_def union_def in_multiset add_is_1 expand_fun_eq)
   6.668 -apply blast
   6.669 -done
   6.670 -
   6.671 -lemma single_is_union:
   6.672 -  "({#a#} = M + N) \<longleftrightarrow> ({#a#} = M \<and> N = {#} \<or> M = {#} \<and> {#a#} = N)"
   6.673 -apply (unfold Mempty_def single_def union_def)
   6.674 -apply (simp add: add_is_1 one_is_add in_multiset expand_fun_eq)
   6.675 -apply (blast dest: sym)
   6.676 -done
   6.677 -
   6.678 -lemma add_eq_conv_diff:
   6.679 -  "(M + {#a#} = N + {#b#}) =
   6.680 -   (M = N \<and> a = b \<or> M = N - {#a#} + {#b#} \<and> N = M - {#b#} + {#a#})"
   6.681 -using [[simproc del: neq]]
   6.682 -apply (unfold single_def union_def diff_def)
   6.683 -apply (simp (no_asm) add: in_multiset expand_fun_eq)
   6.684 -apply (rule conjI, force, safe, simp_all)
   6.685 -apply (simp add: eq_sym_conv)
   6.686 -done
   6.687 -
   6.688 -declare Rep_multiset_inject [symmetric, simp del]
   6.689 -
   6.690 -instance multiset :: (type) cancel_ab_semigroup_add
   6.691 -proof
   6.692 -  fix a b c :: "'a multiset"
   6.693 -  show "a + b = a + c \<Longrightarrow> b = c" by simp
   6.694 +lemma size_eq_Suc_imp_eq_union:
   6.695 +  assumes "size M = Suc n"
   6.696 +  shows "\<exists>a N. M = N + {#a#}"
   6.697 +proof -
   6.698 +  from assms obtain a where "a \<in># M"
   6.699 +    by (erule size_eq_Suc_imp_elem [THEN exE])
   6.700 +  then have "M = M - {#a#} + {#a#}" by simp
   6.701 +  then show ?thesis by blast
   6.702  qed
   6.703  
   6.704 -lemma insert_DiffM:
   6.705 -  "x \<in># M \<Longrightarrow> {#x#} + (M - {#x#}) = M"
   6.706 -by (clarsimp simp: multiset_eq_conv_count_eq)
   6.707 -
   6.708 -lemma insert_DiffM2[simp]:
   6.709 -  "x \<in># M \<Longrightarrow> M - {#x#} + {#x#} = M"
   6.710 -by (clarsimp simp: multiset_eq_conv_count_eq)
   6.711 -
   6.712 -lemma multi_union_self_other_eq: 
   6.713 -  "(A::'a multiset) + X = A + Y \<Longrightarrow> X = Y"
   6.714 -by (induct A arbitrary: X Y) auto
   6.715 -
   6.716 -lemma multi_self_add_other_not_self[simp]: "(A = A + {#x#}) = False"
   6.717 -by (metis single_not_empty union_empty union_left_cancel)
   6.718 -
   6.719 -lemma insert_noteq_member: 
   6.720 -  assumes BC: "B + {#b#} = C + {#c#}"
   6.721 -   and bnotc: "b \<noteq> c"
   6.722 -  shows "c \<in># B"
   6.723 -proof -
   6.724 -  have "c \<in># C + {#c#}" by simp
   6.725 -  have nc: "\<not> c \<in># {#b#}" using bnotc by simp
   6.726 -  then have "c \<in># B + {#b#}" using BC by simp
   6.727 -  then show "c \<in># B" using nc by simp
   6.728 -qed
   6.729 -
   6.730 -
   6.731 -lemma add_eq_conv_ex:
   6.732 -  "(M + {#a#} = N + {#b#}) =
   6.733 -    (M = N \<and> a = b \<or> (\<exists>K. M = K + {#b#} \<and> N = K + {#a#}))"
   6.734 -by (auto simp add: add_eq_conv_diff)
   6.735 -
   6.736 -
   6.737 -lemma empty_multiset_count:
   6.738 -  "(\<forall>x. count A x = 0) = (A = {#})"
   6.739 -by (metis count_empty multiset_eq_conv_count_eq)
   6.740 -
   6.741 -
   6.742 -subsubsection {* Intersection *}
   6.743 -
   6.744 -lemma multiset_inter_count:
   6.745 -  "count (A #\<inter> B) x = min (count A x) (count B x)"
   6.746 -by (simp add: multiset_inter_def)
   6.747 -
   6.748 -lemma multiset_inter_commute: "A #\<inter> B = B #\<inter> A"
   6.749 -by (simp add: multiset_eq_conv_count_eq multiset_inter_count
   6.750 -    min_max.inf_commute)
   6.751 -
   6.752 -lemma multiset_inter_assoc: "A #\<inter> (B #\<inter> C) = A #\<inter> B #\<inter> C"
   6.753 -by (simp add: multiset_eq_conv_count_eq multiset_inter_count
   6.754 -    min_max.inf_assoc)
   6.755 -
   6.756 -lemma multiset_inter_left_commute: "A #\<inter> (B #\<inter> C) = B #\<inter> (A #\<inter> C)"
   6.757 -by (simp add: multiset_eq_conv_count_eq multiset_inter_count min_def)
   6.758 -
   6.759 -lemmas multiset_inter_ac =
   6.760 -  multiset_inter_commute
   6.761 -  multiset_inter_assoc
   6.762 -  multiset_inter_left_commute
   6.763 -
   6.764 -lemma multiset_inter_single: "a \<noteq> b \<Longrightarrow> {#a#} #\<inter> {#b#} = {#}"
   6.765 -by (simp add: multiset_eq_conv_count_eq multiset_inter_count)
   6.766 -
   6.767 -lemma multiset_union_diff_commute: "B #\<inter> C = {#} \<Longrightarrow> A + B - C = A - C + B"
   6.768 -apply (simp add: multiset_eq_conv_count_eq multiset_inter_count
   6.769 -    split: split_if_asm)
   6.770 -apply clarsimp
   6.771 -apply (erule_tac x = a in allE)
   6.772 -apply auto
   6.773 -done
   6.774 -
   6.775 -
   6.776 -subsubsection {* Comprehension (filter) *}
   6.777 -
   6.778 -lemma MCollect_empty [simp]: "MCollect {#} P = {#}"
   6.779 -by (simp add: MCollect_def Mempty_def Abs_multiset_inject
   6.780 -    in_multiset expand_fun_eq)
   6.781 -
   6.782 -lemma MCollect_single [simp]:
   6.783 -  "MCollect {#x#} P = (if P x then {#x#} else {#})"
   6.784 -by (simp add: MCollect_def Mempty_def single_def Abs_multiset_inject
   6.785 -    in_multiset expand_fun_eq)
   6.786 -
   6.787 -lemma MCollect_union [simp]:
   6.788 -  "MCollect (M+N) f = MCollect M f + MCollect N f"
   6.789 -by (simp add: MCollect_def union_def Abs_multiset_inject
   6.790 -    in_multiset expand_fun_eq)
   6.791 -
   6.792  
   6.793  subsection {* Induction and case splits *}
   6.794  
   6.795 @@ -434,17 +610,20 @@
   6.796  shows "P M"
   6.797  proof -
   6.798    note defns = union_def single_def Mempty_def
   6.799 +  note add' = add [unfolded defns, simplified]
   6.800 +  have aux: "\<And>a::'a. count (Abs_multiset (\<lambda>b. if b = a then 1 else 0)) =
   6.801 +    (\<lambda>b. if b = a then 1 else 0)" by (simp add: Abs_multiset_inverse in_multiset) 
   6.802    show ?thesis
   6.803 -    apply (rule Rep_multiset_inverse [THEN subst])
   6.804 -    apply (rule Rep_multiset [THEN rep_multiset_induct])
   6.805 +    apply (rule count_inverse [THEN subst])
   6.806 +    apply (rule count [THEN rep_multiset_induct])
   6.807       apply (rule empty [unfolded defns])
   6.808      apply (subgoal_tac "f(b := f b + 1) = (\<lambda>a. f a + (if a=b then 1 else 0))")
   6.809       prefer 2
   6.810       apply (simp add: expand_fun_eq)
   6.811      apply (erule ssubst)
   6.812      apply (erule Abs_multiset_inverse [THEN subst])
   6.813 -    apply (drule add [unfolded defns, simplified])
   6.814 -    apply(simp add:in_multiset)
   6.815 +    apply (drule add')
   6.816 +    apply (simp add: aux)
   6.817      done
   6.818  qed
   6.819  
   6.820 @@ -470,18 +649,379 @@
   6.821  apply (rule_tac x="M - {#x#}" in exI, simp)
   6.822  done
   6.823  
   6.824 +lemma multi_drop_mem_not_eq: "c \<in># B \<Longrightarrow> B - {#c#} \<noteq> B"
   6.825 +by (cases "B = {#}") (auto dest: multi_member_split)
   6.826 +
   6.827  lemma multiset_partition: "M = {# x:#M. P x #} + {# x:#M. \<not> P x #}"
   6.828  apply (subst multiset_eq_conv_count_eq)
   6.829  apply auto
   6.830  done
   6.831  
   6.832 -declare multiset_typedef [simp del]
   6.833 +lemma mset_less_size: "A \<subset># B \<Longrightarrow> size A < size B"
   6.834 +proof (induct A arbitrary: B)
   6.835 +  case (empty M)
   6.836 +  then have "M \<noteq> {#}" by (simp add: mset_less_empty_nonempty)
   6.837 +  then obtain M' x where "M = M' + {#x#}" 
   6.838 +    by (blast dest: multi_nonempty_split)
   6.839 +  then show ?case by simp
   6.840 +next
   6.841 +  case (add S x T)
   6.842 +  have IH: "\<And>B. S \<subset># B \<Longrightarrow> size S < size B" by fact
   6.843 +  have SxsubT: "S + {#x#} \<subset># T" by fact
   6.844 +  then have "x \<in># T" and "S \<subset># T" by (auto dest: mset_less_insertD)
   6.845 +  then obtain T' where T: "T = T' + {#x#}" 
   6.846 +    by (blast dest: multi_member_split)
   6.847 +  then have "S \<subset># T'" using SxsubT 
   6.848 +    by (blast intro: mset_less_add_bothsides)
   6.849 +  then have "size S < size T'" using IH by simp
   6.850 +  then show ?case using T by simp
   6.851 +qed
   6.852 +
   6.853 +
   6.854 +subsubsection {* Strong induction and subset induction for multisets *}
   6.855 +
   6.856 +text {* Well-foundedness of proper subset operator: *}
   6.857 +
   6.858 +text {* proper multiset subset *}
   6.859 +
   6.860 +definition
   6.861 +  mset_less_rel :: "('a multiset * 'a multiset) set" where
   6.862 +  "mset_less_rel = {(A,B). A \<subset># B}"
   6.863  
   6.864 -lemma multi_drop_mem_not_eq: "c \<in># B \<Longrightarrow> B - {#c#} \<noteq> B"
   6.865 -by (cases "B = {#}") (auto dest: multi_member_split)
   6.866 +lemma multiset_add_sub_el_shuffle: 
   6.867 +  assumes "c \<in># B" and "b \<noteq> c" 
   6.868 +  shows "B - {#c#} + {#b#} = B + {#b#} - {#c#}"
   6.869 +proof -
   6.870 +  from `c \<in># B` obtain A where B: "B = A + {#c#}" 
   6.871 +    by (blast dest: multi_member_split)
   6.872 +  have "A + {#b#} = A + {#b#} + {#c#} - {#c#}" by simp
   6.873 +  then have "A + {#b#} = A + {#c#} + {#b#} - {#c#}" 
   6.874 +    by (simp add: add_ac)
   6.875 +  then show ?thesis using B by simp
   6.876 +qed
   6.877 +
   6.878 +lemma wf_mset_less_rel: "wf mset_less_rel"
   6.879 +apply (unfold mset_less_rel_def)
   6.880 +apply (rule wf_measure [THEN wf_subset, where f1=size])
   6.881 +apply (clarsimp simp: measure_def inv_image_def mset_less_size)
   6.882 +done
   6.883 +
   6.884 +text {* The induction rules: *}
   6.885 +
   6.886 +lemma full_multiset_induct [case_names less]:
   6.887 +assumes ih: "\<And>B. \<forall>A. A \<subset># B \<longrightarrow> P A \<Longrightarrow> P B"
   6.888 +shows "P B"
   6.889 +apply (rule wf_mset_less_rel [THEN wf_induct])
   6.890 +apply (rule ih, auto simp: mset_less_rel_def)
   6.891 +done
   6.892 +
   6.893 +lemma multi_subset_induct [consumes 2, case_names empty add]:
   6.894 +assumes "F \<subseteq># A"
   6.895 +  and empty: "P {#}"
   6.896 +  and insert: "\<And>a F. a \<in># A \<Longrightarrow> P F \<Longrightarrow> P (F + {#a#})"
   6.897 +shows "P F"
   6.898 +proof -
   6.899 +  from `F \<subseteq># A`
   6.900 +  show ?thesis
   6.901 +  proof (induct F)
   6.902 +    show "P {#}" by fact
   6.903 +  next
   6.904 +    fix x F
   6.905 +    assume P: "F \<subseteq># A \<Longrightarrow> P F" and i: "F + {#x#} \<subseteq># A"
   6.906 +    show "P (F + {#x#})"
   6.907 +    proof (rule insert)
   6.908 +      from i show "x \<in># A" by (auto dest: mset_le_insertD)
   6.909 +      from i have "F \<subseteq># A" by (auto dest: mset_le_insertD)
   6.910 +      with P show "P F" .
   6.911 +    qed
   6.912 +  qed
   6.913 +qed
   6.914  
   6.915  
   6.916 -subsection {* Orderings *}
   6.917 +subsection {* Alternative representations *}
   6.918 +
   6.919 +subsubsection {* Lists *}
   6.920 +
   6.921 +primrec multiset_of :: "'a list \<Rightarrow> 'a multiset" where
   6.922 +  "multiset_of [] = {#}" |
   6.923 +  "multiset_of (a # x) = multiset_of x + {# a #}"
   6.924 +
   6.925 +lemma multiset_of_zero_iff[simp]: "(multiset_of x = {#}) = (x = [])"
   6.926 +by (induct x) auto
   6.927 +
   6.928 +lemma multiset_of_zero_iff_right[simp]: "({#} = multiset_of x) = (x = [])"
   6.929 +by (induct x) auto
   6.930 +
   6.931 +lemma set_of_multiset_of[simp]: "set_of(multiset_of x) = set x"
   6.932 +by (induct x) auto
   6.933 +
   6.934 +lemma mem_set_multiset_eq: "x \<in> set xs = (x :# multiset_of xs)"
   6.935 +by (induct xs) auto
   6.936 +
   6.937 +lemma multiset_of_append [simp]:
   6.938 +  "multiset_of (xs @ ys) = multiset_of xs + multiset_of ys"
   6.939 +  by (induct xs arbitrary: ys) (auto simp: add_ac)
   6.940 +
   6.941 +lemma surj_multiset_of: "surj multiset_of"
   6.942 +apply (unfold surj_def)
   6.943 +apply (rule allI)
   6.944 +apply (rule_tac M = y in multiset_induct)
   6.945 + apply auto
   6.946 +apply (rule_tac x = "x # xa" in exI)
   6.947 +apply auto
   6.948 +done
   6.949 +
   6.950 +lemma set_count_greater_0: "set x = {a. count (multiset_of x) a > 0}"
   6.951 +by (induct x) auto
   6.952 +
   6.953 +lemma distinct_count_atmost_1:
   6.954 +  "distinct x = (! a. count (multiset_of x) a = (if a \<in> set x then 1 else 0))"
   6.955 +apply (induct x, simp, rule iffI, simp_all)
   6.956 +apply (rule conjI)
   6.957 +apply (simp_all add: set_of_multiset_of [THEN sym] del: set_of_multiset_of)
   6.958 +apply (erule_tac x = a in allE, simp, clarify)
   6.959 +apply (erule_tac x = aa in allE, simp)
   6.960 +done
   6.961 +
   6.962 +lemma multiset_of_eq_setD:
   6.963 +  "multiset_of xs = multiset_of ys \<Longrightarrow> set xs = set ys"
   6.964 +by (rule) (auto simp add:multiset_eq_conv_count_eq set_count_greater_0)
   6.965 +
   6.966 +lemma set_eq_iff_multiset_of_eq_distinct:
   6.967 +  "distinct x \<Longrightarrow> distinct y \<Longrightarrow>
   6.968 +    (set x = set y) = (multiset_of x = multiset_of y)"
   6.969 +by (auto simp: multiset_eq_conv_count_eq distinct_count_atmost_1)
   6.970 +
   6.971 +lemma set_eq_iff_multiset_of_remdups_eq:
   6.972 +   "(set x = set y) = (multiset_of (remdups x) = multiset_of (remdups y))"
   6.973 +apply (rule iffI)
   6.974 +apply (simp add: set_eq_iff_multiset_of_eq_distinct[THEN iffD1])
   6.975 +apply (drule distinct_remdups [THEN distinct_remdups
   6.976 +      [THEN set_eq_iff_multiset_of_eq_distinct [THEN iffD2]]])
   6.977 +apply simp
   6.978 +done
   6.979 +
   6.980 +lemma multiset_of_compl_union [simp]:
   6.981 +  "multiset_of [x\<leftarrow>xs. P x] + multiset_of [x\<leftarrow>xs. \<not>P x] = multiset_of xs"
   6.982 +  by (induct xs) (auto simp: add_ac)
   6.983 +
   6.984 +lemma count_filter:
   6.985 +  "count (multiset_of xs) x = length [y \<leftarrow> xs. y = x]"
   6.986 +by (induct xs) auto
   6.987 +
   6.988 +lemma nth_mem_multiset_of: "i < length ls \<Longrightarrow> (ls ! i) :# multiset_of ls"
   6.989 +apply (induct ls arbitrary: i)
   6.990 + apply simp
   6.991 +apply (case_tac i)
   6.992 + apply auto
   6.993 +done
   6.994 +
   6.995 +lemma multiset_of_remove1: "multiset_of (remove1 a xs) = multiset_of xs - {#a#}"
   6.996 +by (induct xs) (auto simp add: multiset_eq_conv_count_eq)
   6.997 +
   6.998 +lemma multiset_of_eq_length:
   6.999 +assumes "multiset_of xs = multiset_of ys"
  6.1000 +shows "length xs = length ys"
  6.1001 +using assms
  6.1002 +proof (induct arbitrary: ys rule: length_induct)
  6.1003 +  case (1 xs ys)
  6.1004 +  show ?case
  6.1005 +  proof (cases xs)
  6.1006 +    case Nil with "1.prems" show ?thesis by simp
  6.1007 +  next
  6.1008 +    case (Cons x xs')
  6.1009 +    note xCons = Cons
  6.1010 +    show ?thesis
  6.1011 +    proof (cases ys)
  6.1012 +      case Nil
  6.1013 +      with "1.prems" Cons show ?thesis by simp
  6.1014 +    next
  6.1015 +      case (Cons y ys')
  6.1016 +      have x_in_ys: "x = y \<or> x \<in> set ys'"
  6.1017 +      proof (cases "x = y")
  6.1018 +        case True then show ?thesis ..
  6.1019 +      next
  6.1020 +        case False
  6.1021 +        from "1.prems" [symmetric] xCons Cons have "x :# multiset_of ys' + {#y#}" by simp
  6.1022 +        with False show ?thesis by (simp add: mem_set_multiset_eq)
  6.1023 +      qed
  6.1024 +      from "1.hyps" have IH: "length xs' < length xs \<longrightarrow>
  6.1025 +        (\<forall>x. multiset_of xs' = multiset_of x \<longrightarrow> length xs' = length x)" by blast
  6.1026 +      from "1.prems" x_in_ys Cons xCons have "multiset_of xs' = multiset_of (remove1 x (y#ys'))"
  6.1027 +        apply -
  6.1028 +        apply (simp add: multiset_of_remove1, simp only: add_eq_conv_diff)
  6.1029 +        apply fastsimp
  6.1030 +        done
  6.1031 +      with IH xCons have IH': "length xs' = length (remove1 x (y#ys'))" by fastsimp
  6.1032 +      from x_in_ys have "x \<noteq> y \<Longrightarrow> length ys' > 0" by auto
  6.1033 +      with Cons xCons x_in_ys IH' show ?thesis by (auto simp add: length_remove1)
  6.1034 +    qed
  6.1035 +  qed
  6.1036 +qed
  6.1037 +
  6.1038 +text {*
  6.1039 +  This lemma shows which properties suffice to show that a function
  6.1040 +  @{text "f"} with @{text "f xs = ys"} behaves like sort.
  6.1041 +*}
  6.1042 +lemma properties_for_sort:
  6.1043 +  "multiset_of ys = multiset_of xs \<Longrightarrow> sorted ys \<Longrightarrow> sort xs = ys"
  6.1044 +proof (induct xs arbitrary: ys)
  6.1045 +  case Nil then show ?case by simp
  6.1046 +next
  6.1047 +  case (Cons x xs)
  6.1048 +  then have "x \<in> set ys"
  6.1049 +    by (auto simp add:  mem_set_multiset_eq intro!: ccontr)
  6.1050 +  with Cons.prems Cons.hyps [of "remove1 x ys"] show ?case
  6.1051 +    by (simp add: sorted_remove1 multiset_of_remove1 insort_remove1)
  6.1052 +qed
  6.1053 +
  6.1054 +lemma multiset_of_remdups_le: "multiset_of (remdups xs) \<le># multiset_of xs"
  6.1055 +apply (induct xs)
  6.1056 + apply auto
  6.1057 +apply (rule mset_le_trans)
  6.1058 + apply auto
  6.1059 +done
  6.1060 +
  6.1061 +lemma multiset_of_update:
  6.1062 +  "i < length ls \<Longrightarrow> multiset_of (ls[i := v]) = multiset_of ls - {#ls ! i#} + {#v#}"
  6.1063 +proof (induct ls arbitrary: i)
  6.1064 +  case Nil then show ?case by simp
  6.1065 +next
  6.1066 +  case (Cons x xs)
  6.1067 +  show ?case
  6.1068 +  proof (cases i)
  6.1069 +    case 0 then show ?thesis by simp
  6.1070 +  next
  6.1071 +    case (Suc i')
  6.1072 +    with Cons show ?thesis
  6.1073 +      apply simp
  6.1074 +      apply (subst add_assoc)
  6.1075 +      apply (subst add_commute [of "{#v#}" "{#x#}"])
  6.1076 +      apply (subst add_assoc [symmetric])
  6.1077 +      apply simp
  6.1078 +      apply (rule mset_le_multiset_union_diff_commute)
  6.1079 +      apply (simp add: mset_le_single nth_mem_multiset_of)
  6.1080 +      done
  6.1081 +  qed
  6.1082 +qed
  6.1083 +
  6.1084 +lemma multiset_of_swap:
  6.1085 +  "i < length ls \<Longrightarrow> j < length ls \<Longrightarrow>
  6.1086 +    multiset_of (ls[j := ls ! i, i := ls ! j]) = multiset_of ls"
  6.1087 +  by (cases "i = j") (simp_all add: multiset_of_update nth_mem_multiset_of)
  6.1088 +
  6.1089 +
  6.1090 +subsubsection {* Association lists -- including rudimentary code generation *}
  6.1091 +
  6.1092 +definition count_of :: "('a \<times> nat) list \<Rightarrow> 'a \<Rightarrow> nat" where
  6.1093 +  "count_of xs x = (case map_of xs x of None \<Rightarrow> 0 | Some n \<Rightarrow> n)"
  6.1094 +
  6.1095 +lemma count_of_multiset:
  6.1096 +  "count_of xs \<in> multiset"
  6.1097 +proof -
  6.1098 +  let ?A = "{x::'a. 0 < (case map_of xs x of None \<Rightarrow> 0\<Colon>nat | Some (n\<Colon>nat) \<Rightarrow> n)}"
  6.1099 +  have "?A \<subseteq> dom (map_of xs)"
  6.1100 +  proof
  6.1101 +    fix x
  6.1102 +    assume "x \<in> ?A"
  6.1103 +    then have "0 < (case map_of xs x of None \<Rightarrow> 0\<Colon>nat | Some (n\<Colon>nat) \<Rightarrow> n)" by simp
  6.1104 +    then have "map_of xs x \<noteq> None" by (cases "map_of xs x") auto
  6.1105 +    then show "x \<in> dom (map_of xs)" by auto
  6.1106 +  qed
  6.1107 +  with finite_dom_map_of [of xs] have "finite ?A"
  6.1108 +    by (auto intro: finite_subset)
  6.1109 +  then show ?thesis
  6.1110 +    by (simp add: count_of_def expand_fun_eq multiset_def)
  6.1111 +qed
  6.1112 +
  6.1113 +lemma count_simps [simp]:
  6.1114 +  "count_of [] = (\<lambda>_. 0)"
  6.1115 +  "count_of ((x, n) # xs) = (\<lambda>y. if x = y then n else count_of xs y)"
  6.1116 +  by (simp_all add: count_of_def expand_fun_eq)
  6.1117 +
  6.1118 +lemma count_of_empty:
  6.1119 +  "x \<notin> fst ` set xs \<Longrightarrow> count_of xs x = 0"
  6.1120 +  by (induct xs) (simp_all add: count_of_def)
  6.1121 +
  6.1122 +lemma count_of_filter:
  6.1123 +  "count_of (filter (P \<circ> fst) xs) x = (if P x then count_of xs x else 0)"
  6.1124 +  by (induct xs) auto
  6.1125 +
  6.1126 +definition Bag :: "('a \<times> nat) list \<Rightarrow> 'a multiset" where
  6.1127 +  "Bag xs = Abs_multiset (count_of xs)"
  6.1128 +
  6.1129 +code_datatype Bag
  6.1130 +
  6.1131 +lemma count_Bag [simp, code]:
  6.1132 +  "count (Bag xs) = count_of xs"
  6.1133 +  by (simp add: Bag_def count_of_multiset Abs_multiset_inverse)
  6.1134 +
  6.1135 +lemma Mempty_Bag [code]:
  6.1136 +  "{#} = Bag []"
  6.1137 +  by (simp add: multiset_eq_conv_count_eq)
  6.1138 +  
  6.1139 +lemma single_Bag [code]:
  6.1140 +  "{#x#} = Bag [(x, 1)]"
  6.1141 +  by (simp add: multiset_eq_conv_count_eq)
  6.1142 +
  6.1143 +lemma MCollect_Bag [code]:
  6.1144 +  "MCollect (Bag xs) P = Bag (filter (P \<circ> fst) xs)"
  6.1145 +  by (simp add: multiset_eq_conv_count_eq count_of_filter)
  6.1146 +
  6.1147 +lemma mset_less_eq_Bag [code]:
  6.1148 +  "Bag xs \<subseteq># A \<longleftrightarrow> (\<forall>(x, n) \<in> set xs. count_of xs x \<le> count A x)"
  6.1149 +    (is "?lhs \<longleftrightarrow> ?rhs")
  6.1150 +proof
  6.1151 +  assume ?lhs then show ?rhs
  6.1152 +    by (auto simp add: mset_le_def count_Bag)
  6.1153 +next
  6.1154 +  assume ?rhs
  6.1155 +  show ?lhs
  6.1156 +  proof (rule mset_less_eqI)
  6.1157 +    fix x
  6.1158 +    from `?rhs` have "count_of xs x \<le> count A x"
  6.1159 +      by (cases "x \<in> fst ` set xs") (auto simp add: count_of_empty)
  6.1160 +    then show "count (Bag xs) x \<le> count A x"
  6.1161 +      by (simp add: mset_le_def count_Bag)
  6.1162 +  qed
  6.1163 +qed
  6.1164 +
  6.1165 +instantiation multiset :: (eq) eq
  6.1166 +begin
  6.1167 +
  6.1168 +definition
  6.1169 +  "HOL.eq A B \<longleftrightarrow> A \<subseteq># B \<and> B \<subseteq># A"
  6.1170 +
  6.1171 +instance proof
  6.1172 +qed (simp add: eq_multiset_def mset_order.eq_iff)
  6.1173 +
  6.1174 +end
  6.1175 +
  6.1176 +definition (in term_syntax)
  6.1177 +  bagify :: "('a\<Colon>typerep \<times> nat) list \<times> (unit \<Rightarrow> Code_Evaluation.term)
  6.1178 +    \<Rightarrow> 'a multiset \<times> (unit \<Rightarrow> Code_Evaluation.term)" where
  6.1179 +  [code_unfold]: "bagify xs = Code_Evaluation.valtermify Bag {\<cdot>} xs"
  6.1180 +
  6.1181 +notation fcomp (infixl "o>" 60)
  6.1182 +notation scomp (infixl "o\<rightarrow>" 60)
  6.1183 +
  6.1184 +instantiation multiset :: (random) random
  6.1185 +begin
  6.1186 +
  6.1187 +definition
  6.1188 +  "Quickcheck.random i = Quickcheck.random i o\<rightarrow> (\<lambda>xs. Pair (bagify xs))"
  6.1189 +
  6.1190 +instance ..
  6.1191 +
  6.1192 +end
  6.1193 +
  6.1194 +no_notation fcomp (infixl "o>" 60)
  6.1195 +no_notation scomp (infixl "o\<rightarrow>" 60)
  6.1196 +
  6.1197 +hide (open) const bagify
  6.1198 +
  6.1199 +
  6.1200 +subsection {* The multiset order *}
  6.1201  
  6.1202  subsubsection {* Well-foundedness *}
  6.1203  
  6.1204 @@ -490,7 +1030,7 @@
  6.1205        (\<forall>b. b :# K --> (b, a) \<in> r)}"
  6.1206  
  6.1207  definition mult :: "('a \<times> 'a) set => ('a multiset \<times> 'a multiset) set" where
  6.1208 -  "mult r = (mult1 r)\<^sup>+"
  6.1209 +  [code del]: "mult r = (mult1 r)\<^sup>+"
  6.1210  
  6.1211  lemma not_less_empty [iff]: "(M, {#}) \<notin> mult1 r"
  6.1212  by (simp add: mult1_def)
  6.1213 @@ -523,7 +1063,7 @@
  6.1214      next
  6.1215        fix K'
  6.1216        assume "M0' = K' + {#a#}"
  6.1217 -      with N have n: "N = K' + K + {#a#}" by (simp add: union_ac)
  6.1218 +      with N have n: "N = K' + K + {#a#}" by (simp add: add_ac)
  6.1219  
  6.1220        assume "M0 = K' + {#a'#}"
  6.1221        with r have "?R (K' + K) M0" by blast
  6.1222 @@ -568,7 +1108,7 @@
  6.1223            with wf_hyp have "\<forall>M \<in> ?W. M + {#x#} \<in> ?W" by blast
  6.1224            moreover from add have "M0 + K \<in> ?W" by simp
  6.1225            ultimately have "(M0 + K) + {#x#} \<in> ?W" ..
  6.1226 -          then show "M0 + (K + {#x#}) \<in> ?W" by (simp only: union_assoc)
  6.1227 +          then show "M0 + (K + {#x#}) \<in> ?W" by (simp only: add_assoc)
  6.1228          qed
  6.1229          then show "N \<in> ?W" by (simp only: N)
  6.1230        qed
  6.1231 @@ -610,11 +1150,6 @@
  6.1232  
  6.1233  subsubsection {* Closure-free presentation *}
  6.1234  
  6.1235 -(*Badly needed: a linear arithmetic procedure for multisets*)
  6.1236 -
  6.1237 -lemma diff_union_single_conv: "a :# J ==> I + J - {#a#} = I + (J - {#a#})"
  6.1238 -by (simp add: multiset_eq_conv_count_eq)
  6.1239 -
  6.1240  text {* One direction. *}
  6.1241  
  6.1242  lemma mult_implies_one_step:
  6.1243 @@ -628,7 +1163,7 @@
  6.1244   apply (rule_tac x = I in exI)
  6.1245   apply (simp (no_asm))
  6.1246   apply (rule_tac x = "(K - {#a#}) + Ka" in exI)
  6.1247 - apply (simp (no_asm_simp) add: union_assoc [symmetric])
  6.1248 + apply (simp (no_asm_simp) add: add_assoc [symmetric])
  6.1249   apply (drule_tac f = "\<lambda>M. M - {#a#}" in arg_cong)
  6.1250   apply (simp add: diff_union_single_conv)
  6.1251   apply (simp (no_asm_use) add: trans_def)
  6.1252 @@ -649,14 +1184,6 @@
  6.1253  apply (simp (no_asm))
  6.1254  done
  6.1255  
  6.1256 -lemma elem_imp_eq_diff_union: "a :# M ==> M = M - {#a#} + {#a#}"
  6.1257 -by (simp add: multiset_eq_conv_count_eq)
  6.1258 -
  6.1259 -lemma size_eq_Suc_imp_eq_union: "size M = Suc n ==> \<exists>a N. M = N + {#a#}"
  6.1260 -apply (erule size_eq_Suc_imp_elem [THEN exE])
  6.1261 -apply (drule elem_imp_eq_diff_union, auto)
  6.1262 -done
  6.1263 -
  6.1264  lemma one_step_implies_mult_aux:
  6.1265    "trans r ==>
  6.1266      \<forall>I J K. (size J = n \<and> J \<noteq> {#} \<and> (\<forall>k \<in> set_of K. \<exists>j \<in> set_of J. (k, j) \<in> r))
  6.1267 @@ -679,13 +1206,13 @@
  6.1268      (I + {# x :# K. (x, a) \<in> r #}) + J') \<in> mult r")
  6.1269   prefer 2
  6.1270   apply force
  6.1271 -apply (simp (no_asm_use) add: union_assoc [symmetric] mult_def)
  6.1272 +apply (simp (no_asm_use) add: add_assoc [symmetric] mult_def)
  6.1273  apply (erule trancl_trans)
  6.1274  apply (rule r_into_trancl)
  6.1275  apply (simp add: mult1_def set_of_def)
  6.1276  apply (rule_tac x = a in exI)
  6.1277  apply (rule_tac x = "I + J'" in exI)
  6.1278 -apply (simp add: union_ac)
  6.1279 +apply (simp add: add_ac)
  6.1280  done
  6.1281  
  6.1282  lemma one_step_implies_mult:
  6.1283 @@ -699,10 +1226,10 @@
  6.1284  instantiation multiset :: (order) order
  6.1285  begin
  6.1286  
  6.1287 -definition less_multiset_def [code del]:
  6.1288 +definition less_multiset_def:
  6.1289    "M' < M \<longleftrightarrow> (M', M) \<in> mult {(x', x). x' < x}"
  6.1290  
  6.1291 -definition le_multiset_def [code del]:
  6.1292 +definition le_multiset_def:
  6.1293    "M' <= M \<longleftrightarrow> M' = M \<or> M' < (M::'a multiset)"
  6.1294  
  6.1295  lemma trans_base_order: "trans {(x', x). x' < (x::'a::order)}"
  6.1296 @@ -776,7 +1303,7 @@
  6.1297  apply auto
  6.1298  apply (rule_tac x = a in exI)
  6.1299  apply (rule_tac x = "C + M0" in exI)
  6.1300 -apply (simp add: union_assoc)
  6.1301 +apply (simp add: add_assoc)
  6.1302  done
  6.1303  
  6.1304  lemma union_less_mono2: "B < D ==> C + B < C + (D::'a::order multiset)"
  6.1305 @@ -787,8 +1314,8 @@
  6.1306  done
  6.1307  
  6.1308  lemma union_less_mono1: "B < D ==> B + C < D + (C::'a::order multiset)"
  6.1309 -apply (subst union_commute [of B C])
  6.1310 -apply (subst union_commute [of D C])
  6.1311 +apply (subst add_commute [of B C])
  6.1312 +apply (subst add_commute [of D C])
  6.1313  apply (erule union_less_mono2)
  6.1314  done
  6.1315  
  6.1316 @@ -819,7 +1346,7 @@
  6.1317  qed
  6.1318  
  6.1319  lemma union_upper2: "B <= A + (B::'a::order multiset)"
  6.1320 -by (subst union_commute) (rule union_upper1)
  6.1321 +by (subst add_commute) (rule union_upper1)
  6.1322  
  6.1323  instance multiset :: (order) pordered_ab_semigroup_add
  6.1324  apply intro_classes
  6.1325 @@ -827,416 +1354,6 @@
  6.1326  done
  6.1327  
  6.1328  
  6.1329 -subsection {* Link with lists *}
  6.1330 -
  6.1331 -primrec multiset_of :: "'a list \<Rightarrow> 'a multiset" where
  6.1332 -  "multiset_of [] = {#}" |
  6.1333 -  "multiset_of (a # x) = multiset_of x + {# a #}"
  6.1334 -
  6.1335 -lemma multiset_of_zero_iff[simp]: "(multiset_of x = {#}) = (x = [])"
  6.1336 -by (induct x) auto
  6.1337 -
  6.1338 -lemma multiset_of_zero_iff_right[simp]: "({#} = multiset_of x) = (x = [])"
  6.1339 -by (induct x) auto
  6.1340 -
  6.1341 -lemma set_of_multiset_of[simp]: "set_of(multiset_of x) = set x"
  6.1342 -by (induct x) auto
  6.1343 -
  6.1344 -lemma mem_set_multiset_eq: "x \<in> set xs = (x :# multiset_of xs)"
  6.1345 -by (induct xs) auto
  6.1346 -
  6.1347 -lemma multiset_of_append [simp]:
  6.1348 -  "multiset_of (xs @ ys) = multiset_of xs + multiset_of ys"
  6.1349 -by (induct xs arbitrary: ys) (auto simp: union_ac)
  6.1350 -
  6.1351 -lemma surj_multiset_of: "surj multiset_of"
  6.1352 -apply (unfold surj_def)
  6.1353 -apply (rule allI)
  6.1354 -apply (rule_tac M = y in multiset_induct)
  6.1355 - apply auto
  6.1356 -apply (rule_tac x = "x # xa" in exI)
  6.1357 -apply auto
  6.1358 -done
  6.1359 -
  6.1360 -lemma set_count_greater_0: "set x = {a. count (multiset_of x) a > 0}"
  6.1361 -by (induct x) auto
  6.1362 -
  6.1363 -lemma distinct_count_atmost_1:
  6.1364 -  "distinct x = (! a. count (multiset_of x) a = (if a \<in> set x then 1 else 0))"
  6.1365 -apply (induct x, simp, rule iffI, simp_all)
  6.1366 -apply (rule conjI)
  6.1367 -apply (simp_all add: set_of_multiset_of [THEN sym] del: set_of_multiset_of)
  6.1368 -apply (erule_tac x = a in allE, simp, clarify)
  6.1369 -apply (erule_tac x = aa in allE, simp)
  6.1370 -done
  6.1371 -
  6.1372 -lemma multiset_of_eq_setD:
  6.1373 -  "multiset_of xs = multiset_of ys \<Longrightarrow> set xs = set ys"
  6.1374 -by (rule) (auto simp add:multiset_eq_conv_count_eq set_count_greater_0)
  6.1375 -
  6.1376 -lemma set_eq_iff_multiset_of_eq_distinct:
  6.1377 -  "distinct x \<Longrightarrow> distinct y \<Longrightarrow>
  6.1378 -    (set x = set y) = (multiset_of x = multiset_of y)"
  6.1379 -by (auto simp: multiset_eq_conv_count_eq distinct_count_atmost_1)
  6.1380 -
  6.1381 -lemma set_eq_iff_multiset_of_remdups_eq:
  6.1382 -   "(set x = set y) = (multiset_of (remdups x) = multiset_of (remdups y))"
  6.1383 -apply (rule iffI)
  6.1384 -apply (simp add: set_eq_iff_multiset_of_eq_distinct[THEN iffD1])
  6.1385 -apply (drule distinct_remdups [THEN distinct_remdups
  6.1386 -      [THEN set_eq_iff_multiset_of_eq_distinct [THEN iffD2]]])
  6.1387 -apply simp
  6.1388 -done
  6.1389 -
  6.1390 -lemma multiset_of_compl_union [simp]:
  6.1391 -  "multiset_of [x\<leftarrow>xs. P x] + multiset_of [x\<leftarrow>xs. \<not>P x] = multiset_of xs"
  6.1392 -by (induct xs) (auto simp: union_ac)
  6.1393 -
  6.1394 -lemma count_filter:
  6.1395 -  "count (multiset_of xs) x = length [y \<leftarrow> xs. y = x]"
  6.1396 -by (induct xs) auto
  6.1397 -
  6.1398 -lemma nth_mem_multiset_of: "i < length ls \<Longrightarrow> (ls ! i) :# multiset_of ls"
  6.1399 -apply (induct ls arbitrary: i)
  6.1400 - apply simp
  6.1401 -apply (case_tac i)
  6.1402 - apply auto
  6.1403 -done
  6.1404 -
  6.1405 -lemma multiset_of_remove1: "multiset_of (remove1 a xs) = multiset_of xs - {#a#}"
  6.1406 -by (induct xs) (auto simp add: multiset_eq_conv_count_eq)
  6.1407 -
  6.1408 -lemma multiset_of_eq_length:
  6.1409 -assumes "multiset_of xs = multiset_of ys"
  6.1410 -shows "length xs = length ys"
  6.1411 -using assms
  6.1412 -proof (induct arbitrary: ys rule: length_induct)
  6.1413 -  case (1 xs ys)
  6.1414 -  show ?case
  6.1415 -  proof (cases xs)
  6.1416 -    case Nil with "1.prems" show ?thesis by simp
  6.1417 -  next
  6.1418 -    case (Cons x xs')
  6.1419 -    note xCons = Cons
  6.1420 -    show ?thesis
  6.1421 -    proof (cases ys)
  6.1422 -      case Nil
  6.1423 -      with "1.prems" Cons show ?thesis by simp
  6.1424 -    next
  6.1425 -      case (Cons y ys')
  6.1426 -      have x_in_ys: "x = y \<or> x \<in> set ys'"
  6.1427 -      proof (cases "x = y")
  6.1428 -        case True then show ?thesis ..
  6.1429 -      next
  6.1430 -        case False
  6.1431 -        from "1.prems" [symmetric] xCons Cons have "x :# multiset_of ys' + {#y#}" by simp
  6.1432 -        with False show ?thesis by (simp add: mem_set_multiset_eq)
  6.1433 -      qed
  6.1434 -      from "1.hyps" have IH: "length xs' < length xs \<longrightarrow>
  6.1435 -        (\<forall>x. multiset_of xs' = multiset_of x \<longrightarrow> length xs' = length x)" by blast
  6.1436 -      from "1.prems" x_in_ys Cons xCons have "multiset_of xs' = multiset_of (remove1 x (y#ys'))"
  6.1437 -        apply -
  6.1438 -        apply (simp add: multiset_of_remove1, simp only: add_eq_conv_diff)
  6.1439 -        apply fastsimp
  6.1440 -        done
  6.1441 -      with IH xCons have IH': "length xs' = length (remove1 x (y#ys'))" by fastsimp
  6.1442 -      from x_in_ys have "x \<noteq> y \<Longrightarrow> length ys' > 0" by auto
  6.1443 -      with Cons xCons x_in_ys IH' show ?thesis by (auto simp add: length_remove1)
  6.1444 -    qed
  6.1445 -  qed
  6.1446 -qed
  6.1447 -
  6.1448 -text {*
  6.1449 -  This lemma shows which properties suffice to show that a function
  6.1450 -  @{text "f"} with @{text "f xs = ys"} behaves like sort.
  6.1451 -*}
  6.1452 -lemma properties_for_sort:
  6.1453 -  "multiset_of ys = multiset_of xs \<Longrightarrow> sorted ys \<Longrightarrow> sort xs = ys"
  6.1454 -proof (induct xs arbitrary: ys)
  6.1455 -  case Nil then show ?case by simp
  6.1456 -next
  6.1457 -  case (Cons x xs)
  6.1458 -  then have "x \<in> set ys"
  6.1459 -    by (auto simp add:  mem_set_multiset_eq intro!: ccontr)
  6.1460 -  with Cons.prems Cons.hyps [of "remove1 x ys"] show ?case
  6.1461 -    by (simp add: sorted_remove1 multiset_of_remove1 insort_remove1)
  6.1462 -qed
  6.1463 -
  6.1464 -
  6.1465 -subsection {* Pointwise ordering induced by count *}
  6.1466 -
  6.1467 -definition mset_le :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool"  (infix "\<le>#" 50) where
  6.1468 -  [code del]: "A \<le># B \<longleftrightarrow> (\<forall>a. count A a \<le> count B a)"
  6.1469 -
  6.1470 -definition mset_less :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool"  (infix "<#" 50) where
  6.1471 -  [code del]: "A <# B \<longleftrightarrow> A \<le># B \<and> A \<noteq> B"
  6.1472 -
  6.1473 -notation mset_le  (infix "\<subseteq>#" 50)
  6.1474 -notation mset_less  (infix "\<subset>#" 50)
  6.1475 -
  6.1476 -lemma mset_le_refl[simp]: "A \<le># A"
  6.1477 -unfolding mset_le_def by auto
  6.1478 -
  6.1479 -lemma mset_le_trans: "A \<le># B \<Longrightarrow> B \<le># C \<Longrightarrow> A \<le># C"
  6.1480 -unfolding mset_le_def by (fast intro: order_trans)
  6.1481 -
  6.1482 -lemma mset_le_antisym: "A \<le># B \<Longrightarrow> B \<le># A \<Longrightarrow> A = B"
  6.1483 -apply (unfold mset_le_def)
  6.1484 -apply (rule multiset_eq_conv_count_eq [THEN iffD2])
  6.1485 -apply (blast intro: order_antisym)
  6.1486 -done
  6.1487 -
  6.1488 -lemma mset_le_exists_conv: "(A \<le># B) = (\<exists>C. B = A + C)"
  6.1489 -apply (unfold mset_le_def, rule iffI, rule_tac x = "B - A" in exI)
  6.1490 -apply (auto intro: multiset_eq_conv_count_eq [THEN iffD2])
  6.1491 -done
  6.1492 -
  6.1493 -lemma mset_le_mono_add_right_cancel[simp]: "(A + C \<le># B + C) = (A \<le># B)"
  6.1494 -unfolding mset_le_def by auto
  6.1495 -
  6.1496 -lemma mset_le_mono_add_left_cancel[simp]: "(C + A \<le># C + B) = (A \<le># B)"
  6.1497 -unfolding mset_le_def by auto
  6.1498 -
  6.1499 -lemma mset_le_mono_add: "\<lbrakk> A \<le># B; C \<le># D \<rbrakk> \<Longrightarrow> A + C \<le># B + D"
  6.1500 -apply (unfold mset_le_def)
  6.1501 -apply auto
  6.1502 -apply (erule_tac x = a in allE)+
  6.1503 -apply auto
  6.1504 -done
  6.1505 -
  6.1506 -lemma mset_le_add_left[simp]: "A \<le># A + B"
  6.1507 -unfolding mset_le_def by auto
  6.1508 -
  6.1509 -lemma mset_le_add_right[simp]: "B \<le># A + B"
  6.1510 -unfolding mset_le_def by auto
  6.1511 -
  6.1512 -lemma mset_le_single: "a :# B \<Longrightarrow> {#a#} \<le># B"
  6.1513 -by (simp add: mset_le_def)
  6.1514 -
  6.1515 -lemma multiset_diff_union_assoc: "C \<le># B \<Longrightarrow> A + B - C = A + (B - C)"
  6.1516 -by (simp add: multiset_eq_conv_count_eq mset_le_def)
  6.1517 -
  6.1518 -lemma mset_le_multiset_union_diff_commute:
  6.1519 -assumes "B \<le># A"
  6.1520 -shows "A - B + C = A + C - B"
  6.1521 -proof -
  6.1522 -  from mset_le_exists_conv [of "B" "A"] assms have "\<exists>D. A = B + D" ..
  6.1523 -  from this obtain D where "A = B + D" ..
  6.1524 -  then show ?thesis
  6.1525 -    apply simp
  6.1526 -    apply (subst union_commute)
  6.1527 -    apply (subst multiset_diff_union_assoc)
  6.1528 -    apply simp
  6.1529 -    apply (simp add: diff_cancel)
  6.1530 -    apply (subst union_assoc)
  6.1531 -    apply (subst union_commute[of "B" _])
  6.1532 -    apply (subst multiset_diff_union_assoc)
  6.1533 -    apply simp
  6.1534 -    apply (simp add: diff_cancel)
  6.1535 -    done
  6.1536 -qed
  6.1537 -
  6.1538 -lemma multiset_of_remdups_le: "multiset_of (remdups xs) \<le># multiset_of xs"
  6.1539 -apply (induct xs)
  6.1540 - apply auto
  6.1541 -apply (rule mset_le_trans)
  6.1542 - apply auto
  6.1543 -done
  6.1544 -
  6.1545 -lemma multiset_of_update:
  6.1546 -  "i < length ls \<Longrightarrow> multiset_of (ls[i := v]) = multiset_of ls - {#ls ! i#} + {#v#}"
  6.1547 -proof (induct ls arbitrary: i)
  6.1548 -  case Nil then show ?case by simp
  6.1549 -next
  6.1550 -  case (Cons x xs)
  6.1551 -  show ?case
  6.1552 -  proof (cases i)
  6.1553 -    case 0 then show ?thesis by simp
  6.1554 -  next
  6.1555 -    case (Suc i')
  6.1556 -    with Cons show ?thesis
  6.1557 -      apply simp
  6.1558 -      apply (subst union_assoc)
  6.1559 -      apply (subst union_commute [where M = "{#v#}" and N = "{#x#}"])
  6.1560 -      apply (subst union_assoc [symmetric])
  6.1561 -      apply simp
  6.1562 -      apply (rule mset_le_multiset_union_diff_commute)
  6.1563 -      apply (simp add: mset_le_single nth_mem_multiset_of)
  6.1564 -      done
  6.1565 -  qed
  6.1566 -qed
  6.1567 -
  6.1568 -lemma multiset_of_swap:
  6.1569 -  "i < length ls \<Longrightarrow> j < length ls \<Longrightarrow>
  6.1570 -    multiset_of (ls[j := ls ! i, i := ls ! j]) = multiset_of ls"
  6.1571 -apply (case_tac "i = j")
  6.1572 - apply simp
  6.1573 -apply (simp add: multiset_of_update)
  6.1574 -apply (subst elem_imp_eq_diff_union[symmetric])
  6.1575 - apply (simp add: nth_mem_multiset_of)
  6.1576 -apply simp
  6.1577 -done
  6.1578 -
  6.1579 -interpretation mset_order: order "op \<le>#" "op <#"
  6.1580 -proof qed (auto intro: order.intro mset_le_refl mset_le_antisym
  6.1581 -  mset_le_trans simp: mset_less_def)
  6.1582 -
  6.1583 -interpretation mset_order_cancel_semigroup:
  6.1584 -  pordered_cancel_ab_semigroup_add "op +" "op \<le>#" "op <#"
  6.1585 -proof qed (erule mset_le_mono_add [OF mset_le_refl])
  6.1586 -
  6.1587 -interpretation mset_order_semigroup_cancel:
  6.1588 -  pordered_ab_semigroup_add_imp_le "op +" "op \<le>#" "op <#"
  6.1589 -proof qed simp
  6.1590 -
  6.1591 -
  6.1592 -lemma mset_lessD: "A \<subset># B \<Longrightarrow> x \<in># A \<Longrightarrow> x \<in># B"
  6.1593 -apply (clarsimp simp: mset_le_def mset_less_def)
  6.1594 -apply (erule_tac x=x in allE)
  6.1595 -apply auto
  6.1596 -done
  6.1597 -
  6.1598 -lemma mset_leD: "A \<subseteq># B \<Longrightarrow> x \<in># A \<Longrightarrow> x \<in># B"
  6.1599 -apply (clarsimp simp: mset_le_def mset_less_def)
  6.1600 -apply (erule_tac x = x in allE)
  6.1601 -apply auto
  6.1602 -done
  6.1603 -  
  6.1604 -lemma mset_less_insertD: "(A + {#x#} \<subset># B) \<Longrightarrow> (x \<in># B \<and> A \<subset># B)"
  6.1605 -apply (rule conjI)
  6.1606 - apply (simp add: mset_lessD)
  6.1607 -apply (clarsimp simp: mset_le_def mset_less_def)
  6.1608 -apply safe
  6.1609 - apply (erule_tac x = a in allE)
  6.1610 - apply (auto split: split_if_asm)
  6.1611 -done
  6.1612 -
  6.1613 -lemma mset_le_insertD: "(A + {#x#} \<subseteq># B) \<Longrightarrow> (x \<in># B \<and> A \<subseteq># B)"
  6.1614 -apply (rule conjI)
  6.1615 - apply (simp add: mset_leD)
  6.1616 -apply (force simp: mset_le_def mset_less_def split: split_if_asm)
  6.1617 -done
  6.1618 -
  6.1619 -lemma mset_less_of_empty[simp]: "A \<subset># {#} = False" 
  6.1620 -by (induct A) (auto simp: mset_le_def mset_less_def)
  6.1621 -
  6.1622 -lemma multi_psub_of_add_self[simp]: "A \<subset># A + {#x#}"
  6.1623 -by (auto simp: mset_le_def mset_less_def)
  6.1624 -
  6.1625 -lemma multi_psub_self[simp]: "A \<subset># A = False"
  6.1626 -by (auto simp: mset_le_def mset_less_def)
  6.1627 -
  6.1628 -lemma mset_less_add_bothsides:
  6.1629 -  "T + {#x#} \<subset># S + {#x#} \<Longrightarrow> T \<subset># S"
  6.1630 -by (auto simp: mset_le_def mset_less_def)
  6.1631 -
  6.1632 -lemma mset_less_empty_nonempty: "({#} \<subset># S) = (S \<noteq> {#})"
  6.1633 -by (auto simp: mset_le_def mset_less_def)
  6.1634 -
  6.1635 -lemma mset_less_size: "A \<subset># B \<Longrightarrow> size A < size B"
  6.1636 -proof (induct A arbitrary: B)
  6.1637 -  case (empty M)
  6.1638 -  then have "M \<noteq> {#}" by (simp add: mset_less_empty_nonempty)
  6.1639 -  then obtain M' x where "M = M' + {#x#}" 
  6.1640 -    by (blast dest: multi_nonempty_split)
  6.1641 -  then show ?case by simp
  6.1642 -next
  6.1643 -  case (add S x T)
  6.1644 -  have IH: "\<And>B. S \<subset># B \<Longrightarrow> size S < size B" by fact
  6.1645 -  have SxsubT: "S + {#x#} \<subset># T" by fact
  6.1646 -  then have "x \<in># T" and "S \<subset># T" by (auto dest: mset_less_insertD)
  6.1647 -  then obtain T' where T: "T = T' + {#x#}" 
  6.1648 -    by (blast dest: multi_member_split)
  6.1649 -  then have "S \<subset># T'" using SxsubT 
  6.1650 -    by (blast intro: mset_less_add_bothsides)
  6.1651 -  then have "size S < size T'" using IH by simp
  6.1652 -  then show ?case using T by simp
  6.1653 -qed
  6.1654 -
  6.1655 -lemmas mset_less_trans = mset_order.less_trans
  6.1656 -
  6.1657 -lemma mset_less_diff_self: "c \<in># B \<Longrightarrow> B - {#c#} \<subset># B"
  6.1658 -by (auto simp: mset_le_def mset_less_def multi_drop_mem_not_eq)
  6.1659 -
  6.1660 -
  6.1661 -subsection {* Strong induction and subset induction for multisets *}
  6.1662 -
  6.1663 -text {* Well-foundedness of proper subset operator: *}
  6.1664 -
  6.1665 -text {* proper multiset subset *}
  6.1666 -definition
  6.1667 -  mset_less_rel :: "('a multiset * 'a multiset) set" where
  6.1668 -  "mset_less_rel = {(A,B). A \<subset># B}"
  6.1669 -
  6.1670 -lemma multiset_add_sub_el_shuffle: 
  6.1671 -  assumes "c \<in># B" and "b \<noteq> c" 
  6.1672 -  shows "B - {#c#} + {#b#} = B + {#b#} - {#c#}"
  6.1673 -proof -
  6.1674 -  from `c \<in># B` obtain A where B: "B = A + {#c#}" 
  6.1675 -    by (blast dest: multi_member_split)
  6.1676 -  have "A + {#b#} = A + {#b#} + {#c#} - {#c#}" by simp
  6.1677 -  then have "A + {#b#} = A + {#c#} + {#b#} - {#c#}" 
  6.1678 -    by (simp add: union_ac)
  6.1679 -  then show ?thesis using B by simp
  6.1680 -qed
  6.1681 -
  6.1682 -lemma wf_mset_less_rel: "wf mset_less_rel"
  6.1683 -apply (unfold mset_less_rel_def)
  6.1684 -apply (rule wf_measure [THEN wf_subset, where f1=size])
  6.1685 -apply (clarsimp simp: measure_def inv_image_def mset_less_size)
  6.1686 -done
  6.1687 -
  6.1688 -text {* The induction rules: *}
  6.1689 -
  6.1690 -lemma full_multiset_induct [case_names less]:
  6.1691 -assumes ih: "\<And>B. \<forall>A. A \<subset># B \<longrightarrow> P A \<Longrightarrow> P B"
  6.1692 -shows "P B"
  6.1693 -apply (rule wf_mset_less_rel [THEN wf_induct])
  6.1694 -apply (rule ih, auto simp: mset_less_rel_def)
  6.1695 -done
  6.1696 -
  6.1697 -lemma multi_subset_induct [consumes 2, case_names empty add]:
  6.1698 -assumes "F \<subseteq># A"
  6.1699 -  and empty: "P {#}"
  6.1700 -  and insert: "\<And>a F. a \<in># A \<Longrightarrow> P F \<Longrightarrow> P (F + {#a#})"
  6.1701 -shows "P F"
  6.1702 -proof -
  6.1703 -  from `F \<subseteq># A`
  6.1704 -  show ?thesis
  6.1705 -  proof (induct F)
  6.1706 -    show "P {#}" by fact
  6.1707 -  next
  6.1708 -    fix x F
  6.1709 -    assume P: "F \<subseteq># A \<Longrightarrow> P F" and i: "F + {#x#} \<subseteq># A"
  6.1710 -    show "P (F + {#x#})"
  6.1711 -    proof (rule insert)
  6.1712 -      from i show "x \<in># A" by (auto dest: mset_le_insertD)
  6.1713 -      from i have "F \<subseteq># A" by (auto dest: mset_le_insertD)
  6.1714 -      with P show "P F" .
  6.1715 -    qed
  6.1716 -  qed
  6.1717 -qed 
  6.1718 -
  6.1719 -text{* A consequence: Extensionality. *}
  6.1720 -
  6.1721 -lemma multi_count_eq: "(\<forall>x. count A x = count B x) = (A = B)"
  6.1722 -apply (rule iffI)
  6.1723 - prefer 2
  6.1724 - apply clarsimp 
  6.1725 -apply (induct A arbitrary: B rule: full_multiset_induct)
  6.1726 -apply (rename_tac C)
  6.1727 -apply (case_tac B rule: multiset_cases)
  6.1728 - apply (simp add: empty_multiset_count)
  6.1729 -apply simp
  6.1730 -apply (case_tac "x \<in># C")
  6.1731 - apply (force dest: multi_member_split)
  6.1732 -apply (erule_tac x = x in allE)
  6.1733 -apply simp
  6.1734 -done
  6.1735 -
  6.1736 -lemmas multi_count_ext = multi_count_eq [THEN iffD1, rule_format]
  6.1737 -
  6.1738 -
  6.1739  subsection {* The fold combinator *}
  6.1740  
  6.1741  text {*
  6.1742 @@ -1282,9 +1399,7 @@
  6.1743  lemma fold_mset_empty[simp]: "fold_mset f z {#} = z"
  6.1744  unfolding fold_mset_def by blast
  6.1745  
  6.1746 -locale left_commutative = 
  6.1747 -fixes f :: "'a => 'b => 'b"
  6.1748 -assumes left_commute: "f x (f y z) = f y (f x z)"
  6.1749 +context fun_left_comm
  6.1750  begin
  6.1751  
  6.1752  lemma fold_msetG_determ:
  6.1753 @@ -1324,7 +1439,7 @@
  6.1754          have cinB: "c \<in># B" and binC: "b \<in># C" using MBb MCc diff
  6.1755            by (auto intro: insert_noteq_member dest: sym)
  6.1756          have "B - {#c#} \<subset># B" using cinB by (rule mset_less_diff_self)
  6.1757 -        then have DsubM: "?D \<subset># M" using BsubM by (blast intro: mset_less_trans)
  6.1758 +        then have DsubM: "?D \<subset># M" using BsubM by (blast intro: mset_order.less_trans)
  6.1759          from MBb MCc have "B + {#b#} = C + {#c#}" by blast
  6.1760          then have [simp]: "B + {#b#} - {#c#} = C"
  6.1761            using MBb MCc binC cinB by auto
  6.1762 @@ -1342,7 +1457,7 @@
  6.1763              dest: fold_msetG.insertI [where x=b])
  6.1764          then have "f b d = v" using IH CsubM Cv by blast
  6.1765          ultimately show ?thesis using x\<^isub>1 x\<^isub>2
  6.1766 -          by (auto simp: left_commute)
  6.1767 +          by (auto simp: fun_left_comm)
  6.1768        qed
  6.1769      qed
  6.1770    qed
  6.1771 @@ -1363,7 +1478,7 @@
  6.1772  
  6.1773  lemma fold_mset_insert:
  6.1774    "fold_mset f z (A + {#x#}) = f x (fold_mset f z A)"
  6.1775 -apply (simp add: fold_mset_def fold_mset_insert_aux union_commute)  
  6.1776 +apply (simp add: fold_mset_def fold_mset_insert_aux add_commute)  
  6.1777  apply (rule the_equality)
  6.1778   apply (auto cong add: conj_cong 
  6.1779       simp add: fold_mset_def [symmetric] fold_mset_equality fold_msetG_nonempty)
  6.1780 @@ -1378,7 +1493,7 @@
  6.1781  done
  6.1782  
  6.1783  lemma fold_mset_commute: "f x (fold_mset f z A) = fold_mset f (f x z) A"
  6.1784 -by (induct A) (auto simp: fold_mset_insert left_commute [of x])
  6.1785 +by (induct A) (auto simp: fold_mset_insert fun_left_comm [of x])
  6.1786  
  6.1787  lemma fold_mset_single [simp]: "fold_mset f z {#x#} = f x z"
  6.1788  using fold_mset_insert [of z "{#}"] by simp
  6.1789 @@ -1389,7 +1504,7 @@
  6.1790    case empty then show ?case by simp
  6.1791  next
  6.1792    case (add A x)
  6.1793 -  have "A + {#x#} + B = (A+B) + {#x#}" by(simp add:union_ac)
  6.1794 +  have "A + {#x#} + B = (A+B) + {#x#}" by (simp add: add_ac)
  6.1795    then have "fold_mset f z (A + {#x#} + B) = f x (fold_mset f z (A + B))" 
  6.1796      by (simp add: fold_mset_insert)
  6.1797    also have "\<dots> = fold_mset f (fold_mset f z (A + {#x#})) B"
  6.1798 @@ -1398,10 +1513,10 @@
  6.1799  qed
  6.1800  
  6.1801  lemma fold_mset_fusion:
  6.1802 -  assumes "left_commutative g"
  6.1803 +  assumes "fun_left_comm g"
  6.1804    shows "(\<And>x y. h (g x y) = f x (h y)) \<Longrightarrow> h (fold_mset g w A) = fold_mset f (h w) A" (is "PROP ?P")
  6.1805  proof -
  6.1806 -  interpret left_commutative g by fact
  6.1807 +  interpret fun_left_comm g by (fact assms)
  6.1808    show "PROP ?P" by (induct A) auto
  6.1809  qed
  6.1810  
  6.1811 @@ -1430,11 +1545,11 @@
  6.1812  
  6.1813  subsection {* Image *}
  6.1814  
  6.1815 -definition [code del]:
  6.1816 - "image_mset f = fold_mset (op + o single o f) {#}"
  6.1817 +definition image_mset :: "('a \<Rightarrow> 'b) \<Rightarrow> 'a multiset \<Rightarrow> 'b multiset" where
  6.1818 +  "image_mset f = fold_mset (op + o single o f) {#}"
  6.1819  
  6.1820 -interpretation image_left_comm: left_commutative "op + o single o f"
  6.1821 -  proof qed (simp add:union_ac)
  6.1822 +interpretation image_left_comm: fun_left_comm "op + o single o f"
  6.1823 +proof qed (simp add: add_ac)
  6.1824  
  6.1825  lemma image_mset_empty [simp]: "image_mset f {#} = {#}"
  6.1826  by (simp add: image_mset_def)
  6.1827 @@ -1450,7 +1565,7 @@
  6.1828    "image_mset f (M+N) = image_mset f M + image_mset f N"
  6.1829  apply (induct N)
  6.1830   apply simp
  6.1831 -apply (simp add: union_assoc [symmetric] image_mset_insert)
  6.1832 +apply (simp add: add_assoc [symmetric] image_mset_insert)
  6.1833  done
  6.1834  
  6.1835  lemma size_image_mset [simp]: "size (image_mset f M) = size M"
  6.1836 @@ -1608,7 +1723,7 @@
  6.1837  
  6.1838    val regroup_munion_conv =
  6.1839        Function_Lib.regroup_conv @{const_name Multiset.Mempty} @{const_name plus}
  6.1840 -        (map (fn t => t RS eq_reflection) (@{thms union_ac} @ @{thms empty_idemp}))
  6.1841 +        (map (fn t => t RS eq_reflection) (@{thms add_ac} @ @{thms empty_idemp}))
  6.1842  
  6.1843    fun unfold_pwleq_tac i =
  6.1844      (rtac @{thm pw_leq_step} i THEN (fn st => unfold_pwleq_tac (i + 1) st))
  6.1845 @@ -1629,4 +1744,31 @@
  6.1846  end
  6.1847  *}
  6.1848  
  6.1849 -end
  6.1850 +
  6.1851 +subsection {* Legacy theorem bindings *}
  6.1852 +
  6.1853 +lemmas multi_count_eq = multiset_eq_conv_count_eq [symmetric]
  6.1854 +
  6.1855 +lemma union_commute: "M + N = N + (M::'a multiset)"
  6.1856 +  by (fact add_commute)
  6.1857 +
  6.1858 +lemma union_assoc: "(M + N) + K = M + (N + (K::'a multiset))"
  6.1859 +  by (fact add_assoc)
  6.1860 +
  6.1861 +lemma union_lcomm: "M + (N + K) = N + (M + (K::'a multiset))"
  6.1862 +  by (fact add_left_commute)
  6.1863 +
  6.1864 +lemmas union_ac = union_assoc union_commute union_lcomm
  6.1865 +
  6.1866 +lemma union_right_cancel: "M + K = N + K \<longleftrightarrow> M = (N::'a multiset)"
  6.1867 +  by (fact add_right_cancel)
  6.1868 +
  6.1869 +lemma union_left_cancel: "K + M = K + N \<longleftrightarrow> M = (N::'a multiset)"
  6.1870 +  by (fact add_left_cancel)
  6.1871 +
  6.1872 +lemma multi_union_self_other_eq: "(A::'a multiset) + X = A + Y \<Longrightarrow> X = Y"
  6.1873 +  by (fact add_imp_eq)
  6.1874 +
  6.1875 +lemmas mset_less_trans = mset_order.less_trans
  6.1876 +
  6.1877 +end
  6.1878 \ No newline at end of file
     7.1 --- a/src/HOL/Number_Theory/UniqueFactorization.thy	Fri Jan 22 11:42:28 2010 +0100
     7.2 +++ b/src/HOL/Number_Theory/UniqueFactorization.thy	Fri Jan 22 15:26:29 2010 +0100
     7.3 @@ -1,5 +1,4 @@
     7.4  (*  Title:      UniqueFactorization.thy
     7.5 -    ID:         
     7.6      Author:     Jeremy Avigad
     7.7  
     7.8      
     7.9 @@ -388,7 +387,7 @@
    7.10    apply (subgoal_tac "multiset_prime_factorization n = Abs_multiset
    7.11        f")
    7.12    apply (unfold prime_factors_nat_def multiplicity_nat_def)
    7.13 -  apply (simp add: set_of_def count_def Abs_multiset_inverse multiset_def)
    7.14 +  apply (simp add: set_of_def Abs_multiset_inverse multiset_def)
    7.15    apply (unfold multiset_prime_factorization_def)
    7.16    apply (subgoal_tac "n > 0")
    7.17    prefer 2
    7.18 @@ -401,7 +400,7 @@
    7.19    apply force
    7.20    apply force
    7.21    apply force
    7.22 -  unfolding set_of_def count_def msetprod_def
    7.23 +  unfolding set_of_def msetprod_def
    7.24    apply (subgoal_tac "f : multiset")
    7.25    apply (auto simp only: Abs_multiset_inverse)
    7.26    unfolding multiset_def apply force 
     8.1 --- a/src/HOL/Tools/numeral.ML	Fri Jan 22 11:42:28 2010 +0100
     8.2 +++ b/src/HOL/Tools/numeral.ML	Fri Jan 22 15:26:29 2010 +0100
     8.3 @@ -8,7 +8,7 @@
     8.4  sig
     8.5    val mk_cnumeral: int -> cterm
     8.6    val mk_cnumber: ctyp -> int -> cterm
     8.7 -  val add_code: string -> bool -> bool -> (string -> Pretty.T) -> string -> theory -> theory
     8.8 +  val add_code: string -> bool -> (Code_Printer.literals -> int -> string) -> string -> theory -> theory
     8.9  end;
    8.10  
    8.11  structure Numeral: NUMERAL =
    8.12 @@ -56,7 +56,7 @@
    8.13  
    8.14  local open Basic_Code_Thingol in
    8.15  
    8.16 -fun add_code number_of negative unbounded print target thy =
    8.17 +fun add_code number_of negative print target thy =
    8.18    let
    8.19      fun dest_numeral pls' min' bit0' bit1' thm =
    8.20        let
    8.21 @@ -74,8 +74,7 @@
    8.22            | dest_num _ = Code_Printer.eqn_error thm "Illegal numeral expression: illegal term";
    8.23        in dest_num end;
    8.24      fun pretty literals [pls', min', bit0', bit1'] _ thm _ _ [(t, _)] =
    8.25 -      (print o Code_Printer.literal_numeral literals unbounded
    8.26 -        o the_default 0 o dest_numeral pls' min' bit0' bit1' thm) t;
    8.27 +      (Code_Printer.str o print literals o the_default 0 o dest_numeral pls' min' bit0' bit1' thm) t;
    8.28    in
    8.29      thy |> Code_Target.add_syntax_const target number_of
    8.30        (SOME (1, ([@{const_name Int.Pls}, @{const_name Int.Min},
     9.1 --- a/src/Tools/Code/code_haskell.ML	Fri Jan 22 11:42:28 2010 +0100
     9.2 +++ b/src/Tools/Code/code_haskell.ML	Fri Jan 22 15:26:29 2010 +0100
     9.3 @@ -401,11 +401,14 @@
     9.4      let
     9.5        val s = ML_Syntax.print_char c;
     9.6      in if s = "'" then "\\'" else s end;
     9.7 +  fun numeral_haskell k = if k >= 0 then string_of_int k
     9.8 +    else Library.enclose "(" ")" (signed_string_of_int k);
     9.9  in Literals {
    9.10    literal_char = Library.enclose "'" "'" o char_haskell,
    9.11    literal_string = quote o translate_string char_haskell,
    9.12 -  literal_numeral = fn unbounded => fn k => if k >= 0 then string_of_int k
    9.13 -    else Library.enclose "(" ")" (signed_string_of_int k),
    9.14 +  literal_numeral = numeral_haskell,
    9.15 +  literal_positive_numeral = numeral_haskell,
    9.16 +  literal_naive_numeral = numeral_haskell,
    9.17    literal_list = enum "," "[" "]",
    9.18    infix_cons = (5, ":")
    9.19  } end;
    10.1 --- a/src/Tools/Code/code_ml.ML	Fri Jan 22 11:42:28 2010 +0100
    10.2 +++ b/src/Tools/Code/code_ml.ML	Fri Jan 22 15:26:29 2010 +0100
    10.3 @@ -354,9 +354,9 @@
    10.4  val literals_sml = Literals {
    10.5    literal_char = prefix "#" o quote o ML_Syntax.print_char,
    10.6    literal_string = quote o translate_string ML_Syntax.print_char,
    10.7 -  literal_numeral = fn unbounded => fn k =>
    10.8 -    if unbounded then "(" ^ string_of_int k ^ " : IntInf.int)"
    10.9 -    else string_of_int k,
   10.10 +  literal_numeral = fn k => "(" ^ string_of_int k ^ " : IntInf.int)",
   10.11 +  literal_positive_numeral = fn k => "(" ^ string_of_int k ^ " : IntInf.int)",
   10.12 +  literal_naive_numeral = string_of_int,
   10.13    literal_list = enum "," "[" "]",
   10.14    infix_cons = (7, "::")
   10.15  };
   10.16 @@ -687,18 +687,17 @@
   10.17        val s = if i < 32 orelse i = 34 orelse i = 39 orelse i = 92 orelse i > 126
   10.18          then chr i else c
   10.19      in s end;
   10.20 -  fun bignum_ocaml k = if k <= 1073741823
   10.21 -    then "(Big_int.big_int_of_int " ^ string_of_int k ^ ")"
   10.22 -    else "(Big_int.big_int_of_string " ^ quote (string_of_int k) ^ ")"
   10.23 +  fun numeral_ocaml k = if k < 0
   10.24 +    then "(Big_int.minus_big_int " ^ numeral_ocaml (~ k) ^ ")"
   10.25 +    else if k <= 1073741823
   10.26 +      then "(Big_int.big_int_of_int " ^ string_of_int k ^ ")"
   10.27 +      else "(Big_int.big_int_of_string " ^ quote (string_of_int k) ^ ")"
   10.28  in Literals {
   10.29    literal_char = Library.enclose "'" "'" o char_ocaml,
   10.30    literal_string = quote o translate_string char_ocaml,
   10.31 -  literal_numeral = fn unbounded => fn k => if k >= 0 then
   10.32 -      if unbounded then bignum_ocaml k
   10.33 -      else string_of_int k
   10.34 -    else
   10.35 -      if unbounded then "(Big_int.minus_big_int " ^ bignum_ocaml (~ k) ^ ")"
   10.36 -      else (Library.enclose "(" ")" o prefix "-" o string_of_int o op ~) k,
   10.37 +  literal_numeral = numeral_ocaml,
   10.38 +  literal_positive_numeral = numeral_ocaml,
   10.39 +  literal_naive_numeral = numeral_ocaml,
   10.40    literal_list = enum ";" "[" "]",
   10.41    infix_cons = (6, "::")
   10.42  } end;
   10.43 @@ -975,7 +974,7 @@
   10.44        ]))
   10.45    #> fold (Code_Target.add_reserved target_SML) ML_Syntax.reserved_names
   10.46    #> fold (Code_Target.add_reserved target_SML)
   10.47 -      ["o" (*dictionary projections use it already*), "Fail", "div", "mod" (*standard infixes*)]
   10.48 +      ["o" (*dictionary projections use it already*), "Fail", "div", "mod" (*standard infixes*), "IntInf"]
   10.49    #> fold (Code_Target.add_reserved target_OCaml) [
   10.50        "and", "as", "assert", "begin", "class",
   10.51        "constraint", "do", "done", "downto", "else", "end", "exception",
   10.52 @@ -985,6 +984,6 @@
   10.53        "sig", "struct", "then", "to", "true", "try", "type", "val",
   10.54        "virtual", "when", "while", "with"
   10.55      ]
   10.56 -  #> fold (Code_Target.add_reserved target_OCaml) ["failwith", "mod"];
   10.57 +  #> fold (Code_Target.add_reserved target_OCaml) ["failwith", "mod", "Big_int"];
   10.58  
   10.59  end; (*struct*)
    11.1 --- a/src/Tools/Code/code_printer.ML	Fri Jan 22 11:42:28 2010 +0100
    11.2 +++ b/src/Tools/Code/code_printer.ML	Fri Jan 22 15:26:29 2010 +0100
    11.3 @@ -39,12 +39,15 @@
    11.4  
    11.5    type literals
    11.6    val Literals: { literal_char: string -> string, literal_string: string -> string,
    11.7 -        literal_numeral: bool -> int -> string,
    11.8 +        literal_numeral: int -> string, literal_positive_numeral: int -> string,
    11.9 +        literal_naive_numeral: int -> string,
   11.10          literal_list: Pretty.T list -> Pretty.T, infix_cons: int * string }
   11.11      -> literals
   11.12    val literal_char: literals -> string -> string
   11.13    val literal_string: literals -> string -> string
   11.14 -  val literal_numeral: literals -> bool -> int -> string
   11.15 +  val literal_numeral: literals -> int -> string
   11.16 +  val literal_positive_numeral: literals -> int -> string
   11.17 +  val literal_naive_numeral: literals -> int -> string
   11.18    val literal_list: literals -> Pretty.T list -> Pretty.T
   11.19    val infix_cons: literals -> int * string
   11.20  
   11.21 @@ -163,7 +166,9 @@
   11.22  datatype literals = Literals of {
   11.23    literal_char: string -> string,
   11.24    literal_string: string -> string,
   11.25 -  literal_numeral: bool -> int -> string,
   11.26 +  literal_numeral: int -> string,
   11.27 +  literal_positive_numeral: int -> string,
   11.28 +  literal_naive_numeral: int -> string,
   11.29    literal_list: Pretty.T list -> Pretty.T,
   11.30    infix_cons: int * string
   11.31  };
   11.32 @@ -173,6 +178,8 @@
   11.33  val literal_char = #literal_char o dest_Literals;
   11.34  val literal_string = #literal_string o dest_Literals;
   11.35  val literal_numeral = #literal_numeral o dest_Literals;
   11.36 +val literal_positive_numeral = #literal_positive_numeral o dest_Literals;
   11.37 +val literal_naive_numeral = #literal_naive_numeral o dest_Literals;
   11.38  val literal_list = #literal_list o dest_Literals;
   11.39  val infix_cons = #infix_cons o dest_Literals;
   11.40  
    12.1 --- a/src/Tools/Code/code_scala.ML	Fri Jan 22 11:42:28 2010 +0100
    12.2 +++ b/src/Tools/Code/code_scala.ML	Fri Jan 22 15:26:29 2010 +0100
    12.3 @@ -404,17 +404,18 @@
    12.4      let
    12.5        val s = ML_Syntax.print_char c;
    12.6      in if s = "'" then "\\'" else s end;
    12.7 -  fun bigint_scala k = "(" ^ (if k <= 2147483647
    12.8 -    then string_of_int k else quote (string_of_int k)) ^ ")"
    12.9 +  fun numeral_scala k = if k < 0
   12.10 +    then if k <= 2147483647 then "- " ^ string_of_int (~ k)
   12.11 +      else quote ("- " ^ string_of_int (~ k))
   12.12 +    else if k <= 2147483647 then string_of_int k
   12.13 +      else quote (string_of_int k)
   12.14  in Literals {
   12.15    literal_char = Library.enclose "'" "'" o char_scala,
   12.16    literal_string = quote o translate_string char_scala,
   12.17 -  literal_numeral = fn unbounded => fn k => if k >= 0 then
   12.18 -      if unbounded then bigint_scala k
   12.19 -      else Library.enclose "(" ")" (string_of_int k)
   12.20 -    else
   12.21 -      if unbounded then "(- " ^ bigint_scala (~ k) ^ ")"
   12.22 -      else Library.enclose "(" ")" (signed_string_of_int k),
   12.23 +  literal_numeral = fn k => "BigInt(" ^ numeral_scala k ^ ")",
   12.24 +  literal_positive_numeral = fn k => "Nat.Nat(" ^ numeral_scala k ^ ")",
   12.25 +  literal_naive_numeral = fn k => if k >= 0
   12.26 +    then string_of_int k else "(- " ^ string_of_int (~ k) ^ ")",
   12.27    literal_list = fn [] => str "Nil" | ps => Pretty.block [str "List", enum "," "(" ")" ps],
   12.28    infix_cons = (6, "::")
   12.29  } end;
   12.30 @@ -442,7 +443,7 @@
   12.31        "true", "type", "val", "var", "while", "with"
   12.32      ]
   12.33    #> fold (Code_Target.add_reserved target) [
   12.34 -      "error", "apply", "List", "Nil"
   12.35 +      "error", "apply", "List", "Nil", "BigInt"
   12.36      ];
   12.37  
   12.38  end; (*struct*)