14052
|
1 |
(* Title: ZF/UNITY/MultusetSum.thy
|
|
2 |
ID: $Id$
|
|
3 |
Author: Sidi O Ehmety
|
|
4 |
*)
|
|
5 |
|
15202
|
6 |
header {*Setsum for Multisets*}
|
|
7 |
|
|
8 |
theory MultisetSum
|
|
9 |
imports "../Induct/Multiset"
|
|
10 |
begin
|
|
11 |
|
24893
|
12 |
definition
|
|
13 |
lcomm :: "[i, i, [i,i]=>i]=>o" where
|
14052
|
14 |
"lcomm(A, B, f) ==
|
15202
|
15 |
(\<forall>x \<in> A. \<forall>y \<in> A. \<forall>z \<in> B. f(x, f(y, z))= f(y, f(x, z))) &
|
|
16 |
(\<forall>x \<in> A. \<forall>y \<in> B. f(x, y) \<in> B)"
|
14052
|
17 |
|
24893
|
18 |
definition
|
|
19 |
general_setsum :: "[i,i,i, [i,i]=>i, i=>i] =>i" where
|
14052
|
20 |
"general_setsum(C, B, e, f, g) ==
|
|
21 |
if Finite(C) then fold[cons(e, B)](%x y. f(g(x), y), e, C) else e"
|
|
22 |
|
24893
|
23 |
definition
|
|
24 |
msetsum :: "[i=>i, i, i]=>i" where
|
14052
|
25 |
"msetsum(g, C, B) == normalize(general_setsum(C, Mult(B), 0, op +#, g))"
|
|
26 |
|
24893
|
27 |
|
|
28 |
definition (* sum for naturals *)
|
|
29 |
nsetsum :: "[i=>i, i] =>i" where
|
14052
|
30 |
"nsetsum(g, C) == general_setsum(C, nat, 0, op #+, g)"
|
15202
|
31 |
|
|
32 |
|
|
33 |
lemma mset_of_normalize: "mset_of(normalize(M)) \<subseteq> mset_of(M)"
|
|
34 |
by (auto simp add: mset_of_def normalize_def)
|
|
35 |
|
|
36 |
lemma general_setsum_0 [simp]: "general_setsum(0, B, e, f, g) = e"
|
|
37 |
by (simp add: general_setsum_def)
|
|
38 |
|
|
39 |
lemma general_setsum_cons [simp]:
|
|
40 |
"[| C \<in> Fin(A); a \<in> A; a\<notin>C; e \<in> B; \<forall>x \<in> A. g(x) \<in> B; lcomm(B, B, f) |] ==>
|
|
41 |
general_setsum(cons(a, C), B, e, f, g) =
|
|
42 |
f(g(a), general_setsum(C, B, e, f,g))"
|
|
43 |
apply (simp add: general_setsum_def)
|
|
44 |
apply (auto simp add: Fin_into_Finite [THEN Finite_cons] cons_absorb)
|
|
45 |
prefer 2 apply (blast dest: Fin_into_Finite)
|
|
46 |
apply (rule fold_typing.fold_cons)
|
|
47 |
apply (auto simp add: fold_typing_def lcomm_def)
|
|
48 |
done
|
|
49 |
|
|
50 |
(** lcomm **)
|
|
51 |
|
|
52 |
lemma lcomm_mono: "[| C\<subseteq>A; lcomm(A, B, f) |] ==> lcomm(C, B,f)"
|
|
53 |
by (auto simp add: lcomm_def, blast)
|
|
54 |
|
|
55 |
lemma munion_lcomm [simp]: "lcomm(Mult(A), Mult(A), op +#)"
|
|
56 |
by (auto simp add: lcomm_def Mult_iff_multiset munion_lcommute)
|
|
57 |
|
|
58 |
(** msetsum **)
|
|
59 |
|
|
60 |
lemma multiset_general_setsum:
|
|
61 |
"[| C \<in> Fin(A); \<forall>x \<in> A. multiset(g(x))& mset_of(g(x))\<subseteq>B |]
|
|
62 |
==> multiset(general_setsum(C, B -||> nat - {0}, 0, \<lambda>u v. u +# v, g))"
|
|
63 |
apply (erule Fin_induct, auto)
|
|
64 |
apply (subst general_setsum_cons)
|
|
65 |
apply (auto simp add: Mult_iff_multiset)
|
|
66 |
done
|
|
67 |
|
|
68 |
lemma msetsum_0 [simp]: "msetsum(g, 0, B) = 0"
|
|
69 |
by (simp add: msetsum_def)
|
|
70 |
|
|
71 |
lemma msetsum_cons [simp]:
|
|
72 |
"[| C \<in> Fin(A); a\<notin>C; a \<in> A; \<forall>x \<in> A. multiset(g(x)) & mset_of(g(x))\<subseteq>B |]
|
|
73 |
==> msetsum(g, cons(a, C), B) = g(a) +# msetsum(g, C, B)"
|
|
74 |
apply (simp add: msetsum_def)
|
|
75 |
apply (subst general_setsum_cons)
|
|
76 |
apply (auto simp add: multiset_general_setsum Mult_iff_multiset)
|
|
77 |
done
|
|
78 |
|
|
79 |
(* msetsum type *)
|
|
80 |
|
|
81 |
lemma msetsum_multiset: "multiset(msetsum(g, C, B))"
|
|
82 |
by (simp add: msetsum_def)
|
|
83 |
|
|
84 |
lemma mset_of_msetsum:
|
|
85 |
"[| C \<in> Fin(A); \<forall>x \<in> A. multiset(g(x)) & mset_of(g(x))\<subseteq>B |]
|
|
86 |
==> mset_of(msetsum(g, C, B))\<subseteq>B"
|
|
87 |
by (erule Fin_induct, auto)
|
|
88 |
|
|
89 |
|
|
90 |
(*The reversed orientation looks more natural, but LOOPS as a simprule!*)
|
|
91 |
lemma msetsum_Un_Int:
|
|
92 |
"[| C \<in> Fin(A); D \<in> Fin(A); \<forall>x \<in> A. multiset(g(x)) & mset_of(g(x))\<subseteq>B |]
|
|
93 |
==> msetsum(g, C Un D, B) +# msetsum(g, C Int D, B)
|
|
94 |
= msetsum(g, C, B) +# msetsum(g, D, B)"
|
|
95 |
apply (erule Fin_induct)
|
|
96 |
apply (subgoal_tac [2] "cons (x, y) Un D = cons (x, y Un D) ")
|
|
97 |
apply (auto simp add: msetsum_multiset)
|
|
98 |
apply (subgoal_tac "y Un D \<in> Fin (A) & y Int D \<in> Fin (A) ")
|
|
99 |
apply clarify
|
|
100 |
apply (case_tac "x \<in> D")
|
|
101 |
apply (subgoal_tac [2] "cons (x, y) Int D = y Int D")
|
|
102 |
apply (subgoal_tac "cons (x, y) Int D = cons (x, y Int D) ")
|
|
103 |
apply (simp_all (no_asm_simp) add: cons_absorb munion_assoc msetsum_multiset)
|
|
104 |
apply (simp (no_asm_simp) add: munion_lcommute msetsum_multiset)
|
|
105 |
apply auto
|
|
106 |
done
|
|
107 |
|
|
108 |
|
|
109 |
lemma msetsum_Un_disjoint:
|
|
110 |
"[| C \<in> Fin(A); D \<in> Fin(A); C Int D = 0;
|
|
111 |
\<forall>x \<in> A. multiset(g(x)) & mset_of(g(x))\<subseteq>B |]
|
|
112 |
==> msetsum(g, C Un D, B) = msetsum(g, C, B) +# msetsum(g,D, B)"
|
|
113 |
apply (subst msetsum_Un_Int [symmetric])
|
|
114 |
apply (auto simp add: msetsum_multiset)
|
|
115 |
done
|
|
116 |
|
|
117 |
lemma UN_Fin_lemma [rule_format (no_asm)]:
|
|
118 |
"I \<in> Fin(A) ==> (\<forall>i \<in> I. C(i) \<in> Fin(B)) --> (\<Union>i \<in> I. C(i)):Fin(B)"
|
|
119 |
by (erule Fin_induct, auto)
|
|
120 |
|
|
121 |
lemma msetsum_UN_disjoint [rule_format (no_asm)]:
|
|
122 |
"[| I \<in> Fin(K); \<forall>i \<in> K. C(i) \<in> Fin(A) |] ==>
|
|
123 |
(\<forall>x \<in> A. multiset(f(x)) & mset_of(f(x))\<subseteq>B) -->
|
|
124 |
(\<forall>i \<in> I. \<forall>j \<in> I. i\<noteq>j --> C(i) Int C(j) = 0) -->
|
|
125 |
msetsum(f, \<Union>i \<in> I. C(i), B) = msetsum (%i. msetsum(f, C(i),B), I, B)"
|
|
126 |
apply (erule Fin_induct, auto)
|
|
127 |
apply (subgoal_tac "\<forall>i \<in> y. x \<noteq> i")
|
|
128 |
prefer 2 apply blast
|
|
129 |
apply (subgoal_tac "C(x) Int (\<Union>i \<in> y. C (i)) = 0")
|
|
130 |
prefer 2 apply blast
|
|
131 |
apply (subgoal_tac " (\<Union>i \<in> y. C (i)):Fin (A) & C(x) :Fin (A) ")
|
|
132 |
prefer 2 apply (blast intro: UN_Fin_lemma dest: FinD, clarify)
|
|
133 |
apply (simp (no_asm_simp) add: msetsum_Un_disjoint)
|
|
134 |
apply (subgoal_tac "\<forall>x \<in> K. multiset (msetsum (f, C(x), B)) & mset_of (msetsum (f, C(x), B)) \<subseteq> B")
|
|
135 |
apply (simp (no_asm_simp))
|
|
136 |
apply clarify
|
|
137 |
apply (drule_tac x = xa in bspec)
|
|
138 |
apply (simp_all (no_asm_simp) add: msetsum_multiset mset_of_msetsum)
|
|
139 |
done
|
|
140 |
|
|
141 |
lemma msetsum_addf:
|
|
142 |
"[| C \<in> Fin(A);
|
|
143 |
\<forall>x \<in> A. multiset(f(x)) & mset_of(f(x))\<subseteq>B;
|
|
144 |
\<forall>x \<in> A. multiset(g(x)) & mset_of(g(x))\<subseteq>B |] ==>
|
|
145 |
msetsum(%x. f(x) +# g(x), C, B) = msetsum(f, C, B) +# msetsum(g, C, B)"
|
|
146 |
apply (subgoal_tac "\<forall>x \<in> A. multiset (f(x) +# g(x)) & mset_of (f(x) +# g(x)) \<subseteq> B")
|
|
147 |
apply (erule Fin_induct)
|
|
148 |
apply (auto simp add: munion_ac)
|
|
149 |
done
|
|
150 |
|
|
151 |
lemma msetsum_cong:
|
|
152 |
"[| C=D; !!x. x \<in> D ==> f(x) = g(x) |]
|
|
153 |
==> msetsum(f, C, B) = msetsum(g, D, B)"
|
|
154 |
by (simp add: msetsum_def general_setsum_def cong add: fold_cong)
|
|
155 |
|
|
156 |
lemma multiset_union_diff: "[| multiset(M); multiset(N) |] ==> M +# N -# N = M"
|
|
157 |
by (simp add: multiset_equality)
|
|
158 |
|
|
159 |
lemma msetsum_Un: "[| C \<in> Fin(A); D \<in> Fin(A);
|
|
160 |
\<forall>x \<in> A. multiset(f(x)) & mset_of(f(x)) \<subseteq> B |]
|
|
161 |
==> msetsum(f, C Un D, B) =
|
|
162 |
msetsum(f, C, B) +# msetsum(f, D, B) -# msetsum(f, C Int D, B)"
|
|
163 |
apply (subgoal_tac "C Un D \<in> Fin (A) & C Int D \<in> Fin (A) ")
|
|
164 |
apply clarify
|
|
165 |
apply (subst msetsum_Un_Int [symmetric])
|
|
166 |
apply (simp_all (no_asm_simp) add: msetsum_multiset multiset_union_diff)
|
|
167 |
apply (blast dest: FinD)
|
|
168 |
done
|
|
169 |
|
|
170 |
lemma nsetsum_0 [simp]: "nsetsum(g, 0)=0"
|
|
171 |
by (simp add: nsetsum_def)
|
|
172 |
|
|
173 |
lemma nsetsum_cons [simp]:
|
|
174 |
"[| Finite(C); x\<notin>C |] ==> nsetsum(g, cons(x, C))= g(x) #+ nsetsum(g, C)"
|
|
175 |
apply (simp add: nsetsum_def general_setsum_def)
|
|
176 |
apply (rule_tac A = "cons (x, C)" in fold_typing.fold_cons)
|
|
177 |
apply (auto intro: Finite_cons_lemma simp add: fold_typing_def)
|
|
178 |
done
|
|
179 |
|
|
180 |
lemma nsetsum_type [simp,TC]: "nsetsum(g, C) \<in> nat"
|
|
181 |
apply (case_tac "Finite (C) ")
|
|
182 |
prefer 2 apply (simp add: nsetsum_def general_setsum_def)
|
|
183 |
apply (erule Finite_induct, auto)
|
|
184 |
done
|
|
185 |
|
14052
|
186 |
end |