1376 @{term"\<Sum>x::nat=0..<n. e"} rather than @{text"\<Sum>x<n. e"}: @{text setsum} may |
1376 @{term"\<Sum>x::nat=0..<n. e"} rather than @{text"\<Sum>x<n. e"}: @{text setsum} may |
1377 not provide all lemmas available for @{term"{m..<n}"} also in the |
1377 not provide all lemmas available for @{term"{m..<n}"} also in the |
1378 special form for @{term"{..<n}"}. *} |
1378 special form for @{term"{..<n}"}. *} |
1379 |
1379 |
1380 text{* This congruence rule should be used for sums over intervals as |
1380 text{* This congruence rule should be used for sums over intervals as |
1381 the standard theorem @{text[source]setsum_cong} does not work well |
1381 the standard theorem @{text[source]setsum.cong} does not work well |
1382 with the simplifier who adds the unsimplified premise @{term"x:B"} to |
1382 with the simplifier who adds the unsimplified premise @{term"x:B"} to |
1383 the context. *} |
1383 the context. *} |
1384 |
1384 |
1385 lemma setsum_ivl_cong: |
1385 lemma setsum_ivl_cong: |
1386 "\<lbrakk>a = c; b = d; !!x. \<lbrakk> c \<le> x; x < d \<rbrakk> \<Longrightarrow> f x = g x \<rbrakk> \<Longrightarrow> |
1386 "\<lbrakk>a = c; b = d; !!x. \<lbrakk> c \<le> x; x < d \<rbrakk> \<Longrightarrow> f x = g x \<rbrakk> \<Longrightarrow> |
1387 setsum f {a..<b} = setsum g {c..<d}" |
1387 setsum f {a..<b} = setsum g {c..<d}" |
1388 by(rule setsum_cong, simp_all) |
1388 by(rule setsum.cong, simp_all) |
1389 |
1389 |
1390 (* FIXME why are the following simp rules but the corresponding eqns |
1390 (* FIXME why are the following simp rules but the corresponding eqns |
1391 on intervals are not? *) |
1391 on intervals are not? *) |
1392 |
1392 |
1393 lemma setsum_atMost_Suc[simp]: "(\<Sum>i \<le> Suc n. f i) = (\<Sum>i \<le> n. f i) + f(Suc n)" |
1393 lemma setsum_atMost_Suc[simp]: "(\<Sum>i \<le> Suc n. f i) = (\<Sum>i \<le> n. f i) + f(Suc n)" |
1435 |
1435 |
1436 lemma setsum_ub_add_nat: assumes "(m::nat) \<le> n + 1" |
1436 lemma setsum_ub_add_nat: assumes "(m::nat) \<le> n + 1" |
1437 shows "setsum f {m..n + p} = setsum f {m..n} + setsum f {n + 1..n + p}" |
1437 shows "setsum f {m..n + p} = setsum f {m..n} + setsum f {n + 1..n + p}" |
1438 proof- |
1438 proof- |
1439 have "{m .. n+p} = {m..n} \<union> {n+1..n+p}" using `m \<le> n+1` by auto |
1439 have "{m .. n+p} = {m..n} \<union> {n+1..n+p}" using `m \<le> n+1` by auto |
1440 thus ?thesis by (auto simp: ivl_disj_int setsum_Un_disjoint |
1440 thus ?thesis by (auto simp: ivl_disj_int setsum.union_disjoint |
1441 atLeastSucAtMost_greaterThanAtMost) |
1441 atLeastSucAtMost_greaterThanAtMost) |
1442 qed |
1442 qed |
1443 |
1443 |
1444 lemma setsum_add_nat_ivl: "\<lbrakk> m \<le> n; n \<le> p \<rbrakk> \<Longrightarrow> |
1444 lemma setsum_add_nat_ivl: "\<lbrakk> m \<le> n; n \<le> p \<rbrakk> \<Longrightarrow> |
1445 setsum f {m..<n} + setsum f {n..<p} = setsum f {m..<p::nat}" |
1445 setsum f {m..<n} + setsum f {n..<p} = setsum f {m..<p::nat}" |
1446 by (simp add:setsum_Un_disjoint[symmetric] ivl_disj_int ivl_disj_un) |
1446 by (simp add:setsum.union_disjoint[symmetric] ivl_disj_int ivl_disj_un) |
1447 |
1447 |
1448 lemma setsum_diff_nat_ivl: |
1448 lemma setsum_diff_nat_ivl: |
1449 fixes f :: "nat \<Rightarrow> 'a::ab_group_add" |
1449 fixes f :: "nat \<Rightarrow> 'a::ab_group_add" |
1450 shows "\<lbrakk> m \<le> n; n \<le> p \<rbrakk> \<Longrightarrow> |
1450 shows "\<lbrakk> m \<le> n; n \<le> p \<rbrakk> \<Longrightarrow> |
1451 setsum f {m..<p} - setsum f {m..<n} = setsum f {n..<p}" |
1451 setsum f {m..<p} - setsum f {m..<n} = setsum f {n..<p}" |
1456 lemma setsum_natinterval_difff: |
1456 lemma setsum_natinterval_difff: |
1457 fixes f:: "nat \<Rightarrow> ('a::ab_group_add)" |
1457 fixes f:: "nat \<Rightarrow> ('a::ab_group_add)" |
1458 shows "setsum (\<lambda>k. f k - f(k + 1)) {(m::nat) .. n} = |
1458 shows "setsum (\<lambda>k. f k - f(k + 1)) {(m::nat) .. n} = |
1459 (if m <= n then f m - f(n + 1) else 0)" |
1459 (if m <= n then f m - f(n + 1) else 0)" |
1460 by (induct n, auto simp add: algebra_simps not_le le_Suc_eq) |
1460 by (induct n, auto simp add: algebra_simps not_le le_Suc_eq) |
1461 |
|
1462 lemma setsum_restrict_set': |
|
1463 "finite A \<Longrightarrow> setsum f {x \<in> A. x \<in> B} = (\<Sum>x\<in>A. if x \<in> B then f x else 0)" |
|
1464 by (simp add: setsum_restrict_set [symmetric] Int_def) |
|
1465 |
|
1466 lemma setsum_restrict_set'': |
|
1467 "finite A \<Longrightarrow> setsum f {x \<in> A. P x} = (\<Sum>x\<in>A. if P x then f x else 0)" |
|
1468 by (simp add: setsum_restrict_set' [of A f "{x. P x}", simplified mem_Collect_eq]) |
|
1469 |
|
1470 lemma setsum_setsum_restrict: |
|
1471 "finite S \<Longrightarrow> finite T \<Longrightarrow> |
|
1472 setsum (\<lambda>x. setsum (\<lambda>y. f x y) {y. y \<in> T \<and> R x y}) S = setsum (\<lambda>y. setsum (\<lambda>x. f x y) {x. x \<in> S \<and> R x y}) T" |
|
1473 by (simp add: setsum_restrict_set'') (rule setsum_commute) |
|
1474 |
|
1475 lemma setsum_image_gen: assumes fS: "finite S" |
|
1476 shows "setsum g S = setsum (\<lambda>y. setsum g {x. x \<in> S \<and> f x = y}) (f ` S)" |
|
1477 proof- |
|
1478 { fix x assume "x \<in> S" then have "{y. y\<in> f`S \<and> f x = y} = {f x}" by auto } |
|
1479 hence "setsum g S = setsum (\<lambda>x. setsum (\<lambda>y. g x) {y. y\<in> f`S \<and> f x = y}) S" |
|
1480 by simp |
|
1481 also have "\<dots> = setsum (\<lambda>y. setsum g {x. x \<in> S \<and> f x = y}) (f ` S)" |
|
1482 by (rule setsum_setsum_restrict[OF fS finite_imageI[OF fS]]) |
|
1483 finally show ?thesis . |
|
1484 qed |
|
1485 |
|
1486 lemma setsum_le_included: |
|
1487 fixes f :: "'a \<Rightarrow> 'b::ordered_comm_monoid_add" |
|
1488 assumes "finite s" "finite t" |
|
1489 and "\<forall>y\<in>t. 0 \<le> g y" "(\<forall>x\<in>s. \<exists>y\<in>t. i y = x \<and> f x \<le> g y)" |
|
1490 shows "setsum f s \<le> setsum g t" |
|
1491 proof - |
|
1492 have "setsum f s \<le> setsum (\<lambda>y. setsum g {x. x\<in>t \<and> i x = y}) s" |
|
1493 proof (rule setsum_mono) |
|
1494 fix y assume "y \<in> s" |
|
1495 with assms obtain z where z: "z \<in> t" "y = i z" "f y \<le> g z" by auto |
|
1496 with assms show "f y \<le> setsum g {x \<in> t. i x = y}" (is "?A y \<le> ?B y") |
|
1497 using order_trans[of "?A (i z)" "setsum g {z}" "?B (i z)", intro] |
|
1498 by (auto intro!: setsum_mono2) |
|
1499 qed |
|
1500 also have "... \<le> setsum (\<lambda>y. setsum g {x. x\<in>t \<and> i x = y}) (i ` t)" |
|
1501 using assms(2-4) by (auto intro!: setsum_mono2 setsum_nonneg) |
|
1502 also have "... \<le> setsum g t" |
|
1503 using assms by (auto simp: setsum_image_gen[symmetric]) |
|
1504 finally show ?thesis . |
|
1505 qed |
|
1506 |
|
1507 lemma setsum_multicount_gen: |
|
1508 assumes "finite s" "finite t" "\<forall>j\<in>t. (card {i\<in>s. R i j} = k j)" |
|
1509 shows "setsum (\<lambda>i. (card {j\<in>t. R i j})) s = setsum k t" (is "?l = ?r") |
|
1510 proof- |
|
1511 have "?l = setsum (\<lambda>i. setsum (\<lambda>x.1) {j\<in>t. R i j}) s" by auto |
|
1512 also have "\<dots> = ?r" unfolding setsum_setsum_restrict[OF assms(1-2)] |
|
1513 using assms(3) by auto |
|
1514 finally show ?thesis . |
|
1515 qed |
|
1516 |
|
1517 lemma setsum_multicount: |
|
1518 assumes "finite S" "finite T" "\<forall>j\<in>T. (card {i\<in>S. R i j} = k)" |
|
1519 shows "setsum (\<lambda>i. card {j\<in>T. R i j}) S = k * card T" (is "?l = ?r") |
|
1520 proof- |
|
1521 have "?l = setsum (\<lambda>i. k) T" by(rule setsum_multicount_gen)(auto simp:assms) |
|
1522 also have "\<dots> = ?r" by(simp add: mult_commute) |
|
1523 finally show ?thesis by auto |
|
1524 qed |
|
1525 |
1461 |
1526 lemma setsum_nat_group: "(\<Sum>m<n::nat. setsum f {m * k ..< m*k + k}) = setsum f {..< n * k}" |
1462 lemma setsum_nat_group: "(\<Sum>m<n::nat. setsum f {m * k ..< m*k + k}) = setsum f {..< n * k}" |
1527 apply (subgoal_tac "k = 0 | 0 < k", auto) |
1463 apply (subgoal_tac "k = 0 | 0 < k", auto) |
1528 apply (induct "n") |
1464 apply (induct "n") |
1529 apply (simp_all add: setsum_add_nat_ivl add_commute atLeast0LessThan[symmetric]) |
1465 apply (simp_all add: setsum_add_nat_ivl add_commute atLeast0LessThan[symmetric]) |
1585 shows "(\<Sum>i = m..n. f(Suc i) - f i) = f (Suc n) - f m" |
1521 shows "(\<Sum>i = m..n. f(Suc i) - f i) = f (Suc n) - f m" |
1586 using assms by (induct n) (auto simp: le_Suc_eq) |
1522 using assms by (induct n) (auto simp: le_Suc_eq) |
1587 |
1523 |
1588 lemma nested_setsum_swap: |
1524 lemma nested_setsum_swap: |
1589 "(\<Sum>i = 0..n. (\<Sum>j = 0..<i. a i j)) = (\<Sum>j = 0..<n. \<Sum>i = Suc j..n. a i j)" |
1525 "(\<Sum>i = 0..n. (\<Sum>j = 0..<i. a i j)) = (\<Sum>j = 0..<n. \<Sum>i = Suc j..n. a i j)" |
1590 by (induction n) (auto simp: setsum_addf) |
1526 by (induction n) (auto simp: setsum.distrib) |
1591 |
1527 |
1592 lemma nested_setsum_swap': |
1528 lemma nested_setsum_swap': |
1593 "(\<Sum>i\<le>n. (\<Sum>j<i. a i j)) = (\<Sum>j<n. \<Sum>i = Suc j..n. a i j)" |
1529 "(\<Sum>i\<le>n. (\<Sum>j<i. a i j)) = (\<Sum>j<n. \<Sum>i = Suc j..n. a i j)" |
1594 by (induction n) (auto simp: setsum_addf) |
1530 by (induction n) (auto simp: setsum.distrib) |
1595 |
1531 |
1596 lemma setsum_zero_power [simp]: |
1532 lemma setsum_zero_power [simp]: |
1597 fixes c :: "nat \<Rightarrow> 'a::division_ring" |
1533 fixes c :: "nat \<Rightarrow> 'a::division_ring" |
1598 shows "(\<Sum>i\<in>A. c i * 0^i) = (if finite A \<and> 0 \<in> A then c 0 else 0)" |
1534 shows "(\<Sum>i\<in>A. c i * 0^i) = (if finite A \<and> 0 \<in> A then c 0 else 0)" |
1599 apply (cases "finite A") |
1535 apply (cases "finite A") |
1640 assume ngt1: "n > 1" |
1576 assume ngt1: "n > 1" |
1641 let ?I = "\<lambda>i. of_nat i" and ?n = "of_nat n" |
1577 let ?I = "\<lambda>i. of_nat i" and ?n = "of_nat n" |
1642 have |
1578 have |
1643 "(\<Sum>i\<in>{..<n}. a+?I i*d) = |
1579 "(\<Sum>i\<in>{..<n}. a+?I i*d) = |
1644 ((\<Sum>i\<in>{..<n}. a) + (\<Sum>i\<in>{..<n}. ?I i*d))" |
1580 ((\<Sum>i\<in>{..<n}. a) + (\<Sum>i\<in>{..<n}. ?I i*d))" |
1645 by (rule setsum_addf) |
1581 by (rule setsum.distrib) |
1646 also from ngt1 have "\<dots> = ?n*a + (\<Sum>i\<in>{..<n}. ?I i*d)" by simp |
1582 also from ngt1 have "\<dots> = ?n*a + (\<Sum>i\<in>{..<n}. ?I i*d)" by simp |
1647 also from ngt1 have "\<dots> = (?n*a + d*(\<Sum>i\<in>{1..<n}. ?I i))" |
1583 also from ngt1 have "\<dots> = (?n*a + d*(\<Sum>i\<in>{1..<n}. ?I i))" |
1648 unfolding One_nat_def |
1584 unfolding One_nat_def |
1649 by (simp add: setsum_right_distrib atLeast0LessThan[symmetric] setsum_shift_lb_Suc0_0_upt mult_ac) |
1585 by (simp add: setsum_right_distrib atLeast0LessThan[symmetric] setsum_shift_lb_Suc0_0_upt mult_ac) |
1650 also have "2*\<dots> = 2*?n*a + d*2*(\<Sum>i\<in>{1..<n}. ?I i)" |
1586 also have "2*\<dots> = 2*?n*a + d*2*(\<Sum>i\<in>{1..<n}. ?I i)" |