# HG changeset patch # User haftmann # Date 1266594720 -3600 # Node ID 04673275441a1c33d1bdb9f77844008ef6b2701a # Parent 8dfd816713c662fd3ecbe7ffa053f8398d8d5c70 switched notations for pointwise and multiset order diff -r 8dfd816713c6 -r 04673275441a src/HOL/Library/Multiset.thy --- a/src/HOL/Library/Multiset.thy Fri Feb 19 14:47:01 2010 +0100 +++ b/src/HOL/Library/Multiset.thy Fri Feb 19 16:52:00 2010 +0100 @@ -176,64 +176,6 @@ by (simp add: multiset_eq_conv_count_eq) -subsubsection {* Intersection *} - -definition multiset_inter :: "'a multiset \ 'a multiset \ 'a multiset" (infixl "#\" 70) where - "multiset_inter A B = A - (A - B)" - -lemma multiset_inter_count: - "count (A #\ B) x = min (count A x) (count B x)" - by (simp add: multiset_inter_def multiset_typedef) - -lemma multiset_inter_commute: "A #\ B = B #\ A" - by (rule multi_count_ext) (simp add: multiset_inter_count) - -lemma multiset_inter_assoc: "A #\ (B #\ C) = A #\ B #\ C" - by (rule multi_count_ext) (simp add: multiset_inter_count) - -lemma multiset_inter_left_commute: "A #\ (B #\ C) = B #\ (A #\ C)" - by (rule multi_count_ext) (simp add: multiset_inter_count) - -lemmas multiset_inter_ac = - multiset_inter_commute - multiset_inter_assoc - multiset_inter_left_commute - -lemma multiset_inter_single: "a \ b \ {#a#} #\ {#b#} = {#}" - by (rule multi_count_ext) (auto simp add: multiset_inter_count) - -lemma multiset_union_diff_commute: - assumes "B #\ C = {#}" - shows "A + B - C = A - C + B" -proof (rule multi_count_ext) - fix x - from assms have "min (count B x) (count C x) = 0" - by (auto simp add: multiset_inter_count multiset_eq_conv_count_eq) - then have "count B x = 0 \ count C x = 0" - by auto - then show "count (A + B - C) x = count (A - C + B) x" - by auto -qed - - -subsubsection {* Comprehension (filter) *} - -lemma count_MCollect [simp]: - "count {# x:#M. P x #} a = (if P a then count M a else 0)" - by (simp add: MCollect_def in_multiset multiset_typedef) - -lemma MCollect_empty [simp]: "MCollect {#} P = {#}" - by (rule multi_count_ext) simp - -lemma MCollect_single [simp]: - "MCollect {#x#} P = (if P x then {#x#} else {#})" - by (rule multi_count_ext) simp - -lemma MCollect_union [simp]: - "MCollect (M + N) f = MCollect M f + MCollect N f" - by (rule multi_count_ext) simp - - subsubsection {* Equality of multisets *} lemma single_not_empty [simp]: "{#a#} \ {#} \ {#} \ {#a#}" @@ -335,64 +277,61 @@ subsubsection {* Pointwise ordering induced by count *} -definition mset_le :: "'a multiset \ 'a multiset \ bool" (infix "\#" 50) where - "A \# B \ (\a. count A a \ count B a)" +instantiation multiset :: (type) ordered_ab_semigroup_add_imp_le +begin + +definition less_eq_multiset :: "'a multiset \ 'a multiset \ bool" where + mset_le_def: "A \ B \ (\a. count A a \ count B a)" -definition mset_less :: "'a multiset \ 'a multiset \ bool" (infix "<#" 50) where - "A <# B \ A \# B \ A \ B" +definition less_multiset :: "'a multiset \ 'a multiset \ bool" where + mset_less_def: "(A::'a multiset) < B \ A \ B \ A \ B" -notation mset_le (infix "\#" 50) -notation mset_less (infix "\#" 50) +instance proof +qed (auto simp add: mset_le_def mset_less_def multiset_eq_conv_count_eq intro: order_trans antisym) + +end lemma mset_less_eqI: - "(\x. count A x \ count B x) \ A \# B" + "(\x. count A x \ count B x) \ A \ B" by (simp add: mset_le_def) -lemma mset_le_refl[simp]: "A \# A" -unfolding mset_le_def by auto - -lemma mset_le_trans: "A \# B \ B \# C \ A \# C" -unfolding mset_le_def by (fast intro: order_trans) - -lemma mset_le_antisym: "A \# B \ B \# A \ A = B" -apply (unfold mset_le_def) -apply (rule multiset_eq_conv_count_eq [THEN iffD2]) -apply (blast intro: order_antisym) -done - -lemma mset_le_exists_conv: "(A \# B) = (\C. B = A + C)" +lemma mset_le_exists_conv: + "(A::'a multiset) \ B \ (\C. B = A + C)" apply (unfold mset_le_def, rule iffI, rule_tac x = "B - A" in exI) apply (auto intro: multiset_eq_conv_count_eq [THEN iffD2]) done -lemma mset_le_mono_add_right_cancel[simp]: "(A + C \# B + C) = (A \# B)" -unfolding mset_le_def by auto +lemma mset_le_mono_add_right_cancel [simp]: + "(A::'a multiset) + C \ B + C \ A \ B" + by (fact add_le_cancel_right) -lemma mset_le_mono_add_left_cancel[simp]: "(C + A \# C + B) = (A \# B)" -unfolding mset_le_def by auto +lemma mset_le_mono_add_left_cancel [simp]: + "C + (A::'a multiset) \ C + B \ A \ B" + by (fact add_le_cancel_left) + +lemma mset_le_mono_add: + "(A::'a multiset) \ B \ C \ D \ A + C \ B + D" + by (fact add_mono) -lemma mset_le_mono_add: "\ A \# B; C \# D \ \ A + C \# B + D" -apply (unfold mset_le_def) -apply auto -apply (erule_tac x = a in allE)+ -apply auto -done +lemma mset_le_add_left [simp]: + "(A::'a multiset) \ A + B" + unfolding mset_le_def by auto + +lemma mset_le_add_right [simp]: + "B \ (A::'a multiset) + B" + unfolding mset_le_def by auto -lemma mset_le_add_left[simp]: "A \# A + B" -unfolding mset_le_def by auto - -lemma mset_le_add_right[simp]: "B \# A + B" -unfolding mset_le_def by auto +lemma mset_le_single: + "a :# B \ {#a#} \ B" + by (simp add: mset_le_def) -lemma mset_le_single: "a :# B \ {#a#} \# B" -by (simp add: mset_le_def) - -lemma multiset_diff_union_assoc: "C \# B \ A + B - C = A + (B - C)" -by (simp add: multiset_eq_conv_count_eq mset_le_def) +lemma multiset_diff_union_assoc: + "C \ B \ (A::'a multiset) + B - C = A + (B - C)" + by (simp add: multiset_eq_conv_count_eq mset_le_def) lemma mset_le_multiset_union_diff_commute: -assumes "B \# A" -shows "A - B + C = A + C - B" + assumes "B \ A" + shows "(A::'a multiset) - B + C = A + C - B" proof - from mset_le_exists_conv [of "B" "A"] assms have "\D. A = B + D" .. from this obtain D where "A = B + D" .. @@ -410,31 +349,19 @@ done qed -interpretation mset_order: order "op \#" "op <#" -proof qed (auto intro: order.intro mset_le_refl mset_le_antisym - mset_le_trans simp: mset_less_def) - -interpretation mset_order_cancel_semigroup: - ordered_cancel_ab_semigroup_add "op +" "op \#" "op <#" -proof qed (erule mset_le_mono_add [OF mset_le_refl]) - -interpretation mset_order_semigroup_cancel: - ordered_ab_semigroup_add_imp_le "op +" "op \#" "op <#" -proof qed simp - -lemma mset_lessD: "A \# B \ x \# A \ x \# B" +lemma mset_lessD: "A < B \ x \# A \ x \# B" apply (clarsimp simp: mset_le_def mset_less_def) apply (erule_tac x=x in allE) apply auto done -lemma mset_leD: "A \# B \ x \# A \ x \# B" +lemma mset_leD: "A \ B \ x \# A \ x \# B" apply (clarsimp simp: mset_le_def mset_less_def) apply (erule_tac x = x in allE) apply auto done -lemma mset_less_insertD: "(A + {#x#} \# B) \ (x \# B \ A \# B)" +lemma mset_less_insertD: "(A + {#x#} < B) \ (x \# B \ A < B)" apply (rule conjI) apply (simp add: mset_lessD) apply (clarsimp simp: mset_le_def mset_less_def) @@ -443,30 +370,90 @@ apply (auto split: split_if_asm) done -lemma mset_le_insertD: "(A + {#x#} \# B) \ (x \# B \ A \# B)" +lemma mset_le_insertD: "(A + {#x#} \ B) \ (x \# B \ A \ B)" apply (rule conjI) apply (simp add: mset_leD) apply (force simp: mset_le_def mset_less_def split: split_if_asm) done -lemma mset_less_of_empty[simp]: "A \# {#} \ False" +lemma mset_less_of_empty[simp]: "A < {#} \ False" by (auto simp add: mset_less_def mset_le_def multiset_eq_conv_count_eq) -lemma multi_psub_of_add_self[simp]: "A \# A + {#x#}" -by (auto simp: mset_le_def mset_less_def) +lemma multi_psub_of_add_self[simp]: "A < A + {#x#}" + by (auto simp: mset_le_def mset_less_def) -lemma multi_psub_self[simp]: "A \# A = False" -by (auto simp: mset_le_def mset_less_def) +lemma multi_psub_self[simp]: "(A::'a multiset) < A = False" + by simp lemma mset_less_add_bothsides: - "T + {#x#} \# S + {#x#} \ T \# S" -by (auto simp: mset_le_def mset_less_def) + "T + {#x#} < S + {#x#} \ T < S" + by (fact add_less_imp_less_right) + +lemma mset_less_empty_nonempty: + "{#} < S \ S \ {#}" + by (auto simp: mset_le_def mset_less_def) + +lemma mset_less_diff_self: + "c \# B \ B - {#c#} < B" + by (auto simp: mset_le_def mset_less_def multiset_eq_conv_count_eq) + + +subsubsection {* Intersection *} + +instantiation multiset :: (type) semilattice_inf +begin + +definition inf_multiset :: "'a multiset \ 'a multiset \ 'a multiset" where + multiset_inter_def: "inf_multiset A B = A - (A - B)" + +instance proof - + have aux: "\m n q :: nat. m \ n \ m \ q \ m \ n - (n - q)" by arith + show "OFCLASS('a multiset, semilattice_inf_class)" proof + qed (auto simp add: multiset_inter_def mset_le_def aux) +qed + +end + +abbreviation multiset_inter :: "'a multiset \ 'a multiset \ 'a multiset" (infixl "#\" 70) where + "multiset_inter \ inf" -lemma mset_less_empty_nonempty: "({#} \# S) = (S \ {#})" -by (auto simp: mset_le_def mset_less_def) +lemma multiset_inter_count: + "count (A #\ B) x = min (count A x) (count B x)" + by (simp add: multiset_inter_def multiset_typedef) + +lemma multiset_inter_single: "a \ b \ {#a#} #\ {#b#} = {#}" + by (rule multi_count_ext) (auto simp add: multiset_inter_count) -lemma mset_less_diff_self: "c \# B \ B - {#c#} \# B" - by (auto simp: mset_le_def mset_less_def multiset_eq_conv_count_eq) +lemma multiset_union_diff_commute: + assumes "B #\ C = {#}" + shows "A + B - C = A - C + B" +proof (rule multi_count_ext) + fix x + from assms have "min (count B x) (count C x) = 0" + by (auto simp add: multiset_inter_count multiset_eq_conv_count_eq) + then have "count B x = 0 \ count C x = 0" + by auto + then show "count (A + B - C) x = count (A - C + B) x" + by auto +qed + + +subsubsection {* Comprehension (filter) *} + +lemma count_MCollect [simp]: + "count {# x:#M. P x #} a = (if P a then count M a else 0)" + by (simp add: MCollect_def in_multiset multiset_typedef) + +lemma MCollect_empty [simp]: "MCollect {#} P = {#}" + by (rule multi_count_ext) simp + +lemma MCollect_single [simp]: + "MCollect {#x#} P = (if P x then {#x#} else {#})" + by (rule multi_count_ext) simp + +lemma MCollect_union [simp]: + "MCollect (M + N) f = MCollect M f + MCollect N f" + by (rule multi_count_ext) simp subsubsection {* Set of elements *} @@ -657,7 +644,7 @@ apply auto done -lemma mset_less_size: "A \# B \ size A < size B" +lemma mset_less_size: "(A::'a multiset) < B \ size A < size B" proof (induct A arbitrary: B) case (empty M) then have "M \ {#}" by (simp add: mset_less_empty_nonempty) @@ -666,12 +653,12 @@ then show ?case by simp next case (add S x T) - have IH: "\B. S \# B \ size S < size B" by fact - have SxsubT: "S + {#x#} \# T" by fact - then have "x \# T" and "S \# T" by (auto dest: mset_less_insertD) + have IH: "\B. S < B \ size S < size B" by fact + have SxsubT: "S + {#x#} < T" by fact + then have "x \# T" and "S < T" by (auto dest: mset_less_insertD) then obtain T' where T: "T = T' + {#x#}" by (blast dest: multi_member_split) - then have "S \# T'" using SxsubT + then have "S < T'" using SxsubT by (blast intro: mset_less_add_bothsides) then have "size S < size T'" using IH by simp then show ?case using T by simp @@ -686,7 +673,7 @@ definition mset_less_rel :: "('a multiset * 'a multiset) set" where - "mset_less_rel = {(A,B). A \# B}" + "mset_less_rel = {(A,B). A < B}" lemma multiset_add_sub_el_shuffle: assumes "c \# B" and "b \ c" @@ -709,29 +696,29 @@ text {* The induction rules: *} lemma full_multiset_induct [case_names less]: -assumes ih: "\B. \A. A \# B \ P A \ P B" +assumes ih: "\B. \(A::'a multiset). A < B \ P A \ P B" shows "P B" apply (rule wf_mset_less_rel [THEN wf_induct]) apply (rule ih, auto simp: mset_less_rel_def) done lemma multi_subset_induct [consumes 2, case_names empty add]: -assumes "F \# A" +assumes "F \ A" and empty: "P {#}" and insert: "\a F. a \# A \ P F \ P (F + {#a#})" shows "P F" proof - - from `F \# A` + from `F \ A` show ?thesis proof (induct F) show "P {#}" by fact next fix x F - assume P: "F \# A \ P F" and i: "F + {#x#} \# A" + assume P: "F \ A \ P F" and i: "F + {#x#} \ A" show "P (F + {#x#})" proof (rule insert) from i show "x \# A" by (auto dest: mset_le_insertD) - from i have "F \# A" by (auto dest: mset_le_insertD) + from i have "F \ A" by (auto dest: mset_le_insertD) with P show "P F" . qed qed @@ -875,12 +862,8 @@ by (simp add: sorted_remove1 multiset_of_remove1 insort_remove1) qed -lemma multiset_of_remdups_le: "multiset_of (remdups xs) \# multiset_of xs" -apply (induct xs) - apply auto -apply (rule mset_le_trans) - apply auto -done +lemma multiset_of_remdups_le: "multiset_of (remdups xs) \ multiset_of xs" + by (induct xs) (auto intro: order_trans) lemma multiset_of_update: "i < length ls \ multiset_of (ls[i := v]) = multiset_of ls - {#ls ! i#} + {#v#}" @@ -969,7 +952,7 @@ by (simp add: multiset_eq_conv_count_eq count_of_filter) lemma mset_less_eq_Bag [code]: - "Bag xs \# A \ (\(x, n) \ set xs. count_of xs x \ count A x)" + "Bag xs \ A \ (\(x, n) \ set xs. count_of xs x \ count A x)" (is "?lhs \ ?rhs") proof assume ?lhs then show ?rhs @@ -990,10 +973,10 @@ begin definition - "HOL.eq A B \ A \# B \ B \# A" + "HOL.eq A B \ (A::'a multiset) \ B \ B \ A" instance proof -qed (simp add: eq_multiset_def mset_order.eq_iff) +qed (simp add: eq_multiset_def eq_iff) end @@ -1223,76 +1206,43 @@ subsubsection {* Partial-order properties *} -instantiation multiset :: (order) order -begin - -definition less_multiset_def: - "M' < M \ (M', M) \ mult {(x', x). x' < x}" - -definition le_multiset_def: - "M' <= M \ M' = M \ M' < (M::'a multiset)" - -lemma trans_base_order: "trans {(x', x). x' < (x::'a::order)}" -unfolding trans_def by (blast intro: order_less_trans) - -text {* - \medskip Irreflexivity. -*} +definition less_multiset :: "'a\order multiset \ 'a multiset \ bool" (infix "\#" 50) where + "M' \# M \ (M', M) \ mult {(x', x). x' < x}" -lemma mult_irrefl_aux: - "finite A ==> (\x \ A. \y \ A. x < (y::'a::order)) \ A = {}" -by (induct rule: finite_induct) (auto intro: order_less_trans) - -lemma mult_less_not_refl: "\ M < (M::'a::order multiset)" -apply (unfold less_multiset_def, auto) -apply (drule trans_base_order [THEN mult_implies_one_step], auto) -apply (drule finite_set_of [THEN mult_irrefl_aux [rule_format (no_asm)]]) -apply (simp add: set_of_eq_empty_iff) -done - -lemma mult_less_irrefl [elim!]: "M < (M::'a::order multiset) ==> R" -using insert mult_less_not_refl by fast - - -text {* Transitivity. *} +definition le_multiset :: "'a\order multiset \ 'a multiset \ bool" (infix "\#" 50) where + "M' \# M \ M' \# M \ M' = M" -theorem mult_less_trans: "K < M ==> M < N ==> K < (N::'a::order multiset)" -unfolding less_multiset_def mult_def by (blast intro: trancl_trans) - -text {* Asymmetry. *} - -theorem mult_less_not_sym: "M < N ==> \ N < (M::'a::order multiset)" -apply auto -apply (rule mult_less_not_refl [THEN notE]) -apply (erule mult_less_trans, assumption) -done - -theorem mult_less_asym: - "M < N ==> (\ P ==> N < (M::'a::order multiset)) ==> P" -using mult_less_not_sym by blast - -theorem mult_le_refl [iff]: "M <= (M::'a::order multiset)" -unfolding le_multiset_def by auto +interpretation multiset_order: order le_multiset less_multiset +proof - + have irrefl: "\M :: 'a multiset. \ M \# M" + proof + fix M :: "'a multiset" + assume "M \# M" + then have MM: "(M, M) \ mult {(x, y). x < y}" by (simp add: less_multiset_def) + have "trans {(x'::'a, x). x' < x}" + by (rule transI) simp + moreover note MM + ultimately have "\I J K. M = I + J \ M = I + K + \ J \ {#} \ (\k\set_of K. \j\set_of J. (k, j) \ {(x, y). x < y})" + by (rule mult_implies_one_step) + then obtain I J K where "M = I + J" and "M = I + K" + and "J \ {#}" and "(\k\set_of K. \j\set_of J. (k, j) \ {(x, y). x < y})" by blast + then have aux1: "K \ {#}" and aux2: "\k\set_of K. \j\set_of K. k < j" by auto + have "finite (set_of K)" by simp + moreover note aux2 + ultimately have "set_of K = {}" + by (induct rule: finite_induct) (auto intro: order_less_trans) + with aux1 show False by simp + qed + have trans: "\K M N :: 'a multiset. K \# M \ M \# N \ K \# N" + unfolding less_multiset_def mult_def by (blast intro: trancl_trans) + show "order (le_multiset :: 'a multiset \ _) less_multiset" proof + qed (auto simp add: le_multiset_def irrefl dest: trans) +qed -text {* Anti-symmetry. *} - -theorem mult_le_antisym: - "M <= N ==> N <= M ==> M = (N::'a::order multiset)" -unfolding le_multiset_def by (blast dest: mult_less_not_sym) - -text {* Transitivity. *} - -theorem mult_le_trans: - "K <= M ==> M <= N ==> K <= (N::'a::order multiset)" -unfolding le_multiset_def by (blast intro: mult_less_trans) - -theorem mult_less_le: "(M < N) = (M <= N \ M \ (N::'a::order multiset))" -unfolding le_multiset_def by auto - -instance proof -qed (auto simp add: mult_less_le dest: mult_le_antisym elim: mult_le_trans) - -end +lemma mult_less_irrefl [elim!]: + "M \# (M::'a::order multiset) ==> R" + by (simp add: multiset_order.less_irrefl) subsubsection {* Monotonicity of multiset union *} @@ -1306,52 +1256,26 @@ apply (simp add: add_assoc) done -lemma union_less_mono2: "B < D ==> C + B < C + (D::'a::order multiset)" +lemma union_less_mono2: "B \# D ==> C + B \# C + (D::'a::order multiset)" apply (unfold less_multiset_def mult_def) apply (erule trancl_induct) apply (blast intro: mult1_union transI order_less_trans r_into_trancl) apply (blast intro: mult1_union transI order_less_trans r_into_trancl trancl_trans) done -lemma union_less_mono1: "B < D ==> B + C < D + (C::'a::order multiset)" +lemma union_less_mono1: "B \# D ==> B + C \# D + (C::'a::order multiset)" apply (subst add_commute [of B C]) apply (subst add_commute [of D C]) apply (erule union_less_mono2) done lemma union_less_mono: - "A < C ==> B < D ==> A + B < C + (D::'a::order multiset)" -by (blast intro!: union_less_mono1 union_less_mono2 mult_less_trans) - -lemma union_le_mono: - "A <= C ==> B <= D ==> A + B <= C + (D::'a::order multiset)" -unfolding le_multiset_def -by (blast intro: union_less_mono union_less_mono1 union_less_mono2) + "A \# C ==> B \# D ==> A + B \# C + (D::'a::order multiset)" + by (blast intro!: union_less_mono1 union_less_mono2 multiset_order.less_trans) -lemma empty_leI [iff]: "{#} <= (M::'a::order multiset)" -apply (unfold le_multiset_def less_multiset_def) -apply (case_tac "M = {#}") - prefer 2 - apply (subgoal_tac "({#} + {#}, {#} + M) \ mult (Collect (split op <))") - prefer 2 - apply (rule one_step_implies_mult) - apply (simp only: trans_def) - apply auto -done - -lemma union_upper1: "A <= A + (B::'a::order multiset)" -proof - - have "A + {#} <= A + B" by (blast intro: union_le_mono) - then show ?thesis by simp -qed - -lemma union_upper2: "B <= A + (B::'a::order multiset)" -by (subst add_commute) (rule union_upper1) - -instance multiset :: (order) ordered_ab_semigroup_add -apply intro_classes -apply (erule union_le_mono[OF mult_le_refl]) -done +interpretation multiset_order: ordered_ab_semigroup_add plus le_multiset less_multiset +proof +qed (auto simp add: le_multiset_def intro: union_less_mono2) subsection {* The fold combinator *} @@ -1406,7 +1330,7 @@ "fold_msetG f z A x \ fold_msetG f z A y \ y = x" proof (induct arbitrary: x y z rule: full_multiset_induct) case (less M x\<^isub>1 x\<^isub>2 Z) - have IH: "\A. A \# M \ + have IH: "\A. A < M \ (\x x' x''. fold_msetG f x'' A x \ fold_msetG f x'' A x' \ x' = x)" by fact have Mfoldx\<^isub>1: "fold_msetG f Z M x\<^isub>1" and Mfoldx\<^isub>2: "fold_msetG f Z M x\<^isub>2" by fact+ @@ -1426,8 +1350,8 @@ fix C c v assume "M = C + {#c#}" and "x\<^isub>2 = f c v" and Cv: "fold_msetG f Z C v" then have MCc: "M = C + {#c#}" and x\<^isub>2: "x\<^isub>2 = f c v" by auto - then have CsubM: "C \# M" by simp - from MBb have BsubM: "B \# M" by simp + then have CsubM: "C < M" by simp + from MBb have BsubM: "B < M" by simp show ?case proof cases assume "b=c" @@ -1438,8 +1362,8 @@ let ?D = "B - {#c#}" have cinB: "c \# B" and binC: "b \# C" using MBb MCc diff by (auto intro: insert_noteq_member dest: sym) - have "B - {#c#} \# B" using cinB by (rule mset_less_diff_self) - then have DsubM: "?D \# M" using BsubM by (blast intro: mset_order.less_trans) + have "B - {#c#} < B" using cinB by (rule mset_less_diff_self) + then have DsubM: "?D < M" using BsubM by (blast intro: order_less_trans) from MBb MCc have "B + {#b#} = C + {#c#}" by blast then have [simp]: "B + {#b#} - {#c#} = C" using MBb MCc binC cinB by auto @@ -1769,6 +1693,37 @@ lemma multi_union_self_other_eq: "(A::'a multiset) + X = A + Y \ X = Y" by (fact add_imp_eq) -lemmas mset_less_trans = mset_order.less_trans +lemma mset_less_trans: "(M::'a multiset) < K \ K < N \ M < N" + by (fact order_less_trans) + +lemma multiset_inter_commute: "A #\ B = B #\ A" + by (fact inf.commute) + +lemma multiset_inter_assoc: "A #\ (B #\ C) = A #\ B #\ C" + by (fact inf.assoc [symmetric]) + +lemma multiset_inter_left_commute: "A #\ (B #\ C) = B #\ (A #\ C)" + by (fact inf.left_commute) + +lemmas multiset_inter_ac = + multiset_inter_commute + multiset_inter_assoc + multiset_inter_left_commute + +lemma mult_less_not_refl: + "\ M \# (M::'a::order multiset)" + by (fact multiset_order.less_irrefl) + +lemma mult_less_trans: + "K \# M ==> M \# N ==> K \# (N::'a::order multiset)" + by (fact multiset_order.less_trans) + +lemma mult_less_not_sym: + "M \# N ==> \ N \# (M::'a::order multiset)" + by (fact multiset_order.less_not_sym) + +lemma mult_less_asym: + "M \# N ==> (\ P ==> N \# (M::'a::order multiset)) ==> P" + by (fact multiset_order.less_asym) end \ No newline at end of file