| author | nipkow | 
| Wed, 24 Aug 2016 11:02:23 +0200 | |
| changeset 63720 | bcf2123d059a | 
| parent 63689 | 61171cbeedde | 
| child 63793 | e68a0b651eb5 | 
| permissions | -rw-r--r-- | 
| 10249 | 1 | (* Title: HOL/Library/Multiset.thy | 
| 15072 | 2 | Author: Tobias Nipkow, Markus Wenzel, Lawrence C Paulson, Norbert Voelker | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3 | Author: Andrei Popescu, TU Muenchen | 
| 59813 | 4 | Author: Jasmin Blanchette, Inria, LORIA, MPII | 
| 5 | Author: Dmitriy Traytel, TU Muenchen | |
| 6 | Author: Mathias Fleury, MPII | |
| 10249 | 7 | *) | 
| 8 | ||
| 60500 | 9 | section \<open>(Finite) multisets\<close> | 
| 10249 | 10 | |
| 15131 | 11 | theory Multiset | 
| 51599 
1559e9266280
optionalized very specific code setup for multisets
 haftmann parents: 
51548diff
changeset | 12 | imports Main | 
| 15131 | 13 | begin | 
| 10249 | 14 | |
| 60500 | 15 | subsection \<open>The type of multisets\<close> | 
| 10249 | 16 | |
| 60606 | 17 | definition "multiset = {f :: 'a \<Rightarrow> nat. finite {x. f x > 0}}"
 | 
| 18 | ||
| 19 | typedef 'a multiset = "multiset :: ('a \<Rightarrow> nat) set"
 | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 20 | morphisms count Abs_multiset | 
| 45694 
4a8743618257
prefer typedef without extra definition and alternative name;
 wenzelm parents: 
45608diff
changeset | 21 | unfolding multiset_def | 
| 10249 | 22 | proof | 
| 45694 
4a8743618257
prefer typedef without extra definition and alternative name;
 wenzelm parents: 
45608diff
changeset | 23 |   show "(\<lambda>x. 0::nat) \<in> {f. finite {x. f x > 0}}" by simp
 | 
| 10249 | 24 | qed | 
| 25 | ||
| 47429 
ec64d94cbf9c
multiset operations are defined with lift_definitions;
 bulwahn parents: 
47308diff
changeset | 26 | setup_lifting type_definition_multiset | 
| 19086 | 27 | |
| 60606 | 28 | lemma multiset_eq_iff: "M = N \<longleftrightarrow> (\<forall>a. count M a = count N a)" | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 29 | by (simp only: count_inject [symmetric] fun_eq_iff) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 30 | |
| 60606 | 31 | lemma multiset_eqI: "(\<And>x. count A x = count B x) \<Longrightarrow> A = B" | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 32 | using multiset_eq_iff by auto | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 33 | |
| 60606 | 34 | text \<open>Preservation of the representing set @{term multiset}.\<close>
 | 
| 35 | ||
| 36 | lemma const0_in_multiset: "(\<lambda>a. 0) \<in> multiset" | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 37 | by (simp add: multiset_def) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 38 | |
| 60606 | 39 | lemma only1_in_multiset: "(\<lambda>b. if b = a then n else 0) \<in> multiset" | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 40 | by (simp add: multiset_def) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 41 | |
| 60606 | 42 | lemma union_preserves_multiset: "M \<in> multiset \<Longrightarrow> N \<in> multiset \<Longrightarrow> (\<lambda>a. M a + N a) \<in> multiset" | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 43 | by (simp add: multiset_def) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 44 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 45 | lemma diff_preserves_multiset: | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 46 | assumes "M \<in> multiset" | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 47 | shows "(\<lambda>a. M a - N a) \<in> multiset" | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 48 | proof - | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 49 |   have "{x. N x < M x} \<subseteq> {x. 0 < M x}"
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 50 | by auto | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 51 | with assms show ?thesis | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 52 | by (auto simp add: multiset_def intro: finite_subset) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 53 | qed | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 54 | |
| 41069 
6fabc0414055
name filter operation just filter (c.f. List.filter and list comprehension syntax)
 haftmann parents: 
40968diff
changeset | 55 | lemma filter_preserves_multiset: | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 56 | assumes "M \<in> multiset" | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 57 | shows "(\<lambda>x. if P x then M x else 0) \<in> multiset" | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 58 | proof - | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 59 |   have "{x. (P x \<longrightarrow> 0 < M x) \<and> P x} \<subseteq> {x. 0 < M x}"
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 60 | by auto | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 61 | with assms show ?thesis | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 62 | by (auto simp add: multiset_def intro: finite_subset) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 63 | qed | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 64 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 65 | lemmas in_multiset = const0_in_multiset only1_in_multiset | 
| 41069 
6fabc0414055
name filter operation just filter (c.f. List.filter and list comprehension syntax)
 haftmann parents: 
40968diff
changeset | 66 | union_preserves_multiset diff_preserves_multiset filter_preserves_multiset | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 67 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 68 | |
| 60500 | 69 | subsection \<open>Representing multisets\<close> | 
| 70 | ||
| 71 | text \<open>Multiset enumeration\<close> | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 72 | |
| 48008 | 73 | instantiation multiset :: (type) cancel_comm_monoid_add | 
| 25571 
c9e39eafc7a0
instantiation target rather than legacy instance
 haftmann parents: 
25507diff
changeset | 74 | begin | 
| 
c9e39eafc7a0
instantiation target rather than legacy instance
 haftmann parents: 
25507diff
changeset | 75 | |
| 47429 
ec64d94cbf9c
multiset operations are defined with lift_definitions;
 bulwahn parents: 
47308diff
changeset | 76 | lift_definition zero_multiset :: "'a multiset" is "\<lambda>a. 0" | 
| 
ec64d94cbf9c
multiset operations are defined with lift_definitions;
 bulwahn parents: 
47308diff
changeset | 77 | by (rule const0_in_multiset) | 
| 25571 
c9e39eafc7a0
instantiation target rather than legacy instance
 haftmann parents: 
25507diff
changeset | 78 | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 79 | abbreviation Mempty :: "'a multiset" ("{#}") where
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 80 | "Mempty \<equiv> 0" | 
| 25571 
c9e39eafc7a0
instantiation target rather than legacy instance
 haftmann parents: 
25507diff
changeset | 81 | |
| 60606 | 82 | lift_definition plus_multiset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset" is "\<lambda>M N. (\<lambda>a. M a + N a)" | 
| 47429 
ec64d94cbf9c
multiset operations are defined with lift_definitions;
 bulwahn parents: 
47308diff
changeset | 83 | by (rule union_preserves_multiset) | 
| 25571 
c9e39eafc7a0
instantiation target rather than legacy instance
 haftmann parents: 
25507diff
changeset | 84 | |
| 60606 | 85 | lift_definition minus_multiset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset" is "\<lambda> M N. \<lambda>a. M a - N a" | 
| 59815 
cce82e360c2f
explicit commutative additive inverse operation;
 haftmann parents: 
59813diff
changeset | 86 | by (rule diff_preserves_multiset) | 
| 
cce82e360c2f
explicit commutative additive inverse operation;
 haftmann parents: 
59813diff
changeset | 87 | |
| 48008 | 88 | instance | 
| 60678 | 89 | by (standard; transfer; simp add: fun_eq_iff) | 
| 25571 
c9e39eafc7a0
instantiation target rather than legacy instance
 haftmann parents: 
25507diff
changeset | 90 | |
| 
c9e39eafc7a0
instantiation target rather than legacy instance
 haftmann parents: 
25507diff
changeset | 91 | end | 
| 10249 | 92 | |
| 63195 | 93 | context | 
| 94 | begin | |
| 95 | ||
| 96 | qualified definition is_empty :: "'a multiset \<Rightarrow> bool" where | |
| 97 |   [code_abbrev]: "is_empty A \<longleftrightarrow> A = {#}"
 | |
| 98 | ||
| 99 | end | |
| 100 | ||
| 101 | ||
| 60606 | 102 | lift_definition single :: "'a \<Rightarrow> 'a multiset" is "\<lambda>a b. if b = a then 1 else 0" | 
| 47429 
ec64d94cbf9c
multiset operations are defined with lift_definitions;
 bulwahn parents: 
47308diff
changeset | 103 | by (rule only1_in_multiset) | 
| 15869 | 104 | |
| 26145 | 105 | syntax | 
| 60606 | 106 |   "_multiset" :: "args \<Rightarrow> 'a multiset"    ("{#(_)#}")
 | 
| 25507 | 107 | translations | 
| 108 |   "{#x, xs#}" == "{#x#} + {#xs#}"
 | |
| 109 |   "{#x#}" == "CONST single x"
 | |
| 110 | ||
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 111 | lemma count_empty [simp]: "count {#} a = 0"
 | 
| 47429 
ec64d94cbf9c
multiset operations are defined with lift_definitions;
 bulwahn parents: 
47308diff
changeset | 112 | by (simp add: zero_multiset.rep_eq) | 
| 10249 | 113 | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 114 | lemma count_single [simp]: "count {#b#} a = (if b = a then 1 else 0)"
 | 
| 47429 
ec64d94cbf9c
multiset operations are defined with lift_definitions;
 bulwahn parents: 
47308diff
changeset | 115 | by (simp add: single.rep_eq) | 
| 29901 | 116 | |
| 10249 | 117 | |
| 60500 | 118 | subsection \<open>Basic operations\<close> | 
| 119 | ||
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 120 | subsubsection \<open>Conversion to set and membership\<close> | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 121 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 122 | definition set_mset :: "'a multiset \<Rightarrow> 'a set" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 123 |   where "set_mset M = {x. count M x > 0}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 124 | |
| 62537 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 125 | abbreviation Melem :: "'a \<Rightarrow> 'a multiset \<Rightarrow> bool" | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 126 | where "Melem a M \<equiv> a \<in> set_mset M" | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 127 | |
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 128 | notation | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 129 |   Melem  ("op \<in>#") and
 | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 130 |   Melem  ("(_/ \<in># _)" [51, 51] 50)
 | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 131 | |
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 132 | notation (ASCII) | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 133 |   Melem  ("op :#") and
 | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 134 |   Melem  ("(_/ :# _)" [51, 51] 50)
 | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 135 | |
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 136 | abbreviation not_Melem :: "'a \<Rightarrow> 'a multiset \<Rightarrow> bool" | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 137 | where "not_Melem a M \<equiv> a \<notin> set_mset M" | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 138 | |
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 139 | notation | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 140 |   not_Melem  ("op \<notin>#") and
 | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 141 |   not_Melem  ("(_/ \<notin># _)" [51, 51] 50)
 | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 142 | |
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 143 | notation (ASCII) | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 144 |   not_Melem  ("op ~:#") and
 | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 145 |   not_Melem  ("(_/ ~:# _)" [51, 51] 50)
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 146 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 147 | context | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 148 | begin | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 149 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 150 | qualified abbreviation Ball :: "'a multiset \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> bool"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 151 | where "Ball M \<equiv> Set.Ball (set_mset M)" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 152 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 153 | qualified abbreviation Bex :: "'a multiset \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> bool"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 154 | where "Bex M \<equiv> Set.Bex (set_mset M)" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 155 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 156 | end | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 157 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 158 | syntax | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 159 |   "_MBall"       :: "pttrn \<Rightarrow> 'a set \<Rightarrow> bool \<Rightarrow> bool"      ("(3\<forall>_\<in>#_./ _)" [0, 0, 10] 10)
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 160 |   "_MBex"        :: "pttrn \<Rightarrow> 'a set \<Rightarrow> bool \<Rightarrow> bool"      ("(3\<exists>_\<in>#_./ _)" [0, 0, 10] 10)
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 161 | |
| 62537 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 162 | syntax (ASCII) | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 163 |   "_MBall"       :: "pttrn \<Rightarrow> 'a set \<Rightarrow> bool \<Rightarrow> bool"      ("(3\<forall>_:#_./ _)" [0, 0, 10] 10)
 | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 164 |   "_MBex"        :: "pttrn \<Rightarrow> 'a set \<Rightarrow> bool \<Rightarrow> bool"      ("(3\<exists>_:#_./ _)" [0, 0, 10] 10)
 | 
| 
7a9aa69f9b38
syntax for multiset membership modelled after syntax for set membership
 haftmann parents: 
62430diff
changeset | 165 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 166 | translations | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 167 | "\<forall>x\<in>#A. P" \<rightleftharpoons> "CONST Multiset.Ball A (\<lambda>x. P)" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 168 | "\<exists>x\<in>#A. P" \<rightleftharpoons> "CONST Multiset.Bex A (\<lambda>x. P)" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 169 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 170 | lemma count_eq_zero_iff: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 171 | "count M x = 0 \<longleftrightarrow> x \<notin># M" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 172 | by (auto simp add: set_mset_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 173 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 174 | lemma not_in_iff: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 175 | "x \<notin># M \<longleftrightarrow> count M x = 0" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 176 | by (auto simp add: count_eq_zero_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 177 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 178 | lemma count_greater_zero_iff [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 179 | "count M x > 0 \<longleftrightarrow> x \<in># M" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 180 | by (auto simp add: set_mset_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 181 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 182 | lemma count_inI: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 183 | assumes "count M x = 0 \<Longrightarrow> False" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 184 | shows "x \<in># M" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 185 | proof (rule ccontr) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 186 | assume "x \<notin># M" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 187 | with assms show False by (simp add: not_in_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 188 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 189 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 190 | lemma in_countE: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 191 | assumes "x \<in># M" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 192 | obtains n where "count M x = Suc n" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 193 | proof - | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 194 | from assms have "count M x > 0" by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 195 | then obtain n where "count M x = Suc n" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 196 | using gr0_conv_Suc by blast | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 197 | with that show thesis . | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 198 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 199 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 200 | lemma count_greater_eq_Suc_zero_iff [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 201 | "count M x \<ge> Suc 0 \<longleftrightarrow> x \<in># M" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 202 | by (simp add: Suc_le_eq) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 203 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 204 | lemma count_greater_eq_one_iff [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 205 | "count M x \<ge> 1 \<longleftrightarrow> x \<in># M" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 206 | by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 207 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 208 | lemma set_mset_empty [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 209 |   "set_mset {#} = {}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 210 | by (simp add: set_mset_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 211 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 212 | lemma set_mset_single [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 213 |   "set_mset {#b#} = {b}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 214 | by (simp add: set_mset_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 215 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 216 | lemma set_mset_eq_empty_iff [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 217 |   "set_mset M = {} \<longleftrightarrow> M = {#}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 218 | by (auto simp add: multiset_eq_iff count_eq_zero_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 219 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 220 | lemma finite_set_mset [iff]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 221 | "finite (set_mset M)" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 222 | using count [of M] by (simp add: multiset_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 223 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 224 | |
| 60500 | 225 | subsubsection \<open>Union\<close> | 
| 10249 | 226 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 227 | lemma count_union [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 228 | "count (M + N) a = count M a + count N a" | 
| 47429 
ec64d94cbf9c
multiset operations are defined with lift_definitions;
 bulwahn parents: 
47308diff
changeset | 229 | by (simp add: plus_multiset.rep_eq) | 
| 10249 | 230 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 231 | lemma set_mset_union [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 232 | "set_mset (M + N) = set_mset M \<union> set_mset N" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 233 | by (simp only: set_eq_iff count_greater_zero_iff [symmetric] count_union) simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 234 | |
| 10249 | 235 | |
| 60500 | 236 | subsubsection \<open>Difference\<close> | 
| 10249 | 237 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 238 | instance multiset :: (type) comm_monoid_diff | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 239 | by standard (transfer; simp add: fun_eq_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 240 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 241 | lemma count_diff [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 242 | "count (M - N) a = count M a - count N a" | 
| 47429 
ec64d94cbf9c
multiset operations are defined with lift_definitions;
 bulwahn parents: 
47308diff
changeset | 243 | by (simp add: minus_multiset.rep_eq) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 244 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 245 | lemma in_diff_count: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 246 | "a \<in># M - N \<longleftrightarrow> count N a < count M a" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 247 | by (simp add: set_mset_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 248 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 249 | lemma count_in_diffI: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 250 | assumes "\<And>n. count N x = n + count M x \<Longrightarrow> False" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 251 | shows "x \<in># M - N" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 252 | proof (rule ccontr) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 253 | assume "x \<notin># M - N" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 254 | then have "count N x = (count N x - count M x) + count M x" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 255 | by (simp add: in_diff_count not_less) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 256 | with assms show False by auto | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 257 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 258 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 259 | lemma in_diff_countE: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 260 | assumes "x \<in># M - N" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 261 | obtains n where "count M x = Suc n + count N x" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 262 | proof - | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 263 | from assms have "count M x - count N x > 0" by (simp add: in_diff_count) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 264 | then have "count M x > count N x" by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 265 | then obtain n where "count M x = Suc n + count N x" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 266 | using less_iff_Suc_add by auto | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 267 | with that show thesis . | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 268 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 269 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 270 | lemma in_diffD: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 271 | assumes "a \<in># M - N" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 272 | shows "a \<in># M" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 273 | proof - | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 274 | have "0 \<le> count N a" by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 275 | also from assms have "count N a < count M a" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 276 | by (simp add: in_diff_count) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 277 | finally show ?thesis by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 278 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 279 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 280 | lemma set_mset_diff: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 281 |   "set_mset (M - N) = {a. count N a < count M a}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 282 | by (simp add: set_mset_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 283 | |
| 17161 | 284 | lemma diff_empty [simp]: "M - {#} = M \<and> {#} - M = {#}"
 | 
| 52289 | 285 | by rule (fact Groups.diff_zero, fact Groups.zero_diff) | 
| 36903 | 286 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 287 | lemma diff_cancel [simp]: "A - A = {#}"
 | 
| 52289 | 288 | by (fact Groups.diff_cancel) | 
| 10249 | 289 | |
| 36903 | 290 | lemma diff_union_cancelR [simp]: "M + N - N = (M::'a multiset)" | 
| 52289 | 291 | by (fact add_diff_cancel_right') | 
| 10249 | 292 | |
| 36903 | 293 | lemma diff_union_cancelL [simp]: "N + M - N = (M::'a multiset)" | 
| 52289 | 294 | by (fact add_diff_cancel_left') | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 295 | |
| 52289 | 296 | lemma diff_right_commute: | 
| 60606 | 297 | fixes M N Q :: "'a multiset" | 
| 298 | shows "M - N - Q = M - Q - N" | |
| 52289 | 299 | by (fact diff_right_commute) | 
| 300 | ||
| 301 | lemma diff_add: | |
| 60606 | 302 | fixes M N Q :: "'a multiset" | 
| 303 | shows "M - (N + Q) = M - N - Q" | |
| 52289 | 304 | by (rule sym) (fact diff_diff_add) | 
| 58425 | 305 | |
| 60606 | 306 | lemma insert_DiffM: "x \<in># M \<Longrightarrow> {#x#} + (M - {#x#}) = M"
 | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 307 | by (clarsimp simp: multiset_eq_iff) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 308 | |
| 60606 | 309 | lemma insert_DiffM2 [simp]: "x \<in># M \<Longrightarrow> M - {#x#} + {#x#} = M"
 | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 310 | by (clarsimp simp: multiset_eq_iff) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 311 | |
| 60606 | 312 | lemma diff_union_swap: "a \<noteq> b \<Longrightarrow> M - {#a#} + {#b#} = M + {#b#} - {#a#}"
 | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 313 | by (auto simp add: multiset_eq_iff) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 314 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 315 | lemma diff_union_single_conv: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 316 |   "a \<in># J \<Longrightarrow> I + J - {#a#} = I + (J - {#a#})"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 317 | by (simp add: multiset_eq_iff Suc_le_eq) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 318 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 319 | lemma mset_add [elim?]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 320 | assumes "a \<in># A" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 321 |   obtains B where "A = B + {#a#}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 322 | proof - | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 323 |   from assms have "A = (A - {#a#}) + {#a#}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 324 | by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 325 | with that show thesis . | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 326 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 327 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 328 | lemma union_iff: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 329 | "a \<in># A + B \<longleftrightarrow> a \<in># A \<or> a \<in># B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 330 | by auto | 
| 26143 
314c0bcb7df7
Added useful general lemmas from the work with the HeapMonad
 bulwahn parents: 
26033diff
changeset | 331 | |
| 10249 | 332 | |
| 60500 | 333 | subsubsection \<open>Equality of multisets\<close> | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 334 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 335 | lemma single_not_empty [simp]: "{#a#} \<noteq> {#} \<and> {#} \<noteq> {#a#}"
 | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 336 | by (simp add: multiset_eq_iff) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 337 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 338 | lemma single_eq_single [simp]: "{#a#} = {#b#} \<longleftrightarrow> a = b"
 | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 339 | by (auto simp add: multiset_eq_iff) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 340 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 341 | lemma union_eq_empty [iff]: "M + N = {#} \<longleftrightarrow> M = {#} \<and> N = {#}"
 | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 342 | by (auto simp add: multiset_eq_iff) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 343 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 344 | lemma empty_eq_union [iff]: "{#} = M + N \<longleftrightarrow> M = {#} \<and> N = {#}"
 | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 345 | by (auto simp add: multiset_eq_iff) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 346 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 347 | lemma multi_self_add_other_not_self [simp]: "M = M + {#x#} \<longleftrightarrow> False"
 | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 348 | by (auto simp add: multiset_eq_iff) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 349 | |
| 60606 | 350 | lemma diff_single_trivial: "\<not> x \<in># M \<Longrightarrow> M - {#x#} = M"
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 351 | by (auto simp add: multiset_eq_iff not_in_iff) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 352 | |
| 60606 | 353 | lemma diff_single_eq_union: "x \<in># M \<Longrightarrow> M - {#x#} = N \<longleftrightarrow> M = N + {#x#}"
 | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 354 | by auto | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 355 | |
| 60606 | 356 | lemma union_single_eq_diff: "M + {#x#} = N \<Longrightarrow> M = N - {#x#}"
 | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 357 | by (auto dest: sym) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 358 | |
| 60606 | 359 | lemma union_single_eq_member: "M + {#x#} = N \<Longrightarrow> x \<in># N"
 | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 360 | by auto | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 361 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 362 | lemma union_is_single: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 363 |   "M + N = {#a#} \<longleftrightarrow> M = {#a#} \<and> N = {#} \<or> M = {#} \<and> N = {#a#}"
 | 
| 60606 | 364 | (is "?lhs = ?rhs") | 
| 46730 | 365 | proof | 
| 60606 | 366 | show ?lhs if ?rhs using that by auto | 
| 367 | show ?rhs if ?lhs | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 368 | by (metis Multiset.diff_cancel add.commute add_diff_cancel_left' diff_add_zero diff_single_trivial insert_DiffM that) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 369 | qed | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 370 | |
| 60606 | 371 | lemma single_is_union: "{#a#} = M + N \<longleftrightarrow> {#a#} = M \<and> N = {#} \<or> M = {#} \<and> {#a#} = N"
 | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 372 |   by (auto simp add: eq_commute [of "{#a#}" "M + N"] union_is_single)
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 373 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 374 | lemma add_eq_conv_diff: | 
| 60606 | 375 |   "M + {#a#} = N + {#b#} \<longleftrightarrow> M = N \<and> a = b \<or> M = N - {#a#} + {#b#} \<and> N = M - {#b#} + {#a#}"
 | 
| 376 | (is "?lhs \<longleftrightarrow> ?rhs") | |
| 44890 
22f665a2e91c
new fastforce replacing fastsimp - less confusing name
 nipkow parents: 
44339diff
changeset | 377 | (* shorter: by (simp add: multiset_eq_iff) fastforce *) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 378 | proof | 
| 60606 | 379 | show ?lhs if ?rhs | 
| 380 | using that | |
| 381 |     by (auto simp add: add.assoc add.commute [of "{#b#}"])
 | |
| 382 | (drule sym, simp add: add.assoc [symmetric]) | |
| 383 | show ?rhs if ?lhs | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 384 | proof (cases "a = b") | 
| 60500 | 385 | case True with \<open>?lhs\<close> show ?thesis by simp | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 386 | next | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 387 | case False | 
| 60500 | 388 |     from \<open>?lhs\<close> have "a \<in># N + {#b#}" by (rule union_single_eq_member)
 | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 389 | with False have "a \<in># N" by auto | 
| 60500 | 390 |     moreover from \<open>?lhs\<close> have "M = N + {#b#} - {#a#}" by (rule union_single_eq_diff)
 | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 391 | moreover note False | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 392 |     ultimately show ?thesis by (auto simp add: diff_right_commute [of _ "{#a#}"] diff_union_swap)
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 393 | qed | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 394 | qed | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 395 | |
| 58425 | 396 | lemma insert_noteq_member: | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 397 |   assumes BC: "B + {#b#} = C + {#c#}"
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 398 | and bnotc: "b \<noteq> c" | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 399 | shows "c \<in># B" | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 400 | proof - | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 401 |   have "c \<in># C + {#c#}" by simp
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 402 |   have nc: "\<not> c \<in># {#b#}" using bnotc by simp
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 403 |   then have "c \<in># B + {#b#}" using BC by simp
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 404 | then show "c \<in># B" using nc by simp | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 405 | qed | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 406 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 407 | lemma add_eq_conv_ex: | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 408 |   "(M + {#a#} = N + {#b#}) =
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 409 |     (M = N \<and> a = b \<or> (\<exists>K. M = K + {#b#} \<and> N = K + {#a#}))"
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 410 | by (auto simp add: add_eq_conv_diff) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 411 | |
| 60606 | 412 | lemma multi_member_split: "x \<in># M \<Longrightarrow> \<exists>A. M = A + {#x#}"
 | 
| 60678 | 413 |   by (rule exI [where x = "M - {#x#}"]) simp
 | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 414 | |
| 58425 | 415 | lemma multiset_add_sub_el_shuffle: | 
| 60606 | 416 | assumes "c \<in># B" | 
| 417 | and "b \<noteq> c" | |
| 58098 | 418 |   shows "B - {#c#} + {#b#} = B + {#b#} - {#c#}"
 | 
| 419 | proof - | |
| 60500 | 420 |   from \<open>c \<in># B\<close> obtain A where B: "B = A + {#c#}"
 | 
| 58098 | 421 | by (blast dest: multi_member_split) | 
| 422 |   have "A + {#b#} = A + {#b#} + {#c#} - {#c#}" by simp
 | |
| 58425 | 423 |   then have "A + {#b#} = A + {#c#} + {#b#} - {#c#}"
 | 
| 58098 | 424 | by (simp add: ac_simps) | 
| 425 | then show ?thesis using B by simp | |
| 426 | qed | |
| 427 | ||
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 428 | |
| 60500 | 429 | subsubsection \<open>Pointwise ordering induced by count\<close> | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 430 | |
| 61955 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 431 | definition subseteq_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool" (infix "\<subseteq>#" 50) | 
| 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 432 | where "A \<subseteq># B = (\<forall>a. count A a \<le> count B a)" | 
| 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 433 | |
| 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 434 | definition subset_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool" (infix "\<subset>#" 50) | 
| 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 435 | where "A \<subset># B = (A \<subseteq># B \<and> A \<noteq> B)" | 
| 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 436 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 437 | abbreviation (input) supseteq_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool" (infix "\<supseteq>#" 50) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 438 | where "supseteq_mset A B \<equiv> B \<subseteq># A" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 439 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 440 | abbreviation (input) supset_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool" (infix "\<supset>#" 50) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 441 | where "supset_mset A B \<equiv> B \<subset># A" | 
| 62208 
ad43b3ab06e4
added 'supset' variants for new '<#' etc. symbols on multisets
 blanchet parents: 
62082diff
changeset | 442 | |
| 61955 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 443 | notation (input) | 
| 62208 
ad43b3ab06e4
added 'supset' variants for new '<#' etc. symbols on multisets
 blanchet parents: 
62082diff
changeset | 444 | subseteq_mset (infix "\<le>#" 50) and | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 445 | supseteq_mset (infix "\<ge>#" 50) | 
| 61955 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 446 | |
| 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 447 | notation (ASCII) | 
| 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 448 | subseteq_mset (infix "<=#" 50) and | 
| 62208 
ad43b3ab06e4
added 'supset' variants for new '<#' etc. symbols on multisets
 blanchet parents: 
62082diff
changeset | 449 | subset_mset (infix "<#" 50) and | 
| 
ad43b3ab06e4
added 'supset' variants for new '<#' etc. symbols on multisets
 blanchet parents: 
62082diff
changeset | 450 | supseteq_mset (infix ">=#" 50) and | 
| 
ad43b3ab06e4
added 'supset' variants for new '<#' etc. symbols on multisets
 blanchet parents: 
62082diff
changeset | 451 | supset_mset (infix ">#" 50) | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 452 | |
| 60606 | 453 | interpretation subset_mset: ordered_ab_semigroup_add_imp_le "op +" "op -" "op \<subseteq>#" "op \<subset>#" | 
| 60678 | 454 | by standard (auto simp add: subset_mset_def subseteq_mset_def multiset_eq_iff intro: order_trans antisym) | 
| 62837 | 455 | \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close> | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 456 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 457 | lemma mset_subset_eqI: | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 458 | "(\<And>a. count A a \<le> count B a) \<Longrightarrow> A \<subseteq># B" | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 459 | by (simp add: subseteq_mset_def) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 460 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 461 | lemma mset_subset_eq_count: | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 462 | "A \<subseteq># B \<Longrightarrow> count A a \<le> count B a" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 463 | by (simp add: subseteq_mset_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 464 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 465 | lemma mset_subset_eq_exists_conv: "(A::'a multiset) \<subseteq># B \<longleftrightarrow> (\<exists>C. B = A + C)" | 
| 60678 | 466 | unfolding subseteq_mset_def | 
| 467 | apply (rule iffI) | |
| 468 | apply (rule exI [where x = "B - A"]) | |
| 469 | apply (auto intro: multiset_eq_iff [THEN iffD2]) | |
| 470 | done | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 471 | |
| 63560 
3e3097ac37d1
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63547diff
changeset | 472 | interpretation subset_mset: ordered_cancel_comm_monoid_diff "op +" 0 "op \<le>#" "op <#" "op -" | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 473 | by standard (simp, fact mset_subset_eq_exists_conv) | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 474 | |
| 63560 
3e3097ac37d1
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63547diff
changeset | 475 | interpretation subset_mset: ordered_ab_semigroup_monoid_add_imp_le "op +" 0 "op -" "op \<le>#" "op <#" | 
| 
3e3097ac37d1
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63547diff
changeset | 476 | by standard | 
| 
3e3097ac37d1
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63547diff
changeset | 477 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 478 | lemma mset_subset_eq_mono_add_right_cancel [simp]: "(A::'a multiset) + C \<subseteq># B + C \<longleftrightarrow> A \<subseteq># B" | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 479 | by (fact subset_mset.add_le_cancel_right) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 480 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 481 | lemma mset_subset_eq_mono_add_left_cancel [simp]: "C + (A::'a multiset) \<subseteq># C + B \<longleftrightarrow> A \<subseteq># B" | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 482 | by (fact subset_mset.add_le_cancel_left) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 483 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 484 | lemma mset_subset_eq_mono_add: "(A::'a multiset) \<subseteq># B \<Longrightarrow> C \<subseteq># D \<Longrightarrow> A + C \<subseteq># B + D" | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 485 | by (fact subset_mset.add_mono) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 486 | |
| 63560 
3e3097ac37d1
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63547diff
changeset | 487 | lemma mset_subset_eq_add_left: "(A::'a multiset) \<subseteq># A + B" | 
| 
3e3097ac37d1
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63547diff
changeset | 488 | by simp | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 489 | |
| 63560 
3e3097ac37d1
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63547diff
changeset | 490 | lemma mset_subset_eq_add_right: "B \<subseteq># (A::'a multiset) + B" | 
| 
3e3097ac37d1
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63547diff
changeset | 491 | by simp | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 492 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 493 | lemma single_subset_iff [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 494 |   "{#a#} \<subseteq># M \<longleftrightarrow> a \<in># M"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 495 | by (auto simp add: subseteq_mset_def Suc_le_eq) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 496 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 497 | lemma mset_subset_eq_single: "a \<in># B \<Longrightarrow> {#a#} \<subseteq># B"
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 498 | by (simp add: subseteq_mset_def Suc_le_eq) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 499 | |
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 500 | lemma multiset_diff_union_assoc: | 
| 60606 | 501 | fixes A B C D :: "'a multiset" | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 502 | shows "C \<subseteq># B \<Longrightarrow> A + B - C = A + (B - C)" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 503 | by (fact subset_mset.diff_add_assoc) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 504 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 505 | lemma mset_subset_eq_multiset_union_diff_commute: | 
| 60606 | 506 | fixes A B C D :: "'a multiset" | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 507 | shows "B \<subseteq># A \<Longrightarrow> A - B + C = A + C - B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 508 | by (fact subset_mset.add_diff_assoc2) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 509 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 510 | lemma diff_subset_eq_self[simp]: | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 511 | "(M::'a multiset) - N \<subseteq># M" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 512 | by (simp add: subseteq_mset_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 513 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 514 | lemma mset_subset_eqD: | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 515 | assumes "A \<subseteq># B" and "x \<in># A" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 516 | shows "x \<in># B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 517 | proof - | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 518 | from \<open>x \<in># A\<close> have "count A x > 0" by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 519 | also from \<open>A \<subseteq># B\<close> have "count A x \<le> count B x" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 520 | by (simp add: subseteq_mset_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 521 | finally show ?thesis by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 522 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 523 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 524 | lemma mset_subsetD: | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 525 | "A \<subset># B \<Longrightarrow> x \<in># A \<Longrightarrow> x \<in># B" | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 526 | by (auto intro: mset_subset_eqD [of A]) | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 527 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 528 | lemma set_mset_mono: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 529 | "A \<subseteq># B \<Longrightarrow> set_mset A \<subseteq> set_mset B" | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 530 | by (metis mset_subset_eqD subsetI) | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 531 | |
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 532 | lemma mset_subset_eq_insertD: | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 533 |   "A + {#x#} \<subseteq># B \<Longrightarrow> x \<in># B \<and> A \<subset># B"
 | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 534 | apply (rule conjI) | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 535 | apply (simp add: mset_subset_eqD) | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 536 | apply (clarsimp simp: subset_mset_def subseteq_mset_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 537 | apply safe | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 538 | apply (erule_tac x = a in allE) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 539 | apply (auto split: if_split_asm) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 540 | done | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 541 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 542 | lemma mset_subset_insertD: | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 543 |   "A + {#x#} \<subset># B \<Longrightarrow> x \<in># B \<and> A \<subset># B"
 | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 544 | by (rule mset_subset_eq_insertD) simp | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 545 | |
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 546 | lemma mset_subset_of_empty[simp]: "A \<subset># {#} \<longleftrightarrow> False"
 | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 547 | by (auto simp add: subseteq_mset_def subset_mset_def multiset_eq_iff) | 
| 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 548 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 549 | lemma empty_le [simp]: "{#} \<subseteq># A"
 | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 550 | unfolding mset_subset_eq_exists_conv by auto | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 551 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 552 | lemma insert_subset_eq_iff: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 553 |   "{#a#} + A \<subseteq># B \<longleftrightarrow> a \<in># B \<and> A \<subseteq># B - {#a#}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 554 | using le_diff_conv2 [of "Suc 0" "count B a" "count A a"] | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 555 | apply (auto simp add: subseteq_mset_def not_in_iff Suc_le_eq) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 556 | apply (rule ccontr) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 557 | apply (auto simp add: not_in_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 558 | done | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 559 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 560 | lemma insert_union_subset_iff: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 561 |   "{#a#} + A \<subset># B \<longleftrightarrow> a \<in># B \<and> A \<subset># B - {#a#}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 562 | by (auto simp add: insert_subset_eq_iff subset_mset_def insert_DiffM) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 563 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 564 | lemma subset_eq_diff_conv: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 565 | "A - C \<subseteq># B \<longleftrightarrow> A \<subseteq># B + C" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 566 | by (simp add: subseteq_mset_def le_diff_conv) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 567 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 568 | lemma subset_eq_empty [simp]: "M \<subseteq># {#} \<longleftrightarrow> M = {#}"
 | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 569 | unfolding mset_subset_eq_exists_conv by auto | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 570 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 571 | lemma multi_psub_of_add_self[simp]: "A \<subset># A + {#x#}"
 | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 572 | by (auto simp: subset_mset_def subseteq_mset_def) | 
| 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 573 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 574 | lemma multi_psub_self[simp]: "(A::'a multiset) \<subset># A = False" | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 575 | by simp | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 576 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 577 | lemma mset_subset_add_bothsides: "N + {#x#} \<subset># M + {#x#} \<Longrightarrow> N \<subset># M"
 | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 578 | by (fact subset_mset.add_less_imp_less_right) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 579 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 580 | lemma mset_subset_empty_nonempty: "{#} \<subset># S \<longleftrightarrow> S \<noteq> {#}"
 | 
| 62378 
85ed00c1fe7c
generalize more theorems to support enat and ennreal
 hoelzl parents: 
62376diff
changeset | 581 | by (fact subset_mset.zero_less_iff_neq_zero) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 582 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 583 | lemma mset_subset_diff_self: "c \<in># B \<Longrightarrow> B - {#c#} \<subset># B"
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 584 | by (auto simp: subset_mset_def elim: mset_add) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 585 | |
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 586 | |
| 60500 | 587 | subsubsection \<open>Intersection\<close> | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 588 | |
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 589 | definition inf_subset_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset" (infixl "#\<inter>" 70) where | 
| 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 590 | multiset_inter_def: "inf_subset_mset A B = A - (A - B)" | 
| 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 591 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 592 | interpretation subset_mset: semilattice_inf inf_subset_mset "op \<subseteq>#" "op \<subset>#" | 
| 46921 | 593 | proof - | 
| 60678 | 594 | have [simp]: "m \<le> n \<Longrightarrow> m \<le> q \<Longrightarrow> m \<le> n - (n - q)" for m n q :: nat | 
| 595 | by arith | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 596 | show "class.semilattice_inf op #\<inter> op \<subseteq># op \<subset>#" | 
| 60678 | 597 | by standard (auto simp add: multiset_inter_def subseteq_mset_def) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 598 | qed | 
| 62837 | 599 | \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close> | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 600 | |
| 41069 
6fabc0414055
name filter operation just filter (c.f. List.filter and list comprehension syntax)
 haftmann parents: 
40968diff
changeset | 601 | lemma multiset_inter_count [simp]: | 
| 60606 | 602 | fixes A B :: "'a multiset" | 
| 603 | shows "count (A #\<inter> B) x = min (count A x) (count B x)" | |
| 47429 
ec64d94cbf9c
multiset operations are defined with lift_definitions;
 bulwahn parents: 
47308diff
changeset | 604 | by (simp add: multiset_inter_def) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 605 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 606 | lemma set_mset_inter [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 607 | "set_mset (A #\<inter> B) = set_mset A \<inter> set_mset B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 608 | by (simp only: set_eq_iff count_greater_zero_iff [symmetric] multiset_inter_count) simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 609 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 610 | lemma diff_intersect_left_idem [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 611 | "M - M #\<inter> N = M - N" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 612 | by (simp add: multiset_eq_iff min_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 613 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 614 | lemma diff_intersect_right_idem [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 615 | "M - N #\<inter> M = M - N" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 616 | by (simp add: multiset_eq_iff min_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 617 | |
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 618 | lemma multiset_inter_single: "a \<noteq> b \<Longrightarrow> {#a#} #\<inter> {#b#} = {#}"
 | 
| 46730 | 619 | by (rule multiset_eqI) auto | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 620 | |
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 621 | lemma multiset_union_diff_commute: | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 622 |   assumes "B #\<inter> C = {#}"
 | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 623 | shows "A + B - C = A - C + B" | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 624 | proof (rule multiset_eqI) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 625 | fix x | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 626 | from assms have "min (count B x) (count C x) = 0" | 
| 46730 | 627 | by (auto simp add: multiset_eq_iff) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 628 | then have "count B x = 0 \<or> count C x = 0" | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 629 | unfolding min_def by (auto split: if_splits) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 630 | then show "count (A + B - C) x = count (A - C + B) x" | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 631 | by auto | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 632 | qed | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 633 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 634 | lemma disjunct_not_in: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 635 |   "A #\<inter> B = {#} \<longleftrightarrow> (\<forall>a. a \<notin># A \<or> a \<notin># B)" (is "?P \<longleftrightarrow> ?Q")
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 636 | proof | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 637 | assume ?P | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 638 | show ?Q | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 639 | proof | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 640 | fix a | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 641 | from \<open>?P\<close> have "min (count A a) (count B a) = 0" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 642 | by (simp add: multiset_eq_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 643 | then have "count A a = 0 \<or> count B a = 0" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 644 | by (cases "count A a \<le> count B a") (simp_all add: min_def) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 645 | then show "a \<notin># A \<or> a \<notin># B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 646 | by (simp add: not_in_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 647 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 648 | next | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 649 | assume ?Q | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 650 | show ?P | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 651 | proof (rule multiset_eqI) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 652 | fix a | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 653 | from \<open>?Q\<close> have "count A a = 0 \<or> count B a = 0" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 654 | by (auto simp add: not_in_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 655 |     then show "count (A #\<inter> B) a = count {#} a"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 656 | by auto | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 657 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 658 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 659 | |
| 60606 | 660 | lemma empty_inter [simp]: "{#} #\<inter> M = {#}"
 | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 661 | by (simp add: multiset_eq_iff) | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 662 | |
| 60606 | 663 | lemma inter_empty [simp]: "M #\<inter> {#} = {#}"
 | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 664 | by (simp add: multiset_eq_iff) | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 665 | |
| 60606 | 666 | lemma inter_add_left1: "\<not> x \<in># N \<Longrightarrow> (M + {#x#}) #\<inter> N = M #\<inter> N"
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 667 | by (simp add: multiset_eq_iff not_in_iff) | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 668 | |
| 60606 | 669 | lemma inter_add_left2: "x \<in># N \<Longrightarrow> (M + {#x#}) #\<inter> N = (M #\<inter> (N - {#x#})) + {#x#}"
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 670 | by (auto simp add: multiset_eq_iff elim: mset_add) | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 671 | |
| 60606 | 672 | lemma inter_add_right1: "\<not> x \<in># N \<Longrightarrow> N #\<inter> (M + {#x#}) = N #\<inter> M"
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 673 | by (simp add: multiset_eq_iff not_in_iff) | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 674 | |
| 60606 | 675 | lemma inter_add_right2: "x \<in># N \<Longrightarrow> N #\<inter> (M + {#x#}) = ((N - {#x#}) #\<inter> M) + {#x#}"
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 676 | by (auto simp add: multiset_eq_iff elim: mset_add) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 677 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 678 | lemma disjunct_set_mset_diff: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 679 |   assumes "M #\<inter> N = {#}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 680 | shows "set_mset (M - N) = set_mset M" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 681 | proof (rule set_eqI) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 682 | fix a | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 683 | from assms have "a \<notin># M \<or> a \<notin># N" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 684 | by (simp add: disjunct_not_in) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 685 | then show "a \<in># M - N \<longleftrightarrow> a \<in># M" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 686 | by (auto dest: in_diffD) (simp add: in_diff_count not_in_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 687 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 688 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 689 | lemma at_most_one_mset_mset_diff: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 690 |   assumes "a \<notin># M - {#a#}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 691 |   shows "set_mset (M - {#a#}) = set_mset M - {a}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 692 | using assms by (auto simp add: not_in_iff in_diff_count set_eq_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 693 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 694 | lemma more_than_one_mset_mset_diff: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 695 |   assumes "a \<in># M - {#a#}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 696 |   shows "set_mset (M - {#a#}) = set_mset M"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 697 | proof (rule set_eqI) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 698 | fix b | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 699 | have "Suc 0 < count M b \<Longrightarrow> count M b > 0" by arith | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 700 |   then show "b \<in># M - {#a#} \<longleftrightarrow> b \<in># M"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 701 | using assms by (auto simp add: in_diff_count) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 702 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 703 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 704 | lemma inter_iff: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 705 | "a \<in># A #\<inter> B \<longleftrightarrow> a \<in># A \<and> a \<in># B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 706 | by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 707 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 708 | lemma inter_union_distrib_left: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 709 | "A #\<inter> B + C = (A + C) #\<inter> (B + C)" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 710 | by (simp add: multiset_eq_iff min_add_distrib_left) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 711 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 712 | lemma inter_union_distrib_right: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 713 | "C + A #\<inter> B = (C + A) #\<inter> (C + B)" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 714 | using inter_union_distrib_left [of A B C] by (simp add: ac_simps) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 715 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 716 | lemma inter_subset_eq_union: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 717 | "A #\<inter> B \<subseteq># A + B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 718 | by (auto simp add: subseteq_mset_def) | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 719 | |
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 720 | |
| 60500 | 721 | subsubsection \<open>Bounded union\<close> | 
| 60678 | 722 | |
| 723 | definition sup_subset_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset"(infixl "#\<union>" 70) | |
| 62837 | 724 | where "sup_subset_mset A B = A + (B - A)" \<comment> \<open>FIXME irregular fact name\<close> | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 725 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 726 | interpretation subset_mset: semilattice_sup sup_subset_mset "op \<subseteq>#" "op \<subset>#" | 
| 51623 | 727 | proof - | 
| 60678 | 728 | have [simp]: "m \<le> n \<Longrightarrow> q \<le> n \<Longrightarrow> m + (q - m) \<le> n" for m n q :: nat | 
| 729 | by arith | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 730 | show "class.semilattice_sup op #\<union> op \<subseteq># op \<subset>#" | 
| 60678 | 731 | by standard (auto simp add: sup_subset_mset_def subseteq_mset_def) | 
| 51623 | 732 | qed | 
| 62837 | 733 | \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close> | 
| 734 | ||
| 735 | lemma sup_subset_mset_count [simp]: \<comment> \<open>FIXME irregular fact name\<close> | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 736 | "count (A #\<union> B) x = max (count A x) (count B x)" | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 737 | by (simp add: sup_subset_mset_def) | 
| 51623 | 738 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 739 | lemma set_mset_sup [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 740 | "set_mset (A #\<union> B) = set_mset A \<union> set_mset B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 741 | by (simp only: set_eq_iff count_greater_zero_iff [symmetric] sup_subset_mset_count) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 742 | (auto simp add: not_in_iff elim: mset_add) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 743 | |
| 60606 | 744 | lemma empty_sup [simp]: "{#} #\<union> M = M"
 | 
| 51623 | 745 | by (simp add: multiset_eq_iff) | 
| 746 | ||
| 60606 | 747 | lemma sup_empty [simp]: "M #\<union> {#} = M"
 | 
| 51623 | 748 | by (simp add: multiset_eq_iff) | 
| 749 | ||
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 750 | lemma sup_union_left1: "\<not> x \<in># N \<Longrightarrow> (M + {#x#}) #\<union> N = (M #\<union> N) + {#x#}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 751 | by (simp add: multiset_eq_iff not_in_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 752 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 753 | lemma sup_union_left2: "x \<in># N \<Longrightarrow> (M + {#x#}) #\<union> N = (M #\<union> (N - {#x#})) + {#x#}"
 | 
| 51623 | 754 | by (simp add: multiset_eq_iff) | 
| 755 | ||
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 756 | lemma sup_union_right1: "\<not> x \<in># N \<Longrightarrow> N #\<union> (M + {#x#}) = (N #\<union> M) + {#x#}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 757 | by (simp add: multiset_eq_iff not_in_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 758 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 759 | lemma sup_union_right2: "x \<in># N \<Longrightarrow> N #\<union> (M + {#x#}) = ((N - {#x#}) #\<union> M) + {#x#}"
 | 
| 51623 | 760 | by (simp add: multiset_eq_iff) | 
| 761 | ||
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 762 | lemma sup_union_distrib_left: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 763 | "A #\<union> B + C = (A + C) #\<union> (B + C)" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 764 | by (simp add: multiset_eq_iff max_add_distrib_left) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 765 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 766 | lemma union_sup_distrib_right: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 767 | "C + A #\<union> B = (C + A) #\<union> (C + B)" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 768 | using sup_union_distrib_left [of A B C] by (simp add: ac_simps) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 769 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 770 | lemma union_diff_inter_eq_sup: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 771 | "A + B - A #\<inter> B = A #\<union> B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 772 | by (auto simp add: multiset_eq_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 773 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 774 | lemma union_diff_sup_eq_inter: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 775 | "A + B - A #\<union> B = A #\<inter> B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 776 | by (auto simp add: multiset_eq_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 777 | |
| 51623 | 778 | |
| 60500 | 779 | subsubsection \<open>Subset is an order\<close> | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 780 | |
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 781 | interpretation subset_mset: order "op \<le>#" "op <#" by unfold_locales auto | 
| 51623 | 782 | |
| 63409 
3f3223b90239
moved lemmas and locales around (with minor incompatibilities)
 blanchet parents: 
63388diff
changeset | 783 | |
| 63358 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 784 | subsubsection \<open>Conditionally complete lattice\<close> | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 785 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 786 | instantiation multiset :: (type) Inf | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 787 | begin | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 788 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 789 | lift_definition Inf_multiset :: "'a multiset set \<Rightarrow> 'a multiset" is | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 790 |   "\<lambda>A i. if A = {} then 0 else Inf ((\<lambda>f. f i) ` A)"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 791 | proof - | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 792 |   fix A :: "('a \<Rightarrow> nat) set" assume *: "\<And>x. x \<in> A \<Longrightarrow> x \<in> multiset"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 793 |   have "finite {i. (if A = {} then 0 else Inf ((\<lambda>f. f i) ` A)) > 0}" unfolding multiset_def
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 794 |   proof (cases "A = {}")
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 795 | case False | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 796 | then obtain f where "f \<in> A" by blast | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 797 |     hence "{i. Inf ((\<lambda>f. f i) ` A) > 0} \<subseteq> {i. f i > 0}"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 798 | by (auto intro: less_le_trans[OF _ cInf_lower]) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 799 | moreover from \<open>f \<in> A\<close> * have "finite \<dots>" by (simp add: multiset_def) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 800 |     ultimately have "finite {i. Inf ((\<lambda>f. f i) ` A) > 0}" by (rule finite_subset)
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 801 | with False show ?thesis by simp | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 802 | qed simp_all | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 803 |   thus "(\<lambda>i. if A = {} then 0 else INF f:A. f i) \<in> multiset" by (simp add: multiset_def)
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 804 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 805 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 806 | instance .. | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 807 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 808 | end | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 809 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 810 | lemma Inf_multiset_empty: "Inf {} = {#}"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 811 | by transfer simp_all | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 812 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 813 | lemma count_Inf_multiset_nonempty: "A \<noteq> {} \<Longrightarrow> count (Inf A) x = Inf ((\<lambda>X. count X x) ` A)"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 814 | by transfer simp_all | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 815 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 816 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 817 | instantiation multiset :: (type) Sup | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 818 | begin | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 819 | |
| 63360 | 820 | definition Sup_multiset :: "'a multiset set \<Rightarrow> 'a multiset" where | 
| 821 |   "Sup_multiset A = (if A \<noteq> {} \<and> subset_mset.bdd_above A then
 | |
| 822 |            Abs_multiset (\<lambda>i. Sup ((\<lambda>X. count X i) ` A)) else {#})"
 | |
| 823 | ||
| 824 | lemma Sup_multiset_empty: "Sup {} = {#}"
 | |
| 825 | by (simp add: Sup_multiset_def) | |
| 826 | ||
| 827 | lemma Sup_multiset_unbounded: "\<not>subset_mset.bdd_above A \<Longrightarrow> Sup A = {#}"
 | |
| 828 | by (simp add: Sup_multiset_def) | |
| 63358 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 829 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 830 | instance .. | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 831 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 832 | end | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 833 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 834 | lemma bdd_below_multiset [simp]: "subset_mset.bdd_below A" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 835 |   by (intro subset_mset.bdd_belowI[of _ "{#}"]) simp_all
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 836 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 837 | lemma bdd_above_multiset_imp_bdd_above_count: | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 838 | assumes "subset_mset.bdd_above (A :: 'a multiset set)" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 839 | shows "bdd_above ((\<lambda>X. count X x) ` A)" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 840 | proof - | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 841 | from assms obtain Y where Y: "\<forall>X\<in>A. X \<subseteq># Y" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 842 | by (auto simp: subset_mset.bdd_above_def) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 843 | hence "count X x \<le> count Y x" if "X \<in> A" for X | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 844 | using that by (auto intro: mset_subset_eq_count) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 845 | thus ?thesis by (intro bdd_aboveI[of _ "count Y x"]) auto | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 846 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 847 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 848 | lemma bdd_above_multiset_imp_finite_support: | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 849 |   assumes "A \<noteq> {}" "subset_mset.bdd_above (A :: 'a multiset set)"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 850 |   shows   "finite (\<Union>X\<in>A. {x. count X x > 0})"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 851 | proof - | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 852 | from assms obtain Y where Y: "\<forall>X\<in>A. X \<subseteq># Y" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 853 | by (auto simp: subset_mset.bdd_above_def) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 854 | hence "count X x \<le> count Y x" if "X \<in> A" for X x | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 855 | using that by (auto intro: mset_subset_eq_count) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 856 |   hence "(\<Union>X\<in>A. {x. count X x > 0}) \<subseteq> {x. count Y x > 0}"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 857 | by safe (erule less_le_trans) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 858 | moreover have "finite \<dots>" by simp | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 859 | ultimately show ?thesis by (rule finite_subset) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 860 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 861 | |
| 63360 | 862 | lemma Sup_multiset_in_multiset: | 
| 863 |   assumes "A \<noteq> {}" "subset_mset.bdd_above A"
 | |
| 864 | shows "(\<lambda>i. SUP X:A. count X i) \<in> multiset" | |
| 865 | unfolding multiset_def | |
| 866 | proof | |
| 867 |   have "{i. Sup ((\<lambda>X. count X i) ` A) > 0} \<subseteq> (\<Union>X\<in>A. {i. 0 < count X i})"
 | |
| 868 | proof safe | |
| 869 | fix i assume pos: "(SUP X:A. count X i) > 0" | |
| 870 |     show "i \<in> (\<Union>X\<in>A. {i. 0 < count X i})"
 | |
| 871 | proof (rule ccontr) | |
| 872 |       assume "i \<notin> (\<Union>X\<in>A. {i. 0 < count X i})"
 | |
| 873 | hence "\<forall>X\<in>A. count X i \<le> 0" by (auto simp: count_eq_zero_iff) | |
| 874 | with assms have "(SUP X:A. count X i) \<le> 0" | |
| 875 | by (intro cSup_least bdd_above_multiset_imp_bdd_above_count) auto | |
| 876 | with pos show False by simp | |
| 877 | qed | |
| 878 | qed | |
| 879 | moreover from assms have "finite \<dots>" by (rule bdd_above_multiset_imp_finite_support) | |
| 880 |   ultimately show "finite {i. Sup ((\<lambda>X. count X i) ` A) > 0}" by (rule finite_subset)
 | |
| 881 | qed | |
| 882 | ||
| 63358 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 883 | lemma count_Sup_multiset_nonempty: | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 884 |   assumes "A \<noteq> {}" "subset_mset.bdd_above A"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 885 | shows "count (Sup A) x = (SUP X:A. count X x)" | 
| 63360 | 886 | using assms by (simp add: Sup_multiset_def Abs_multiset_inverse Sup_multiset_in_multiset) | 
| 63358 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 887 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 888 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 889 | interpretation subset_mset: conditionally_complete_lattice Inf Sup "op #\<inter>" "op \<subseteq>#" "op \<subset>#" "op #\<union>" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 890 | proof | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 891 | fix X :: "'a multiset" and A | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 892 | assume "X \<in> A" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 893 | show "Inf A \<subseteq># X" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 894 | proof (rule mset_subset_eqI) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 895 | fix x | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 896 |     from \<open>X \<in> A\<close> have "A \<noteq> {}" by auto
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 897 | hence "count (Inf A) x = (INF X:A. count X x)" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 898 | by (simp add: count_Inf_multiset_nonempty) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 899 | also from \<open>X \<in> A\<close> have "\<dots> \<le> count X x" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 900 | by (intro cInf_lower) simp_all | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 901 | finally show "count (Inf A) x \<le> count X x" . | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 902 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 903 | next | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 904 | fix X :: "'a multiset" and A | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 905 |   assume nonempty: "A \<noteq> {}" and le: "\<And>Y. Y \<in> A \<Longrightarrow> X \<subseteq># Y"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 906 | show "X \<subseteq># Inf A" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 907 | proof (rule mset_subset_eqI) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 908 | fix x | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 909 | from nonempty have "count X x \<le> (INF X:A. count X x)" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 910 | by (intro cInf_greatest) (auto intro: mset_subset_eq_count le) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 911 | also from nonempty have "\<dots> = count (Inf A) x" by (simp add: count_Inf_multiset_nonempty) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 912 | finally show "count X x \<le> count (Inf A) x" . | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 913 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 914 | next | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 915 | fix X :: "'a multiset" and A | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 916 | assume X: "X \<in> A" and bdd: "subset_mset.bdd_above A" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 917 | show "X \<subseteq># Sup A" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 918 | proof (rule mset_subset_eqI) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 919 | fix x | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 920 |     from X have "A \<noteq> {}" by auto
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 921 | have "count X x \<le> (SUP X:A. count X x)" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 922 | by (intro cSUP_upper X bdd_above_multiset_imp_bdd_above_count bdd) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 923 |     also from count_Sup_multiset_nonempty[OF \<open>A \<noteq> {}\<close> bdd]
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 924 | have "(SUP X:A. count X x) = count (Sup A) x" by simp | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 925 | finally show "count X x \<le> count (Sup A) x" . | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 926 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 927 | next | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 928 | fix X :: "'a multiset" and A | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 929 |   assume nonempty: "A \<noteq> {}" and ge: "\<And>Y. Y \<in> A \<Longrightarrow> Y \<subseteq># X"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 930 | from ge have bdd: "subset_mset.bdd_above A" by (rule subset_mset.bdd_aboveI[of _ X]) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 931 | show "Sup A \<subseteq># X" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 932 | proof (rule mset_subset_eqI) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 933 | fix x | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 934 |     from count_Sup_multiset_nonempty[OF \<open>A \<noteq> {}\<close> bdd]
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 935 | have "count (Sup A) x = (SUP X:A. count X x)" . | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 936 | also from nonempty have "\<dots> \<le> count X x" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 937 | by (intro cSup_least) (auto intro: mset_subset_eq_count ge) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 938 | finally show "count (Sup A) x \<le> count X x" . | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 939 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 940 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 941 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 942 | lemma set_mset_Inf: | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 943 |   assumes "A \<noteq> {}"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 944 | shows "set_mset (Inf A) = (\<Inter>X\<in>A. set_mset X)" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 945 | proof safe | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 946 | fix x X assume "x \<in># Inf A" "X \<in> A" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 947 |   hence nonempty: "A \<noteq> {}" by (auto simp: Inf_multiset_empty)
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 948 |   from \<open>x \<in># Inf A\<close> have "{#x#} \<subseteq># Inf A" by auto
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 949 | also from \<open>X \<in> A\<close> have "\<dots> \<subseteq># X" by (rule subset_mset.cInf_lower) simp_all | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 950 | finally show "x \<in># X" by simp | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 951 | next | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 952 | fix x assume x: "x \<in> (\<Inter>X\<in>A. set_mset X)" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 953 |   hence "{#x#} \<subseteq># X" if "X \<in> A" for X using that by auto
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 954 |   from assms and this have "{#x#} \<subseteq># Inf A" by (rule subset_mset.cInf_greatest)
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 955 | thus "x \<in># Inf A" by simp | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 956 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 957 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 958 | lemma in_Inf_multiset_iff: | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 959 |   assumes "A \<noteq> {}"
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 960 | shows "x \<in># Inf A \<longleftrightarrow> (\<forall>X\<in>A. x \<in># X)" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 961 | proof - | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 962 | from assms have "set_mset (Inf A) = (\<Inter>X\<in>A. set_mset X)" by (rule set_mset_Inf) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 963 | also have "x \<in> \<dots> \<longleftrightarrow> (\<forall>X\<in>A. x \<in># X)" by simp | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 964 | finally show ?thesis . | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 965 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 966 | |
| 63360 | 967 | lemma in_Inf_multisetD: "x \<in># Inf A \<Longrightarrow> X \<in> A \<Longrightarrow> x \<in># X" | 
| 968 | by (subst (asm) in_Inf_multiset_iff) auto | |
| 969 | ||
| 63358 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 970 | lemma set_mset_Sup: | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 971 | assumes "subset_mset.bdd_above A" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 972 | shows "set_mset (Sup A) = (\<Union>X\<in>A. set_mset X)" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 973 | proof safe | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 974 | fix x assume "x \<in># Sup A" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 975 |   hence nonempty: "A \<noteq> {}" by (auto simp: Sup_multiset_empty)
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 976 | show "x \<in> (\<Union>X\<in>A. set_mset X)" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 977 | proof (rule ccontr) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 978 | assume x: "x \<notin> (\<Union>X\<in>A. set_mset X)" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 979 | have "count X x \<le> count (Sup A) x" if "X \<in> A" for X x | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 980 | using that by (intro mset_subset_eq_count subset_mset.cSup_upper assms) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 981 |     with x have "X \<subseteq># Sup A - {#x#}" if "X \<in> A" for X
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 982 | using that by (auto simp: subseteq_mset_def algebra_simps not_in_iff) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 983 |     hence "Sup A \<subseteq># Sup A - {#x#}" by (intro subset_mset.cSup_least nonempty)
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 984 | with \<open>x \<in># Sup A\<close> show False | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 985 | by (auto simp: subseteq_mset_def count_greater_zero_iff [symmetric] | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 986 | simp del: count_greater_zero_iff dest!: spec[of _ x]) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 987 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 988 | next | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 989 | fix x X assume "x \<in> set_mset X" "X \<in> A" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 990 |   hence "{#x#} \<subseteq># X" by auto
 | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 991 | also have "X \<subseteq># Sup A" by (intro subset_mset.cSup_upper \<open>X \<in> A\<close> assms) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 992 | finally show "x \<in> set_mset (Sup A)" by simp | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 993 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 994 | |
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 995 | lemma in_Sup_multiset_iff: | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 996 | assumes "subset_mset.bdd_above A" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 997 | shows "x \<in># Sup A \<longleftrightarrow> (\<exists>X\<in>A. x \<in># X)" | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 998 | proof - | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 999 | from assms have "set_mset (Sup A) = (\<Union>X\<in>A. set_mset X)" by (rule set_mset_Sup) | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 1000 | also have "x \<in> \<dots> \<longleftrightarrow> (\<exists>X\<in>A. x \<in># X)" by simp | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 1001 | finally show ?thesis . | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 1002 | qed | 
| 
a500677d4cec
Conditionally complete lattice of multisets
 Manuel Eberl <eberlm@in.tum.de> parents: 
63310diff
changeset | 1003 | |
| 63360 | 1004 | lemma in_Sup_multisetD: | 
| 1005 | assumes "x \<in># Sup A" | |
| 1006 | shows "\<exists>X\<in>A. x \<in># X" | |
| 1007 | proof - | |
| 1008 | have "subset_mset.bdd_above A" | |
| 1009 | by (rule ccontr) (insert assms, simp_all add: Sup_multiset_unbounded) | |
| 1010 | with assms show ?thesis by (simp add: in_Sup_multiset_iff) | |
| 63534 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1011 | qed | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1012 | |
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1013 | interpretation subset_mset: distrib_lattice "op #\<inter>" "op \<subseteq>#" "op \<subset>#" "op #\<union>" | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1014 | proof | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1015 | fix A B C :: "'a multiset" | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1016 | show "A #\<union> (B #\<inter> C) = A #\<union> B #\<inter> (A #\<union> C)" | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1017 | by (intro multiset_eqI) simp_all | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1018 | qed | 
| 63360 | 1019 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1020 | |
| 60500 | 1021 | subsubsection \<open>Filter (with comprehension syntax)\<close> | 
| 1022 | ||
| 1023 | text \<open>Multiset comprehension\<close> | |
| 41069 
6fabc0414055
name filter operation just filter (c.f. List.filter and list comprehension syntax)
 haftmann parents: 
40968diff
changeset | 1024 | |
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1025 | lift_definition filter_mset :: "('a \<Rightarrow> bool) \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset"
 | 
| 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1026 | is "\<lambda>P M. \<lambda>x. if P x then M x else 0" | 
| 47429 
ec64d94cbf9c
multiset operations are defined with lift_definitions;
 bulwahn parents: 
47308diff
changeset | 1027 | by (rule filter_preserves_multiset) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 1028 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1029 | syntax (ASCII) | 
| 63689 | 1030 |   "_MCollect" :: "pttrn \<Rightarrow> 'a multiset \<Rightarrow> bool \<Rightarrow> 'a multiset"    ("(1{#_ :# _./ _#})")
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1031 | syntax | 
| 63689 | 1032 |   "_MCollect" :: "pttrn \<Rightarrow> 'a multiset \<Rightarrow> bool \<Rightarrow> 'a multiset"    ("(1{#_ \<in># _./ _#})")
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1033 | translations | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1034 |   "{#x \<in># M. P#}" == "CONST filter_mset (\<lambda>x. P) M"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1035 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1036 | lemma count_filter_mset [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1037 | "count (filter_mset P M) a = (if P a then count M a else 0)" | 
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1038 | by (simp add: filter_mset.rep_eq) | 
| 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1039 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1040 | lemma set_mset_filter [simp]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1041 |   "set_mset (filter_mset P M) = {a \<in> set_mset M. P a}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1042 | by (simp only: set_eq_iff count_greater_zero_iff [symmetric] count_filter_mset) simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1043 | |
| 60606 | 1044 | lemma filter_empty_mset [simp]: "filter_mset P {#} = {#}"
 | 
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1045 | by (rule multiset_eqI) simp | 
| 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1046 | |
| 60606 | 1047 | lemma filter_single_mset [simp]: "filter_mset P {#x#} = (if P x then {#x#} else {#})"
 | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 1048 | by (rule multiset_eqI) simp | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 1049 | |
| 60606 | 1050 | lemma filter_union_mset [simp]: "filter_mset P (M + N) = filter_mset P M + filter_mset P N" | 
| 41069 
6fabc0414055
name filter operation just filter (c.f. List.filter and list comprehension syntax)
 haftmann parents: 
40968diff
changeset | 1051 | by (rule multiset_eqI) simp | 
| 
6fabc0414055
name filter operation just filter (c.f. List.filter and list comprehension syntax)
 haftmann parents: 
40968diff
changeset | 1052 | |
| 60606 | 1053 | lemma filter_diff_mset [simp]: "filter_mset P (M - N) = filter_mset P M - filter_mset P N" | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 1054 | by (rule multiset_eqI) simp | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 1055 | |
| 60606 | 1056 | lemma filter_inter_mset [simp]: "filter_mset P (M #\<inter> N) = filter_mset P M #\<inter> filter_mset P N" | 
| 41069 
6fabc0414055
name filter operation just filter (c.f. List.filter and list comprehension syntax)
 haftmann parents: 
40968diff
changeset | 1057 | by (rule multiset_eqI) simp | 
| 
6fabc0414055
name filter operation just filter (c.f. List.filter and list comprehension syntax)
 haftmann parents: 
40968diff
changeset | 1058 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1059 | lemma multiset_filter_subset[simp]: "filter_mset f M \<subseteq># M" | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1060 | by (simp add: mset_subset_eqI) | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 1061 | |
| 60606 | 1062 | lemma multiset_filter_mono: | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1063 | assumes "A \<subseteq># B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1064 | shows "filter_mset f A \<subseteq># filter_mset f B" | 
| 58035 | 1065 | proof - | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1066 | from assms[unfolded mset_subset_eq_exists_conv] | 
| 58035 | 1067 | obtain C where B: "B = A + C" by auto | 
| 1068 | show ?thesis unfolding B by auto | |
| 1069 | qed | |
| 1070 | ||
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1071 | lemma filter_mset_eq_conv: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1072 | "filter_mset P M = N \<longleftrightarrow> N \<subseteq># M \<and> (\<forall>b\<in>#N. P b) \<and> (\<forall>a\<in>#M - N. \<not> P a)" (is "?P \<longleftrightarrow> ?Q") | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1073 | proof | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1074 | assume ?P then show ?Q by auto (simp add: multiset_eq_iff in_diff_count) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1075 | next | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1076 | assume ?Q | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1077 | then obtain Q where M: "M = N + Q" | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1078 | by (auto simp add: mset_subset_eq_exists_conv) | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1079 | then have MN: "M - N = Q" by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1080 | show ?P | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1081 | proof (rule multiset_eqI) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1082 | fix a | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1083 | from \<open>?Q\<close> MN have *: "\<not> P a \<Longrightarrow> a \<notin># N" "P a \<Longrightarrow> a \<notin># Q" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1084 | by auto | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1085 | show "count (filter_mset P M) a = count N a" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1086 | proof (cases "a \<in># M") | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1087 | case True | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1088 | with * show ?thesis | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1089 | by (simp add: not_in_iff M) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1090 | next | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1091 | case False then have "count M a = 0" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1092 | by (simp add: not_in_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1093 | with M show ?thesis by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1094 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1095 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1096 | qed | 
| 59813 | 1097 | |
| 1098 | ||
| 60500 | 1099 | subsubsection \<open>Size\<close> | 
| 10249 | 1100 | |
| 56656 | 1101 | definition wcount where "wcount f M = (\<lambda>x. count M x * Suc (f x))" | 
| 1102 | ||
| 1103 | lemma wcount_union: "wcount f (M + N) a = wcount f M a + wcount f N a" | |
| 1104 | by (auto simp: wcount_def add_mult_distrib) | |
| 1105 | ||
| 1106 | definition size_multiset :: "('a \<Rightarrow> nat) \<Rightarrow> 'a multiset \<Rightarrow> nat" where
 | |
| 60495 | 1107 | "size_multiset f M = setsum (wcount f M) (set_mset M)" | 
| 56656 | 1108 | |
| 1109 | lemmas size_multiset_eq = size_multiset_def[unfolded wcount_def] | |
| 1110 | ||
| 60606 | 1111 | instantiation multiset :: (type) size | 
| 1112 | begin | |
| 1113 | ||
| 56656 | 1114 | definition size_multiset where | 
| 1115 | size_multiset_overloaded_def: "size_multiset = Multiset.size_multiset (\<lambda>_. 0)" | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1116 | instance .. | 
| 60606 | 1117 | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1118 | end | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1119 | |
| 56656 | 1120 | lemmas size_multiset_overloaded_eq = | 
| 1121 | size_multiset_overloaded_def[THEN fun_cong, unfolded size_multiset_eq, simplified] | |
| 1122 | ||
| 1123 | lemma size_multiset_empty [simp]: "size_multiset f {#} = 0"
 | |
| 1124 | by (simp add: size_multiset_def) | |
| 1125 | ||
| 28708 
a1a436f09ec6
explicit check for pattern discipline before code translation
 haftmann parents: 
28562diff
changeset | 1126 | lemma size_empty [simp]: "size {#} = 0"
 | 
| 56656 | 1127 | by (simp add: size_multiset_overloaded_def) | 
| 1128 | ||
| 1129 | lemma size_multiset_single [simp]: "size_multiset f {#b#} = Suc (f b)"
 | |
| 1130 | by (simp add: size_multiset_eq) | |
| 10249 | 1131 | |
| 28708 
a1a436f09ec6
explicit check for pattern discipline before code translation
 haftmann parents: 
28562diff
changeset | 1132 | lemma size_single [simp]: "size {#b#} = 1"
 | 
| 56656 | 1133 | by (simp add: size_multiset_overloaded_def) | 
| 1134 | ||
| 1135 | lemma setsum_wcount_Int: | |
| 60495 | 1136 | "finite A \<Longrightarrow> setsum (wcount f N) (A \<inter> set_mset N) = setsum (wcount f N) A" | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1137 | by (induct rule: finite_induct) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1138 | (simp_all add: Int_insert_left wcount_def count_eq_zero_iff) | 
| 56656 | 1139 | |
| 1140 | lemma size_multiset_union [simp]: | |
| 1141 | "size_multiset f (M + N::'a multiset) = size_multiset f M + size_multiset f N" | |
| 57418 | 1142 | apply (simp add: size_multiset_def setsum_Un_nat setsum.distrib setsum_wcount_Int wcount_union) | 
| 56656 | 1143 | apply (subst Int_commute) | 
| 1144 | apply (simp add: setsum_wcount_Int) | |
| 26178 | 1145 | done | 
| 10249 | 1146 | |
| 28708 
a1a436f09ec6
explicit check for pattern discipline before code translation
 haftmann parents: 
28562diff
changeset | 1147 | lemma size_union [simp]: "size (M + N::'a multiset) = size M + size N" | 
| 56656 | 1148 | by (auto simp add: size_multiset_overloaded_def) | 
| 1149 | ||
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1150 | lemma size_multiset_eq_0_iff_empty [iff]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1151 |   "size_multiset f M = 0 \<longleftrightarrow> M = {#}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1152 | by (auto simp add: size_multiset_eq count_eq_zero_iff) | 
| 10249 | 1153 | |
| 17161 | 1154 | lemma size_eq_0_iff_empty [iff]: "(size M = 0) = (M = {#})"
 | 
| 56656 | 1155 | by (auto simp add: size_multiset_overloaded_def) | 
| 26016 | 1156 | |
| 1157 | lemma nonempty_has_size: "(S \<noteq> {#}) = (0 < size S)"
 | |
| 26178 | 1158 | by (metis gr0I gr_implies_not0 size_empty size_eq_0_iff_empty) | 
| 10249 | 1159 | |
| 60607 | 1160 | lemma size_eq_Suc_imp_elem: "size M = Suc n \<Longrightarrow> \<exists>a. a \<in># M" | 
| 56656 | 1161 | apply (unfold size_multiset_overloaded_eq) | 
| 26178 | 1162 | apply (drule setsum_SucD) | 
| 1163 | apply auto | |
| 1164 | done | |
| 10249 | 1165 | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1166 | lemma size_eq_Suc_imp_eq_union: | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1167 | assumes "size M = Suc n" | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1168 |   shows "\<exists>a N. M = N + {#a#}"
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1169 | proof - | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1170 | from assms obtain a where "a \<in># M" | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1171 | by (erule size_eq_Suc_imp_elem [THEN exE]) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1172 |   then have "M = M - {#a#} + {#a#}" by simp
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1173 | then show ?thesis by blast | 
| 23611 | 1174 | qed | 
| 15869 | 1175 | |
| 60606 | 1176 | lemma size_mset_mono: | 
| 1177 | fixes A B :: "'a multiset" | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1178 | assumes "A \<subseteq># B" | 
| 60606 | 1179 | shows "size A \<le> size B" | 
| 59949 | 1180 | proof - | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1181 | from assms[unfolded mset_subset_eq_exists_conv] | 
| 59949 | 1182 | obtain C where B: "B = A + C" by auto | 
| 60606 | 1183 | show ?thesis unfolding B by (induct C) auto | 
| 59949 | 1184 | qed | 
| 1185 | ||
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1186 | lemma size_filter_mset_lesseq[simp]: "size (filter_mset f M) \<le> size M" | 
| 59949 | 1187 | by (rule size_mset_mono[OF multiset_filter_subset]) | 
| 1188 | ||
| 1189 | lemma size_Diff_submset: | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1190 | "M \<subseteq># M' \<Longrightarrow> size (M' - M) = size M' - size(M::'a multiset)" | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1191 | by (metis add_diff_cancel_left' size_union mset_subset_eq_exists_conv) | 
| 26016 | 1192 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1193 | |
| 60500 | 1194 | subsection \<open>Induction and case splits\<close> | 
| 10249 | 1195 | |
| 18258 | 1196 | theorem multiset_induct [case_names empty add, induct type: multiset]: | 
| 48009 | 1197 |   assumes empty: "P {#}"
 | 
| 1198 |   assumes add: "\<And>M x. P M \<Longrightarrow> P (M + {#x#})"
 | |
| 1199 | shows "P M" | |
| 1200 | proof (induct n \<equiv> "size M" arbitrary: M) | |
| 1201 | case 0 thus "P M" by (simp add: empty) | |
| 1202 | next | |
| 1203 | case (Suc k) | |
| 1204 |   obtain N x where "M = N + {#x#}"
 | |
| 60500 | 1205 | using \<open>Suc k = size M\<close> [symmetric] | 
| 48009 | 1206 | using size_eq_Suc_imp_eq_union by fast | 
| 1207 | with Suc add show "P M" by simp | |
| 10249 | 1208 | qed | 
| 1209 | ||
| 25610 | 1210 | lemma multi_nonempty_split: "M \<noteq> {#} \<Longrightarrow> \<exists>A a. M = A + {#a#}"
 | 
| 26178 | 1211 | by (induct M) auto | 
| 25610 | 1212 | |
| 55913 | 1213 | lemma multiset_cases [cases type]: | 
| 1214 |   obtains (empty) "M = {#}"
 | |
| 1215 |     | (add) N x where "M = N + {#x#}"
 | |
| 63092 | 1216 | by (induct M) simp_all | 
| 25610 | 1217 | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1218 | lemma multi_drop_mem_not_eq: "c \<in># B \<Longrightarrow> B - {#c#} \<noteq> B"
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1219 | by (cases "B = {#}") (auto dest: multi_member_split)
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1220 | |
| 60607 | 1221 | lemma multiset_partition: "M = {# x\<in>#M. P x #} + {# x\<in>#M. \<not> P x #}"
 | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 1222 | apply (subst multiset_eq_iff) | 
| 26178 | 1223 | apply auto | 
| 1224 | done | |
| 10249 | 1225 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1226 | lemma mset_subset_size: "(A::'a multiset) \<subset># B \<Longrightarrow> size A < size B" | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1227 | proof (induct A arbitrary: B) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1228 | case (empty M) | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1229 |   then have "M \<noteq> {#}" by (simp add: mset_subset_empty_nonempty)
 | 
| 58425 | 1230 |   then obtain M' x where "M = M' + {#x#}"
 | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1231 | by (blast dest: multi_nonempty_split) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1232 | then show ?case by simp | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1233 | next | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1234 | case (add S x T) | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1235 | have IH: "\<And>B. S \<subset># B \<Longrightarrow> size S < size B" by fact | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1236 |   have SxsubT: "S + {#x#} \<subset># T" by fact
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1237 | then have "x \<in># T" and "S \<subset># T" | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1238 | by (auto dest: mset_subset_insertD) | 
| 58425 | 1239 |   then obtain T' where T: "T = T' + {#x#}"
 | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1240 | by (blast dest: multi_member_split) | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1241 | then have "S \<subset># T'" using SxsubT | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1242 | by (blast intro: mset_subset_add_bothsides) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1243 | then have "size S < size T'" using IH by simp | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1244 | then show ?case using T by simp | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1245 | qed | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1246 | |
| 59949 | 1247 | lemma size_1_singleton_mset: "size M = 1 \<Longrightarrow> \<exists>a. M = {#a#}"
 | 
| 1248 | by (cases M) auto | |
| 1249 | ||
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1250 | |
| 60500 | 1251 | subsubsection \<open>Strong induction and subset induction for multisets\<close> | 
| 1252 | ||
| 1253 | text \<open>Well-foundedness of strict subset relation\<close> | |
| 58098 | 1254 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1255 | lemma wf_subset_mset_rel: "wf {(M, N :: 'a multiset). M \<subset># N}"
 | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1256 | apply (rule wf_measure [THEN wf_subset, where f1=size]) | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1257 | apply (clarsimp simp: measure_def inv_image_def mset_subset_size) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1258 | done | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1259 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1260 | lemma full_multiset_induct [case_names less]: | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1261 | assumes ih: "\<And>B. \<forall>(A::'a multiset). A \<subset># B \<longrightarrow> P A \<Longrightarrow> P B" | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1262 | shows "P B" | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1263 | apply (rule wf_subset_mset_rel [THEN wf_induct]) | 
| 58098 | 1264 | apply (rule ih, auto) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1265 | done | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1266 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1267 | lemma multi_subset_induct [consumes 2, case_names empty add]: | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1268 | assumes "F \<subseteq># A" | 
| 60606 | 1269 |     and empty: "P {#}"
 | 
| 1270 |     and insert: "\<And>a F. a \<in># A \<Longrightarrow> P F \<Longrightarrow> P (F + {#a#})"
 | |
| 1271 | shows "P F" | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1272 | proof - | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1273 | from \<open>F \<subseteq># A\<close> | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1274 | show ?thesis | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1275 | proof (induct F) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1276 |     show "P {#}" by fact
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1277 | next | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1278 | fix x F | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1279 |     assume P: "F \<subseteq># A \<Longrightarrow> P F" and i: "F + {#x#} \<subseteq># A"
 | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1280 |     show "P (F + {#x#})"
 | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1281 | proof (rule insert) | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1282 | from i show "x \<in># A" by (auto dest: mset_subset_eq_insertD) | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1283 | from i have "F \<subseteq># A" by (auto dest: mset_subset_eq_insertD) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1284 | with P show "P F" . | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1285 | qed | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1286 | qed | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1287 | qed | 
| 26145 | 1288 | |
| 17161 | 1289 | |
| 60500 | 1290 | subsection \<open>The fold combinator\<close> | 
| 48023 | 1291 | |
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1292 | definition fold_mset :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a multiset \<Rightarrow> 'b"
 | 
| 48023 | 1293 | where | 
| 60495 | 1294 | "fold_mset f s M = Finite_Set.fold (\<lambda>x. f x ^^ count M x) s (set_mset M)" | 
| 48023 | 1295 | |
| 60606 | 1296 | lemma fold_mset_empty [simp]: "fold_mset f s {#} = s"
 | 
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1297 | by (simp add: fold_mset_def) | 
| 48023 | 1298 | |
| 1299 | context comp_fun_commute | |
| 1300 | begin | |
| 1301 | ||
| 60606 | 1302 | lemma fold_mset_insert: "fold_mset f s (M + {#x#}) = f x (fold_mset f s M)"
 | 
| 49822 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1303 | proof - | 
| 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1304 | interpret mset: comp_fun_commute "\<lambda>y. f y ^^ count M y" | 
| 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1305 | by (fact comp_fun_commute_funpow) | 
| 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1306 |   interpret mset_union: comp_fun_commute "\<lambda>y. f y ^^ count (M + {#x#}) y"
 | 
| 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1307 | by (fact comp_fun_commute_funpow) | 
| 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1308 | show ?thesis | 
| 60495 | 1309 | proof (cases "x \<in> set_mset M") | 
| 49822 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1310 | case False | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1311 |     then have *: "count (M + {#x#}) x = 1"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1312 | by (simp add: not_in_iff) | 
| 60495 | 1313 |     from False have "Finite_Set.fold (\<lambda>y. f y ^^ count (M + {#x#}) y) s (set_mset M) =
 | 
| 1314 | Finite_Set.fold (\<lambda>y. f y ^^ count M y) s (set_mset M)" | |
| 49822 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1315 | by (auto intro!: Finite_Set.fold_cong comp_fun_commute_funpow) | 
| 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1316 | with False * show ?thesis | 
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1317 | by (simp add: fold_mset_def del: count_union) | 
| 48023 | 1318 | next | 
| 49822 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1319 | case True | 
| 63040 | 1320 |     define N where "N = set_mset M - {x}"
 | 
| 60495 | 1321 | from N_def True have *: "set_mset M = insert x N" "x \<notin> N" "finite N" by auto | 
| 49822 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1322 |     then have "Finite_Set.fold (\<lambda>y. f y ^^ count (M + {#x#}) y) s N =
 | 
| 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1323 | Finite_Set.fold (\<lambda>y. f y ^^ count M y) s N" | 
| 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1324 | by (auto intro!: Finite_Set.fold_cong comp_fun_commute_funpow) | 
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1325 | with * show ?thesis by (simp add: fold_mset_def del: count_union) simp | 
| 48023 | 1326 | qed | 
| 1327 | qed | |
| 1328 | ||
| 60606 | 1329 | corollary fold_mset_single [simp]: "fold_mset f s {#x#} = f x s"
 | 
| 49822 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1330 | proof - | 
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1331 |   have "fold_mset f s ({#} + {#x#}) = f x s" by (simp only: fold_mset_insert) simp
 | 
| 49822 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1332 | then show ?thesis by simp | 
| 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1333 | qed | 
| 48023 | 1334 | |
| 60606 | 1335 | lemma fold_mset_fun_left_comm: "f x (fold_mset f s M) = fold_mset f (f x s) M" | 
| 49822 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1336 | by (induct M) (simp_all add: fold_mset_insert fun_left_comm) | 
| 48023 | 1337 | |
| 60606 | 1338 | lemma fold_mset_union [simp]: "fold_mset f s (M + N) = fold_mset f (fold_mset f s M) N" | 
| 49822 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1339 | proof (induct M) | 
| 48023 | 1340 | case empty then show ?case by simp | 
| 1341 | next | |
| 49822 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1342 | case (add M x) | 
| 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1343 |   have "M + {#x#} + N = (M + N) + {#x#}"
 | 
| 57514 
bdc2c6b40bf2
prefer ac_simps collections over separate name bindings for add and mult
 haftmann parents: 
57512diff
changeset | 1344 | by (simp add: ac_simps) | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1345 | with add show ?case by (simp add: fold_mset_insert fold_mset_fun_left_comm) | 
| 48023 | 1346 | qed | 
| 1347 | ||
| 1348 | lemma fold_mset_fusion: | |
| 1349 | assumes "comp_fun_commute g" | |
| 60606 | 1350 | and *: "\<And>x y. h (g x y) = f x (h y)" | 
| 1351 | shows "h (fold_mset g w A) = fold_mset f (h w) A" | |
| 48023 | 1352 | proof - | 
| 1353 | interpret comp_fun_commute g by (fact assms) | |
| 60606 | 1354 | from * show ?thesis by (induct A) auto | 
| 48023 | 1355 | qed | 
| 1356 | ||
| 1357 | end | |
| 1358 | ||
| 60500 | 1359 | text \<open> | 
| 48023 | 1360 | A note on code generation: When defining some function containing a | 
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1361 |   subterm @{term "fold_mset F"}, code generation is not automatic. When
 | 
| 61585 | 1362 | interpreting locale \<open>left_commutative\<close> with \<open>F\<close>, the | 
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1363 |   would be code thms for @{const fold_mset} become thms like
 | 
| 61585 | 1364 |   @{term "fold_mset F z {#} = z"} where \<open>F\<close> is not a pattern but
 | 
| 48023 | 1365 | contains defined symbols, i.e.\ is not a code thm. Hence a separate | 
| 61585 | 1366 | constant with its own code thms needs to be introduced for \<open>F\<close>. See the image operator below. | 
| 60500 | 1367 | \<close> | 
| 1368 | ||
| 1369 | ||
| 1370 | subsection \<open>Image\<close> | |
| 48023 | 1371 | |
| 1372 | definition image_mset :: "('a \<Rightarrow> 'b) \<Rightarrow> 'a multiset \<Rightarrow> 'b multiset" where
 | |
| 60607 | 1373 |   "image_mset f = fold_mset (plus \<circ> single \<circ> f) {#}"
 | 
| 1374 | ||
| 1375 | lemma comp_fun_commute_mset_image: "comp_fun_commute (plus \<circ> single \<circ> f)" | |
| 49823 | 1376 | proof | 
| 57514 
bdc2c6b40bf2
prefer ac_simps collections over separate name bindings for add and mult
 haftmann parents: 
57512diff
changeset | 1377 | qed (simp add: ac_simps fun_eq_iff) | 
| 48023 | 1378 | |
| 1379 | lemma image_mset_empty [simp]: "image_mset f {#} = {#}"
 | |
| 49823 | 1380 | by (simp add: image_mset_def) | 
| 48023 | 1381 | |
| 1382 | lemma image_mset_single [simp]: "image_mset f {#x#} = {#f x#}"
 | |
| 49823 | 1383 | proof - | 
| 60607 | 1384 | interpret comp_fun_commute "plus \<circ> single \<circ> f" | 
| 49823 | 1385 | by (fact comp_fun_commute_mset_image) | 
| 1386 | show ?thesis by (simp add: image_mset_def) | |
| 1387 | qed | |
| 48023 | 1388 | |
| 60606 | 1389 | lemma image_mset_union [simp]: "image_mset f (M + N) = image_mset f M + image_mset f N" | 
| 49823 | 1390 | proof - | 
| 60607 | 1391 | interpret comp_fun_commute "plus \<circ> single \<circ> f" | 
| 49823 | 1392 | by (fact comp_fun_commute_mset_image) | 
| 57514 
bdc2c6b40bf2
prefer ac_simps collections over separate name bindings for add and mult
 haftmann parents: 
57512diff
changeset | 1393 | show ?thesis by (induct N) (simp_all add: image_mset_def ac_simps) | 
| 49823 | 1394 | qed | 
| 1395 | ||
| 60606 | 1396 | corollary image_mset_insert: "image_mset f (M + {#a#}) = image_mset f M + {#f a#}"
 | 
| 49823 | 1397 | by simp | 
| 48023 | 1398 | |
| 60606 | 1399 | lemma set_image_mset [simp]: "set_mset (image_mset f M) = image f (set_mset M)" | 
| 49823 | 1400 | by (induct M) simp_all | 
| 48040 | 1401 | |
| 60606 | 1402 | lemma size_image_mset [simp]: "size (image_mset f M) = size M" | 
| 49823 | 1403 | by (induct M) simp_all | 
| 48023 | 1404 | |
| 60606 | 1405 | lemma image_mset_is_empty_iff [simp]: "image_mset f M = {#} \<longleftrightarrow> M = {#}"
 | 
| 49823 | 1406 | by (cases M) auto | 
| 48023 | 1407 | |
| 63099 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1408 | lemma image_mset_If: | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1409 | "image_mset (\<lambda>x. if P x then f x else g x) A = | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1410 | image_mset f (filter_mset P A) + image_mset g (filter_mset (\<lambda>x. \<not>P x) A)" | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1411 | by (induction A) (auto simp: add_ac) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1412 | |
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1413 | lemma image_mset_Diff: | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1414 | assumes "B \<subseteq># A" | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1415 | shows "image_mset f (A - B) = image_mset f A - image_mset f B" | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1416 | proof - | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1417 | have "image_mset f (A - B + B) = image_mset f (A - B) + image_mset f B" | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1418 | by simp | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1419 | also from assms have "A - B + B = A" | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1420 | by (simp add: subset_mset.diff_add) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1421 | finally show ?thesis by simp | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1422 | qed | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1423 | |
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1424 | lemma count_image_mset: | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1425 |   "count (image_mset f A) x = (\<Sum>y\<in>f -` {x} \<inter> set_mset A. count A y)"
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1426 | by (induction A) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1427 | (auto simp: setsum.distrib setsum.delta' intro!: setsum.mono_neutral_left) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1428 | |
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1429 | |
| 61955 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1430 | syntax (ASCII) | 
| 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1431 |   "_comprehension_mset" :: "'a \<Rightarrow> 'b \<Rightarrow> 'b multiset \<Rightarrow> 'a multiset"  ("({#_/. _ :# _#})")
 | 
| 48023 | 1432 | syntax | 
| 61955 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1433 |   "_comprehension_mset" :: "'a \<Rightarrow> 'b \<Rightarrow> 'b multiset \<Rightarrow> 'a multiset"  ("({#_/. _ \<in># _#})")
 | 
| 59813 | 1434 | translations | 
| 61955 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1435 |   "{#e. x \<in># M#}" \<rightleftharpoons> "CONST image_mset (\<lambda>x. e) M"
 | 
| 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1436 | |
| 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1437 | syntax (ASCII) | 
| 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1438 |   "_comprehension_mset'" :: "'a \<Rightarrow> 'b \<Rightarrow> 'b multiset \<Rightarrow> bool \<Rightarrow> 'a multiset"  ("({#_/ | _ :# _./ _#})")
 | 
| 48023 | 1439 | syntax | 
| 61955 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1440 |   "_comprehension_mset'" :: "'a \<Rightarrow> 'b \<Rightarrow> 'b multiset \<Rightarrow> bool \<Rightarrow> 'a multiset"  ("({#_/ | _ \<in># _./ _#})")
 | 
| 59813 | 1441 | translations | 
| 60606 | 1442 |   "{#e | x\<in>#M. P#}" \<rightharpoonup> "{#e. x \<in># {# x\<in>#M. P#}#}"
 | 
| 59813 | 1443 | |
| 60500 | 1444 | text \<open> | 
| 60607 | 1445 |   This allows to write not just filters like @{term "{#x\<in>#M. x<c#}"}
 | 
| 1446 |   but also images like @{term "{#x+x. x\<in>#M #}"} and @{term [source]
 | |
| 1447 |   "{#x+x|x\<in>#M. x<c#}"}, where the latter is currently displayed as
 | |
| 1448 |   @{term "{#x+x|x\<in>#M. x<c#}"}.
 | |
| 60500 | 1449 | \<close> | 
| 48023 | 1450 | |
| 60495 | 1451 | lemma in_image_mset: "y \<in># {#f x. x \<in># M#} \<longleftrightarrow> y \<in> f ` set_mset M"
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1452 | by (metis set_image_mset) | 
| 59813 | 1453 | |
| 55467 
a5c9002bc54d
renamed 'enriched_type' to more informative 'functor' (following the renaming of enriched type constructors to bounded natural functors)
 blanchet parents: 
55417diff
changeset | 1454 | functor image_mset: image_mset | 
| 48023 | 1455 | proof - | 
| 1456 | fix f g show "image_mset f \<circ> image_mset g = image_mset (f \<circ> g)" | |
| 1457 | proof | |
| 1458 | fix A | |
| 1459 | show "(image_mset f \<circ> image_mset g) A = image_mset (f \<circ> g) A" | |
| 1460 | by (induct A) simp_all | |
| 1461 | qed | |
| 1462 | show "image_mset id = id" | |
| 1463 | proof | |
| 1464 | fix A | |
| 1465 | show "image_mset id A = id A" | |
| 1466 | by (induct A) simp_all | |
| 1467 | qed | |
| 1468 | qed | |
| 1469 | ||
| 59813 | 1470 | declare | 
| 1471 | image_mset.id [simp] | |
| 1472 | image_mset.identity [simp] | |
| 1473 | ||
| 1474 | lemma image_mset_id[simp]: "image_mset id x = x" | |
| 1475 | unfolding id_def by auto | |
| 1476 | ||
| 1477 | lemma image_mset_cong: "(\<And>x. x \<in># M \<Longrightarrow> f x = g x) \<Longrightarrow> {#f x. x \<in># M#} = {#g x. x \<in># M#}"
 | |
| 1478 | by (induct M) auto | |
| 1479 | ||
| 1480 | lemma image_mset_cong_pair: | |
| 1481 |   "(\<forall>x y. (x, y) \<in># M \<longrightarrow> f x y = g x y) \<Longrightarrow> {#f x y. (x, y) \<in># M#} = {#g x y. (x, y) \<in># M#}"
 | |
| 1482 | by (metis image_mset_cong split_cong) | |
| 49717 | 1483 | |
| 48023 | 1484 | |
| 60500 | 1485 | subsection \<open>Further conversions\<close> | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1486 | |
| 60515 | 1487 | primrec mset :: "'a list \<Rightarrow> 'a multiset" where | 
| 1488 |   "mset [] = {#}" |
 | |
| 1489 |   "mset (a # x) = mset x + {# a #}"
 | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1490 | |
| 37107 | 1491 | lemma in_multiset_in_set: | 
| 60515 | 1492 | "x \<in># mset xs \<longleftrightarrow> x \<in> set xs" | 
| 37107 | 1493 | by (induct xs) simp_all | 
| 1494 | ||
| 60515 | 1495 | lemma count_mset: | 
| 1496 | "count (mset xs) x = length (filter (\<lambda>y. x = y) xs)" | |
| 37107 | 1497 | by (induct xs) simp_all | 
| 1498 | ||
| 60515 | 1499 | lemma mset_zero_iff[simp]: "(mset x = {#}) = (x = [])"
 | 
| 59813 | 1500 | by (induct x) auto | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1501 | |
| 60515 | 1502 | lemma mset_zero_iff_right[simp]: "({#} = mset x) = (x = [])"
 | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1503 | by (induct x) auto | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1504 | |
| 60515 | 1505 | lemma set_mset_mset[simp]: "set_mset (mset x) = set x" | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1506 | by (induct x) auto | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1507 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1508 | lemma set_mset_comp_mset [simp]: "set_mset \<circ> mset = set" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1509 | by (simp add: fun_eq_iff) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1510 | |
| 60515 | 1511 | lemma size_mset [simp]: "size (mset xs) = length xs" | 
| 48012 | 1512 | by (induct xs) simp_all | 
| 1513 | ||
| 60606 | 1514 | lemma mset_append [simp]: "mset (xs @ ys) = mset xs + mset ys" | 
| 57514 
bdc2c6b40bf2
prefer ac_simps collections over separate name bindings for add and mult
 haftmann parents: 
57512diff
changeset | 1515 | by (induct xs arbitrary: ys) (auto simp: ac_simps) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1516 | |
| 60607 | 1517 | lemma mset_filter: "mset (filter P xs) = {#x \<in># mset xs. P x #}"
 | 
| 40303 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 1518 | by (induct xs) simp_all | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 1519 | |
| 60515 | 1520 | lemma mset_rev [simp]: | 
| 1521 | "mset (rev xs) = mset xs" | |
| 40950 | 1522 | by (induct xs) simp_all | 
| 1523 | ||
| 60515 | 1524 | lemma surj_mset: "surj mset" | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1525 | apply (unfold surj_def) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1526 | apply (rule allI) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1527 | apply (rule_tac M = y in multiset_induct) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1528 | apply auto | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1529 | apply (rule_tac x = "x # xa" in exI) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1530 | apply auto | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1531 | done | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1532 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1533 | lemma distinct_count_atmost_1: | 
| 60606 | 1534 | "distinct x = (\<forall>a. count (mset x) a = (if a \<in> set x then 1 else 0))" | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1535 | proof (induct x) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1536 | case Nil then show ?case by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1537 | next | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1538 | case (Cons x xs) show ?case (is "?lhs \<longleftrightarrow> ?rhs") | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1539 | proof | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1540 | assume ?lhs then show ?rhs using Cons by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1541 | next | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1542 | assume ?rhs then have "x \<notin> set xs" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1543 | by (simp split: if_splits) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1544 | moreover from \<open>?rhs\<close> have "(\<forall>a. count (mset xs) a = | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1545 | (if a \<in> set xs then 1 else 0))" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1546 | by (auto split: if_splits simp add: count_eq_zero_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1547 | ultimately show ?lhs using Cons by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1548 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1549 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1550 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1551 | lemma mset_eq_setD: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1552 | assumes "mset xs = mset ys" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1553 | shows "set xs = set ys" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1554 | proof - | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1555 | from assms have "set_mset (mset xs) = set_mset (mset ys)" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1556 | by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1557 | then show ?thesis by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1558 | qed | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1559 | |
| 60515 | 1560 | lemma set_eq_iff_mset_eq_distinct: | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1561 | "distinct x \<Longrightarrow> distinct y \<Longrightarrow> | 
| 60515 | 1562 | (set x = set y) = (mset x = mset y)" | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 1563 | by (auto simp: multiset_eq_iff distinct_count_atmost_1) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1564 | |
| 60515 | 1565 | lemma set_eq_iff_mset_remdups_eq: | 
| 1566 | "(set x = set y) = (mset (remdups x) = mset (remdups y))" | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1567 | apply (rule iffI) | 
| 60515 | 1568 | apply (simp add: set_eq_iff_mset_eq_distinct[THEN iffD1]) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1569 | apply (drule distinct_remdups [THEN distinct_remdups | 
| 60515 | 1570 | [THEN set_eq_iff_mset_eq_distinct [THEN iffD2]]]) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1571 | apply simp | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1572 | done | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1573 | |
| 60606 | 1574 | lemma mset_compl_union [simp]: "mset [x\<leftarrow>xs. P x] + mset [x\<leftarrow>xs. \<not>P x] = mset xs" | 
| 57514 
bdc2c6b40bf2
prefer ac_simps collections over separate name bindings for add and mult
 haftmann parents: 
57512diff
changeset | 1575 | by (induct xs) (auto simp: ac_simps) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1576 | |
| 60607 | 1577 | lemma nth_mem_mset: "i < length ls \<Longrightarrow> (ls ! i) \<in># mset ls" | 
| 60678 | 1578 | proof (induct ls arbitrary: i) | 
| 1579 | case Nil | |
| 1580 | then show ?case by simp | |
| 1581 | next | |
| 1582 | case Cons | |
| 1583 | then show ?case by (cases i) auto | |
| 1584 | qed | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1585 | |
| 60606 | 1586 | lemma mset_remove1[simp]: "mset (remove1 a xs) = mset xs - {#a#}"
 | 
| 60678 | 1587 | by (induct xs) (auto simp add: multiset_eq_iff) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1588 | |
| 60515 | 1589 | lemma mset_eq_length: | 
| 1590 | assumes "mset xs = mset ys" | |
| 37107 | 1591 | shows "length xs = length ys" | 
| 60515 | 1592 | using assms by (metis size_mset) | 
| 1593 | ||
| 1594 | lemma mset_eq_length_filter: | |
| 1595 | assumes "mset xs = mset ys" | |
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 1596 | shows "length (filter (\<lambda>x. z = x) xs) = length (filter (\<lambda>y. z = y) ys)" | 
| 60515 | 1597 | using assms by (metis count_mset) | 
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 1598 | |
| 45989 
b39256df5f8a
moved theorem requiring multisets from More_List to Multiset
 haftmann parents: 
45866diff
changeset | 1599 | lemma fold_multiset_equiv: | 
| 
b39256df5f8a
moved theorem requiring multisets from More_List to Multiset
 haftmann parents: 
45866diff
changeset | 1600 | assumes f: "\<And>x y. x \<in> set xs \<Longrightarrow> y \<in> set xs \<Longrightarrow> f x \<circ> f y = f y \<circ> f x" | 
| 60515 | 1601 | and equiv: "mset xs = mset ys" | 
| 49822 
0cfc1651be25
simplified construction of fold combinator on multisets;
 haftmann parents: 
49717diff
changeset | 1602 | shows "List.fold f xs = List.fold f ys" | 
| 60606 | 1603 | using f equiv [symmetric] | 
| 46921 | 1604 | proof (induct xs arbitrary: ys) | 
| 60678 | 1605 | case Nil | 
| 1606 | then show ?case by simp | |
| 45989 
b39256df5f8a
moved theorem requiring multisets from More_List to Multiset
 haftmann parents: 
45866diff
changeset | 1607 | next | 
| 
b39256df5f8a
moved theorem requiring multisets from More_List to Multiset
 haftmann parents: 
45866diff
changeset | 1608 | case (Cons x xs) | 
| 60678 | 1609 | then have *: "set ys = set (x # xs)" | 
| 1610 | by (blast dest: mset_eq_setD) | |
| 58425 | 1611 | have "\<And>x y. x \<in> set ys \<Longrightarrow> y \<in> set ys \<Longrightarrow> f x \<circ> f y = f y \<circ> f x" | 
| 45989 
b39256df5f8a
moved theorem requiring multisets from More_List to Multiset
 haftmann parents: 
45866diff
changeset | 1612 | by (rule Cons.prems(1)) (simp_all add: *) | 
| 60678 | 1613 | moreover from * have "x \<in> set ys" | 
| 1614 | by simp | |
| 1615 | ultimately have "List.fold f ys = List.fold f (remove1 x ys) \<circ> f x" | |
| 1616 | by (fact fold_remove1_split) | |
| 1617 | moreover from Cons.prems have "List.fold f xs = List.fold f (remove1 x ys)" | |
| 1618 | by (auto intro: Cons.hyps) | |
| 45989 
b39256df5f8a
moved theorem requiring multisets from More_List to Multiset
 haftmann parents: 
45866diff
changeset | 1619 | ultimately show ?case by simp | 
| 
b39256df5f8a
moved theorem requiring multisets from More_List to Multiset
 haftmann parents: 
45866diff
changeset | 1620 | qed | 
| 
b39256df5f8a
moved theorem requiring multisets from More_List to Multiset
 haftmann parents: 
45866diff
changeset | 1621 | |
| 60606 | 1622 | lemma mset_insort [simp]: "mset (insort x xs) = mset xs + {#x#}"
 | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1623 | by (induct xs) (simp_all add: ac_simps) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1624 | |
| 63524 
4ec755485732
adding mset_map to the simp rules
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63410diff
changeset | 1625 | lemma mset_map[simp]: "mset (map f xs) = image_mset f (mset xs)" | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 1626 | by (induct xs) simp_all | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 1627 | |
| 61890 
f6ded81f5690
abandoned attempt to unify sublocale and interpretation into global theories
 haftmann parents: 
61832diff
changeset | 1628 | global_interpretation mset_set: folding "\<lambda>x M. {#x#} + M" "{#}"
 | 
| 61832 | 1629 |   defines mset_set = "folding.F (\<lambda>x M. {#x#} + M) {#}"
 | 
| 1630 | by standard (simp add: fun_eq_iff ac_simps) | |
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1631 | |
| 60513 | 1632 | lemma count_mset_set [simp]: | 
| 1633 | "finite A \<Longrightarrow> x \<in> A \<Longrightarrow> count (mset_set A) x = 1" (is "PROP ?P") | |
| 1634 | "\<not> finite A \<Longrightarrow> count (mset_set A) x = 0" (is "PROP ?Q") | |
| 1635 | "x \<notin> A \<Longrightarrow> count (mset_set A) x = 0" (is "PROP ?R") | |
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 1636 | proof - | 
| 60606 | 1637 | have *: "count (mset_set A) x = 0" if "x \<notin> A" for A | 
| 1638 | proof (cases "finite A") | |
| 1639 | case False then show ?thesis by simp | |
| 1640 | next | |
| 1641 | case True from True \<open>x \<notin> A\<close> show ?thesis by (induct A) auto | |
| 1642 | qed | |
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 1643 | then show "PROP ?P" "PROP ?Q" "PROP ?R" | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 1644 | by (auto elim!: Set.set_insert) | 
| 61585 | 1645 | qed \<comment> \<open>TODO: maybe define @{const mset_set} also in terms of @{const Abs_multiset}\<close>
 | 
| 60513 | 1646 | |
| 1647 | lemma elem_mset_set[simp, intro]: "finite A \<Longrightarrow> x \<in># mset_set A \<longleftrightarrow> x \<in> A" | |
| 59813 | 1648 | by (induct A rule: finite_induct) simp_all | 
| 1649 | ||
| 63099 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1650 | lemma mset_set_Union: | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1651 |   "finite A \<Longrightarrow> finite B \<Longrightarrow> A \<inter> B = {} \<Longrightarrow> mset_set (A \<union> B) = mset_set A + mset_set B"
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1652 | by (induction A rule: finite_induct) (auto simp: add_ac) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1653 | |
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1654 | lemma filter_mset_mset_set [simp]: | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1655 |   "finite A \<Longrightarrow> filter_mset P (mset_set A) = mset_set {x\<in>A. P x}"
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1656 | proof (induction A rule: finite_induct) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1657 | case (insert x A) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1658 | from insert.hyps have "filter_mset P (mset_set (insert x A)) = | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1659 |       filter_mset P (mset_set A) + mset_set (if P x then {x} else {})"
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1660 | by (simp add: add_ac) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1661 |   also have "filter_mset P (mset_set A) = mset_set {x\<in>A. P x}"
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1662 | by (rule insert.IH) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1663 | also from insert.hyps | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1664 |     have "\<dots> + mset_set (if P x then {x} else {}) =
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1665 |             mset_set ({x \<in> A. P x} \<union> (if P x then {x} else {}))" (is "_ = mset_set ?A")
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1666 | by (intro mset_set_Union [symmetric]) simp_all | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1667 |   also from insert.hyps have "?A = {y\<in>insert x A. P y}" by auto
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1668 | finally show ?case . | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1669 | qed simp_all | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1670 | |
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1671 | lemma mset_set_Diff: | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1672 | assumes "finite A" "B \<subseteq> A" | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1673 | shows "mset_set (A - B) = mset_set A - mset_set B" | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1674 | proof - | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1675 | from assms have "mset_set ((A - B) \<union> B) = mset_set (A - B) + mset_set B" | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1676 | by (intro mset_set_Union) (auto dest: finite_subset) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1677 | also from assms have "A - B \<union> B = A" by blast | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1678 | finally show ?thesis by simp | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1679 | qed | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1680 | |
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1681 | lemma mset_set_set: "distinct xs \<Longrightarrow> mset_set (set xs) = mset xs" | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1682 | by (induction xs) (simp_all add: add_ac) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1683 | |
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1684 | context linorder | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1685 | begin | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1686 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1687 | definition sorted_list_of_multiset :: "'a multiset \<Rightarrow> 'a list" | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1688 | where | 
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1689 | "sorted_list_of_multiset M = fold_mset insort [] M" | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1690 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1691 | lemma sorted_list_of_multiset_empty [simp]: | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1692 |   "sorted_list_of_multiset {#} = []"
 | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1693 | by (simp add: sorted_list_of_multiset_def) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1694 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1695 | lemma sorted_list_of_multiset_singleton [simp]: | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1696 |   "sorted_list_of_multiset {#x#} = [x]"
 | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1697 | proof - | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1698 | interpret comp_fun_commute insort by (fact comp_fun_commute_insort) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1699 | show ?thesis by (simp add: sorted_list_of_multiset_def) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1700 | qed | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1701 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1702 | lemma sorted_list_of_multiset_insert [simp]: | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1703 |   "sorted_list_of_multiset (M + {#x#}) = List.insort x (sorted_list_of_multiset M)"
 | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1704 | proof - | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1705 | interpret comp_fun_commute insort by (fact comp_fun_commute_insort) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1706 | show ?thesis by (simp add: sorted_list_of_multiset_def) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1707 | qed | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1708 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1709 | end | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1710 | |
| 60515 | 1711 | lemma mset_sorted_list_of_multiset [simp]: | 
| 1712 | "mset (sorted_list_of_multiset M) = M" | |
| 60513 | 1713 | by (induct M) simp_all | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1714 | |
| 60515 | 1715 | lemma sorted_list_of_multiset_mset [simp]: | 
| 1716 | "sorted_list_of_multiset (mset xs) = sort xs" | |
| 60513 | 1717 | by (induct xs) simp_all | 
| 1718 | ||
| 1719 | lemma finite_set_mset_mset_set[simp]: | |
| 1720 | "finite A \<Longrightarrow> set_mset (mset_set A) = A" | |
| 1721 | by (induct A rule: finite_induct) simp_all | |
| 1722 | ||
| 63099 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1723 | lemma mset_set_empty_iff: "mset_set A = {#} \<longleftrightarrow> A = {} \<or> infinite A"
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1724 | using finite_set_mset_mset_set by fastforce | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1725 | |
| 60513 | 1726 | lemma infinite_set_mset_mset_set: | 
| 1727 |   "\<not> finite A \<Longrightarrow> set_mset (mset_set A) = {}"
 | |
| 1728 | by simp | |
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1729 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1730 | lemma set_sorted_list_of_multiset [simp]: | 
| 60495 | 1731 | "set (sorted_list_of_multiset M) = set_mset M" | 
| 60513 | 1732 | by (induct M) (simp_all add: set_insort) | 
| 1733 | ||
| 1734 | lemma sorted_list_of_mset_set [simp]: | |
| 1735 | "sorted_list_of_multiset (mset_set A) = sorted_list_of_set A" | |
| 1736 | by (cases "finite A") (induct A rule: finite_induct, simp_all add: ac_simps) | |
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1737 | |
| 63099 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1738 | lemma mset_upt [simp]: "mset [m..<n] = mset_set {m..<n}"
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1739 | by (induction n) (simp_all add: atLeastLessThanSuc add_ac) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1740 | |
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1741 | lemma image_mset_map_of: | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1742 |   "distinct (map fst xs) \<Longrightarrow> {#the (map_of xs i). i \<in># mset (map fst xs)#} = mset (map snd xs)"
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1743 | proof (induction xs) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1744 | case (Cons x xs) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1745 |   have "{#the (map_of (x # xs) i). i \<in># mset (map fst (x # xs))#} = 
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1746 |           {#the (if i = fst x then Some (snd x) else map_of xs i). 
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1747 |              i \<in># mset (map fst xs)#} + {#snd x#}" (is "_ = ?A + _") by simp
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1748 |   also from Cons.prems have "?A = {#the (map_of xs i). i :# mset (map fst xs)#}"
 | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1749 | by (cases x, intro image_mset_cong) (auto simp: in_multiset_in_set) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1750 | also from Cons.prems have "\<dots> = mset (map snd xs)" by (intro Cons.IH) simp_all | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1751 | finally show ?case by simp | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1752 | qed simp_all | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1753 | |
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1754 | |
| 60804 | 1755 | subsection \<open>Replicate operation\<close> | 
| 1756 | ||
| 1757 | definition replicate_mset :: "nat \<Rightarrow> 'a \<Rightarrow> 'a multiset" where | |
| 1758 |   "replicate_mset n x = ((op + {#x#}) ^^ n) {#}"
 | |
| 1759 | ||
| 1760 | lemma replicate_mset_0[simp]: "replicate_mset 0 x = {#}"
 | |
| 1761 | unfolding replicate_mset_def by simp | |
| 1762 | ||
| 1763 | lemma replicate_mset_Suc[simp]: "replicate_mset (Suc n) x = replicate_mset n x + {#x#}"
 | |
| 1764 | unfolding replicate_mset_def by (induct n) (auto intro: add.commute) | |
| 1765 | ||
| 1766 | lemma in_replicate_mset[simp]: "x \<in># replicate_mset n y \<longleftrightarrow> n > 0 \<and> x = y" | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1767 | unfolding replicate_mset_def by (induct n) auto | 
| 60804 | 1768 | |
| 1769 | lemma count_replicate_mset[simp]: "count (replicate_mset n x) y = (if y = x then n else 0)" | |
| 1770 | unfolding replicate_mset_def by (induct n) simp_all | |
| 1771 | ||
| 1772 | lemma set_mset_replicate_mset_subset[simp]: "set_mset (replicate_mset n x) = (if n = 0 then {} else {x})"
 | |
| 1773 | by (auto split: if_splits) | |
| 1774 | ||
| 1775 | lemma size_replicate_mset[simp]: "size (replicate_mset n M) = n" | |
| 1776 | by (induct n, simp_all) | |
| 1777 | ||
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1778 | lemma count_le_replicate_mset_subset_eq: "n \<le> count M x \<longleftrightarrow> replicate_mset n x \<subseteq># M" | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 1779 | by (auto simp add: mset_subset_eqI) (metis count_replicate_mset subseteq_mset_def) | 
| 60804 | 1780 | |
| 1781 | lemma filter_eq_replicate_mset: "{#y \<in># D. y = x#} = replicate_mset (count D x) x"
 | |
| 1782 | by (induct D) simp_all | |
| 1783 | ||
| 61031 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 1784 | lemma replicate_count_mset_eq_filter_eq: | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 1785 | "replicate (count (mset xs) k) k = filter (HOL.eq k) xs" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 1786 | by (induct xs) auto | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 1787 | |
| 62366 | 1788 | lemma replicate_mset_eq_empty_iff [simp]: | 
| 1789 |   "replicate_mset n a = {#} \<longleftrightarrow> n = 0"
 | |
| 1790 | by (induct n) simp_all | |
| 1791 | ||
| 1792 | lemma replicate_mset_eq_iff: | |
| 1793 | "replicate_mset m a = replicate_mset n b \<longleftrightarrow> | |
| 1794 | m = 0 \<and> n = 0 \<or> m = n \<and> a = b" | |
| 1795 | by (auto simp add: multiset_eq_iff) | |
| 1796 | ||
| 60804 | 1797 | |
| 60500 | 1798 | subsection \<open>Big operators\<close> | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1799 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1800 | locale comm_monoid_mset = comm_monoid | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1801 | begin | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1802 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1803 | definition F :: "'a multiset \<Rightarrow> 'a" | 
| 63290 
9ac558ab0906
boldify syntax in abstract algebraic structures, to avoid clashes with concrete syntax in corresponding type classes
 haftmann parents: 
63195diff
changeset | 1804 | where eq_fold: "F M = fold_mset f \<^bold>1 M" | 
| 
9ac558ab0906
boldify syntax in abstract algebraic structures, to avoid clashes with concrete syntax in corresponding type classes
 haftmann parents: 
63195diff
changeset | 1805 | |
| 
9ac558ab0906
boldify syntax in abstract algebraic structures, to avoid clashes with concrete syntax in corresponding type classes
 haftmann parents: 
63195diff
changeset | 1806 | lemma empty [simp]: "F {#} = \<^bold>1"
 | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1807 | by (simp add: eq_fold) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1808 | |
| 60678 | 1809 | lemma singleton [simp]: "F {#x#} = x"
 | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1810 | proof - | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1811 | interpret comp_fun_commute | 
| 60678 | 1812 | by standard (simp add: fun_eq_iff left_commute) | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1813 | show ?thesis by (simp add: eq_fold) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1814 | qed | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1815 | |
| 63290 
9ac558ab0906
boldify syntax in abstract algebraic structures, to avoid clashes with concrete syntax in corresponding type classes
 haftmann parents: 
63195diff
changeset | 1816 | lemma union [simp]: "F (M + N) = F M \<^bold>* F N" | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1817 | proof - | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1818 | interpret comp_fun_commute f | 
| 60678 | 1819 | by standard (simp add: fun_eq_iff left_commute) | 
| 1820 | show ?thesis | |
| 1821 | by (induct N) (simp_all add: left_commute eq_fold) | |
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1822 | qed | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1823 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1824 | end | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1825 | |
| 61076 | 1826 | lemma comp_fun_commute_plus_mset[simp]: "comp_fun_commute (op + :: 'a multiset \<Rightarrow> _ \<Rightarrow> _)" | 
| 60678 | 1827 | by standard (simp add: add_ac comp_def) | 
| 59813 | 1828 | |
| 1829 | declare comp_fun_commute.fold_mset_insert[OF comp_fun_commute_plus_mset, simp] | |
| 1830 | ||
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1831 | lemma in_mset_fold_plus_iff[iff]: "x \<in># fold_mset (op +) M NN \<longleftrightarrow> x \<in># M \<or> (\<exists>N. N \<in># NN \<and> x \<in># N)" | 
| 59813 | 1832 | by (induct NN) auto | 
| 1833 | ||
| 54868 | 1834 | context comm_monoid_add | 
| 1835 | begin | |
| 1836 | ||
| 61605 | 1837 | sublocale msetsum: comm_monoid_mset plus 0 | 
| 61832 | 1838 | defines msetsum = msetsum.F .. | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1839 | |
| 60804 | 1840 | lemma (in semiring_1) msetsum_replicate_mset [simp]: | 
| 1841 | "msetsum (replicate_mset n a) = of_nat n * a" | |
| 1842 | by (induct n) (simp_all add: algebra_simps) | |
| 1843 | ||
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1844 | lemma setsum_unfold_msetsum: | 
| 60513 | 1845 | "setsum f A = msetsum (image_mset f (mset_set A))" | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1846 | by (cases "finite A") (induct A rule: finite_induct, simp_all) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1847 | |
| 63534 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1848 | lemma msetsum_delta: "msetsum (image_mset (\<lambda>x. if x = y then c else 0) A) = c * count A y" | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1849 | by (induction A) simp_all | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1850 | |
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1851 | lemma msetsum_delta': "msetsum (image_mset (\<lambda>x. if y = x then c else 0) A) = c * count A y" | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1852 | by (induction A) simp_all | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1853 | |
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1854 | end | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1855 | |
| 59813 | 1856 | lemma msetsum_diff: | 
| 61076 | 1857 |   fixes M N :: "('a :: ordered_cancel_comm_monoid_diff) multiset"
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1858 | shows "N \<subseteq># M \<Longrightarrow> msetsum (M - N) = msetsum M - msetsum N" | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 1859 | by (metis add_diff_cancel_right' msetsum.union subset_mset.diff_add) | 
| 59813 | 1860 | |
| 59949 | 1861 | lemma size_eq_msetsum: "size M = msetsum (image_mset (\<lambda>_. 1) M)" | 
| 1862 | proof (induct M) | |
| 1863 | case empty then show ?case by simp | |
| 1864 | next | |
| 1865 | case (add M x) then show ?case | |
| 60495 | 1866 | by (cases "x \<in> set_mset M") | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1867 | (simp_all add: size_multiset_overloaded_eq setsum.distrib setsum.delta' insert_absorb not_in_iff) | 
| 59949 | 1868 | qed | 
| 1869 | ||
| 63099 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1870 | lemma size_mset_set [simp]: "size (mset_set A) = card A" | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1871 | by (simp only: size_eq_msetsum card_eq_setsum setsum_unfold_msetsum) | 
| 
af0e964aad7b
Moved material from AFP/Randomised_Social_Choice to distribution
 eberlm parents: 
63092diff
changeset | 1872 | |
| 62366 | 1873 | syntax (ASCII) | 
| 1874 |   "_msetsum_image" :: "pttrn \<Rightarrow> 'b set \<Rightarrow> 'a \<Rightarrow> 'a::comm_monoid_add"  ("(3SUM _:#_. _)" [0, 51, 10] 10)
 | |
| 1875 | syntax | |
| 1876 |   "_msetsum_image" :: "pttrn \<Rightarrow> 'b set \<Rightarrow> 'a \<Rightarrow> 'a::comm_monoid_add"  ("(3\<Sum>_\<in>#_. _)" [0, 51, 10] 10)
 | |
| 1877 | translations | |
| 1878 | "\<Sum>i \<in># A. b" \<rightleftharpoons> "CONST msetsum (CONST image_mset (\<lambda>i. b) A)" | |
| 59949 | 1879 | |
| 61955 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1880 | abbreviation Union_mset :: "'a multiset multiset \<Rightarrow> 'a multiset"  ("\<Union>#_" [900] 900)
 | 
| 62837 | 1881 | where "\<Union># MM \<equiv> msetsum MM" \<comment> \<open>FIXME ambiguous notation -- | 
| 1882 | could likewise refer to \<open>\<Squnion>#\<close>\<close> | |
| 59813 | 1883 | |
| 60495 | 1884 | lemma set_mset_Union_mset[simp]: "set_mset (\<Union># MM) = (\<Union>M \<in> set_mset MM. set_mset M)" | 
| 59813 | 1885 | by (induct MM) auto | 
| 1886 | ||
| 1887 | lemma in_Union_mset_iff[iff]: "x \<in># \<Union># MM \<longleftrightarrow> (\<exists>M. M \<in># MM \<and> x \<in># M)" | |
| 1888 | by (induct MM) auto | |
| 1889 | ||
| 62366 | 1890 | lemma count_setsum: | 
| 1891 | "count (setsum f A) x = setsum (\<lambda>a. count (f a) x) A" | |
| 1892 | by (induct A rule: infinite_finite_induct) simp_all | |
| 1893 | ||
| 1894 | lemma setsum_eq_empty_iff: | |
| 1895 | assumes "finite A" | |
| 1896 |   shows "setsum f A = {#} \<longleftrightarrow> (\<forall>a\<in>A. f a = {#})"
 | |
| 1897 | using assms by induct simp_all | |
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1898 | |
| 54868 | 1899 | context comm_monoid_mult | 
| 1900 | begin | |
| 1901 | ||
| 61605 | 1902 | sublocale msetprod: comm_monoid_mset times 1 | 
| 61832 | 1903 | defines msetprod = msetprod.F .. | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1904 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1905 | lemma msetprod_empty: | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1906 |   "msetprod {#} = 1"
 | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1907 | by (fact msetprod.empty) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1908 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1909 | lemma msetprod_singleton: | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1910 |   "msetprod {#x#} = x"
 | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1911 | by (fact msetprod.singleton) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1912 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1913 | lemma msetprod_Un: | 
| 58425 | 1914 | "msetprod (A + B) = msetprod A * msetprod B" | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1915 | by (fact msetprod.union) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1916 | |
| 60804 | 1917 | lemma msetprod_replicate_mset [simp]: | 
| 1918 | "msetprod (replicate_mset n a) = a ^ n" | |
| 1919 | by (induct n) (simp_all add: ac_simps) | |
| 1920 | ||
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1921 | lemma setprod_unfold_msetprod: | 
| 60513 | 1922 | "setprod f A = msetprod (image_mset f (mset_set A))" | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1923 | by (cases "finite A") (induct A rule: finite_induct, simp_all) | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1924 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1925 | lemma msetprod_multiplicity: | 
| 60495 | 1926 | "msetprod M = setprod (\<lambda>x. x ^ count M x) (set_mset M)" | 
| 59998 
c54d36be22ef
renamed Multiset.fold -> fold_mset, Multiset.filter -> filter_mset
 nipkow parents: 
59986diff
changeset | 1927 | by (simp add: fold_mset_def setprod.eq_fold msetprod.eq_fold funpow_times_power comp_def) | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1928 | |
| 63534 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1929 | lemma msetprod_delta: "msetprod (image_mset (\<lambda>x. if x = y then c else 1) A) = c ^ count A y" | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1930 | by (induction A) (simp_all add: mult_ac) | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1931 | |
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1932 | lemma msetprod_delta': "msetprod (image_mset (\<lambda>x. if y = x then c else 1) A) = c ^ count A y" | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1933 | by (induction A) (simp_all add: mult_ac) | 
| 
523b488b15c9
Overhaul of prime/multiplicity/prime_factors
 eberlm <eberlm@in.tum.de> parents: 
63524diff
changeset | 1934 | |
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1935 | end | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1936 | |
| 61955 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1937 | syntax (ASCII) | 
| 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1938 |   "_msetprod_image" :: "pttrn \<Rightarrow> 'b set \<Rightarrow> 'a \<Rightarrow> 'a::comm_monoid_mult"  ("(3PROD _:#_. _)" [0, 51, 10] 10)
 | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1939 | syntax | 
| 61955 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1940 |   "_msetprod_image" :: "pttrn \<Rightarrow> 'b set \<Rightarrow> 'a \<Rightarrow> 'a::comm_monoid_mult"  ("(3\<Prod>_\<in>#_. _)" [0, 51, 10] 10)
 | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1941 | translations | 
| 61955 
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
 wenzelm parents: 
61890diff
changeset | 1942 | "\<Prod>i \<in># A. b" \<rightleftharpoons> "CONST msetprod (CONST image_mset (\<lambda>i. b) A)" | 
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1943 | |
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1944 | lemma (in comm_semiring_1) dvd_msetprod: | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1945 | assumes "x \<in># A" | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1946 | shows "x dvd msetprod A" | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1947 | proof - | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1948 |   from assms have "A = (A - {#x#}) + {#x#}" by simp
 | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1949 |   then obtain B where "A = B + {#x#}" ..
 | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1950 | then show ?thesis by simp | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1951 | qed | 
| 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1952 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1953 | lemma (in semidom) msetprod_zero_iff [iff]: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1954 | "msetprod A = 0 \<longleftrightarrow> 0 \<in># A" | 
| 62366 | 1955 | by (induct A) auto | 
| 1956 | ||
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1957 | lemma (in semidom_divide) msetprod_diff: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1958 | assumes "B \<subseteq># A" and "0 \<notin># B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1959 | shows "msetprod (A - B) = msetprod A div msetprod B" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1960 | proof - | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1961 | from assms obtain C where "A = B + C" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1962 | by (metis subset_mset.add_diff_inverse) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1963 | with assms show ?thesis by simp | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1964 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1965 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1966 | lemma (in semidom_divide) msetprod_minus: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1967 | assumes "a \<in># A" and "a \<noteq> 0" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1968 |   shows "msetprod (A - {#a#}) = msetprod A div a"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1969 |   using assms msetprod_diff [of "{#a#}" A]
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1970 | by (auto simp add: single_subset_iff) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1971 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1972 | lemma (in normalization_semidom) normalized_msetprodI: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1973 | assumes "\<And>a. a \<in># A \<Longrightarrow> normalize a = a" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1974 | shows "normalize (msetprod A) = msetprod A" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1975 | using assms by (induct A) (simp_all add: normalize_mult) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 1976 | |
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1977 | |
| 60500 | 1978 | subsection \<open>Alternative representations\<close> | 
| 1979 | ||
| 1980 | subsubsection \<open>Lists\<close> | |
| 51548 
757fa47af981
centralized various multiset operations in theory multiset;
 haftmann parents: 
51161diff
changeset | 1981 | |
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 1982 | context linorder | 
| 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 1983 | begin | 
| 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 1984 | |
| 60515 | 1985 | lemma mset_insort [simp]: | 
| 1986 |   "mset (insort_key k x xs) = {#x#} + mset xs"
 | |
| 37107 | 1987 | by (induct xs) (simp_all add: ac_simps) | 
| 58425 | 1988 | |
| 60515 | 1989 | lemma mset_sort [simp]: | 
| 1990 | "mset (sort_key k xs) = mset xs" | |
| 37107 | 1991 | by (induct xs) (simp_all add: ac_simps) | 
| 1992 | ||
| 60500 | 1993 | text \<open> | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 1994 | This lemma shows which properties suffice to show that a function | 
| 61585 | 1995 | \<open>f\<close> with \<open>f xs = ys\<close> behaves like sort. | 
| 60500 | 1996 | \<close> | 
| 37074 | 1997 | |
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 1998 | lemma properties_for_sort_key: | 
| 60515 | 1999 | assumes "mset ys = mset xs" | 
| 60606 | 2000 | and "\<And>k. k \<in> set ys \<Longrightarrow> filter (\<lambda>x. f k = f x) ys = filter (\<lambda>x. f k = f x) xs" | 
| 2001 | and "sorted (map f ys)" | |
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2002 | shows "sort_key f xs = ys" | 
| 60606 | 2003 | using assms | 
| 46921 | 2004 | proof (induct xs arbitrary: ys) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2005 | case Nil then show ?case by simp | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2006 | next | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2007 | case (Cons x xs) | 
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2008 | from Cons.prems(2) have | 
| 40305 
41833242cc42
tuned lemma proposition of properties_for_sort_key
 haftmann parents: 
40303diff
changeset | 2009 | "\<forall>k \<in> set ys. filter (\<lambda>x. f k = f x) (remove1 x ys) = filter (\<lambda>x. f k = f x) xs" | 
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2010 | by (simp add: filter_remove1) | 
| 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2011 | with Cons.prems have "sort_key f xs = remove1 x ys" | 
| 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2012 | by (auto intro!: Cons.hyps simp add: sorted_map_remove1) | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2013 | moreover from Cons.prems have "x \<in># mset ys" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2014 | by auto | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2015 | then have "x \<in> set ys" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2016 | by simp | 
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2017 | ultimately show ?case using Cons.prems by (simp add: insort_key_remove1) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2018 | qed | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2019 | |
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2020 | lemma properties_for_sort: | 
| 60515 | 2021 | assumes multiset: "mset ys = mset xs" | 
| 60606 | 2022 | and "sorted ys" | 
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2023 | shows "sort xs = ys" | 
| 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2024 | proof (rule properties_for_sort_key) | 
| 60515 | 2025 | from multiset show "mset ys = mset xs" . | 
| 60500 | 2026 | from \<open>sorted ys\<close> show "sorted (map (\<lambda>x. x) ys)" by simp | 
| 60678 | 2027 | from multiset have "length (filter (\<lambda>y. k = y) ys) = length (filter (\<lambda>x. k = x) xs)" for k | 
| 60515 | 2028 | by (rule mset_eq_length_filter) | 
| 60678 | 2029 | then have "replicate (length (filter (\<lambda>y. k = y) ys)) k = | 
| 2030 | replicate (length (filter (\<lambda>x. k = x) xs)) k" for k | |
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2031 | by simp | 
| 60678 | 2032 | then show "k \<in> set ys \<Longrightarrow> filter (\<lambda>y. k = y) ys = filter (\<lambda>x. k = x) xs" for k | 
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2033 | by (simp add: replicate_length_filter) | 
| 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2034 | qed | 
| 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2035 | |
| 61031 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2036 | lemma sort_key_inj_key_eq: | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2037 | assumes mset_equal: "mset xs = mset ys" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2038 | and "inj_on f (set xs)" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2039 | and "sorted (map f ys)" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2040 | shows "sort_key f xs = ys" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2041 | proof (rule properties_for_sort_key) | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2042 | from mset_equal | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2043 | show "mset ys = mset xs" by simp | 
| 61188 | 2044 | from \<open>sorted (map f ys)\<close> | 
| 61031 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2045 | show "sorted (map f ys)" . | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2046 | show "[x\<leftarrow>ys . f k = f x] = [x\<leftarrow>xs . f k = f x]" if "k \<in> set ys" for k | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2047 | proof - | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2048 | from mset_equal | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2049 | have set_equal: "set xs = set ys" by (rule mset_eq_setD) | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2050 | with that have "insert k (set ys) = set ys" by auto | 
| 61188 | 2051 | with \<open>inj_on f (set xs)\<close> have inj: "inj_on f (insert k (set ys))" | 
| 61031 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2052 | by (simp add: set_equal) | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2053 | from inj have "[x\<leftarrow>ys . f k = f x] = filter (HOL.eq k) ys" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2054 | by (auto intro!: inj_on_filter_key_eq) | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2055 | also have "\<dots> = replicate (count (mset ys) k) k" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2056 | by (simp add: replicate_count_mset_eq_filter_eq) | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2057 | also have "\<dots> = replicate (count (mset xs) k) k" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2058 | using mset_equal by simp | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2059 | also have "\<dots> = filter (HOL.eq k) xs" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2060 | by (simp add: replicate_count_mset_eq_filter_eq) | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2061 | also have "\<dots> = [x\<leftarrow>xs . f k = f x]" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2062 | using inj by (auto intro!: inj_on_filter_key_eq [symmetric] simp add: set_equal) | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2063 | finally show ?thesis . | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2064 | qed | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2065 | qed | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2066 | |
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2067 | lemma sort_key_eq_sort_key: | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2068 | assumes "mset xs = mset ys" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2069 | and "inj_on f (set xs)" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2070 | shows "sort_key f xs = sort_key f ys" | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2071 | by (rule sort_key_inj_key_eq) (simp_all add: assms) | 
| 
162bd20dae23
more lemmas on sorting and multisets (due to Thomas Sewell)
 haftmann parents: 
60804diff
changeset | 2072 | |
| 40303 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2073 | lemma sort_key_by_quicksort: | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2074 | "sort_key f xs = sort_key f [x\<leftarrow>xs. f x < f (xs ! (length xs div 2))] | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2075 | @ [x\<leftarrow>xs. f x = f (xs ! (length xs div 2))] | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2076 | @ sort_key f [x\<leftarrow>xs. f x > f (xs ! (length xs div 2))]" (is "sort_key f ?lhs = ?rhs") | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2077 | proof (rule properties_for_sort_key) | 
| 60515 | 2078 | show "mset ?rhs = mset ?lhs" | 
| 2079 | by (rule multiset_eqI) (auto simp add: mset_filter) | |
| 40303 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2080 | show "sorted (map f ?rhs)" | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2081 | by (auto simp add: sorted_append intro: sorted_map_same) | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2082 | next | 
| 40305 
41833242cc42
tuned lemma proposition of properties_for_sort_key
 haftmann parents: 
40303diff
changeset | 2083 | fix l | 
| 
41833242cc42
tuned lemma proposition of properties_for_sort_key
 haftmann parents: 
40303diff
changeset | 2084 | assume "l \<in> set ?rhs" | 
| 40346 | 2085 | let ?pivot = "f (xs ! (length xs div 2))" | 
| 2086 | have *: "\<And>x. f l = f x \<longleftrightarrow> f x = f l" by auto | |
| 40306 | 2087 | have "[x \<leftarrow> sort_key f xs . f x = f l] = [x \<leftarrow> xs. f x = f l]" | 
| 40305 
41833242cc42
tuned lemma proposition of properties_for_sort_key
 haftmann parents: 
40303diff
changeset | 2088 | unfolding filter_sort by (rule properties_for_sort_key) (auto intro: sorted_map_same) | 
| 40346 | 2089 | with * have **: "[x \<leftarrow> sort_key f xs . f l = f x] = [x \<leftarrow> xs. f l = f x]" by simp | 
| 2090 | have "\<And>x P. P (f x) ?pivot \<and> f l = f x \<longleftrightarrow> P (f l) ?pivot \<and> f l = f x" by auto | |
| 2091 | then have "\<And>P. [x \<leftarrow> sort_key f xs . P (f x) ?pivot \<and> f l = f x] = | |
| 2092 | [x \<leftarrow> sort_key f xs. P (f l) ?pivot \<and> f l = f x]" by simp | |
| 2093 | note *** = this [of "op <"] this [of "op >"] this [of "op ="] | |
| 40306 | 2094 | show "[x \<leftarrow> ?rhs. f l = f x] = [x \<leftarrow> ?lhs. f l = f x]" | 
| 40305 
41833242cc42
tuned lemma proposition of properties_for_sort_key
 haftmann parents: 
40303diff
changeset | 2095 | proof (cases "f l" ?pivot rule: linorder_cases) | 
| 46730 | 2096 | case less | 
| 2097 | then have "f l \<noteq> ?pivot" and "\<not> f l > ?pivot" by auto | |
| 2098 | with less show ?thesis | |
| 40346 | 2099 | by (simp add: filter_sort [symmetric] ** ***) | 
| 40305 
41833242cc42
tuned lemma proposition of properties_for_sort_key
 haftmann parents: 
40303diff
changeset | 2100 | next | 
| 40306 | 2101 | case equal then show ?thesis | 
| 40346 | 2102 | by (simp add: * less_le) | 
| 40305 
41833242cc42
tuned lemma proposition of properties_for_sort_key
 haftmann parents: 
40303diff
changeset | 2103 | next | 
| 46730 | 2104 | case greater | 
| 2105 | then have "f l \<noteq> ?pivot" and "\<not> f l < ?pivot" by auto | |
| 2106 | with greater show ?thesis | |
| 40346 | 2107 | by (simp add: filter_sort [symmetric] ** ***) | 
| 40306 | 2108 | qed | 
| 40303 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2109 | qed | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2110 | |
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2111 | lemma sort_by_quicksort: | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2112 | "sort xs = sort [x\<leftarrow>xs. x < xs ! (length xs div 2)] | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2113 | @ [x\<leftarrow>xs. x = xs ! (length xs div 2)] | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2114 | @ sort [x\<leftarrow>xs. x > xs ! (length xs div 2)]" (is "sort ?lhs = ?rhs") | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2115 | using sort_key_by_quicksort [of "\<lambda>x. x", symmetric] by simp | 
| 
2d507370e879
lemmas multiset_of_filter, sort_key_by_quicksort
 haftmann parents: 
40250diff
changeset | 2116 | |
| 60500 | 2117 | text \<open>A stable parametrized quicksort\<close> | 
| 40347 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2118 | |
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2119 | definition part :: "('b \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'b list \<Rightarrow> 'b list \<times> 'b list \<times> 'b list" where
 | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2120 | "part f pivot xs = ([x \<leftarrow> xs. f x < pivot], [x \<leftarrow> xs. f x = pivot], [x \<leftarrow> xs. pivot < f x])" | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2121 | |
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2122 | lemma part_code [code]: | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2123 | "part f pivot [] = ([], [], [])" | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2124 | "part f pivot (x # xs) = (let (lts, eqs, gts) = part f pivot xs; x' = f x in | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2125 | if x' < pivot then (x # lts, eqs, gts) | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2126 | else if x' > pivot then (lts, eqs, x # gts) | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2127 | else (lts, x # eqs, gts))" | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2128 | by (auto simp add: part_def Let_def split_def) | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2129 | |
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2130 | lemma sort_key_by_quicksort_code [code]: | 
| 60606 | 2131 | "sort_key f xs = | 
| 2132 | (case xs of | |
| 2133 | [] \<Rightarrow> [] | |
| 40347 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2134 | | [x] \<Rightarrow> xs | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2135 | | [x, y] \<Rightarrow> (if f x \<le> f y then xs else [y, x]) | 
| 60606 | 2136 | | _ \<Rightarrow> | 
| 2137 | let (lts, eqs, gts) = part f (f (xs ! (length xs div 2))) xs | |
| 2138 | in sort_key f lts @ eqs @ sort_key f gts)" | |
| 40347 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2139 | proof (cases xs) | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2140 | case Nil then show ?thesis by simp | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2141 | next | 
| 46921 | 2142 | case (Cons _ ys) note hyps = Cons show ?thesis | 
| 2143 | proof (cases ys) | |
| 40347 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2144 | case Nil with hyps show ?thesis by simp | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2145 | next | 
| 46921 | 2146 | case (Cons _ zs) note hyps = hyps Cons show ?thesis | 
| 2147 | proof (cases zs) | |
| 40347 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2148 | case Nil with hyps show ?thesis by auto | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2149 | next | 
| 58425 | 2150 | case Cons | 
| 40347 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2151 | from sort_key_by_quicksort [of f xs] | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2152 | have "sort_key f xs = (let (lts, eqs, gts) = part f (f (xs ! (length xs div 2))) xs | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2153 | in sort_key f lts @ eqs @ sort_key f gts)" | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2154 | by (simp only: split_def Let_def part_def fst_conv snd_conv) | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2155 | with hyps Cons show ?thesis by (simp only: list.cases) | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2156 | qed | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2157 | qed | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2158 | qed | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2159 | |
| 39533 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2160 | end | 
| 
91a0ff0ff237
generalized lemmas multiset_of_insort, multiset_of_sort, properties_for_sort for *_key variants
 haftmann parents: 
39314diff
changeset | 2161 | |
| 40347 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2162 | hide_const (open) part | 
| 
429bf4388b2f
added code lemmas for stable parametrized quicksort
 haftmann parents: 
40346diff
changeset | 2163 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2164 | lemma mset_remdups_subset_eq: "mset (remdups xs) \<subseteq># mset xs" | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 2165 | by (induct xs) (auto intro: subset_mset.order_trans) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2166 | |
| 60515 | 2167 | lemma mset_update: | 
| 2168 |   "i < length ls \<Longrightarrow> mset (ls[i := v]) = mset ls - {#ls ! i#} + {#v#}"
 | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2169 | proof (induct ls arbitrary: i) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2170 | case Nil then show ?case by simp | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2171 | next | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2172 | case (Cons x xs) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2173 | show ?case | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2174 | proof (cases i) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2175 | case 0 then show ?thesis by simp | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2176 | next | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2177 | case (Suc i') | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2178 | with Cons show ?thesis | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2179 | apply simp | 
| 57512 
cc97b347b301
reduced name variants for assoc and commute on plus and mult
 haftmann parents: 
57492diff
changeset | 2180 | apply (subst add.assoc) | 
| 
cc97b347b301
reduced name variants for assoc and commute on plus and mult
 haftmann parents: 
57492diff
changeset | 2181 |       apply (subst add.commute [of "{#v#}" "{#x#}"])
 | 
| 
cc97b347b301
reduced name variants for assoc and commute on plus and mult
 haftmann parents: 
57492diff
changeset | 2182 | apply (subst add.assoc [symmetric]) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2183 | apply simp | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2184 | apply (rule mset_subset_eq_multiset_union_diff_commute) | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2185 | apply (simp add: mset_subset_eq_single nth_mem_mset) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2186 | done | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2187 | qed | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2188 | qed | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2189 | |
| 60515 | 2190 | lemma mset_swap: | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2191 | "i < length ls \<Longrightarrow> j < length ls \<Longrightarrow> | 
| 60515 | 2192 | mset (ls[j := ls ! i, i := ls ! j]) = mset ls" | 
| 2193 | by (cases "i = j") (simp_all add: mset_update nth_mem_mset) | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2194 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2195 | |
| 60500 | 2196 | subsection \<open>The multiset order\<close> | 
| 2197 | ||
| 2198 | subsubsection \<open>Well-foundedness\<close> | |
| 10249 | 2199 | |
| 60606 | 2200 | definition mult1 :: "('a \<times> 'a) set \<Rightarrow> ('a multiset \<times> 'a multiset) set" where
 | 
| 37765 | 2201 |   "mult1 r = {(N, M). \<exists>a M0 K. M = M0 + {#a#} \<and> N = M0 + K \<and>
 | 
| 60607 | 2202 | (\<forall>b. b \<in># K \<longrightarrow> (b, a) \<in> r)}" | 
| 60606 | 2203 | |
| 2204 | definition mult :: "('a \<times> 'a) set \<Rightarrow> ('a multiset \<times> 'a multiset) set" where
 | |
| 37765 | 2205 | "mult r = (mult1 r)\<^sup>+" | 
| 10249 | 2206 | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2207 | lemma mult1I: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2208 |   assumes "M = M0 + {#a#}" and "N = M0 + K" and "\<And>b. b \<in># K \<Longrightarrow> (b, a) \<in> r"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2209 | shows "(N, M) \<in> mult1 r" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2210 | using assms unfolding mult1_def by blast | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2211 | |
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2212 | lemma mult1E: | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2213 | assumes "(N, M) \<in> mult1 r" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2214 |   obtains a M0 K where "M = M0 + {#a#}" "N = M0 + K" "\<And>b. b \<in># K \<Longrightarrow> (b, a) \<in> r"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2215 | using assms unfolding mult1_def by blast | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2216 | |
| 63660 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2217 | lemma mono_mult1: | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2218 | assumes "r \<subseteq> r'" shows "mult1 r \<subseteq> mult1 r'" | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2219 | unfolding mult1_def using assms by blast | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2220 | |
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2221 | lemma mono_mult: | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2222 | assumes "r \<subseteq> r'" shows "mult r \<subseteq> mult r'" | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2223 | unfolding mult_def using mono_mult1[OF assms] trancl_mono by blast | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2224 | |
| 23751 | 2225 | lemma not_less_empty [iff]: "(M, {#}) \<notin> mult1 r"
 | 
| 26178 | 2226 | by (simp add: mult1_def) | 
| 10249 | 2227 | |
| 60608 | 2228 | lemma less_add: | 
| 2229 |   assumes mult1: "(N, M0 + {#a#}) \<in> mult1 r"
 | |
| 2230 | shows | |
| 2231 |     "(\<exists>M. (M, M0) \<in> mult1 r \<and> N = M + {#a#}) \<or>
 | |
| 2232 | (\<exists>K. (\<forall>b. b \<in># K \<longrightarrow> (b, a) \<in> r) \<and> N = M0 + K)" | |
| 2233 | proof - | |
| 60607 | 2234 | let ?r = "\<lambda>K a. \<forall>b. b \<in># K \<longrightarrow> (b, a) \<in> r" | 
| 11464 | 2235 |   let ?R = "\<lambda>N M. \<exists>a M0 K. M = M0 + {#a#} \<and> N = M0 + K \<and> ?r K a"
 | 
| 60608 | 2236 |   obtain a' M0' K where M0: "M0 + {#a#} = M0' + {#a'#}"
 | 
| 2237 | and N: "N = M0' + K" | |
| 2238 | and r: "?r K a'" | |
| 2239 | using mult1 unfolding mult1_def by auto | |
| 2240 | show ?thesis (is "?case1 \<or> ?case2") | |
| 60606 | 2241 | proof - | 
| 2242 | from M0 consider "M0 = M0'" "a = a'" | |
| 2243 |       | K' where "M0 = K' + {#a'#}" "M0' = K' + {#a#}"
 | |
| 2244 | by atomize_elim (simp only: add_eq_conv_ex) | |
| 18258 | 2245 | then show ?thesis | 
| 60606 | 2246 | proof cases | 
| 2247 | case 1 | |
| 11464 | 2248 | with N r have "?r K a \<and> N = M0 + K" by simp | 
| 60606 | 2249 | then have ?case2 .. | 
| 2250 | then show ?thesis .. | |
| 10249 | 2251 | next | 
| 60606 | 2252 | case 2 | 
| 2253 |       from N 2(2) have n: "N = K' + K + {#a#}" by (simp add: ac_simps)
 | |
| 2254 | with r 2(1) have "?R (K' + K) M0" by blast | |
| 60608 | 2255 | with n have ?case1 by (simp add: mult1_def) | 
| 60606 | 2256 | then show ?thesis .. | 
| 10249 | 2257 | qed | 
| 2258 | qed | |
| 2259 | qed | |
| 2260 | ||
| 60608 | 2261 | lemma all_accessible: | 
| 2262 | assumes "wf r" | |
| 2263 | shows "\<forall>M. M \<in> Wellfounded.acc (mult1 r)" | |
| 10249 | 2264 | proof | 
| 2265 | let ?R = "mult1 r" | |
| 54295 | 2266 | let ?W = "Wellfounded.acc ?R" | 
| 10249 | 2267 |   {
 | 
| 2268 | fix M M0 a | |
| 23751 | 2269 | assume M0: "M0 \<in> ?W" | 
| 60606 | 2270 |       and wf_hyp: "\<And>b. (b, a) \<in> r \<Longrightarrow> (\<forall>M \<in> ?W. M + {#b#} \<in> ?W)"
 | 
| 2271 |       and acc_hyp: "\<forall>M. (M, M0) \<in> ?R \<longrightarrow> M + {#a#} \<in> ?W"
 | |
| 23751 | 2272 |     have "M0 + {#a#} \<in> ?W"
 | 
| 2273 |     proof (rule accI [of "M0 + {#a#}"])
 | |
| 10249 | 2274 | fix N | 
| 23751 | 2275 |       assume "(N, M0 + {#a#}) \<in> ?R"
 | 
| 60608 | 2276 |       then consider M where "(M, M0) \<in> ?R" "N = M + {#a#}"
 | 
| 2277 | | K where "\<forall>b. b \<in># K \<longrightarrow> (b, a) \<in> r" "N = M0 + K" | |
| 2278 | by atomize_elim (rule less_add) | |
| 23751 | 2279 | then show "N \<in> ?W" | 
| 60608 | 2280 | proof cases | 
| 2281 | case 1 | |
| 60606 | 2282 |         from acc_hyp have "(M, M0) \<in> ?R \<longrightarrow> M + {#a#} \<in> ?W" ..
 | 
| 60500 | 2283 |         from this and \<open>(M, M0) \<in> ?R\<close> have "M + {#a#} \<in> ?W" ..
 | 
| 60608 | 2284 |         then show "N \<in> ?W" by (simp only: \<open>N = M + {#a#}\<close>)
 | 
| 10249 | 2285 | next | 
| 60608 | 2286 | case 2 | 
| 2287 | from this(1) have "M0 + K \<in> ?W" | |
| 10249 | 2288 | proof (induct K) | 
| 18730 | 2289 | case empty | 
| 23751 | 2290 |           from M0 show "M0 + {#} \<in> ?W" by simp
 | 
| 18730 | 2291 | next | 
| 2292 | case (add K x) | |
| 23751 | 2293 | from add.prems have "(x, a) \<in> r" by simp | 
| 2294 |           with wf_hyp have "\<forall>M \<in> ?W. M + {#x#} \<in> ?W" by blast
 | |
| 2295 | moreover from add have "M0 + K \<in> ?W" by simp | |
| 2296 |           ultimately have "(M0 + K) + {#x#} \<in> ?W" ..
 | |
| 57512 
cc97b347b301
reduced name variants for assoc and commute on plus and mult
 haftmann parents: 
57492diff
changeset | 2297 |           then show "M0 + (K + {#x#}) \<in> ?W" by (simp only: add.assoc)
 | 
| 10249 | 2298 | qed | 
| 60608 | 2299 | then show "N \<in> ?W" by (simp only: 2(2)) | 
| 10249 | 2300 | qed | 
| 2301 | qed | |
| 2302 | } note tedious_reasoning = this | |
| 2303 | ||
| 60608 | 2304 | show "M \<in> ?W" for M | 
| 10249 | 2305 | proof (induct M) | 
| 23751 | 2306 |     show "{#} \<in> ?W"
 | 
| 10249 | 2307 | proof (rule accI) | 
| 23751 | 2308 |       fix b assume "(b, {#}) \<in> ?R"
 | 
| 2309 | with not_less_empty show "b \<in> ?W" by contradiction | |
| 10249 | 2310 | qed | 
| 2311 | ||
| 23751 | 2312 | fix M a assume "M \<in> ?W" | 
| 60608 | 2313 |     from \<open>wf r\<close> have "\<forall>M \<in> ?W. M + {#a#} \<in> ?W"
 | 
| 10249 | 2314 | proof induct | 
| 2315 | fix a | |
| 60606 | 2316 |       assume r: "\<And>b. (b, a) \<in> r \<Longrightarrow> (\<forall>M \<in> ?W. M + {#b#} \<in> ?W)"
 | 
| 23751 | 2317 |       show "\<forall>M \<in> ?W. M + {#a#} \<in> ?W"
 | 
| 10249 | 2318 | proof | 
| 23751 | 2319 | fix M assume "M \<in> ?W" | 
| 2320 |         then show "M + {#a#} \<in> ?W"
 | |
| 23373 | 2321 | by (rule acc_induct) (rule tedious_reasoning [OF _ r]) | 
| 10249 | 2322 | qed | 
| 2323 | qed | |
| 60500 | 2324 |     from this and \<open>M \<in> ?W\<close> show "M + {#a#} \<in> ?W" ..
 | 
| 10249 | 2325 | qed | 
| 2326 | qed | |
| 2327 | ||
| 60606 | 2328 | theorem wf_mult1: "wf r \<Longrightarrow> wf (mult1 r)" | 
| 26178 | 2329 | by (rule acc_wfI) (rule all_accessible) | 
| 10249 | 2330 | |
| 60606 | 2331 | theorem wf_mult: "wf r \<Longrightarrow> wf (mult r)" | 
| 26178 | 2332 | unfolding mult_def by (rule wf_trancl) (rule wf_mult1) | 
| 10249 | 2333 | |
| 2334 | ||
| 60500 | 2335 | subsubsection \<open>Closure-free presentation\<close> | 
| 2336 | ||
| 2337 | text \<open>One direction.\<close> | |
| 10249 | 2338 | |
| 2339 | lemma mult_implies_one_step: | |
| 60606 | 2340 | "trans r \<Longrightarrow> (M, N) \<in> mult r \<Longrightarrow> | 
| 11464 | 2341 |     \<exists>I J K. N = I + J \<and> M = I + K \<and> J \<noteq> {#} \<and>
 | 
| 60495 | 2342 | (\<forall>k \<in> set_mset K. \<exists>j \<in> set_mset J. (k, j) \<in> r)" | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2343 | apply (unfold mult_def mult1_def) | 
| 26178 | 2344 | apply (erule converse_trancl_induct, clarify) | 
| 2345 | apply (rule_tac x = M0 in exI, simp, clarify) | |
| 60607 | 2346 | apply (case_tac "a \<in># K") | 
| 26178 | 2347 | apply (rule_tac x = I in exI) | 
| 2348 | apply (simp (no_asm)) | |
| 2349 |  apply (rule_tac x = "(K - {#a#}) + Ka" in exI)
 | |
| 57512 
cc97b347b301
reduced name variants for assoc and commute on plus and mult
 haftmann parents: 
57492diff
changeset | 2350 | apply (simp (no_asm_simp) add: add.assoc [symmetric]) | 
| 59807 | 2351 |  apply (drule_tac f = "\<lambda>M. M - {#a#}" and x="S + T" for S T in arg_cong)
 | 
| 26178 | 2352 | apply (simp add: diff_union_single_conv) | 
| 2353 | apply (simp (no_asm_use) add: trans_def) | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2354 | apply (metis (no_types, hide_lams) Multiset.diff_right_commute Un_iff diff_single_trivial multi_drop_mem_not_eq) | 
| 60607 | 2355 | apply (subgoal_tac "a \<in># I") | 
| 26178 | 2356 |  apply (rule_tac x = "I - {#a#}" in exI)
 | 
| 2357 |  apply (rule_tac x = "J + {#a#}" in exI)
 | |
| 2358 | apply (rule_tac x = "K + Ka" in exI) | |
| 2359 | apply (rule conjI) | |
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 2360 | apply (simp add: multiset_eq_iff split: nat_diff_split) | 
| 26178 | 2361 | apply (rule conjI) | 
| 59807 | 2362 |   apply (drule_tac f = "\<lambda>M. M - {#a#}" and x="S + T" for S T in arg_cong, simp)
 | 
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 2363 | apply (simp add: multiset_eq_iff split: nat_diff_split) | 
| 26178 | 2364 | apply (simp (no_asm_use) add: trans_def) | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2365 | apply (subgoal_tac "a \<in># (M0 + {#a#})")
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2366 | apply (simp_all add: not_in_iff) | 
| 26178 | 2367 | apply blast | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2368 | apply (metis add.comm_neutral add_diff_cancel_right' count_eq_zero_iff diff_single_trivial multi_self_add_other_not_self plus_multiset.rep_eq) | 
| 26178 | 2369 | done | 
| 10249 | 2370 | |
| 2371 | lemma one_step_implies_mult_aux: | |
| 60678 | 2372 |   "\<forall>I J K. size J = n \<and> J \<noteq> {#} \<and> (\<forall>k \<in> set_mset K. \<exists>j \<in> set_mset J. (k, j) \<in> r)
 | 
| 2373 | \<longrightarrow> (I + K, I + J) \<in> mult r" | |
| 2374 | apply (induct n) | |
| 2375 | apply auto | |
| 26178 | 2376 | apply (frule size_eq_Suc_imp_eq_union, clarify) | 
| 2377 | apply (rename_tac "J'", simp) | |
| 2378 | apply (erule notE, auto) | |
| 2379 | apply (case_tac "J' = {#}")
 | |
| 2380 | apply (simp add: mult_def) | |
| 2381 | apply (rule r_into_trancl) | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2382 | apply (simp add: mult1_def, blast) | 
| 60500 | 2383 | txt \<open>Now we know @{term "J' \<noteq> {#}"}.\<close>
 | 
| 26178 | 2384 | apply (cut_tac M = K and P = "\<lambda>x. (x, a) \<in> r" in multiset_partition) | 
| 60495 | 2385 | apply (erule_tac P = "\<forall>k \<in> set_mset K. P k" for P in rev_mp) | 
| 26178 | 2386 | apply (erule ssubst) | 
| 2387 | apply (simp add: Ball_def, auto) | |
| 2388 | apply (subgoal_tac | |
| 60607 | 2389 |   "((I + {# x \<in># K. (x, a) \<in> r #}) + {# x \<in># K. (x, a) \<notin> r #},
 | 
| 2390 |     (I + {# x \<in># K. (x, a) \<in> r #}) + J') \<in> mult r")
 | |
| 26178 | 2391 | prefer 2 | 
| 2392 | apply force | |
| 57512 
cc97b347b301
reduced name variants for assoc and commute on plus and mult
 haftmann parents: 
57492diff
changeset | 2393 | apply (simp (no_asm_use) add: add.assoc [symmetric] mult_def) | 
| 26178 | 2394 | apply (erule trancl_trans) | 
| 2395 | apply (rule r_into_trancl) | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2396 | apply (simp add: mult1_def) | 
| 26178 | 2397 | apply (rule_tac x = a in exI) | 
| 2398 | apply (rule_tac x = "I + J'" in exI) | |
| 57514 
bdc2c6b40bf2
prefer ac_simps collections over separate name bindings for add and mult
 haftmann parents: 
57512diff
changeset | 2399 | apply (simp add: ac_simps) | 
| 26178 | 2400 | done | 
| 10249 | 2401 | |
| 17161 | 2402 | lemma one_step_implies_mult: | 
| 62651 | 2403 |   "J \<noteq> {#} \<Longrightarrow> \<forall>k \<in> set_mset K. \<exists>j \<in> set_mset J. (k, j) \<in> r
 | 
| 60606 | 2404 | \<Longrightarrow> (I + K, I + J) \<in> mult r" | 
| 26178 | 2405 | using one_step_implies_mult_aux by blast | 
| 10249 | 2406 | |
| 63660 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2407 | |
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2408 | subsection \<open>The multiset extension is cancellative for multiset union\<close> | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2409 | |
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2410 | lemma mult_cancel: | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2411 | assumes "trans s" and "irrefl s" | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2412 | shows "(X + Z, Y + Z) \<in> mult s \<longleftrightarrow> (X, Y) \<in> mult s" (is "?L \<longleftrightarrow> ?R") | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2413 | proof | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2414 | assume ?L thus ?R | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2415 | proof (induct Z) | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2416 | case (add Z z) | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2417 |     obtain X' Y' Z' where *: "X + Z + {#z#} = Z' + X'" "Y + Z + {#z#} = Z' + Y'" "Y' \<noteq> {#}"
 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2418 | "\<forall>x \<in> set_mset X'. \<exists>y \<in> set_mset Y'. (x, y) \<in> s" | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2419 | using mult_implies_one_step[OF `trans s` add(2)] unfolding add.assoc by blast | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2420 |     consider Z2 where "Z' = Z2 + {#z#}" | X2 Y2 where "X' = X2 + {#z#}" "Y' = Y2 + {#z#}"
 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2421 | using *(1,2) by (metis mset_add union_iff union_single_eq_member) | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2422 | thus ?case | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2423 | proof (cases) | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2424 | case 1 thus ?thesis using * one_step_implies_mult[of Y' X' s Z2] | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2425 |         by (auto simp: add.commute[of _ "{#_#}"] add.assoc intro: add(1))
 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2426 | next | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2427 | case 2 then obtain y where "y \<in> set_mset Y2" "(z, y) \<in> s" using *(4) `irrefl s` | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2428 | by (auto simp: irrefl_def) | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2429 | moreover from this transD[OF `trans s` _ this(2)] | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2430 | have "x' \<in> set_mset X2 \<Longrightarrow> \<exists>y \<in> set_mset Y2. (x', y) \<in> s" for x' | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2431 | using 2 *(4)[rule_format, of x'] by auto | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2432 | ultimately show ?thesis using * one_step_implies_mult[of Y2 X2 s Z'] 2 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2433 |         by (force simp: add.commute[of "{#_#}"] add.assoc[symmetric] intro: add(1))
 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2434 | qed | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2435 | qed auto | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2436 | next | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2437 | assume ?R then obtain I J K | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2438 |     where "Y = I + J" "X = I + K" "J \<noteq> {#}" "\<forall>k \<in> set_mset K. \<exists>j \<in> set_mset J. (k, j) \<in> s"
 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2439 | using mult_implies_one_step[OF `trans s`] by blast | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2440 | thus ?L using one_step_implies_mult[of J K s "I + Z"] by (auto simp: ac_simps) | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2441 | qed | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2442 | |
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2443 | lemma mult_cancel_max: | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2444 | assumes "trans s" and "irrefl s" | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2445 | shows "(X, Y) \<in> mult s \<longleftrightarrow> (X - X #\<inter> Y, Y - X #\<inter> Y) \<in> mult s" (is "?L \<longleftrightarrow> ?R") | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2446 | proof - | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2447 | have "X - X #\<inter> Y + X #\<inter> Y = X" "Y - X #\<inter> Y + X #\<inter> Y = Y" by (auto simp: count_inject[symmetric]) | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2448 | thus ?thesis using mult_cancel[OF assms, of "X - X #\<inter> Y" "X #\<inter> Y" "Y - X #\<inter> Y"] by auto | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2449 | qed | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2450 | |
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2451 | |
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2452 | subsection \<open>Quasi-executable version of the multiset extension\<close> | 
| 63088 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2453 | |
| 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2454 | text \<open> | 
| 63660 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2455 | Predicate variants of \<open>mult\<close> and the reflexive closure of \<open>mult\<close>, which are | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2456 | executable whenever the given predicate \<open>P\<close> is. Together with the standard | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2457 | code equations for \<open>op #\<inter>\<close> and \<open>op -\<close> this should yield quadratic | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2458 | (with respect to calls to \<open>P\<close>) implementations of \<open>multp\<close> and \<open>multeqp\<close>. | 
| 63088 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2459 | \<close> | 
| 63660 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2460 | |
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2461 | definition multp :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool" where
 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2462 | "multp P N M = | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2463 | (let Z = M #\<inter> N; X = M - Z in | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2464 |     X \<noteq> {#} \<and> (let Y = N - Z in (\<forall>y \<in> set_mset Y. \<exists>x \<in> set_mset X. P y x)))"
 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2465 | |
| 63088 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2466 | definition multeqp :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool" where
 | 
| 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2467 | "multeqp P N M = | 
| 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2468 | (let Z = M #\<inter> N; X = M - Z; Y = N - Z in | 
| 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2469 | (\<forall>y \<in> set_mset Y. \<exists>x \<in> set_mset X. P y x))" | 
| 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2470 | |
| 63660 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2471 | lemma multp_iff: | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2472 | assumes "irrefl R" and "trans R" and [simp]: "\<And>x y. P x y \<longleftrightarrow> (x, y) \<in> R" | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2473 | shows "multp P N M \<longleftrightarrow> (N, M) \<in> mult R" (is "?L \<longleftrightarrow> ?R") | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2474 | proof - | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2475 | have *: "M #\<inter> N + (N - M #\<inter> N) = N" "M #\<inter> N + (M - M #\<inter> N) = M" | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2476 |     "(M - M #\<inter> N) #\<inter> (N - M #\<inter> N) = {#}" by (auto simp: count_inject[symmetric])
 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2477 | show ?thesis | 
| 63088 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2478 | proof | 
| 63660 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2479 | assume ?L thus ?R | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2480 | using one_step_implies_mult[of "M - M #\<inter> N" "N - M #\<inter> N" R "M #\<inter> N"] * | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2481 | by (auto simp: multp_def Let_def) | 
| 63088 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2482 | next | 
| 63660 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2483 |     { fix I J K :: "'a multiset" assume "(I + J) #\<inter> (I + K) = {#}"
 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2484 |       then have "I = {#}" by (metis inter_union_distrib_right union_eq_empty)
 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2485 | } note [dest!] = this | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2486 | assume ?R thus ?L | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2487 | using mult_implies_one_step[OF assms(2), of "N - M #\<inter> N" "M - M #\<inter> N"] | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2488 | mult_cancel_max[OF assms(2,1), of "N" "M"] * by (auto simp: multp_def ac_simps) | 
| 63088 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2489 | qed | 
| 63660 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2490 | qed | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2491 | |
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2492 | lemma multeqp_iff: | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2493 | assumes "irrefl R" and "trans R" and "\<And>x y. P x y \<longleftrightarrow> (x, y) \<in> R" | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2494 | shows "multeqp P N M \<longleftrightarrow> (N, M) \<in> (mult R)\<^sup>=" | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2495 | proof - | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2496 |   { assume "N \<noteq> M" "M - M #\<inter> N = {#}"
 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2497 | then obtain y where "count N y \<noteq> count M y" by (auto simp: count_inject[symmetric]) | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2498 |     then have "\<exists>y. count M y < count N y" using `M - M #\<inter> N = {#}`
 | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2499 | by (auto simp: count_inject[symmetric] dest!: le_neq_implies_less fun_cong[of _ _ y]) | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2500 | } | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2501 | then have "multeqp P N M \<longleftrightarrow> multp P N M \<or> N = M" | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2502 | by (auto simp: multeqp_def multp_def Let_def in_diff_count) | 
| 
76302202a92d
add monotonicity propertyies of `mult1` and `mult`
 Bertram Felgenhauer <bertram.felgenhauer@uibk.ac.at> parents: 
63560diff
changeset | 2503 | thus ?thesis using multp_iff[OF assms] by simp | 
| 63088 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2504 | qed | 
| 
f2177f5d2aed
a quasi-recursive characterization of the multiset order (by Christian Sternagel)
 haftmann parents: 
63060diff
changeset | 2505 | |
| 10249 | 2506 | |
| 60500 | 2507 | subsubsection \<open>Partial-order properties\<close> | 
| 10249 | 2508 | |
| 63410 
9789ccc2a477
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63409diff
changeset | 2509 | lemma (in preorder) mult1_lessE: | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2510 |   assumes "(N, M) \<in> mult1 {(a, b). a < b}"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2511 |   obtains a M0 K where "M = M0 + {#a#}" "N = M0 + K"
 | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2512 | "a \<notin># K" "\<And>b. b \<in># K \<Longrightarrow> b < a" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2513 | proof - | 
| 63539 | 2514 |   from assms obtain a M0 K where "M = M0 + {#a#}" "N = M0 + K" and
 | 
| 2515 | *: "b \<in># K \<Longrightarrow> b < a" for b by (blast elim: mult1E) | |
| 2516 | moreover from * [of a] have "a \<notin># K" by auto | |
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2517 | ultimately show thesis by (auto intro: that) | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2518 | qed | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2519 | |
| 63410 
9789ccc2a477
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63409diff
changeset | 2520 | instantiation multiset :: (preorder) order | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2521 | begin | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2522 | |
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2523 | definition less_multiset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool" | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2524 |   where "M' < M \<longleftrightarrow> (M', M) \<in> mult {(x', x). x' < x}"
 | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2525 | |
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2526 | definition less_eq_multiset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool" | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2527 | where "less_eq_multiset M' M \<longleftrightarrow> M' < M \<or> M' = M" | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2528 | |
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2529 | instance | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2530 | proof - | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2531 | have irrefl: "\<not> M < M" for M :: "'a multiset" | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2532 | proof | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2533 | assume "M < M" | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2534 |     then have MM: "(M, M) \<in> mult {(x, y). x < y}" by (simp add: less_multiset_def)
 | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2535 |     have "trans {(x'::'a, x). x' < x}"
 | 
| 63410 
9789ccc2a477
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63409diff
changeset | 2536 | by (metis (mono_tags, lifting) case_prodD case_prodI less_trans mem_Collect_eq transI) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2537 | moreover note MM | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2538 | ultimately have "\<exists>I J K. M = I + J \<and> M = I + K | 
| 60495 | 2539 |       \<and> J \<noteq> {#} \<and> (\<forall>k\<in>set_mset K. \<exists>j\<in>set_mset J. (k, j) \<in> {(x, y). x < y})"
 | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2540 | by (rule mult_implies_one_step) | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2541 | then obtain I J K where "M = I + J" and "M = I + K" | 
| 60495 | 2542 |       and "J \<noteq> {#}" and "(\<forall>k\<in>set_mset K. \<exists>j\<in>set_mset J. (k, j) \<in> {(x, y). x < y})" by blast
 | 
| 60678 | 2543 |     then have *: "K \<noteq> {#}" and **: "\<forall>k\<in>set_mset K. \<exists>j\<in>set_mset K. k < j" by auto
 | 
| 60495 | 2544 | have "finite (set_mset K)" by simp | 
| 60678 | 2545 | moreover note ** | 
| 60495 | 2546 |     ultimately have "set_mset K = {}"
 | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2547 | by (induct rule: finite_induct) (auto intro: order_less_trans) | 
| 60678 | 2548 | with * show False by simp | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2549 | qed | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2550 | have trans: "K < M \<Longrightarrow> M < N \<Longrightarrow> K < N" for K M N :: "'a multiset" | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2551 | unfolding less_multiset_def mult_def by (blast intro: trancl_trans) | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2552 |   show "OFCLASS('a multiset, order_class)"
 | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2553 | by standard (auto simp add: less_eq_multiset_def irrefl dest: trans) | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2554 | qed | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2555 | end \<comment> \<open>FIXME avoid junk stemming from type class interpretation\<close> | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2556 | |
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2557 | lemma mset_le_irrefl [elim!]: | 
| 63410 
9789ccc2a477
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63409diff
changeset | 2558 | fixes M :: "'a::preorder multiset" | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2559 | shows "M < M \<Longrightarrow> R" | 
| 46730 | 2560 | by simp | 
| 26567 
7bcebb8c2d33
instantiation replacing primitive instance plus overloaded defs; more conservative type arities
 haftmann parents: 
26178diff
changeset | 2561 | |
| 10249 | 2562 | |
| 60500 | 2563 | subsubsection \<open>Monotonicity of multiset union\<close> | 
| 10249 | 2564 | |
| 60606 | 2565 | lemma mult1_union: "(B, D) \<in> mult1 r \<Longrightarrow> (C + B, C + D) \<in> mult1 r" | 
| 26178 | 2566 | apply (unfold mult1_def) | 
| 2567 | apply auto | |
| 2568 | apply (rule_tac x = a in exI) | |
| 2569 | apply (rule_tac x = "C + M0" in exI) | |
| 57512 
cc97b347b301
reduced name variants for assoc and commute on plus and mult
 haftmann parents: 
57492diff
changeset | 2570 | apply (simp add: add.assoc) | 
| 26178 | 2571 | done | 
| 10249 | 2572 | |
| 63410 
9789ccc2a477
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63409diff
changeset | 2573 | lemma union_le_mono2: "B < D \<Longrightarrow> C + B < C + (D::'a::preorder multiset)" | 
| 26178 | 2574 | apply (unfold less_multiset_def mult_def) | 
| 2575 | apply (erule trancl_induct) | |
| 40249 
cd404ecb9107
Remove unnecessary premise of mult1_union
 Lars Noschinski <noschinl@in.tum.de> parents: 
39533diff
changeset | 2576 | apply (blast intro: mult1_union) | 
| 
cd404ecb9107
Remove unnecessary premise of mult1_union
 Lars Noschinski <noschinl@in.tum.de> parents: 
39533diff
changeset | 2577 | apply (blast intro: mult1_union trancl_trans) | 
| 26178 | 2578 | done | 
| 10249 | 2579 | |
| 63410 
9789ccc2a477
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63409diff
changeset | 2580 | lemma union_le_mono1: "B < D \<Longrightarrow> B + C < D + (C::'a::preorder multiset)" | 
| 57512 
cc97b347b301
reduced name variants for assoc and commute on plus and mult
 haftmann parents: 
57492diff
changeset | 2581 | apply (subst add.commute [of B C]) | 
| 
cc97b347b301
reduced name variants for assoc and commute on plus and mult
 haftmann parents: 
57492diff
changeset | 2582 | apply (subst add.commute [of D C]) | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2583 | apply (erule union_le_mono2) | 
| 26178 | 2584 | done | 
| 10249 | 2585 | |
| 17161 | 2586 | lemma union_less_mono: | 
| 63410 
9789ccc2a477
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63409diff
changeset | 2587 | fixes A B C D :: "'a::preorder multiset" | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2588 | shows "A < C \<Longrightarrow> B < D \<Longrightarrow> A + B < C + D" | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2589 | by (blast intro!: union_le_mono1 union_le_mono2 less_trans) | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2590 | |
| 63410 
9789ccc2a477
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63409diff
changeset | 2591 | instantiation multiset :: (preorder) ordered_ab_semigroup_add | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2592 | begin | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2593 | instance | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2594 | by standard (auto simp add: less_eq_multiset_def intro: union_le_mono2) | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2595 | end | 
| 15072 | 2596 | |
| 63409 
3f3223b90239
moved lemmas and locales around (with minor incompatibilities)
 blanchet parents: 
63388diff
changeset | 2597 | |
| 60500 | 2598 | subsubsection \<open>Termination proofs with multiset orders\<close> | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2599 | |
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2600 | lemma multi_member_skip: "x \<in># XS \<Longrightarrow> x \<in># {# y #} + XS"
 | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2601 |   and multi_member_this: "x \<in># {# x #} + XS"
 | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2602 |   and multi_member_last: "x \<in># {# x #}"
 | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2603 | by auto | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2604 | |
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2605 | definition "ms_strict = mult pair_less" | 
| 37765 | 2606 | definition "ms_weak = ms_strict \<union> Id" | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2607 | |
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2608 | lemma ms_reduction_pair: "reduction_pair (ms_strict, ms_weak)" | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2609 | unfolding reduction_pair_def ms_strict_def ms_weak_def pair_less_def | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2610 | by (auto intro: wf_mult1 wf_trancl simp: mult_def) | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2611 | |
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2612 | lemma smsI: | 
| 60495 | 2613 | "(set_mset A, set_mset B) \<in> max_strict \<Longrightarrow> (Z + A, Z + B) \<in> ms_strict" | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2614 | unfolding ms_strict_def | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2615 | by (rule one_step_implies_mult) (auto simp add: max_strict_def pair_less_def elim!:max_ext.cases) | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2616 | |
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2617 | lemma wmsI: | 
| 60495 | 2618 |   "(set_mset A, set_mset B) \<in> max_strict \<or> A = {#} \<and> B = {#}
 | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2619 | \<Longrightarrow> (Z + A, Z + B) \<in> ms_weak" | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2620 | unfolding ms_weak_def ms_strict_def | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2621 | by (auto simp add: pair_less_def max_strict_def elim!:max_ext.cases intro: one_step_implies_mult) | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2622 | |
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2623 | inductive pw_leq | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2624 | where | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2625 |   pw_leq_empty: "pw_leq {#} {#}"
 | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2626 | | pw_leq_step:  "\<lbrakk>(x,y) \<in> pair_leq; pw_leq X Y \<rbrakk> \<Longrightarrow> pw_leq ({#x#} + X) ({#y#} + Y)"
 | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2627 | |
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2628 | lemma pw_leq_lstep: | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2629 |   "(x, y) \<in> pair_leq \<Longrightarrow> pw_leq {#x#} {#y#}"
 | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2630 | by (drule pw_leq_step) (rule pw_leq_empty, simp) | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2631 | |
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2632 | lemma pw_leq_split: | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2633 | assumes "pw_leq X Y" | 
| 60495 | 2634 |   shows "\<exists>A B Z. X = A + Z \<and> Y = B + Z \<and> ((set_mset A, set_mset B) \<in> max_strict \<or> (B = {#} \<and> A = {#}))"
 | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2635 | using assms | 
| 60606 | 2636 | proof induct | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2637 | case pw_leq_empty thus ?case by auto | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2638 | next | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2639 | case (pw_leq_step x y X Y) | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2640 | then obtain A B Z where | 
| 58425 | 2641 | [simp]: "X = A + Z" "Y = B + Z" | 
| 60495 | 2642 |       and 1[simp]: "(set_mset A, set_mset B) \<in> max_strict \<or> (B = {#} \<and> A = {#})"
 | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2643 | by auto | 
| 60606 | 2644 | from pw_leq_step consider "x = y" | "(x, y) \<in> pair_less" | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2645 | unfolding pair_leq_def by auto | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2646 | thus ?case | 
| 60606 | 2647 | proof cases | 
| 2648 | case [simp]: 1 | |
| 2649 |     have "{#x#} + X = A + ({#y#}+Z) \<and> {#y#} + Y = B + ({#y#}+Z) \<and>
 | |
| 2650 |       ((set_mset A, set_mset B) \<in> max_strict \<or> (B = {#} \<and> A = {#}))"
 | |
| 57514 
bdc2c6b40bf2
prefer ac_simps collections over separate name bindings for add and mult
 haftmann parents: 
57512diff
changeset | 2651 | by (auto simp: ac_simps) | 
| 60606 | 2652 | thus ?thesis by blast | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2653 | next | 
| 60606 | 2654 | case 2 | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2655 |     let ?A' = "{#x#} + A" and ?B' = "{#y#} + B"
 | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2656 |     have "{#x#} + X = ?A' + Z"
 | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2657 |       "{#y#} + Y = ?B' + Z"
 | 
| 57514 
bdc2c6b40bf2
prefer ac_simps collections over separate name bindings for add and mult
 haftmann parents: 
57512diff
changeset | 2658 | by (auto simp add: ac_simps) | 
| 58425 | 2659 | moreover have | 
| 60495 | 2660 | "(set_mset ?A', set_mset ?B') \<in> max_strict" | 
| 60606 | 2661 | using 1 2 unfolding max_strict_def | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2662 | by (auto elim!: max_ext.cases) | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2663 | ultimately show ?thesis by blast | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2664 | qed | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2665 | qed | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2666 | |
| 58425 | 2667 | lemma | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2668 | assumes pwleq: "pw_leq Z Z'" | 
| 60495 | 2669 | shows ms_strictI: "(set_mset A, set_mset B) \<in> max_strict \<Longrightarrow> (Z + A, Z' + B) \<in> ms_strict" | 
| 60606 | 2670 | and ms_weakI1: "(set_mset A, set_mset B) \<in> max_strict \<Longrightarrow> (Z + A, Z' + B) \<in> ms_weak" | 
| 2671 |     and ms_weakI2:  "(Z + {#}, Z' + {#}) \<in> ms_weak"
 | |
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2672 | proof - | 
| 58425 | 2673 | from pw_leq_split[OF pwleq] | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2674 | obtain A' B' Z'' | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2675 | where [simp]: "Z = A' + Z''" "Z' = B' + Z''" | 
| 60495 | 2676 |     and mx_or_empty: "(set_mset A', set_mset B') \<in> max_strict \<or> (A' = {#} \<and> B' = {#})"
 | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2677 | by blast | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2678 |   {
 | 
| 60495 | 2679 | assume max: "(set_mset A, set_mset B) \<in> max_strict" | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2680 | from mx_or_empty | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2681 | have "(Z'' + (A + A'), Z'' + (B + B')) \<in> ms_strict" | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2682 | proof | 
| 60495 | 2683 | assume max': "(set_mset A', set_mset B') \<in> max_strict" | 
| 2684 | with max have "(set_mset (A + A'), set_mset (B + B')) \<in> max_strict" | |
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2685 | by (auto simp: max_strict_def intro: max_ext_additive) | 
| 58425 | 2686 | thus ?thesis by (rule smsI) | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2687 | next | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2688 |       assume [simp]: "A' = {#} \<and> B' = {#}"
 | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2689 | show ?thesis by (rule smsI) (auto intro: max) | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2690 | qed | 
| 60606 | 2691 | thus "(Z + A, Z' + B) \<in> ms_strict" by (simp add: ac_simps) | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2692 | thus "(Z + A, Z' + B) \<in> ms_weak" by (simp add: ms_weak_def) | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2693 | } | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2694 | from mx_or_empty | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2695 | have "(Z'' + A', Z'' + B') \<in> ms_weak" by (rule wmsI) | 
| 57514 
bdc2c6b40bf2
prefer ac_simps collections over separate name bindings for add and mult
 haftmann parents: 
57512diff
changeset | 2696 |   thus "(Z + {#}, Z' + {#}) \<in> ms_weak" by (simp add:ac_simps)
 | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2697 | qed | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2698 | |
| 39301 | 2699 | lemma empty_neutral: "{#} + x = x" "x + {#} = x"
 | 
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2700 | and nonempty_plus: "{# x #} + rs \<noteq> {#}"
 | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2701 | and nonempty_single: "{# x #} \<noteq> {#}"
 | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2702 | by auto | 
| 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2703 | |
| 60500 | 2704 | setup \<open> | 
| 60606 | 2705 | let | 
| 2706 |     fun msetT T = Type (@{type_name multiset}, [T]);
 | |
| 2707 | ||
| 2708 |     fun mk_mset T [] = Const (@{const_abbrev Mempty}, msetT T)
 | |
| 2709 |       | mk_mset T [x] = Const (@{const_name single}, T --> msetT T) $ x
 | |
| 2710 | | mk_mset T (x :: xs) = | |
| 2711 |             Const (@{const_name plus}, msetT T --> msetT T --> msetT T) $
 | |
| 2712 | mk_mset T [x] $ mk_mset T xs | |
| 2713 | ||
| 60752 | 2714 | fun mset_member_tac ctxt m i = | 
| 60606 | 2715 | if m <= 0 then | 
| 60752 | 2716 |         resolve_tac ctxt @{thms multi_member_this} i ORELSE
 | 
| 2717 |         resolve_tac ctxt @{thms multi_member_last} i
 | |
| 60606 | 2718 | else | 
| 60752 | 2719 |         resolve_tac ctxt @{thms multi_member_skip} i THEN mset_member_tac ctxt (m - 1) i
 | 
| 2720 | ||
| 2721 | fun mset_nonempty_tac ctxt = | |
| 2722 |       resolve_tac ctxt @{thms nonempty_plus} ORELSE'
 | |
| 2723 |       resolve_tac ctxt @{thms nonempty_single}
 | |
| 29125 
d41182a8135c
method "sizechange" proves termination of functions; added more infrastructure for termination proofs
 krauss parents: 
28823diff
changeset | 2724 | |
| 60606 | 2725 | fun regroup_munion_conv ctxt = | 
| 2726 |       Function_Lib.regroup_conv ctxt @{const_abbrev Mempty} @{const_name plus}
 | |
| 2727 |         (map (fn t => t RS eq_reflection) (@{thms ac_simps} @ @{thms empty_neutral}))
 | |
| 2728 | ||
| 60752 | 2729 | fun unfold_pwleq_tac ctxt i = | 
| 2730 |       (resolve_tac ctxt @{thms pw_leq_step} i THEN (fn st => unfold_pwleq_tac ctxt (i + 1) st))
 | |
| 2731 |         ORELSE (resolve_tac ctxt @{thms pw_leq_lstep} i)
 | |
| 2732 |         ORELSE (resolve_tac ctxt @{thms pw_leq_empty} i)
 | |
| 60606 | 2733 | |
| 2734 |     val set_mset_simps = [@{thm set_mset_empty}, @{thm set_mset_single}, @{thm set_mset_union},
 | |
| 2735 |                         @{thm Un_insert_left}, @{thm Un_empty_left}]
 | |
| 2736 | in | |
| 2737 | ScnpReconstruct.multiset_setup (ScnpReconstruct.Multiset | |
| 2738 |     {
 | |
| 2739 | msetT=msetT, mk_mset=mk_mset, mset_regroup_conv=regroup_munion_conv, | |
| 2740 | mset_member_tac=mset_member_tac, mset_nonempty_tac=mset_nonempty_tac, | |
| 2741 | mset_pwleq_tac=unfold_pwleq_tac, set_of_simps=set_mset_simps, | |
| 2742 |       smsI'= @{thm ms_strictI}, wmsI2''= @{thm ms_weakI2}, wmsI1= @{thm ms_weakI1},
 | |
| 60752 | 2743 |       reduction_pair = @{thm ms_reduction_pair}
 | 
| 60606 | 2744 | }) | 
| 2745 | end | |
| 60500 | 2746 | \<close> | 
| 2747 | ||
| 2748 | ||
| 2749 | subsection \<open>Legacy theorem bindings\<close> | |
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2750 | |
| 39302 
d7728f65b353
renamed lemmas: ext_iff -> fun_eq_iff, set_ext_iff -> set_eq_iff, set_ext -> set_eqI
 nipkow parents: 
39301diff
changeset | 2751 | lemmas multi_count_eq = multiset_eq_iff [symmetric] | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2752 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2753 | lemma union_commute: "M + N = N + (M::'a multiset)" | 
| 57512 
cc97b347b301
reduced name variants for assoc and commute on plus and mult
 haftmann parents: 
57492diff
changeset | 2754 | by (fact add.commute) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2755 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2756 | lemma union_assoc: "(M + N) + K = M + (N + (K::'a multiset))" | 
| 57512 
cc97b347b301
reduced name variants for assoc and commute on plus and mult
 haftmann parents: 
57492diff
changeset | 2757 | by (fact add.assoc) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2758 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2759 | lemma union_lcomm: "M + (N + K) = N + (M + (K::'a multiset))" | 
| 57512 
cc97b347b301
reduced name variants for assoc and commute on plus and mult
 haftmann parents: 
57492diff
changeset | 2760 | by (fact add.left_commute) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2761 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2762 | lemmas union_ac = union_assoc union_commute union_lcomm | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2763 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2764 | lemma union_right_cancel: "M + K = N + K \<longleftrightarrow> M = (N::'a multiset)" | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2765 | by (fact add_right_cancel) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2766 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2767 | lemma union_left_cancel: "K + M = K + N \<longleftrightarrow> M = (N::'a multiset)" | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2768 | by (fact add_left_cancel) | 
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2769 | |
| 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2770 | lemma multi_union_self_other_eq: "(A::'a multiset) + X = A + Y \<Longrightarrow> X = Y" | 
| 59557 | 2771 | by (fact add_left_imp_eq) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2772 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2773 | lemma mset_subset_trans: "(M::'a multiset) \<subset># K \<Longrightarrow> K \<subset># N \<Longrightarrow> M \<subset># N" | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 2774 | by (fact subset_mset.less_trans) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2775 | |
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2776 | lemma multiset_inter_commute: "A #\<inter> B = B #\<inter> A" | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 2777 | by (fact subset_mset.inf.commute) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2778 | |
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2779 | lemma multiset_inter_assoc: "A #\<inter> (B #\<inter> C) = A #\<inter> B #\<inter> C" | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 2780 | by (fact subset_mset.inf.assoc [symmetric]) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2781 | |
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2782 | lemma multiset_inter_left_commute: "A #\<inter> (B #\<inter> C) = B #\<inter> (A #\<inter> C)" | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 2783 | by (fact subset_mset.inf.left_commute) | 
| 35268 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2784 | |
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2785 | lemmas multiset_inter_ac = | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2786 | multiset_inter_commute | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2787 | multiset_inter_assoc | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2788 | multiset_inter_left_commute | 
| 
04673275441a
switched notations for pointwise and multiset order
 haftmann parents: 
35028diff
changeset | 2789 | |
| 63410 
9789ccc2a477
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63409diff
changeset | 2790 | lemma mset_le_not_refl: "\<not> M < (M::'a::preorder multiset)" | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2791 | by (fact less_irrefl) | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2792 | |
| 63410 
9789ccc2a477
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63409diff
changeset | 2793 | lemma mset_le_trans: "K < M \<Longrightarrow> M < N \<Longrightarrow> K < (N::'a::preorder multiset)" | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2794 | by (fact less_trans) | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2795 | |
| 63410 
9789ccc2a477
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63409diff
changeset | 2796 | lemma mset_le_not_sym: "M < N \<Longrightarrow> \<not> N < (M::'a::preorder multiset)" | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2797 | by (fact less_not_sym) | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2798 | |
| 63410 
9789ccc2a477
more instantiations for multiset
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63409diff
changeset | 2799 | lemma mset_le_asym: "M < N \<Longrightarrow> (\<not> P \<Longrightarrow> N < (M::'a::preorder multiset)) \<Longrightarrow> P" | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2800 | by (fact less_asym) | 
| 34943 
e97b22500a5c
cleanup of Multiset.thy: less duplication, tuned and simplified a couple of proofs, less historical organization of sections, conversion from associations lists to multisets, rudimentary code generation
 haftmann parents: 
33102diff
changeset | 2801 | |
| 60500 | 2802 | declaration \<open> | 
| 60606 | 2803 | let | 
| 2804 | fun multiset_postproc _ maybe_name all_values (T as Type (_, [elem_T])) (Const _ $ t') = | |
| 2805 | let | |
| 2806 | val (maybe_opt, ps) = | |
| 2807 | Nitpick_Model.dest_plain_fun t' | |
| 2808 | ||> op ~~ | |
| 2809 | ||> map (apsnd (snd o HOLogic.dest_number)) | |
| 2810 | fun elems_for t = | |
| 2811 | (case AList.lookup (op =) ps t of | |
| 2812 | SOME n => replicate n t | |
| 2813 | | NONE => [Const (maybe_name, elem_T --> elem_T) $ t]) | |
| 2814 | in | |
| 2815 | (case maps elems_for (all_values elem_T) @ | |
| 61333 | 2816 | (if maybe_opt then [Const (Nitpick_Model.unrep_mixfix (), elem_T)] else []) of | 
| 60606 | 2817 |               [] => Const (@{const_name zero_class.zero}, T)
 | 
| 2818 | | ts => | |
| 2819 | foldl1 (fn (t1, t2) => | |
| 2820 |                     Const (@{const_name plus_class.plus}, T --> T --> T) $ t1 $ t2)
 | |
| 2821 |                   (map (curry (op $) (Const (@{const_name single}, elem_T --> T))) ts))
 | |
| 2822 | end | |
| 2823 | | multiset_postproc _ _ _ _ t = t | |
| 2824 |   in Nitpick_Model.register_term_postprocessor @{typ "'a multiset"} multiset_postproc end
 | |
| 60500 | 2825 | \<close> | 
| 2826 | ||
| 2827 | ||
| 2828 | subsection \<open>Naive implementation using lists\<close> | |
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2829 | |
| 60515 | 2830 | code_datatype mset | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2831 | |
| 60606 | 2832 | lemma [code]: "{#} = mset []"
 | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2833 | by simp | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2834 | |
| 63195 | 2835 | lemma [code]: "Multiset.is_empty (mset xs) \<longleftrightarrow> List.null xs" | 
| 2836 | by (simp add: Multiset.is_empty_def List.null_def) | |
| 2837 | ||
| 60606 | 2838 | lemma [code]: "{#x#} = mset [x]"
 | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2839 | by simp | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2840 | |
| 60606 | 2841 | lemma union_code [code]: "mset xs + mset ys = mset (xs @ ys)" | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2842 | by simp | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2843 | |
| 60606 | 2844 | lemma [code]: "image_mset f (mset xs) = mset (map f xs)" | 
| 60515 | 2845 | by (simp add: mset_map) | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2846 | |
| 60606 | 2847 | lemma [code]: "filter_mset f (mset xs) = mset (filter f xs)" | 
| 60515 | 2848 | by (simp add: mset_filter) | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2849 | |
| 60606 | 2850 | lemma [code]: "mset xs - mset ys = mset (fold remove1 ys xs)" | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2851 | by (rule sym, induct ys arbitrary: xs) (simp_all add: diff_add diff_right_commute) | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2852 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2853 | lemma [code]: | 
| 60515 | 2854 | "mset xs #\<inter> mset ys = | 
| 2855 | mset (snd (fold (\<lambda>x (ys, zs). | |
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2856 | if x \<in> set ys then (remove1 x ys, x # zs) else (ys, zs)) xs (ys, [])))" | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2857 | proof - | 
| 60515 | 2858 | have "\<And>zs. mset (snd (fold (\<lambda>x (ys, zs). | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2859 | if x \<in> set ys then (remove1 x ys, x # zs) else (ys, zs)) xs (ys, zs))) = | 
| 60515 | 2860 | (mset xs #\<inter> mset ys) + mset zs" | 
| 51623 | 2861 | by (induct xs arbitrary: ys) | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2862 | (auto simp add: inter_add_right1 inter_add_right2 ac_simps) | 
| 51623 | 2863 | then show ?thesis by simp | 
| 2864 | qed | |
| 2865 | ||
| 2866 | lemma [code]: | |
| 60515 | 2867 | "mset xs #\<union> mset ys = | 
| 61424 
c3658c18b7bc
prod_case as canonical name for product type eliminator
 haftmann parents: 
61378diff
changeset | 2868 | mset (case_prod append (fold (\<lambda>x (ys, zs). (remove1 x ys, x # zs)) xs (ys, [])))" | 
| 51623 | 2869 | proof - | 
| 61424 
c3658c18b7bc
prod_case as canonical name for product type eliminator
 haftmann parents: 
61378diff
changeset | 2870 | have "\<And>zs. mset (case_prod append (fold (\<lambda>x (ys, zs). (remove1 x ys, x # zs)) xs (ys, zs))) = | 
| 60515 | 2871 | (mset xs #\<union> mset ys) + mset zs" | 
| 51623 | 2872 | by (induct xs arbitrary: ys) (simp_all add: multiset_eq_iff) | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2873 | then show ?thesis by simp | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2874 | qed | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2875 | |
| 59813 | 2876 | declare in_multiset_in_set [code_unfold] | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2877 | |
| 60606 | 2878 | lemma [code]: "count (mset xs) x = fold (\<lambda>y. if x = y then Suc else id) xs 0" | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2879 | proof - | 
| 60515 | 2880 | have "\<And>n. fold (\<lambda>y. if x = y then Suc else id) xs n = count (mset xs) x + n" | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2881 | by (induct xs) simp_all | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2882 | then show ?thesis by simp | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2883 | qed | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2884 | |
| 60515 | 2885 | declare set_mset_mset [code] | 
| 2886 | ||
| 2887 | declare sorted_list_of_multiset_mset [code] | |
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2888 | |
| 61585 | 2889 | lemma [code]: \<comment> \<open>not very efficient, but representation-ignorant!\<close> | 
| 60515 | 2890 | "mset_set A = mset (sorted_list_of_set A)" | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2891 | apply (cases "finite A") | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2892 | apply simp_all | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2893 | apply (induct A rule: finite_induct) | 
| 59813 | 2894 | apply (simp_all add: add.commute) | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2895 | done | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2896 | |
| 60515 | 2897 | declare size_mset [code] | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2898 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2899 | fun subset_eq_mset_impl :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool option" where | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2900 | "subset_eq_mset_impl [] ys = Some (ys \<noteq> [])" | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2901 | | "subset_eq_mset_impl (Cons x xs) ys = (case List.extract (op = x) ys of | 
| 55808 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2902 | None \<Rightarrow> None | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2903 | | Some (ys1,_,ys2) \<Rightarrow> subset_eq_mset_impl xs (ys1 @ ys2))" | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2904 | |
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2905 | lemma subset_eq_mset_impl: "(subset_eq_mset_impl xs ys = None \<longleftrightarrow> \<not> mset xs \<subseteq># mset ys) \<and> | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2906 | (subset_eq_mset_impl xs ys = Some True \<longleftrightarrow> mset xs \<subset># mset ys) \<and> | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2907 | (subset_eq_mset_impl xs ys = Some False \<longrightarrow> mset xs = mset ys)" | 
| 55808 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2908 | proof (induct xs arbitrary: ys) | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2909 | case (Nil ys) | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2910 | show ?case by (auto simp: mset_subset_empty_nonempty) | 
| 55808 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2911 | next | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2912 | case (Cons x xs ys) | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2913 | show ?case | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2914 | proof (cases "List.extract (op = x) ys") | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2915 | case None | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2916 | hence x: "x \<notin> set ys" by (simp add: extract_None_iff) | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2917 |     {
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2918 | assume "mset (x # xs) \<subseteq># mset ys" | 
| 60495 | 2919 | from set_mset_mono[OF this] x have False by simp | 
| 55808 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2920 | } note nle = this | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2921 | moreover | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2922 |     {
 | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2923 | assume "mset (x # xs) \<subset># mset ys" | 
| 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 2924 | hence "mset (x # xs) \<subseteq># mset ys" by auto | 
| 55808 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2925 | from nle[OF this] have False . | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2926 | } | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2927 | ultimately show ?thesis using None by auto | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2928 | next | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2929 | case (Some res) | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2930 | obtain ys1 y ys2 where res: "res = (ys1,y,ys2)" by (cases res, auto) | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2931 | note Some = Some[unfolded res] | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2932 | from extract_SomeE[OF Some] have "ys = ys1 @ x # ys2" by simp | 
| 60515 | 2933 |     hence id: "mset ys = mset (ys1 @ ys2) + {#x#}"
 | 
| 55808 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2934 | by (auto simp: ac_simps) | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2935 | show ?thesis unfolding subset_eq_mset_impl.simps | 
| 55808 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2936 | unfolding Some option.simps split | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2937 | unfolding id | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2938 | using Cons[of "ys1 @ ys2"] | 
| 60397 
f8a513fedb31
Renaming multiset operators < ~> <#,...
 Mathias Fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
59999diff
changeset | 2939 | unfolding subset_mset_def subseteq_mset_def by auto | 
| 55808 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2940 | qed | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2941 | qed | 
| 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2942 | |
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2943 | lemma [code]: "mset xs \<subseteq># mset ys \<longleftrightarrow> subset_eq_mset_impl xs ys \<noteq> None" | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2944 | using subset_eq_mset_impl[of xs ys] by (cases "subset_eq_mset_impl xs ys", auto) | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2945 | |
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2946 | lemma [code]: "mset xs \<subset># mset ys \<longleftrightarrow> subset_eq_mset_impl xs ys = Some True" | 
| 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2947 | using subset_eq_mset_impl[of xs ys] by (cases "subset_eq_mset_impl xs ys", auto) | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2948 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2949 | instantiation multiset :: (equal) equal | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2950 | begin | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2951 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2952 | definition | 
| 55808 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2953 | [code del]: "HOL.equal A (B :: 'a multiset) \<longleftrightarrow> A = B" | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2954 | lemma [code]: "HOL.equal (mset xs) (mset ys) \<longleftrightarrow> subset_eq_mset_impl xs ys = Some False" | 
| 55808 
488c3e8282c8
added Rene Thiemann's patch for the nonterminating equality/subset test code for multisets
 nipkow parents: 
55565diff
changeset | 2955 | unfolding equal_multiset_def | 
| 63310 
caaacf37943f
normalising multiset theorem names
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63290diff
changeset | 2956 | using subset_eq_mset_impl[of xs ys] by (cases "subset_eq_mset_impl xs ys", auto) | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2957 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2958 | instance | 
| 60678 | 2959 | by standard (simp add: equal_multiset_def) | 
| 2960 | ||
| 37169 
f69efa106feb
make Nitpick "show_all" option behave less surprisingly
 blanchet parents: 
37107diff
changeset | 2961 | end | 
| 49388 | 2962 | |
| 60606 | 2963 | lemma [code]: "msetsum (mset xs) = listsum xs" | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2964 | by (induct xs) (simp_all add: add.commute) | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2965 | |
| 60606 | 2966 | lemma [code]: "msetprod (mset xs) = fold times xs 1" | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2967 | proof - | 
| 60515 | 2968 | have "\<And>x. fold times xs x = msetprod (mset xs) * x" | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2969 | by (induct xs) (simp_all add: mult.assoc) | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2970 | then show ?thesis by simp | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2971 | qed | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2972 | |
| 60500 | 2973 | text \<open> | 
| 63388 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2974 |   Exercise for the casual reader: add implementations for @{term "op \<le>"}
 | 
| 
a095acd4cfbf
instantiate multiset with multiset ordering
 fleury <Mathias.Fleury@mpi-inf.mpg.de> parents: 
63360diff
changeset | 2975 |   and @{term "op <"} (multiset order).
 | 
| 60500 | 2976 | \<close> | 
| 2977 | ||
| 2978 | text \<open>Quickcheck generators\<close> | |
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2979 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2980 | definition (in term_syntax) | 
| 61076 | 2981 | msetify :: "'a::typerep list \<times> (unit \<Rightarrow> Code_Evaluation.term) | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2982 | \<Rightarrow> 'a multiset \<times> (unit \<Rightarrow> Code_Evaluation.term)" where | 
| 60515 | 2983 |   [code_unfold]: "msetify xs = Code_Evaluation.valtermify mset {\<cdot>} xs"
 | 
| 51600 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2984 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2985 | notation fcomp (infixl "\<circ>>" 60) | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2986 | notation scomp (infixl "\<circ>\<rightarrow>" 60) | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2987 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2988 | instantiation multiset :: (random) random | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2989 | begin | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2990 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2991 | definition | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2992 | "Quickcheck_Random.random i = Quickcheck_Random.random i \<circ>\<rightarrow> (\<lambda>xs. Pair (msetify xs))" | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2993 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2994 | instance .. | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2995 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2996 | end | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2997 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2998 | no_notation fcomp (infixl "\<circ>>" 60) | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 2999 | no_notation scomp (infixl "\<circ>\<rightarrow>" 60) | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3000 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3001 | instantiation multiset :: (full_exhaustive) full_exhaustive | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3002 | begin | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3003 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3004 | definition full_exhaustive_multiset :: "('a multiset \<times> (unit \<Rightarrow> term) \<Rightarrow> (bool \<times> term list) option) \<Rightarrow> natural \<Rightarrow> (bool \<times> term list) option"
 | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3005 | where | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3006 | "full_exhaustive_multiset f i = Quickcheck_Exhaustive.full_exhaustive (\<lambda>xs. f (msetify xs)) i" | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3007 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3008 | instance .. | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3009 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3010 | end | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3011 | |
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3012 | hide_const (open) msetify | 
| 
197e25f13f0c
default implementation of multisets by list with reasonable coverage of operations on multisets
 haftmann parents: 
51599diff
changeset | 3013 | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3014 | |
| 60500 | 3015 | subsection \<open>BNF setup\<close> | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3016 | |
| 57966 | 3017 | definition rel_mset where | 
| 60515 | 3018 | "rel_mset R X Y \<longleftrightarrow> (\<exists>xs ys. mset xs = X \<and> mset ys = Y \<and> list_all2 R xs ys)" | 
| 3019 | ||
| 3020 | lemma mset_zip_take_Cons_drop_twice: | |
| 57966 | 3021 | assumes "length xs = length ys" "j \<le> length xs" | 
| 60515 | 3022 | shows "mset (zip (take j xs @ x # drop j xs) (take j ys @ y # drop j ys)) = | 
| 3023 |     mset (zip xs ys) + {#(x, y)#}"
 | |
| 60606 | 3024 | using assms | 
| 57966 | 3025 | proof (induct xs ys arbitrary: x y j rule: list_induct2) | 
| 3026 | case Nil | |
| 3027 | thus ?case | |
| 3028 | by simp | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3029 | next | 
| 57966 | 3030 | case (Cons x xs y ys) | 
| 3031 | thus ?case | |
| 3032 | proof (cases "j = 0") | |
| 3033 | case True | |
| 3034 | thus ?thesis | |
| 3035 | by simp | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3036 | next | 
| 57966 | 3037 | case False | 
| 3038 | then obtain k where k: "j = Suc k" | |
| 60678 | 3039 | by (cases j) simp | 
| 57966 | 3040 | hence "k \<le> length xs" | 
| 3041 | using Cons.prems by auto | |
| 60515 | 3042 | hence "mset (zip (take k xs @ x # drop k xs) (take k ys @ y # drop k ys)) = | 
| 3043 |       mset (zip xs ys) + {#(x, y)#}"
 | |
| 57966 | 3044 | by (rule Cons.hyps(2)) | 
| 3045 | thus ?thesis | |
| 3046 | unfolding k by (auto simp: add.commute union_lcomm) | |
| 58425 | 3047 | qed | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3048 | qed | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3049 | |
| 60515 | 3050 | lemma ex_mset_zip_left: | 
| 3051 | assumes "length xs = length ys" "mset xs' = mset xs" | |
| 3052 | shows "\<exists>ys'. length ys' = length xs' \<and> mset (zip xs' ys') = mset (zip xs ys)" | |
| 58425 | 3053 | using assms | 
| 57966 | 3054 | proof (induct xs ys arbitrary: xs' rule: list_induct2) | 
| 3055 | case Nil | |
| 3056 | thus ?case | |
| 3057 | by auto | |
| 3058 | next | |
| 3059 | case (Cons x xs y ys xs') | |
| 3060 | obtain j where j_len: "j < length xs'" and nth_j: "xs' ! j = x" | |
| 60515 | 3061 | by (metis Cons.prems in_set_conv_nth list.set_intros(1) mset_eq_setD) | 
| 58425 | 3062 | |
| 63040 | 3063 | define xsa where "xsa = take j xs' @ drop (Suc j) xs'" | 
| 60515 | 3064 |   have "mset xs' = {#x#} + mset xsa"
 | 
| 57966 | 3065 | unfolding xsa_def using j_len nth_j | 
| 58247 
98d0f85d247f
enamed drop_Suc_conv_tl and nth_drop' to Cons_nth_drop_Suc
 nipkow parents: 
58098diff
changeset | 3066 | by (metis (no_types) ab_semigroup_add_class.add_ac(1) append_take_drop_id Cons_nth_drop_Suc | 
| 60515 | 3067 | mset.simps(2) union_code add.commute) | 
| 3068 | hence ms_x: "mset xsa = mset xs" | |
| 3069 | by (metis Cons.prems add.commute add_right_imp_eq mset.simps(2)) | |
| 57966 | 3070 | then obtain ysa where | 
| 60515 | 3071 | len_a: "length ysa = length xsa" and ms_a: "mset (zip xsa ysa) = mset (zip xs ys)" | 
| 57966 | 3072 | using Cons.hyps(2) by blast | 
| 3073 | ||
| 63040 | 3074 | define ys' where "ys' = take j ysa @ y # drop j ysa" | 
| 57966 | 3075 | have xs': "xs' = take j xsa @ x # drop j xsa" | 
| 3076 | using ms_x j_len nth_j Cons.prems xsa_def | |
| 58247 
98d0f85d247f
enamed drop_Suc_conv_tl and nth_drop' to Cons_nth_drop_Suc
 nipkow parents: 
58098diff
changeset | 3077 | by (metis append_eq_append_conv append_take_drop_id diff_Suc_Suc Cons_nth_drop_Suc length_Cons | 
| 60515 | 3078 | length_drop size_mset) | 
| 57966 | 3079 | have j_len': "j \<le> length xsa" | 
| 3080 | using j_len xs' xsa_def | |
| 3081 | by (metis add_Suc_right append_take_drop_id length_Cons length_append less_eq_Suc_le not_less) | |
| 3082 | have "length ys' = length xs'" | |
| 3083 | unfolding ys'_def using Cons.prems len_a ms_x | |
| 60515 | 3084 | by (metis add_Suc_right append_take_drop_id length_Cons length_append mset_eq_length) | 
| 3085 | moreover have "mset (zip xs' ys') = mset (zip (x # xs) (y # ys))" | |
| 57966 | 3086 | unfolding xs' ys'_def | 
| 60515 | 3087 | by (rule trans[OF mset_zip_take_Cons_drop_twice]) | 
| 57966 | 3088 | (auto simp: len_a ms_a j_len' add.commute) | 
| 3089 | ultimately show ?case | |
| 3090 | by blast | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3091 | qed | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3092 | |
| 57966 | 3093 | lemma list_all2_reorder_left_invariance: | 
| 60515 | 3094 | assumes rel: "list_all2 R xs ys" and ms_x: "mset xs' = mset xs" | 
| 3095 | shows "\<exists>ys'. list_all2 R xs' ys' \<and> mset ys' = mset ys" | |
| 57966 | 3096 | proof - | 
| 3097 | have len: "length xs = length ys" | |
| 3098 | using rel list_all2_conv_all_nth by auto | |
| 3099 | obtain ys' where | |
| 60515 | 3100 | len': "length xs' = length ys'" and ms_xy: "mset (zip xs' ys') = mset (zip xs ys)" | 
| 3101 | using len ms_x by (metis ex_mset_zip_left) | |
| 57966 | 3102 | have "list_all2 R xs' ys'" | 
| 60515 | 3103 | using assms(1) len' ms_xy unfolding list_all2_iff by (blast dest: mset_eq_setD) | 
| 3104 | moreover have "mset ys' = mset ys" | |
| 3105 | using len len' ms_xy map_snd_zip mset_map by metis | |
| 57966 | 3106 | ultimately show ?thesis | 
| 3107 | by blast | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3108 | qed | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3109 | |
| 60515 | 3110 | lemma ex_mset: "\<exists>xs. mset xs = X" | 
| 3111 | by (induct X) (simp, metis mset.simps(2)) | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3112 | |
| 62324 | 3113 | inductive pred_mset :: "('a \<Rightarrow> bool) \<Rightarrow> 'a multiset \<Rightarrow> bool"
 | 
| 3114 | where | |
| 3115 |   "pred_mset P {#}"
 | |
| 3116 | | "\<lbrakk>P a; pred_mset P M\<rbrakk> \<Longrightarrow> pred_mset P (M + {#a#})"
 | |
| 3117 | ||
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3118 | bnf "'a multiset" | 
| 57966 | 3119 | map: image_mset | 
| 60495 | 3120 | sets: set_mset | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3121 | bd: natLeq | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3122 |   wits: "{#}"
 | 
| 57966 | 3123 | rel: rel_mset | 
| 62324 | 3124 | pred: pred_mset | 
| 57966 | 3125 | proof - | 
| 3126 | show "image_mset id = id" | |
| 3127 | by (rule image_mset.id) | |
| 60606 | 3128 | show "image_mset (g \<circ> f) = image_mset g \<circ> image_mset f" for f g | 
| 59813 | 3129 | unfolding comp_def by (rule ext) (simp add: comp_def image_mset.compositionality) | 
| 60606 | 3130 | show "(\<And>z. z \<in> set_mset X \<Longrightarrow> f z = g z) \<Longrightarrow> image_mset f X = image_mset g X" for f g X | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 3131 | by (induct X) simp_all | 
| 60606 | 3132 | show "set_mset \<circ> image_mset f = op ` f \<circ> set_mset" for f | 
| 57966 | 3133 | by auto | 
| 3134 | show "card_order natLeq" | |
| 3135 | by (rule natLeq_card_order) | |
| 3136 | show "BNF_Cardinal_Arithmetic.cinfinite natLeq" | |
| 3137 | by (rule natLeq_cinfinite) | |
| 60606 | 3138 | show "ordLeq3 (card_of (set_mset X)) natLeq" for X | 
| 57966 | 3139 | by transfer | 
| 3140 | (auto intro!: ordLess_imp_ordLeq simp: finite_iff_ordLess_natLeq[symmetric] multiset_def) | |
| 60606 | 3141 | show "rel_mset R OO rel_mset S \<le> rel_mset (R OO S)" for R S | 
| 57966 | 3142 | unfolding rel_mset_def[abs_def] OO_def | 
| 3143 | apply clarify | |
| 60678 | 3144 | subgoal for X Z Y xs ys' ys zs | 
| 3145 | apply (drule list_all2_reorder_left_invariance [where xs = ys' and ys = zs and xs' = ys]) | |
| 3146 | apply (auto intro: list_all2_trans) | |
| 3147 | done | |
| 60606 | 3148 | done | 
| 3149 | show "rel_mset R = | |
| 62324 | 3150 |     (\<lambda>x y. \<exists>z. set_mset z \<subseteq> {(x, y). R x y} \<and>
 | 
| 3151 | image_mset fst z = x \<and> image_mset snd z = y)" for R | |
| 3152 | unfolding rel_mset_def[abs_def] | |
| 57966 | 3153 | apply (rule ext)+ | 
| 62324 | 3154 | apply safe | 
| 3155 | apply (rule_tac x = "mset (zip xs ys)" in exI; | |
| 3156 | auto simp: in_set_zip list_all2_iff mset_map[symmetric]) | |
| 57966 | 3157 | apply (rename_tac XY) | 
| 60515 | 3158 | apply (cut_tac X = XY in ex_mset) | 
| 57966 | 3159 | apply (erule exE) | 
| 3160 | apply (rename_tac xys) | |
| 3161 | apply (rule_tac x = "map fst xys" in exI) | |
| 60515 | 3162 | apply (auto simp: mset_map) | 
| 57966 | 3163 | apply (rule_tac x = "map snd xys" in exI) | 
| 60515 | 3164 | apply (auto simp: mset_map list_all2I subset_eq zip_map_fst_snd) | 
| 59997 | 3165 | done | 
| 60606 | 3166 |   show "z \<in> set_mset {#} \<Longrightarrow> False" for z
 | 
| 57966 | 3167 | by auto | 
| 62324 | 3168 | show "pred_mset P = (\<lambda>x. Ball (set_mset x) P)" for P | 
| 3169 | proof (intro ext iffI) | |
| 3170 | fix x | |
| 3171 | assume "pred_mset P x" | |
| 3172 | then show "Ball (set_mset x) P" by (induct pred: pred_mset; simp) | |
| 3173 | next | |
| 3174 | fix x | |
| 3175 | assume "Ball (set_mset x) P" | |
| 3176 | then show "pred_mset P x" by (induct x; auto intro: pred_mset.intros) | |
| 3177 | qed | |
| 57966 | 3178 | qed | 
| 3179 | ||
| 60606 | 3180 | inductive rel_mset' | 
| 3181 | where | |
| 57966 | 3182 |   Zero[intro]: "rel_mset' R {#} {#}"
 | 
| 3183 | | Plus[intro]: "\<lbrakk>R a b; rel_mset' R M N\<rbrakk> \<Longrightarrow> rel_mset' R (M + {#a#}) (N + {#b#})"
 | |
| 3184 | ||
| 3185 | lemma rel_mset_Zero: "rel_mset R {#} {#}"
 | |
| 3186 | unfolding rel_mset_def Grp_def by auto | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3187 | |
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3188 | declare multiset.count[simp] | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3189 | declare Abs_multiset_inverse[simp] | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3190 | declare multiset.count_inverse[simp] | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3191 | declare union_preserves_multiset[simp] | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3192 | |
| 57966 | 3193 | lemma rel_mset_Plus: | 
| 60606 | 3194 | assumes ab: "R a b" | 
| 3195 | and MN: "rel_mset R M N" | |
| 3196 |   shows "rel_mset R (M + {#a#}) (N + {#b#})"
 | |
| 3197 | proof - | |
| 3198 |   have "\<exists>ya. image_mset fst y + {#a#} = image_mset fst ya \<and>
 | |
| 3199 |     image_mset snd y + {#b#} = image_mset snd ya \<and>
 | |
| 3200 |     set_mset ya \<subseteq> {(x, y). R x y}"
 | |
| 3201 |     if "R a b" and "set_mset y \<subseteq> {(x, y). R x y}" for y
 | |
| 3202 |     using that by (intro exI[of _ "y + {#(a,b)#}"]) auto
 | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3203 | thus ?thesis | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3204 | using assms | 
| 57966 | 3205 | unfolding multiset.rel_compp_Grp Grp_def by blast | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3206 | qed | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3207 | |
| 60606 | 3208 | lemma rel_mset'_imp_rel_mset: "rel_mset' R M N \<Longrightarrow> rel_mset R M N" | 
| 60678 | 3209 | by (induct rule: rel_mset'.induct) (auto simp: rel_mset_Zero rel_mset_Plus) | 
| 57966 | 3210 | |
| 60606 | 3211 | lemma rel_mset_size: "rel_mset R M N \<Longrightarrow> size M = size N" | 
| 60678 | 3212 | unfolding multiset.rel_compp_Grp Grp_def by auto | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3213 | |
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3214 | lemma multiset_induct2[case_names empty addL addR]: | 
| 60678 | 3215 |   assumes empty: "P {#} {#}"
 | 
| 3216 |     and addL: "\<And>M N a. P M N \<Longrightarrow> P (M + {#a#}) N"
 | |
| 3217 |     and addR: "\<And>M N a. P M N \<Longrightarrow> P M (N + {#a#})"
 | |
| 3218 | shows "P M N" | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3219 | apply(induct N rule: multiset_induct) | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3220 | apply(induct M rule: multiset_induct, rule empty, erule addL) | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3221 | apply(induct M rule: multiset_induct, erule addR, erule addR) | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3222 | done | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3223 | |
| 59949 | 3224 | lemma multiset_induct2_size[consumes 1, case_names empty add]: | 
| 60606 | 3225 | assumes c: "size M = size N" | 
| 3226 |     and empty: "P {#} {#}"
 | |
| 3227 |     and add: "\<And>M N a b. P M N \<Longrightarrow> P (M + {#a#}) (N + {#b#})"
 | |
| 3228 | shows "P M N" | |
| 60678 | 3229 | using c | 
| 3230 | proof (induct M arbitrary: N rule: measure_induct_rule[of size]) | |
| 60606 | 3231 | case (less M) | 
| 3232 | show ?case | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3233 |   proof(cases "M = {#}")
 | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3234 |     case True hence "N = {#}" using less.prems by auto
 | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3235 | thus ?thesis using True empty by auto | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3236 | next | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3237 |     case False then obtain M1 a where M: "M = M1 + {#a#}" by (metis multi_nonempty_split)
 | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3238 |     have "N \<noteq> {#}" using False less.prems by auto
 | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3239 |     then obtain N1 b where N: "N = N1 + {#b#}" by (metis multi_nonempty_split)
 | 
| 59949 | 3240 | have "size M1 = size N1" using less.prems unfolding M N by auto | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3241 | thus ?thesis using M N less.hyps add by auto | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3242 | qed | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3243 | qed | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3244 | |
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3245 | lemma msed_map_invL: | 
| 60606 | 3246 |   assumes "image_mset f (M + {#a#}) = N"
 | 
| 3247 |   shows "\<exists>N1. N = N1 + {#f a#} \<and> image_mset f M = N1"
 | |
| 3248 | proof - | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3249 | have "f a \<in># N" | 
| 60606 | 3250 |     using assms multiset.set_map[of f "M + {#a#}"] by auto
 | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3251 |   then obtain N1 where N: "N = N1 + {#f a#}" using multi_member_split by metis
 | 
| 57966 | 3252 | have "image_mset f M = N1" using assms unfolding N by simp | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3253 | thus ?thesis using N by blast | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3254 | qed | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3255 | |
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3256 | lemma msed_map_invR: | 
| 60606 | 3257 |   assumes "image_mset f M = N + {#b#}"
 | 
| 3258 |   shows "\<exists>M1 a. M = M1 + {#a#} \<and> f a = b \<and> image_mset f M1 = N"
 | |
| 3259 | proof - | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3260 | obtain a where a: "a \<in># M" and fa: "f a = b" | 
| 60606 | 3261 | using multiset.set_map[of f M] unfolding assms | 
| 62430 
9527ff088c15
more succint formulation of membership for multisets, similar to lists;
 haftmann parents: 
62390diff
changeset | 3262 | by (metis image_iff union_single_eq_member) | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3263 |   then obtain M1 where M: "M = M1 + {#a#}" using multi_member_split by metis
 | 
| 57966 | 3264 | have "image_mset f M1 = N" using assms unfolding M fa[symmetric] by simp | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3265 | thus ?thesis using M fa by blast | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3266 | qed | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3267 | |
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3268 | lemma msed_rel_invL: | 
| 60606 | 3269 |   assumes "rel_mset R (M + {#a#}) N"
 | 
| 3270 |   shows "\<exists>N1 b. N = N1 + {#b#} \<and> R a b \<and> rel_mset R M N1"
 | |
| 3271 | proof - | |
| 57966 | 3272 |   obtain K where KM: "image_mset fst K = M + {#a#}"
 | 
| 60606 | 3273 |     and KN: "image_mset snd K = N" and sK: "set_mset K \<subseteq> {(a, b). R a b}"
 | 
| 3274 | using assms | |
| 3275 | unfolding multiset.rel_compp_Grp Grp_def by auto | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3276 |   obtain K1 ab where K: "K = K1 + {#ab#}" and a: "fst ab = a"
 | 
| 60606 | 3277 | and K1M: "image_mset fst K1 = M" using msed_map_invR[OF KM] by auto | 
| 57966 | 3278 |   obtain N1 where N: "N = N1 + {#snd ab#}" and K1N1: "image_mset snd K1 = N1"
 | 
| 60606 | 3279 | using msed_map_invL[OF KN[unfolded K]] by auto | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3280 | have Rab: "R a (snd ab)" using sK a unfolding K by auto | 
| 57966 | 3281 | have "rel_mset R M N1" using sK K1M K1N1 | 
| 60606 | 3282 | unfolding K multiset.rel_compp_Grp Grp_def by auto | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3283 | thus ?thesis using N Rab by auto | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3284 | qed | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3285 | |
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3286 | lemma msed_rel_invR: | 
| 60606 | 3287 |   assumes "rel_mset R M (N + {#b#})"
 | 
| 3288 |   shows "\<exists>M1 a. M = M1 + {#a#} \<and> R a b \<and> rel_mset R M1 N"
 | |
| 3289 | proof - | |
| 57966 | 3290 |   obtain K where KN: "image_mset snd K = N + {#b#}"
 | 
| 60606 | 3291 |     and KM: "image_mset fst K = M" and sK: "set_mset K \<subseteq> {(a, b). R a b}"
 | 
| 3292 | using assms | |
| 3293 | unfolding multiset.rel_compp_Grp Grp_def by auto | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3294 |   obtain K1 ab where K: "K = K1 + {#ab#}" and b: "snd ab = b"
 | 
| 60606 | 3295 | and K1N: "image_mset snd K1 = N" using msed_map_invR[OF KN] by auto | 
| 57966 | 3296 |   obtain M1 where M: "M = M1 + {#fst ab#}" and K1M1: "image_mset fst K1 = M1"
 | 
| 60606 | 3297 | using msed_map_invL[OF KM[unfolded K]] by auto | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3298 | have Rab: "R (fst ab) b" using sK b unfolding K by auto | 
| 57966 | 3299 | have "rel_mset R M1 N" using sK K1N K1M1 | 
| 60606 | 3300 | unfolding K multiset.rel_compp_Grp Grp_def by auto | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3301 | thus ?thesis using M Rab by auto | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3302 | qed | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3303 | |
| 57966 | 3304 | lemma rel_mset_imp_rel_mset': | 
| 60606 | 3305 | assumes "rel_mset R M N" | 
| 3306 | shows "rel_mset' R M N" | |
| 59949 | 3307 | using assms proof(induct M arbitrary: N rule: measure_induct_rule[of size]) | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3308 | case (less M) | 
| 59949 | 3309 | have c: "size M = size N" using rel_mset_size[OF less.prems] . | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3310 | show ?case | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3311 |   proof(cases "M = {#}")
 | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3312 |     case True hence "N = {#}" using c by simp
 | 
| 57966 | 3313 | thus ?thesis using True rel_mset'.Zero by auto | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3314 | next | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3315 |     case False then obtain M1 a where M: "M = M1 + {#a#}" by (metis multi_nonempty_split)
 | 
| 57966 | 3316 |     obtain N1 b where N: "N = N1 + {#b#}" and R: "R a b" and ms: "rel_mset R M1 N1"
 | 
| 60606 | 3317 | using msed_rel_invL[OF less.prems[unfolded M]] by auto | 
| 57966 | 3318 | have "rel_mset' R M1 N1" using less.hyps[of M1 N1] ms unfolding M by simp | 
| 3319 | thus ?thesis using rel_mset'.Plus[of R a b, OF R] unfolding M N by simp | |
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3320 | qed | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3321 | qed | 
| 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3322 | |
| 60606 | 3323 | lemma rel_mset_rel_mset': "rel_mset R M N = rel_mset' R M N" | 
| 60678 | 3324 | using rel_mset_imp_rel_mset' rel_mset'_imp_rel_mset by auto | 
| 57966 | 3325 | |
| 60613 | 3326 | text \<open>The main end product for @{const rel_mset}: inductive characterization:\<close>
 | 
| 61337 | 3327 | lemmas rel_mset_induct[case_names empty add, induct pred: rel_mset] = | 
| 60606 | 3328 | rel_mset'.induct[unfolded rel_mset_rel_mset'[symmetric]] | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3329 | |
| 56656 | 3330 | |
| 60500 | 3331 | subsection \<open>Size setup\<close> | 
| 56656 | 3332 | |
| 57966 | 3333 | lemma multiset_size_o_map: "size_multiset g \<circ> image_mset f = size_multiset (g \<circ> f)" | 
| 60678 | 3334 | apply (rule ext) | 
| 3335 | subgoal for x by (induct x) auto | |
| 3336 | done | |
| 56656 | 3337 | |
| 60500 | 3338 | setup \<open> | 
| 60606 | 3339 |   BNF_LFP_Size.register_size_global @{type_name multiset} @{const_name size_multiset}
 | 
| 62082 | 3340 |     @{thm size_multiset_overloaded_def}
 | 
| 60606 | 3341 |     @{thms size_multiset_empty size_multiset_single size_multiset_union size_empty size_single
 | 
| 3342 | size_union} | |
| 3343 |     @{thms multiset_size_o_map}
 | |
| 60500 | 3344 | \<close> | 
| 56656 | 3345 | |
| 3346 | hide_const (open) wcount | |
| 3347 | ||
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
54868diff
changeset | 3348 | end |