84 |
88 |
85 text {* |
89 text {* |
86 \medskip Preservation of the representing set @{term multiset}. |
90 \medskip Preservation of the representing set @{term multiset}. |
87 *} |
91 *} |
88 |
92 |
89 lemma const0_in_multiset [simp]: "(\<lambda>a. 0) \<in> multiset" |
93 lemma const0_in_multiset: "(\<lambda>a. 0) \<in> multiset" |
90 by (simp add: multiset_def) |
94 by (simp add: multiset_def) |
91 |
95 |
92 lemma only1_in_multiset [simp]: "(\<lambda>b. if b = a then 1 else 0) \<in> multiset" |
96 lemma only1_in_multiset: "(\<lambda>b. if b = a then 1 else 0) \<in> multiset" |
93 by (simp add: multiset_def) |
97 by (simp add: multiset_def) |
94 |
98 |
95 lemma union_preserves_multiset [simp]: |
99 lemma union_preserves_multiset: |
96 "M \<in> multiset ==> N \<in> multiset ==> (\<lambda>a. M a + N a) \<in> multiset" |
100 "M \<in> multiset ==> N \<in> multiset ==> (\<lambda>a. M a + N a) \<in> multiset" |
97 apply (simp add: multiset_def) |
101 apply (simp add: multiset_def) |
98 apply (drule (1) finite_UnI) |
102 apply (drule (1) finite_UnI) |
99 apply (simp del: finite_Un add: Un_def) |
103 apply (simp del: finite_Un add: Un_def) |
100 done |
104 done |
101 |
105 |
102 lemma diff_preserves_multiset [simp]: |
106 lemma diff_preserves_multiset: |
103 "M \<in> multiset ==> (\<lambda>a. M a - N a) \<in> multiset" |
107 "M \<in> multiset ==> (\<lambda>a. M a - N a) \<in> multiset" |
104 apply (simp add: multiset_def) |
108 apply (simp add: multiset_def) |
105 apply (rule finite_subset) |
109 apply (rule finite_subset) |
106 apply auto |
110 apply auto |
107 done |
111 done |
108 |
112 |
109 |
113 lemma MCollect_preserves_multiset: |
110 subsection {* Algebraic properties of multisets *} |
114 "M \<in> multiset ==> (\<lambda>x. if P x then M x else 0) \<in> multiset" |
|
115 apply (simp add: multiset_def) |
|
116 apply (rule finite_subset, auto) |
|
117 done |
|
118 |
|
119 lemmas in_multiset = const0_in_multiset only1_in_multiset |
|
120 union_preserves_multiset diff_preserves_multiset MCollect_preserves_multiset |
|
121 |
|
122 subsection {* Algebraic properties *} |
111 |
123 |
112 subsubsection {* Union *} |
124 subsubsection {* Union *} |
113 |
125 |
114 lemma union_empty [simp]: "M + {#} = M \<and> {#} + M = M" |
126 lemma union_empty [simp]: "M + {#} = M \<and> {#} + M = M" |
115 by (simp add: union_def Mempty_def) |
127 by (simp add: union_def Mempty_def in_multiset) |
116 |
128 |
117 lemma union_commute: "M + N = N + (M::'a multiset)" |
129 lemma union_commute: "M + N = N + (M::'a multiset)" |
118 by (simp add: union_def add_ac) |
130 by (simp add: union_def add_ac in_multiset) |
119 |
131 |
120 lemma union_assoc: "(M + N) + K = M + (N + (K::'a multiset))" |
132 lemma union_assoc: "(M + N) + K = M + (N + (K::'a multiset))" |
121 by (simp add: union_def add_ac) |
133 by (simp add: union_def add_ac in_multiset) |
122 |
134 |
123 lemma union_lcomm: "M + (N + K) = N + (M + (K::'a multiset))" |
135 lemma union_lcomm: "M + (N + K) = N + (M + (K::'a multiset))" |
124 proof - |
136 proof - |
125 have "M + (N + K) = (N + K) + M" |
137 have "M + (N + K) = (N + K) + M" |
126 by (rule union_commute) |
138 by (rule union_commute) |
143 |
155 |
144 |
156 |
145 subsubsection {* Difference *} |
157 subsubsection {* Difference *} |
146 |
158 |
147 lemma diff_empty [simp]: "M - {#} = M \<and> {#} - M = {#}" |
159 lemma diff_empty [simp]: "M - {#} = M \<and> {#} - M = {#}" |
148 by (simp add: Mempty_def diff_def) |
160 by (simp add: Mempty_def diff_def in_multiset) |
149 |
161 |
150 lemma diff_union_inverse2 [simp]: "M + {#a#} - {#a#} = M" |
162 lemma diff_union_inverse2 [simp]: "M + {#a#} - {#a#} = M" |
151 by (simp add: union_def diff_def) |
163 by (simp add: union_def diff_def in_multiset) |
152 |
164 |
153 |
165 |
154 subsubsection {* Count of elements *} |
166 subsubsection {* Count of elements *} |
155 |
167 |
156 lemma count_empty [simp]: "count {#} a = 0" |
168 lemma count_empty [simp]: "count {#} a = 0" |
157 by (simp add: count_def Mempty_def) |
169 by (simp add: count_def Mempty_def in_multiset) |
158 |
170 |
159 lemma count_single [simp]: "count {#b#} a = (if b = a then 1 else 0)" |
171 lemma count_single [simp]: "count {#b#} a = (if b = a then 1 else 0)" |
160 by (simp add: count_def single_def) |
172 by (simp add: count_def single_def in_multiset) |
161 |
173 |
162 lemma count_union [simp]: "count (M + N) a = count M a + count N a" |
174 lemma count_union [simp]: "count (M + N) a = count M a + count N a" |
163 by (simp add: count_def union_def) |
175 by (simp add: count_def union_def in_multiset) |
164 |
176 |
165 lemma count_diff [simp]: "count (M - N) a = count M a - count N a" |
177 lemma count_diff [simp]: "count (M - N) a = count M a - count N a" |
166 by (simp add: count_def diff_def) |
178 by (simp add: count_def diff_def in_multiset) |
|
179 |
|
180 lemma count_MCollect [simp]: |
|
181 "count {# x:M. P x #} a = (if P a then count M a else 0)" |
|
182 by (simp add: count_def MCollect_def in_multiset) |
167 |
183 |
168 |
184 |
169 subsubsection {* Set of elements *} |
185 subsubsection {* Set of elements *} |
170 |
186 |
171 lemma set_of_empty [simp]: "set_of {#} = {}" |
187 lemma set_of_empty [simp]: "set_of {#} = {}" |
172 by (simp add: set_of_def) |
188 by (simp add: set_of_def) |
173 |
189 |
174 lemma set_of_single [simp]: "set_of {#b#} = {b}" |
190 lemma set_of_single [simp]: "set_of {#b#} = {b}" |
175 by (simp add: set_of_def) |
191 by (simp add: set_of_def) |
176 |
192 |
177 lemma set_of_union [simp]: "set_of (M + N) = set_of M \<union> set_of N" |
193 lemma set_of_union [simp]: "set_of (M + N) = set_of M \<union> set_of N" |
178 by (auto simp add: set_of_def) |
194 by (auto simp add: set_of_def) |
179 |
195 |
180 lemma set_of_eq_empty_iff [simp]: "(set_of M = {}) = (M = {#})" |
196 lemma set_of_eq_empty_iff [simp]: "(set_of M = {}) = (M = {#})" |
181 by (auto simp add: set_of_def Mempty_def count_def expand_fun_eq) |
197 by(auto simp: set_of_def Mempty_def in_multiset count_def expand_fun_eq) |
182 |
198 |
183 lemma mem_set_of_iff [simp]: "(x \<in> set_of M) = (x :# M)" |
199 lemma mem_set_of_iff [simp]: "(x \<in> set_of M) = (x :# M)" |
184 by (auto simp add: set_of_def) |
200 by (auto simp add: set_of_def) |
|
201 |
|
202 lemma set_of_MCollect [simp]: "set_of {# x:M. P x #} = set_of M \<inter> {x. P x}" |
|
203 by (auto simp add: set_of_def) |
185 |
204 |
186 |
205 |
187 subsubsection {* Size *} |
206 subsubsection {* Size *} |
188 |
207 |
189 lemma size_empty [simp]: "size {#} = 0" |
208 lemma size_empty [simp,code func]: "size {#} = 0" |
190 by (simp add: size_def) |
209 by (simp add: size_def) |
191 |
210 |
192 lemma size_single [simp]: "size {#b#} = 1" |
211 lemma size_single [simp,code func]: "size {#b#} = 1" |
193 by (simp add: size_def) |
212 by (simp add: size_def) |
194 |
213 |
195 lemma finite_set_of [iff]: "finite (set_of M)" |
214 lemma finite_set_of [iff]: "finite (set_of M)" |
196 using Rep_multiset [of M] |
215 using Rep_multiset [of M] |
197 by (simp add: multiset_def set_of_def count_def) |
216 by (simp add: multiset_def set_of_def count_def) |
198 |
217 |
201 apply (induct rule: finite_induct) |
220 apply (induct rule: finite_induct) |
202 apply simp |
221 apply simp |
203 apply (simp add: Int_insert_left set_of_def) |
222 apply (simp add: Int_insert_left set_of_def) |
204 done |
223 done |
205 |
224 |
206 lemma size_union [simp]: "size (M + N::'a multiset) = size M + size N" |
225 lemma size_union[simp,code func]: "size (M + N::'a multiset) = size M + size N" |
207 apply (unfold size_def) |
226 apply (unfold size_def) |
208 apply (subgoal_tac "count (M + N) = (\<lambda>a. count M a + count N a)") |
227 apply (subgoal_tac "count (M + N) = (\<lambda>a. count M a + count N a)") |
209 prefer 2 |
228 prefer 2 |
210 apply (rule ext, simp) |
229 apply (rule ext, simp) |
211 apply (simp (no_asm_simp) add: setsum_Un_nat setsum_addf setsum_count_Int) |
230 apply (simp (no_asm_simp) add: setsum_Un_nat setsum_addf setsum_count_Int) |
212 apply (subst Int_commute) |
231 apply (subst Int_commute) |
213 apply (simp (no_asm_simp) add: setsum_count_Int) |
232 apply (simp (no_asm_simp) add: setsum_count_Int) |
214 done |
233 done |
215 |
234 |
216 lemma size_eq_0_iff_empty [iff]: "(size M = 0) = (M = {#})" |
235 lemma size_eq_0_iff_empty [iff]: "(size M = 0) = (M = {#})" |
217 apply (unfold size_def Mempty_def count_def, auto) |
236 apply (unfold size_def Mempty_def count_def, auto simp: in_multiset) |
218 apply (simp add: set_of_def count_def expand_fun_eq) |
237 apply (simp add: set_of_def count_def in_multiset expand_fun_eq) |
219 done |
238 done |
|
239 |
|
240 lemma nonempty_has_size: "(S \<noteq> {#}) = (0 < size S)" |
|
241 by(metis gr0I gr_implies_not0 size_empty size_eq_0_iff_empty) |
220 |
242 |
221 lemma size_eq_Suc_imp_elem: "size M = Suc n ==> \<exists>a. a :# M" |
243 lemma size_eq_Suc_imp_elem: "size M = Suc n ==> \<exists>a. a :# M" |
222 apply (unfold size_def) |
244 apply (unfold size_def) |
223 apply (drule setsum_SucD, auto) |
245 apply (drule setsum_SucD, auto) |
224 done |
246 done |
227 |
249 |
228 lemma multiset_eq_conv_count_eq: "(M = N) = (\<forall>a. count M a = count N a)" |
250 lemma multiset_eq_conv_count_eq: "(M = N) = (\<forall>a. count M a = count N a)" |
229 by (simp add: count_def expand_fun_eq) |
251 by (simp add: count_def expand_fun_eq) |
230 |
252 |
231 lemma single_not_empty [simp]: "{#a#} \<noteq> {#} \<and> {#} \<noteq> {#a#}" |
253 lemma single_not_empty [simp]: "{#a#} \<noteq> {#} \<and> {#} \<noteq> {#a#}" |
232 by (simp add: single_def Mempty_def expand_fun_eq) |
254 by (simp add: single_def Mempty_def in_multiset expand_fun_eq) |
233 |
255 |
234 lemma single_eq_single [simp]: "({#a#} = {#b#}) = (a = b)" |
256 lemma single_eq_single [simp]: "({#a#} = {#b#}) = (a = b)" |
235 by (auto simp add: single_def expand_fun_eq) |
257 by (auto simp add: single_def in_multiset expand_fun_eq) |
236 |
258 |
237 lemma union_eq_empty [iff]: "(M + N = {#}) = (M = {#} \<and> N = {#})" |
259 lemma union_eq_empty [iff]: "(M + N = {#}) = (M = {#} \<and> N = {#})" |
238 by (auto simp add: union_def Mempty_def expand_fun_eq) |
260 by (auto simp add: union_def Mempty_def in_multiset expand_fun_eq) |
239 |
261 |
240 lemma empty_eq_union [iff]: "({#} = M + N) = (M = {#} \<and> N = {#})" |
262 lemma empty_eq_union [iff]: "({#} = M + N) = (M = {#} \<and> N = {#})" |
241 by (auto simp add: union_def Mempty_def expand_fun_eq) |
263 by (auto simp add: union_def Mempty_def in_multiset expand_fun_eq) |
242 |
264 |
243 lemma union_right_cancel [simp]: "(M + K = N + K) = (M = (N::'a multiset))" |
265 lemma union_right_cancel [simp]: "(M + K = N + K) = (M = (N::'a multiset))" |
244 by (simp add: union_def expand_fun_eq) |
266 by (simp add: union_def in_multiset expand_fun_eq) |
245 |
267 |
246 lemma union_left_cancel [simp]: "(K + M = K + N) = (M = (N::'a multiset))" |
268 lemma union_left_cancel [simp]: "(K + M = K + N) = (M = (N::'a multiset))" |
247 by (simp add: union_def expand_fun_eq) |
269 by (simp add: union_def in_multiset expand_fun_eq) |
248 |
270 |
249 lemma union_is_single: |
271 lemma union_is_single: |
250 "(M + N = {#a#}) = (M = {#a#} \<and> N={#} \<or> M = {#} \<and> N = {#a#})" |
272 "(M + N = {#a#}) = (M = {#a#} \<and> N={#} \<or> M = {#} \<and> N = {#a#})" |
251 apply (simp add: Mempty_def single_def union_def add_is_1 expand_fun_eq) |
273 apply (simp add: Mempty_def single_def union_def in_multiset add_is_1 expand_fun_eq) |
252 apply blast |
274 apply blast |
253 done |
275 done |
254 |
276 |
255 lemma single_is_union: |
277 lemma single_is_union: |
256 "({#a#} = M + N) = ({#a#} = M \<and> N = {#} \<or> M = {#} \<and> {#a#} = N)" |
278 "({#a#} = M + N) = ({#a#} = M \<and> N = {#} \<or> M = {#} \<and> {#a#} = N)" |
257 apply (unfold Mempty_def single_def union_def) |
279 apply (unfold Mempty_def single_def union_def) |
258 apply (simp add: add_is_1 one_is_add expand_fun_eq) |
280 apply (simp add: add_is_1 one_is_add in_multiset expand_fun_eq) |
259 apply (blast dest: sym) |
281 apply (blast dest: sym) |
260 done |
282 done |
261 |
283 |
262 lemma add_eq_conv_diff: |
284 lemma add_eq_conv_diff: |
263 "(M + {#a#} = N + {#b#}) = |
285 "(M + {#a#} = N + {#b#}) = |
264 (M = N \<and> a = b \<or> M = N - {#a#} + {#b#} \<and> N = M - {#b#} + {#a#})" |
286 (M = N \<and> a = b \<or> M = N - {#a#} + {#b#} \<and> N = M - {#b#} + {#a#})" |
265 using [[simproc del: neq]] |
287 using [[simproc del: neq]] |
266 apply (unfold single_def union_def diff_def) |
288 apply (unfold single_def union_def diff_def) |
267 apply (simp (no_asm) add: expand_fun_eq) |
289 apply (simp (no_asm) add: in_multiset expand_fun_eq) |
268 apply (rule conjI, force, safe, simp_all) |
290 apply (rule conjI, force, safe, simp_all) |
269 apply (simp add: eq_sym_conv) |
291 apply (simp add: eq_sym_conv) |
270 done |
292 done |
271 |
293 |
272 declare Rep_multiset_inject [symmetric, simp del] |
294 declare Rep_multiset_inject [symmetric, simp del] |
288 lemma multi_union_self_other_eq: |
310 lemma multi_union_self_other_eq: |
289 "(A::'a multiset) + X = A + Y \<Longrightarrow> X = Y" |
311 "(A::'a multiset) + X = A + Y \<Longrightarrow> X = Y" |
290 by (induct A arbitrary: X Y, auto) |
312 by (induct A arbitrary: X Y, auto) |
291 |
313 |
292 lemma multi_self_add_other_not_self[simp]: "(A = A + {#x#}) = False" |
314 lemma multi_self_add_other_not_self[simp]: "(A = A + {#x#}) = False" |
293 proof - |
315 by (metis single_not_empty union_empty union_left_cancel) |
294 { |
|
295 assume a: "A = A + {#x#}" |
|
296 have "A = A + {#}" by simp |
|
297 hence "A + {#} = A + {#x#}" using a by auto |
|
298 hence "{#} = {#x#}" |
|
299 by - (drule multi_union_self_other_eq) |
|
300 hence False by auto |
|
301 } |
|
302 thus ?thesis by blast |
|
303 qed |
|
304 |
316 |
305 lemma insert_noteq_member: |
317 lemma insert_noteq_member: |
306 assumes BC: "B + {#b#} = C + {#c#}" |
318 assumes BC: "B + {#b#} = C + {#c#}" |
307 and bnotc: "b \<noteq> c" |
319 and bnotc: "b \<noteq> c" |
308 shows "c \<in># B" |
320 shows "c \<in># B" |
312 hence "c \<in># B + {#b#}" using BC by simp |
324 hence "c \<in># B + {#b#}" using BC by simp |
313 thus "c \<in># B" using nc by simp |
325 thus "c \<in># B" using nc by simp |
314 qed |
326 qed |
315 |
327 |
316 |
328 |
|
329 lemma add_eq_conv_ex: |
|
330 "(M + {#a#} = N + {#b#}) = |
|
331 (M = N \<and> a = b \<or> (\<exists>K. M = K + {#b#} \<and> N = K + {#a#}))" |
|
332 by (auto simp add: add_eq_conv_diff) |
|
333 |
|
334 |
|
335 lemma empty_multiset_count: |
|
336 "(\<forall>x. count A x = 0) = (A = {#})" |
|
337 by(metis count_empty multiset_eq_conv_count_eq) |
|
338 |
|
339 |
317 subsubsection {* Intersection *} |
340 subsubsection {* Intersection *} |
318 |
341 |
319 lemma multiset_inter_count: |
342 lemma multiset_inter_count: |
320 "count (A #\<inter> B) x = min (count A x) (count B x)" |
343 "count (A #\<inter> B) x = min (count A x) (count B x)" |
321 by (simp add: multiset_inter_def min_def) |
344 by (simp add: multiset_inter_def min_def) |
322 |
345 |
323 lemma multiset_inter_commute: "A #\<inter> B = B #\<inter> A" |
346 lemma multiset_inter_commute: "A #\<inter> B = B #\<inter> A" |
324 by (simp add: multiset_eq_conv_count_eq multiset_inter_count |
347 by (simp add: multiset_eq_conv_count_eq multiset_inter_count |
325 min_max.inf_commute) |
348 min_max.inf_commute) |
326 |
349 |
327 lemma multiset_inter_assoc: "A #\<inter> (B #\<inter> C) = A #\<inter> B #\<inter> C" |
350 lemma multiset_inter_assoc: "A #\<inter> (B #\<inter> C) = A #\<inter> B #\<inter> C" |
328 by (simp add: multiset_eq_conv_count_eq multiset_inter_count |
351 by (simp add: multiset_eq_conv_count_eq multiset_inter_count |
329 min_max.inf_assoc) |
352 min_max.inf_assoc) |
330 |
353 |
331 lemma multiset_inter_left_commute: "A #\<inter> (B #\<inter> C) = B #\<inter> (A #\<inter> C)" |
354 lemma multiset_inter_left_commute: "A #\<inter> (B #\<inter> C) = B #\<inter> (A #\<inter> C)" |
332 by (simp add: multiset_eq_conv_count_eq multiset_inter_count min_def) |
355 by (simp add: multiset_eq_conv_count_eq multiset_inter_count min_def) |
333 |
356 |
334 lemmas multiset_inter_ac = |
357 lemmas multiset_inter_ac = |
335 multiset_inter_commute |
358 multiset_inter_commute |
336 multiset_inter_assoc |
359 multiset_inter_assoc |
337 multiset_inter_left_commute |
360 multiset_inter_left_commute |
343 apply (erule_tac x = a in allE) |
366 apply (erule_tac x = a in allE) |
344 apply auto |
367 apply auto |
345 done |
368 done |
346 |
369 |
347 |
370 |
348 subsection {* Induction over multisets *} |
371 subsubsection {* Comprehension (filter) *} |
|
372 |
|
373 lemma MCollect_empty[simp, code func]: "MCollect {#} P = {#}" |
|
374 by(simp add:MCollect_def Mempty_def Abs_multiset_inject in_multiset expand_fun_eq) |
|
375 |
|
376 lemma MCollect_single[simp, code func]: |
|
377 "MCollect {#x#} P = (if P x then {#x#} else {#})" |
|
378 by(simp add:MCollect_def Mempty_def single_def Abs_multiset_inject in_multiset expand_fun_eq) |
|
379 |
|
380 lemma MCollect_union[simp, code func]: |
|
381 "MCollect (M+N) f = MCollect M f + MCollect N f" |
|
382 by(simp add:MCollect_def union_def Abs_multiset_inject in_multiset expand_fun_eq) |
|
383 |
|
384 |
|
385 subsection {* Induction and case splits *} |
349 |
386 |
350 lemma setsum_decr: |
387 lemma setsum_decr: |
351 "finite F ==> (0::nat) < f a ==> |
388 "finite F ==> (0::nat) < f a ==> |
352 setsum (f (a := f a - 1)) F = (if a\<in>F then setsum f F - 1 else setsum f F)" |
389 setsum (f (a := f a - 1)) F = (if a\<in>F then setsum f F - 1 else setsum f F)" |
353 apply (induct rule: finite_induct) |
390 apply (induct rule: finite_induct) |
408 apply (subgoal_tac "f(b := f b + 1) = (\<lambda>a. f a + (if a=b then 1 else 0))") |
445 apply (subgoal_tac "f(b := f b + 1) = (\<lambda>a. f a + (if a=b then 1 else 0))") |
409 prefer 2 |
446 prefer 2 |
410 apply (simp add: expand_fun_eq) |
447 apply (simp add: expand_fun_eq) |
411 apply (erule ssubst) |
448 apply (erule ssubst) |
412 apply (erule Abs_multiset_inverse [THEN subst]) |
449 apply (erule Abs_multiset_inverse [THEN subst]) |
413 apply (erule add [unfolded defns, simplified]) |
450 apply (drule add [unfolded defns, simplified]) |
|
451 apply(simp add:in_multiset) |
414 done |
452 done |
415 qed |
453 qed |
416 |
|
417 lemma empty_multiset_count: |
|
418 "(\<forall>x. count A x = 0) = (A = {#})" |
|
419 apply (rule iffI) |
|
420 apply (induct A, simp) |
|
421 apply (erule_tac x=x in allE) |
|
422 apply auto |
|
423 done |
|
424 |
|
425 subsection {* Case splits *} |
|
426 |
454 |
427 lemma multi_nonempty_split: "M \<noteq> {#} \<Longrightarrow> \<exists>A a. M = A + {#a#}" |
455 lemma multi_nonempty_split: "M \<noteq> {#} \<Longrightarrow> \<exists>A a. M = A + {#a#}" |
428 by (induct M, auto) |
456 by (induct M, auto) |
429 |
457 |
430 lemma multiset_cases [cases type, case_names empty add]: |
458 lemma multiset_cases [cases type, case_names empty add]: |
443 lemma multi_member_split: "x \<in># M \<Longrightarrow> \<exists>A. M = A + {#x#}" |
471 lemma multi_member_split: "x \<in># M \<Longrightarrow> \<exists>A. M = A + {#x#}" |
444 apply (cases M, simp) |
472 apply (cases M, simp) |
445 apply (rule_tac x="M - {#x#}" in exI, simp) |
473 apply (rule_tac x="M - {#x#}" in exI, simp) |
446 done |
474 done |
447 |
475 |
448 lemma MCollect_preserves_multiset: |
|
449 "M \<in> multiset ==> (\<lambda>x. if P x then M x else 0) \<in> multiset" |
|
450 apply (simp add: multiset_def) |
|
451 apply (rule finite_subset, auto) |
|
452 done |
|
453 |
|
454 lemma count_MCollect [simp]: |
|
455 "count {# x:M. P x #} a = (if P a then count M a else 0)" |
|
456 by (simp add: count_def MCollect_def MCollect_preserves_multiset) |
|
457 |
|
458 lemma set_of_MCollect [simp]: "set_of {# x:M. P x #} = set_of M \<inter> {x. P x}" |
|
459 by (auto simp add: set_of_def) |
|
460 |
|
461 lemma multiset_partition: "M = {# x:M. P x #} + {# x:M. \<not> P x #}" |
476 lemma multiset_partition: "M = {# x:M. P x #} + {# x:M. \<not> P x #}" |
462 by (subst multiset_eq_conv_count_eq, auto) |
477 by (subst multiset_eq_conv_count_eq, auto) |
463 |
478 |
464 lemma add_eq_conv_ex: |
|
465 "(M + {#a#} = N + {#b#}) = |
|
466 (M = N \<and> a = b \<or> (\<exists>K. M = K + {#b#} \<and> N = K + {#a#}))" |
|
467 by (auto simp add: add_eq_conv_diff) |
|
468 |
|
469 declare multiset_typedef [simp del] |
479 declare multiset_typedef [simp del] |
470 |
|
471 lemma nonempty_has_size: "(S \<noteq> {#}) = (0 < size S)" |
|
472 apply (rule iffI) |
|
473 apply (case_tac "size S = 0") |
|
474 apply clarsimp |
|
475 apply (subst (asm) neq0_conv) |
|
476 apply auto |
|
477 done |
|
478 |
480 |
479 lemma multi_drop_mem_not_eq: "c \<in># B \<Longrightarrow> B - {#c#} \<noteq> B" |
481 lemma multi_drop_mem_not_eq: "c \<in># B \<Longrightarrow> B - {#c#} \<noteq> B" |
480 by (cases "B={#}", auto dest: multi_member_split) |
482 by (cases "B={#}", auto dest: multi_member_split) |
481 |
483 |
482 subsection {* Multiset orderings *} |
484 subsection {* Orderings *} |
483 |
485 |
484 subsubsection {* Well-foundedness *} |
486 subsubsection {* Well-foundedness *} |
485 |
487 |
486 definition |
488 definition |
487 mult1 :: "('a \<times> 'a) set => ('a multiset \<times> 'a multiset) set" where |
489 mult1 :: "('a \<times> 'a) set => ('a multiset \<times> 'a multiset) set" where |
1065 apply (unfold mset_less_rel_def) |
1065 apply (unfold mset_less_rel_def) |
1066 apply (rule wf_measure [THEN wf_subset, where f1=size]) |
1066 apply (rule wf_measure [THEN wf_subset, where f1=size]) |
1067 apply (clarsimp simp: measure_def inv_image_def mset_less_size) |
1067 apply (clarsimp simp: measure_def inv_image_def mset_less_size) |
1068 done |
1068 done |
1069 |
1069 |
1070 subsubsection {* The induction rules *} |
1070 text {* The induction rules: *} |
1071 |
1071 |
1072 lemma full_multiset_induct [case_names less]: |
1072 lemma full_multiset_induct [case_names less]: |
1073 assumes ih: "\<And>B. \<forall>A. A \<subset># B \<longrightarrow> P A \<Longrightarrow> P B" |
1073 assumes ih: "\<And>B. \<forall>A. A \<subset># B \<longrightarrow> P A \<Longrightarrow> P B" |
1074 shows "P B" |
1074 shows "P B" |
1075 apply (rule wf_mset_less_rel [THEN wf_induct]) |
1075 apply (rule wf_mset_less_rel [THEN wf_induct]) |
1285 proof - |
1285 proof - |
1286 from a obtain A' where "A = A' + {#a#}" by (blast dest: multi_member_split) |
1286 from a obtain A' where "A = A' + {#a#}" by (blast dest: multi_member_split) |
1287 thus ?thesis by simp |
1287 thus ?thesis by simp |
1288 qed |
1288 qed |
1289 |
1289 |
|
1290 text{* A note on code generation: When defining some |
|
1291 function containing a subterm @{term"fold_mset F"}, code generation is |
|
1292 not automatic. When interpreting locale @{text left_commutative} with |
|
1293 @{text F}, the would be code thms for @{const fold_mset} become thms like |
|
1294 @{term"fold_mset F z {#} = z"} where @{text F} is not a pattern but contains |
|
1295 defined symbols, i.e.\ is not a code thm. Hence a separate constant with its |
|
1296 own code thms needs to be introduced for @{text F}. See the image operator |
|
1297 below. *} |
|
1298 |
|
1299 subsection {* Image *} |
|
1300 |
|
1301 definition [code func del]: "image_mset f == fold_mset (op + o single o f) {#}" |
|
1302 |
|
1303 interpretation image_left_comm: left_commutative["op + o single o f"] |
|
1304 by(unfold_locales)(simp add:union_ac) |
|
1305 |
|
1306 lemma image_mset_empty[simp,code func]: "image_mset f {#} = {#}" |
|
1307 by(simp add:image_mset_def) |
|
1308 |
|
1309 lemma image_mset_single[simp,code func]: "image_mset f {#x#} = {#f x#}" |
|
1310 by(simp add:image_mset_def) |
|
1311 |
|
1312 lemma image_mset_insert: |
|
1313 "image_mset f (M + {#a#}) = image_mset f M + {#f a#}" |
|
1314 by(simp add:image_mset_def add_ac) |
|
1315 |
|
1316 lemma image_mset_union[simp, code func]: |
|
1317 "image_mset f (M+N) = image_mset f M + image_mset f N" |
|
1318 apply(induct N) |
|
1319 apply simp |
|
1320 apply(simp add:union_assoc[symmetric] image_mset_insert) |
|
1321 done |
|
1322 |
|
1323 lemma size_image_mset[simp]: "size(image_mset f M) = size M" |
|
1324 by(induct M) simp_all |
|
1325 |
|
1326 lemma image_mset_is_empty_iff[simp]: "image_mset f M = {#} \<longleftrightarrow> M={#}" |
|
1327 by (cases M) auto |
|
1328 |
|
1329 |
|
1330 syntax comprehension1_mset :: "'a \<Rightarrow> 'b \<Rightarrow> 'b multiset \<Rightarrow> 'a multiset" |
|
1331 ("({#_/. _ :# _#})") |
|
1332 translations "{#e. x:#M#}" == "CONST image_mset (%x. e) M" |
|
1333 |
|
1334 syntax comprehension2_mset :: "'a \<Rightarrow> 'b \<Rightarrow> 'b multiset \<Rightarrow> bool \<Rightarrow> 'a multiset" |
|
1335 ("({#_/ | _ :# _./ _#})") |
|
1336 translations |
|
1337 "{#e | x:#M. P#}" => "{#e. x :# {# x:M. P#}#}" |
|
1338 |
|
1339 text{* This allows to write not just filters like @{term"{#x:M. x<c#}"} |
|
1340 but also images like @{term"{#x+x. x:#M #}"} |
|
1341 and @{term[source]"{#x+x|x:#M. x<c#}"}, where the latter is currently |
|
1342 displayed as @{term"{#x+x|x:#M. x<c#}"}. *} |
|
1343 |
1290 end |
1344 end |