|
| 1 | +/- |
| 2 | +Copyright (c) 2017 Johannes Hölzl. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Johannes Hölzl |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module algebra.big_operators.ring |
| 7 | +! leanprover-community/mathlib commit 008205aa645b3f194c1da47025c5f110c8406eab |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Algebra.BigOperators.Basic |
| 12 | +import Mathlib.Algebra.Field.Defs |
| 13 | +import Mathlib.Data.Finset.Pi |
| 14 | +import Mathlib.Data.Finset.Powerset |
| 15 | + |
| 16 | +/-! |
| 17 | +# Results about big operators with values in a (semi)ring |
| 18 | +
|
| 19 | +We prove results about big operators that involve some interaction between |
| 20 | +multiplicative and additive structures on the values being combined. |
| 21 | +-/ |
| 22 | + |
| 23 | + |
| 24 | +universe u v w |
| 25 | + |
| 26 | +-- open BigOperators -- Porting note: commented out locale |
| 27 | + |
| 28 | +variable {α : Type u} {β : Type v} {γ : Type w} |
| 29 | + |
| 30 | +namespace Finset |
| 31 | + |
| 32 | +variable {s s₁ s₂ : Finset α} {a : α} {b : β} {f g : α → β} |
| 33 | + |
| 34 | +section CommMonoid |
| 35 | + |
| 36 | +variable [CommMonoid β] |
| 37 | + |
| 38 | +open Classical |
| 39 | + |
| 40 | +theorem prod_pow_eq_pow_sum {x : β} {f : α → ℕ} : |
| 41 | + ∀ {s : Finset α}, (∏ i in s, x ^ f i) = x ^ ∑ x in s, f x := |
| 42 | + by |
| 43 | + apply Finset.induction |
| 44 | + · simp |
| 45 | + · intro a s has H |
| 46 | + rw [Finset.prod_insert has, Finset.sum_insert has, pow_add, H] |
| 47 | +#align finset.prod_pow_eq_pow_sum Finset.prod_pow_eq_pow_sum |
| 48 | + |
| 49 | +end CommMonoid |
| 50 | + |
| 51 | +section Semiring |
| 52 | + |
| 53 | +variable [NonUnitalNonAssocSemiring β] |
| 54 | + |
| 55 | +theorem sum_mul : (∑ x in s, f x) * b = ∑ x in s, f x * b := |
| 56 | + map_sum (AddMonoidHom.mulRight b) _ s |
| 57 | +#align finset.sum_mul Finset.sum_mul |
| 58 | + |
| 59 | +theorem mul_sum : (b * ∑ x in s, f x) = ∑ x in s, b * f x := |
| 60 | + map_sum (AddMonoidHom.mulLeft b) _ s |
| 61 | +#align finset.mul_sum Finset.mul_sum |
| 62 | + |
| 63 | +theorem sum_mul_sum {ι₁ : Type _} {ι₂ : Type _} (s₁ : Finset ι₁) (s₂ : Finset ι₂) (f₁ : ι₁ → β) |
| 64 | + (f₂ : ι₂ → β) : ((∑ x₁ in s₁, f₁ x₁) * ∑ x₂ in s₂, f₂ x₂) = ∑ p in s₁ ×ᶠ s₂, f₁ p.1 * f₂ p.2 := |
| 65 | + by |
| 66 | + rw [sum_product, sum_mul, sum_congr rfl] |
| 67 | + intros |
| 68 | + rw [mul_sum] |
| 69 | +#align finset.sum_mul_sum Finset.sum_mul_sum |
| 70 | + |
| 71 | +end Semiring |
| 72 | + |
| 73 | +section Semiring |
| 74 | + |
| 75 | +variable [NonAssocSemiring β] |
| 76 | + |
| 77 | +theorem sum_mul_boole [DecidableEq α] (s : Finset α) (f : α → β) (a : α) : |
| 78 | + (∑ x in s, f x * ite (a = x) 1 0) = ite (a ∈ s) (f a) 0 := by simp |
| 79 | +#align finset.sum_mul_boole Finset.sum_mul_boole |
| 80 | + |
| 81 | +theorem sum_boole_mul [DecidableEq α] (s : Finset α) (f : α → β) (a : α) : |
| 82 | + (∑ x in s, ite (a = x) 1 0 * f x) = ite (a ∈ s) (f a) 0 := by simp |
| 83 | +#align finset.sum_boole_mul Finset.sum_boole_mul |
| 84 | + |
| 85 | +end Semiring |
| 86 | + |
| 87 | +theorem sum_div [DivisionSemiring β] {s : Finset α} {f : α → β} {b : β} : |
| 88 | + (∑ x in s, f x) / b = ∑ x in s, f x / b := by simp only [div_eq_mul_inv, sum_mul] |
| 89 | +#align finset.sum_div Finset.sum_div |
| 90 | + |
| 91 | +section CommSemiring |
| 92 | + |
| 93 | +variable [CommSemiring β] |
| 94 | + |
| 95 | +/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`. |
| 96 | + `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/ |
| 97 | +theorem prod_sum {δ : α → Type _} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α} |
| 98 | + {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} : |
| 99 | + (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := |
| 100 | + by |
| 101 | + induction' s using Finset.induction with a s ha ih |
| 102 | + · rw [pi_empty, sum_singleton] |
| 103 | + rfl |
| 104 | + · have h₁ : ∀ x ∈ t a,∀ y ∈ t a, |
| 105 | + x ≠ y → Disjoint (image (pi.cons s a x) (pi s t)) (image (pi.cons s a y) (pi s t)) := by |
| 106 | + intro x _ y _ h |
| 107 | + simp only [disjoint_iff_ne, mem_image] |
| 108 | + rintro _ ⟨p₂, _, eq₂⟩ _ ⟨p₃, _, eq₃⟩ eq |
| 109 | + have : pi.cons s a x p₂ a (mem_insert_self _ _) = pi.cons s a y p₃ a (mem_insert_self _ _) := |
| 110 | + by rw [eq₂, eq₃, eq] |
| 111 | + rw [pi.cons_same, pi.cons_same] at this |
| 112 | + exact h this |
| 113 | + rw [prod_insert ha, pi_insert ha, ih, sum_mul, sum_bunionᵢ h₁] |
| 114 | + refine' sum_congr rfl fun b _ => _ |
| 115 | + have h₂ : ∀ p₁ ∈ pi s t, ∀ p₂ ∈ pi s t, pi.cons s a b p₁ = pi.cons s a b p₂ → p₁ = p₂ := |
| 116 | + fun p₁ _ p₂ _ eq => pi_cons_injective ha eq |
| 117 | + rw [sum_image h₂, mul_sum] |
| 118 | + refine' sum_congr rfl fun g _ => _ |
| 119 | + rw [attach_insert, prod_insert, prod_image] |
| 120 | + · simp only [pi.cons_same] |
| 121 | + congr with ⟨v, hv⟩ |
| 122 | + congr |
| 123 | + exact (pi.cons_ne (by rintro rfl; exact ha hv)).symm |
| 124 | + · exact fun _ _ _ _ => Subtype.eq ∘ Subtype.mk.inj |
| 125 | + · simpa only [mem_image, mem_attach, Subtype.mk.injEq, true_and, |
| 126 | + Subtype.exists, exists_prop, exists_eq_right] using ha |
| 127 | +#align finset.prod_sum Finset.prod_sum |
| 128 | + |
| 129 | +open Classical |
| 130 | +/-- The product of `f a + g a` over all of `s` is the sum |
| 131 | + over the powerset of `s` of the product of `f` over a subset `t` times |
| 132 | + the product of `g` over the complement of `t` -/ |
| 133 | +theorem prod_add (f g : α → β) (s : Finset α) : |
| 134 | + (∏ a in s, f a + g a) = ∑ t in s.powerset, (∏ a in t, f a) * ∏ a in s \ t, g a := |
| 135 | + calc |
| 136 | + (∏ a in s, f a + g a) = |
| 137 | + ∏ a in s, ∑ p in ({True, False} : Finset Prop), if p then f a else g a := |
| 138 | + by simp |
| 139 | + _ = ∑ p in (s.pi fun _ => {True, False} : Finset (∀ a ∈ s, Prop)), |
| 140 | + ∏ a in s.attach, if p a.1 a.2 then f a.1 else g a.1 := |
| 141 | + prod_sum |
| 142 | + _ = ∑ t in s.powerset, (∏ a in t, f a) * ∏ a in s \ t, g a := |
| 143 | + sum_bij' |
| 144 | + (fun f _ => s.filter (fun a => ∀ h : a ∈ s, f a h)) |
| 145 | + (by simp) |
| 146 | + (fun a _ => by |
| 147 | + rw [prod_ite] |
| 148 | + congr 1 |
| 149 | + exact prod_bij' |
| 150 | + (fun a _ => a.1) (by simp; tauto) (by simp) |
| 151 | + (fun a ha => ⟨a, (mem_filter.1 ha).1⟩) (fun a ha => by simp at ha; simp; tauto) |
| 152 | + (by simp) (by simp) |
| 153 | + exact prod_bij' |
| 154 | + (fun a _ => a.1) (by simp) (by simp) |
| 155 | + (fun a ha => ⟨a, (mem_sdiff.1 ha).1⟩) (fun a ha => by simp at ha; simp; tauto) |
| 156 | + (by simp) (by simp)) |
| 157 | + (fun t _ a _ => a ∈ t) |
| 158 | + (by simp [Classical.em]) |
| 159 | + (by simp [Function.funext_iff]; tauto) |
| 160 | + (by simp [Finset.ext_iff, @mem_filter _ _ (id _)]; tauto) |
| 161 | +#align finset.prod_add Finset.prod_add |
| 162 | + |
| 163 | +/-- `∏ i, (f i + g i) = (∏ i, f i) + ∑ i, g i * (∏ j < i, f j + g j) * (∏ j > i, f j)`. -/ |
| 164 | +theorem prod_add_ordered {ι R : Type _} [CommSemiring R] [LinearOrder ι] (s : Finset ι) |
| 165 | + (f g : ι → R) : |
| 166 | + (∏ i in s, f i + g i) = |
| 167 | + (∏ i in s, f i) + |
| 168 | + ∑ i in s, |
| 169 | + (g i * ∏ j in s.filter (· < i), f j + g j) * ∏ j in s.filter fun j => i < j, f j := |
| 170 | + by |
| 171 | + refine' Finset.induction_on_max s (by simp) _ |
| 172 | + clear s |
| 173 | + intro a s ha ihs |
| 174 | + have ha' : a ∉ s := fun ha' => lt_irrefl a (ha a ha') |
| 175 | + rw [prod_insert ha', prod_insert ha', sum_insert ha', filter_insert, if_neg (lt_irrefl a), |
| 176 | + filter_true_of_mem ha, ihs, add_mul, mul_add, mul_add, add_assoc] |
| 177 | + congr 1 |
| 178 | + rw [add_comm] |
| 179 | + congr 1 |
| 180 | + · rw [filter_false_of_mem, prod_empty, mul_one] |
| 181 | + exact (forall_mem_insert _ _ _).2 ⟨lt_irrefl a, fun i hi => (ha i hi).not_lt⟩ |
| 182 | + · rw [mul_sum] |
| 183 | + refine' sum_congr rfl fun i hi => _ |
| 184 | + rw [filter_insert, if_neg (ha i hi).not_lt, filter_insert, if_pos (ha i hi), prod_insert, |
| 185 | + mul_left_comm] |
| 186 | + exact mt (fun ha => (mem_filter.1 ha).1) ha' |
| 187 | +#align finset.prod_add_ordered Finset.prod_add_ordered |
| 188 | + |
| 189 | +/-- `∏ i, (f i - g i) = (∏ i, f i) - ∑ i, g i * (∏ j < i, f j - g j) * (∏ j > i, f j)`. -/ |
| 190 | +theorem prod_sub_ordered {ι R : Type _} [CommRing R] [LinearOrder ι] (s : Finset ι) (f g : ι → R) : |
| 191 | + (∏ i in s, f i - g i) = |
| 192 | + (∏ i in s, f i) - |
| 193 | + ∑ i in s, |
| 194 | + (g i * ∏ j in s.filter (· < i), f j - g j) * ∏ j in s.filter fun j => i < j, f j := |
| 195 | + by |
| 196 | + simp only [sub_eq_add_neg] |
| 197 | + convert prod_add_ordered s f fun i => -g i |
| 198 | + simp |
| 199 | +#align finset.prod_sub_ordered Finset.prod_sub_ordered |
| 200 | + |
| 201 | +/-- `∏ i, (1 - f i) = 1 - ∑ i, f i * (∏ j < i, 1 - f j)`. This formula is useful in construction of |
| 202 | +a partition of unity from a collection of “bump” functions. -/ |
| 203 | +theorem prod_one_sub_ordered {ι R : Type _} [CommRing R] [LinearOrder ι] (s : Finset ι) |
| 204 | + (f : ι → R) : (∏ i in s, 1 - f i) = 1 - ∑ i in s, f i * ∏ j in s.filter (· < i), 1 - f j := |
| 205 | + by |
| 206 | + rw [prod_sub_ordered] |
| 207 | + simp |
| 208 | +#align finset.prod_one_sub_ordered Finset.prod_one_sub_ordered |
| 209 | + |
| 210 | +/-- Summing `a^s.card * b^(n-s.card)` over all finite subsets `s` of a `Finset` |
| 211 | +gives `(a + b)^s.card`.-/ |
| 212 | +theorem sum_pow_mul_eq_add_pow {α R : Type _} [CommSemiring R] (a b : R) (s : Finset α) : |
| 213 | + (∑ t in s.powerset, a ^ t.card * b ^ (s.card - t.card)) = (a + b) ^ s.card := |
| 214 | + by |
| 215 | + rw [← prod_const, prod_add] |
| 216 | + refine' Finset.sum_congr rfl fun t ht => _ |
| 217 | + rw [prod_const, prod_const, ← card_sdiff (mem_powerset.1 ht)] |
| 218 | +#align finset.sum_pow_mul_eq_add_pow Finset.sum_pow_mul_eq_add_pow |
| 219 | + |
| 220 | +theorem dvd_sum {b : β} {s : Finset α} {f : α → β} (h : ∀ x ∈ s, b ∣ f x) : b ∣ ∑ x in s, f x := |
| 221 | + Multiset.dvd_sum fun y hy => by rcases Multiset.mem_map.1 hy with ⟨x, hx, rfl⟩; exact h x hx |
| 222 | +#align finset.dvd_sum Finset.dvd_sum |
| 223 | + |
| 224 | +@[norm_cast] |
| 225 | +theorem prod_nat_cast (s : Finset α) (f : α → ℕ) : ↑(∏ x in s, f x : ℕ) = ∏ x in s, (f x : β) := |
| 226 | + (Nat.castRingHom β).map_prod f s |
| 227 | +#align finset.prod_nat_cast Finset.prod_nat_cast |
| 228 | + |
| 229 | +end CommSemiring |
| 230 | + |
| 231 | +section CommRing |
| 232 | + |
| 233 | +variable {R : Type _} [CommRing R] |
| 234 | + |
| 235 | +theorem prod_range_cast_nat_sub (n k : ℕ) : |
| 236 | + (∏ i in range k, (n - i : R)) = (∏ i in range k, n - i : ℕ) := |
| 237 | + by |
| 238 | + rw [prod_nat_cast] |
| 239 | + cases' le_or_lt k n with hkn hnk |
| 240 | + · exact prod_congr rfl fun i hi => (Nat.cast_sub <| (mem_range.1 hi).le.trans hkn).symm |
| 241 | + · rw [← mem_range] at hnk |
| 242 | + rw [prod_eq_zero hnk, prod_eq_zero hnk] <;> simp |
| 243 | +#align finset.prod_range_cast_nat_sub Finset.prod_range_cast_nat_sub |
| 244 | + |
| 245 | +end CommRing |
| 246 | + |
| 247 | +/-- A product over all subsets of `s ∪ {x}` is obtained by multiplying the product over all subsets |
| 248 | +of `s`, and over all subsets of `s` to which one adds `x`. -/ |
| 249 | +@[to_additive |
| 250 | + "A sum over all subsets of `s ∪ {x}` is obtained by summing the sum over all subsets |
| 251 | + of `s`, and over all subsets of `s` to which one adds `x`."] |
| 252 | +theorem prod_powerset_insert [DecidableEq α] [CommMonoid β] {s : Finset α} {x : α} (h : x ∉ s) |
| 253 | + (f : Finset α → β) : |
| 254 | + (∏ a in (insert x s).powerset, f a) = |
| 255 | + (∏ a in s.powerset, f a) * ∏ t in s.powerset, f (insert x t) := |
| 256 | + by |
| 257 | + rw [powerset_insert, Finset.prod_union, Finset.prod_image] |
| 258 | + · intro t₁ h₁ t₂ h₂ heq |
| 259 | + rw [← Finset.erase_insert (not_mem_of_mem_powerset_of_not_mem h₁ h), ← |
| 260 | + Finset.erase_insert (not_mem_of_mem_powerset_of_not_mem h₂ h), heq] |
| 261 | + · rw [Finset.disjoint_iff_ne] |
| 262 | + intro t₁ h₁ t₂ h₂ |
| 263 | + rcases Finset.mem_image.1 h₂ with ⟨t₃, _h₃, H₃₂⟩ |
| 264 | + rw [← H₃₂] |
| 265 | + exact ne_insert_of_not_mem _ _ (not_mem_of_mem_powerset_of_not_mem h₁ h) |
| 266 | +#align finset.prod_powerset_insert Finset.prod_powerset_insert |
| 267 | + |
| 268 | +/-- A product over `powerset s` is equal to the double product over sets of subsets of `s` with |
| 269 | +`card s = k`, for `k = 1, ..., card s`. -/ |
| 270 | +@[to_additive |
| 271 | + "A sum over `powerset s` is equal to the double sum over sets of subsets of `s` with |
| 272 | + `card s = k`, for `k = 1, ..., card s`"] |
| 273 | +theorem prod_powerset [CommMonoid β] (s : Finset α) (f : Finset α → β) : |
| 274 | + (∏ t in powerset s, f t) = ∏ j in range (card s + 1), ∏ t in powersetLen j s, f t := by |
| 275 | + rw [powerset_card_disjUnionᵢ, prod_disjUnionᵢ] |
| 276 | +#align finset.prod_powerset Finset.prod_powerset |
| 277 | + |
| 278 | +theorem sum_range_succ_mul_sum_range_succ [NonUnitalNonAssocSemiring β] (n k : ℕ) (f g : ℕ → β) : |
| 279 | + ((∑ i in range (n + 1), f i) * ∑ i in range (k + 1), g i) = |
| 280 | + (((∑ i in range n, f i) * ∑ i in range k, g i) + f n * ∑ i in range k, g i) + |
| 281 | + (∑ i in range n, f i) * g k + |
| 282 | + f n * g k := |
| 283 | + by simp only [add_mul, mul_add, add_assoc, sum_range_succ] |
| 284 | +#align finset.sum_range_succ_mul_sum_range_succ Finset.sum_range_succ_mul_sum_range_succ |
| 285 | + |
| 286 | +end Finset |
0 commit comments