Skip to content

Commit 12aa913

Browse files
LukasMiasChrisHughes24jcommelin
committed
feat: port Algebra.BigOperators.Ring (#1645)
Co-authored-by: ChrisHughes24 <chrishughes24@gmail.com> Co-authored-by: Johan Commelin <johan@commelin.net>
1 parent 1050066 commit 12aa913

File tree

2 files changed

+287
-0
lines changed

2 files changed

+287
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Mathlib.Algebra.BigOperators.Multiset.Basic
55
import Mathlib.Algebra.BigOperators.Multiset.Lemmas
66
import Mathlib.Algebra.BigOperators.NatAntidiagonal
77
import Mathlib.Algebra.BigOperators.Option
8+
import Mathlib.Algebra.BigOperators.Ring
89
import Mathlib.Algebra.BigOperators.RingEquiv
910
import Mathlib.Algebra.Bounds
1011
import Mathlib.Algebra.CharZero.Defs
Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
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

Comments
 (0)