src/HOL/Set_Interval.thy
changeset 57418 6ab1c7cb0b8d
parent 57129 7edb7550663e
child 57447 87429bdecad5
equal deleted inserted replaced
57417:29fe9bac501b 57418:6ab1c7cb0b8d
  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)"
  1789   case False
  1725   case False
  1790   then show ?thesis
  1726   then show ?thesis
  1791     by auto
  1727     by auto
  1792 qed
  1728 qed
  1793 
  1729 
  1794 lemma setprod_power_distrib:
       
  1795   fixes f :: "'a \<Rightarrow> 'b::comm_semiring_1"
       
  1796   shows "setprod f A ^ n = setprod (\<lambda>x. (f x)^n) A"
       
  1797 proof (cases "finite A") 
       
  1798   case True then show ?thesis 
       
  1799     by (induct A rule: finite_induct) (auto simp add: power_mult_distrib)
       
  1800 next
       
  1801   case False then show ?thesis 
       
  1802     by (metis setprod_infinite power_one)
       
  1803 qed
       
  1804 
       
  1805 end
  1730 end