71 show "comm_monoid_list plus 0" .. |
71 show "comm_monoid_list plus 0" .. |
72 then interpret sum_list: comm_monoid_list plus 0 . |
72 then interpret sum_list: comm_monoid_list plus 0 . |
73 from sum_list_def show "monoid_list.F plus 0 = sum_list" by simp |
73 from sum_list_def show "monoid_list.F plus 0 = sum_list" by simp |
74 qed |
74 qed |
75 |
75 |
76 sublocale setsum: comm_monoid_list_set plus 0 |
76 sublocale sum: comm_monoid_list_set plus 0 |
77 rewrites |
77 rewrites |
78 "monoid_list.F plus 0 = sum_list" |
78 "monoid_list.F plus 0 = sum_list" |
79 and "comm_monoid_set.F plus 0 = setsum" |
79 and "comm_monoid_set.F plus 0 = sum" |
80 proof - |
80 proof - |
81 show "comm_monoid_list_set plus 0" .. |
81 show "comm_monoid_list_set plus 0" .. |
82 then interpret setsum: comm_monoid_list_set plus 0 . |
82 then interpret sum: comm_monoid_list_set plus 0 . |
83 from sum_list_def show "monoid_list.F plus 0 = sum_list" by simp |
83 from sum_list_def show "monoid_list.F plus 0 = sum_list" by simp |
84 from setsum_def show "comm_monoid_set.F plus 0 = setsum" by (auto intro: sym) |
84 from sum_def show "comm_monoid_set.F plus 0 = sum" by (auto intro: sym) |
85 qed |
85 qed |
86 |
86 |
87 end |
87 end |
88 |
88 |
89 text \<open>Some syntactic sugar for summing a function over a list:\<close> |
89 text \<open>Some syntactic sugar for summing a function over a list:\<close> |
132 lemma (in monoid_add) sum_list_map_filter: |
132 lemma (in monoid_add) sum_list_map_filter: |
133 assumes "\<And>x. x \<in> set xs \<Longrightarrow> \<not> P x \<Longrightarrow> f x = 0" |
133 assumes "\<And>x. x \<in> set xs \<Longrightarrow> \<not> P x \<Longrightarrow> f x = 0" |
134 shows "sum_list (map f (filter P xs)) = sum_list (map f xs)" |
134 shows "sum_list (map f (filter P xs)) = sum_list (map f xs)" |
135 using assms by (induct xs) auto |
135 using assms by (induct xs) auto |
136 |
136 |
137 lemma (in comm_monoid_add) distinct_sum_list_conv_Setsum: |
137 lemma (in comm_monoid_add) distinct_sum_list_conv_Sum: |
138 "distinct xs \<Longrightarrow> sum_list xs = Setsum (set xs)" |
138 "distinct xs \<Longrightarrow> sum_list xs = Sum (set xs)" |
139 by (induct xs) simp_all |
139 by (induct xs) simp_all |
140 |
140 |
141 lemma sum_list_upt[simp]: |
141 lemma sum_list_upt[simp]: |
142 "m \<le> n \<Longrightarrow> sum_list [m..<n] = \<Sum> {m..<n}" |
142 "m \<le> n \<Longrightarrow> sum_list [m..<n] = \<Sum> {m..<n}" |
143 by(simp add: distinct_sum_list_conv_Setsum) |
143 by(simp add: distinct_sum_list_conv_Sum) |
144 |
144 |
145 lemma sum_list_eq_0_nat_iff_nat [simp]: |
145 lemma sum_list_eq_0_nat_iff_nat [simp]: |
146 "sum_list ns = (0::nat) \<longleftrightarrow> (\<forall>n \<in> set ns. n = 0)" |
146 "sum_list ns = (0::nat) \<longleftrightarrow> (\<forall>n \<in> set ns. n = 0)" |
147 by (induct ns) simp_all |
147 by (induct ns) simp_all |
148 |
148 |
198 lemma sum_list_mono: |
198 lemma sum_list_mono: |
199 fixes f g :: "'a \<Rightarrow> 'b::{monoid_add, ordered_ab_semigroup_add}" |
199 fixes f g :: "'a \<Rightarrow> 'b::{monoid_add, ordered_ab_semigroup_add}" |
200 shows "(\<And>x. x \<in> set xs \<Longrightarrow> f x \<le> g x) \<Longrightarrow> (\<Sum>x\<leftarrow>xs. f x) \<le> (\<Sum>x\<leftarrow>xs. g x)" |
200 shows "(\<And>x. x \<in> set xs \<Longrightarrow> f x \<le> g x) \<Longrightarrow> (\<Sum>x\<leftarrow>xs. f x) \<le> (\<Sum>x\<leftarrow>xs. g x)" |
201 by (induct xs) (simp, simp add: add_mono) |
201 by (induct xs) (simp, simp add: add_mono) |
202 |
202 |
203 lemma (in monoid_add) sum_list_distinct_conv_setsum_set: |
203 lemma (in monoid_add) sum_list_distinct_conv_sum_set: |
204 "distinct xs \<Longrightarrow> sum_list (map f xs) = setsum f (set xs)" |
204 "distinct xs \<Longrightarrow> sum_list (map f xs) = sum f (set xs)" |
205 by (induct xs) simp_all |
205 by (induct xs) simp_all |
206 |
206 |
207 lemma (in monoid_add) interv_sum_list_conv_setsum_set_nat: |
207 lemma (in monoid_add) interv_sum_list_conv_sum_set_nat: |
208 "sum_list (map f [m..<n]) = setsum f (set [m..<n])" |
208 "sum_list (map f [m..<n]) = sum f (set [m..<n])" |
209 by (simp add: sum_list_distinct_conv_setsum_set) |
209 by (simp add: sum_list_distinct_conv_sum_set) |
210 |
210 |
211 lemma (in monoid_add) interv_sum_list_conv_setsum_set_int: |
211 lemma (in monoid_add) interv_sum_list_conv_sum_set_int: |
212 "sum_list (map f [k..l]) = setsum f (set [k..l])" |
212 "sum_list (map f [k..l]) = sum f (set [k..l])" |
213 by (simp add: sum_list_distinct_conv_setsum_set) |
213 by (simp add: sum_list_distinct_conv_sum_set) |
214 |
214 |
215 text \<open>General equivalence between @{const sum_list} and @{const setsum}\<close> |
215 text \<open>General equivalence between @{const sum_list} and @{const sum}\<close> |
216 lemma (in monoid_add) sum_list_setsum_nth: |
216 lemma (in monoid_add) sum_list_sum_nth: |
217 "sum_list xs = (\<Sum> i = 0 ..< length xs. xs ! i)" |
217 "sum_list xs = (\<Sum> i = 0 ..< length xs. xs ! i)" |
218 using interv_sum_list_conv_setsum_set_nat [of "op ! xs" 0 "length xs"] by (simp add: map_nth) |
218 using interv_sum_list_conv_sum_set_nat [of "op ! xs" 0 "length xs"] by (simp add: map_nth) |
219 |
219 |
220 lemma sum_list_map_eq_setsum_count: |
220 lemma sum_list_map_eq_sum_count: |
221 "sum_list (map f xs) = setsum (\<lambda>x. count_list xs x * f x) (set xs)" |
221 "sum_list (map f xs) = sum (\<lambda>x. count_list xs x * f x) (set xs)" |
222 proof(induction xs) |
222 proof(induction xs) |
223 case (Cons x xs) |
223 case (Cons x xs) |
224 show ?case (is "?l = ?r") |
224 show ?case (is "?l = ?r") |
225 proof cases |
225 proof cases |
226 assume "x \<in> set xs" |
226 assume "x \<in> set xs" |
227 have "?l = f x + (\<Sum>x\<in>set xs. count_list xs x * f x)" by (simp add: Cons.IH) |
227 have "?l = f x + (\<Sum>x\<in>set xs. count_list xs x * f x)" by (simp add: Cons.IH) |
228 also have "set xs = insert x (set xs - {x})" using \<open>x \<in> set xs\<close>by blast |
228 also have "set xs = insert x (set xs - {x})" using \<open>x \<in> set xs\<close>by blast |
229 also have "f x + (\<Sum>x\<in>insert x (set xs - {x}). count_list xs x * f x) = ?r" |
229 also have "f x + (\<Sum>x\<in>insert x (set xs - {x}). count_list xs x * f x) = ?r" |
230 by (simp add: setsum.insert_remove eq_commute) |
230 by (simp add: sum.insert_remove eq_commute) |
231 finally show ?thesis . |
231 finally show ?thesis . |
232 next |
232 next |
233 assume "x \<notin> set xs" |
233 assume "x \<notin> set xs" |
234 hence "\<And>xa. xa \<in> set xs \<Longrightarrow> x \<noteq> xa" by blast |
234 hence "\<And>xa. xa \<in> set xs \<Longrightarrow> x \<noteq> xa" by blast |
235 thus ?thesis by (simp add: Cons.IH \<open>x \<notin> set xs\<close>) |
235 thus ?thesis by (simp add: Cons.IH \<open>x \<notin> set xs\<close>) |
236 qed |
236 qed |
237 qed simp |
237 qed simp |
238 |
238 |
239 lemma sum_list_map_eq_setsum_count2: |
239 lemma sum_list_map_eq_sum_count2: |
240 assumes "set xs \<subseteq> X" "finite X" |
240 assumes "set xs \<subseteq> X" "finite X" |
241 shows "sum_list (map f xs) = setsum (\<lambda>x. count_list xs x * f x) X" |
241 shows "sum_list (map f xs) = sum (\<lambda>x. count_list xs x * f x) X" |
242 proof- |
242 proof- |
243 let ?F = "\<lambda>x. count_list xs x * f x" |
243 let ?F = "\<lambda>x. count_list xs x * f x" |
244 have "setsum ?F X = setsum ?F (set xs \<union> (X - set xs))" |
244 have "sum ?F X = sum ?F (set xs \<union> (X - set xs))" |
245 using Un_absorb1[OF assms(1)] by(simp) |
245 using Un_absorb1[OF assms(1)] by(simp) |
246 also have "\<dots> = setsum ?F (set xs)" |
246 also have "\<dots> = sum ?F (set xs)" |
247 using assms(2) |
247 using assms(2) |
248 by(simp add: setsum.union_disjoint[OF _ _ Diff_disjoint] del: Un_Diff_cancel) |
248 by(simp add: sum.union_disjoint[OF _ _ Diff_disjoint] del: Un_Diff_cancel) |
249 finally show ?thesis by(simp add:sum_list_map_eq_setsum_count) |
249 finally show ?thesis by(simp add:sum_list_map_eq_sum_count) |
250 qed |
250 qed |
251 |
251 |
252 lemma sum_list_nonneg: |
252 lemma sum_list_nonneg: |
253 "(\<And>x. x \<in> set xs \<Longrightarrow> (x :: 'a :: ordered_comm_monoid_add) \<ge> 0) \<Longrightarrow> sum_list xs \<ge> 0" |
253 "(\<And>x. x \<in> set xs \<Longrightarrow> (x :: 'a :: ordered_comm_monoid_add) \<ge> 0) \<Longrightarrow> sum_list xs \<ge> 0" |
254 by (induction xs) simp_all |
254 by (induction xs) simp_all |
296 qed |
296 qed |
297 |
297 |
298 |
298 |
299 subsection \<open>Tools setup\<close> |
299 subsection \<open>Tools setup\<close> |
300 |
300 |
301 lemmas setsum_code = setsum.set_conv_list |
301 lemmas sum_code = sum.set_conv_list |
302 |
302 |
303 lemma setsum_set_upto_conv_sum_list_int [code_unfold]: |
303 lemma sum_set_upto_conv_sum_list_int [code_unfold]: |
304 "setsum f (set [i..j::int]) = sum_list (map f [i..j])" |
304 "sum f (set [i..j::int]) = sum_list (map f [i..j])" |
305 by (simp add: interv_sum_list_conv_setsum_set_int) |
305 by (simp add: interv_sum_list_conv_sum_set_int) |
306 |
306 |
307 lemma setsum_set_upt_conv_sum_list_nat [code_unfold]: |
307 lemma sum_set_upt_conv_sum_list_nat [code_unfold]: |
308 "setsum f (set [m..<n]) = sum_list (map f [m..<n])" |
308 "sum f (set [m..<n]) = sum_list (map f [m..<n])" |
309 by (simp add: interv_sum_list_conv_setsum_set_nat) |
309 by (simp add: interv_sum_list_conv_sum_set_nat) |
310 |
310 |
311 lemma sum_list_transfer[transfer_rule]: |
311 lemma sum_list_transfer[transfer_rule]: |
312 includes lifting_syntax |
312 includes lifting_syntax |
313 assumes [transfer_rule]: "A 0 0" |
313 assumes [transfer_rule]: "A 0 0" |
314 assumes [transfer_rule]: "(A ===> A ===> A) op + op +" |
314 assumes [transfer_rule]: "(A ===> A ===> A) op + op +" |