Skip to content

Commit 22a8ffd

Browse files
feat: Ixx summation filters (#30380)
We prove some results about sums over intervals of the form Ixx which are needed for defining the Eisenstein series E2 (see #26014). We also define these as summation filters. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent 7622f00 commit 22a8ffd

File tree

9 files changed

+355
-2
lines changed

9 files changed

+355
-2
lines changed

Mathlib.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import Mathlib.Algebra.BigOperators.Finsupp.Fin
6060
import Mathlib.Algebra.BigOperators.Group.Finset.Basic
6161
import Mathlib.Algebra.BigOperators.Group.Finset.Defs
6262
import Mathlib.Algebra.BigOperators.Group.Finset.Indicator
63+
import Mathlib.Algebra.BigOperators.Group.Finset.Interval
6364
import Mathlib.Algebra.BigOperators.Group.Finset.Lemmas
6465
import Mathlib.Algebra.BigOperators.Group.Finset.Pi
6566
import Mathlib.Algebra.BigOperators.Group.Finset.Piecewise
@@ -5202,6 +5203,7 @@ import Mathlib.Order.Filter.AtTopBot.Finite
52025203
import Mathlib.Order.Filter.AtTopBot.Finset
52035204
import Mathlib.Order.Filter.AtTopBot.Floor
52045205
import Mathlib.Order.Filter.AtTopBot.Group
5206+
import Mathlib.Order.Filter.AtTopBot.Interval
52055207
import Mathlib.Order.Filter.AtTopBot.Map
52065208
import Mathlib.Order.Filter.AtTopBot.ModEq
52075209
import Mathlib.Order.Filter.AtTopBot.Monoid
@@ -6524,6 +6526,7 @@ import Mathlib.Topology.Algebra.GroupCompletion
65246526
import Mathlib.Topology.Algebra.GroupWithZero
65256527
import Mathlib.Topology.Algebra.Indicator
65266528
import Mathlib.Topology.Algebra.InfiniteSum.Basic
6529+
import Mathlib.Topology.Algebra.InfiniteSum.ConditionalInt
65276530
import Mathlib.Topology.Algebra.InfiniteSum.Constructions
65286531
import Mathlib.Topology.Algebra.InfiniteSum.Defs
65296532
import Mathlib.Topology.Algebra.InfiniteSum.ENNReal
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/-
2+
Copyright (c) 2025 Chris Birkbeck. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Chris Birkbeck
5+
-/
6+
7+
import Mathlib.Algebra.CharP.Defs
8+
import Mathlib.Algebra.Group.EvenFunction
9+
import Mathlib.Data.Int.Interval
10+
import Mathlib.Tactic.Zify
11+
12+
/-!
13+
# Sums/products over integer intervals
14+
15+
This file contains some lemmas about sums and products over integer intervals `Ixx`.
16+
17+
-/
18+
19+
namespace Finset
20+
21+
@[to_additive]
22+
lemma prod_Icc_of_even_eq_range {α : Type*} [CommGroup α] {f : ℤ → α} (hf : f.Even) (N : ℕ) :
23+
∏ m ∈ Icc (-N : ℤ) N, f m = (∏ m ∈ range (N + 1), f m) ^ 2 / f 0 := by
24+
induction N with
25+
| zero => simp [sq]
26+
| succ N ih =>
27+
rw [Nat.cast_add, Nat.cast_one, Icc_succ_succ, prod_union (by simp), prod_pair (by omega), ih,
28+
prod_range_succ _ (N + 1), hf, ← pow_two, div_mul_eq_mul_div, ← mul_pow, Nat.cast_succ]
29+
30+
@[to_additive]
31+
lemma prod_Icc_eq_prod_Ico_mul {α : Type*} [CommMonoid α] (f : ℤ → α) {l u : ℤ}
32+
(h : l ≤ u) : ∏ m ∈ Icc l u, f m = (∏ m ∈ Ico l u, f m) * f u := by
33+
simp [Icc_eq_cons_Ico h, mul_comm]
34+
35+
@[to_additive]
36+
lemma prod_Icc_succ_eq_mul_endpoints {R : Type*} [CommGroup R] (f : ℤ → R) {N : ℕ} :
37+
∏ m ∈ Icc (-(N + 1) : ℤ) (N + 1), f m =
38+
f (N + 1) * f (-(N + 1) : ℤ) * ∏ m ∈ Icc (-N : ℤ) N, f m := by
39+
induction N
40+
· rw [Icc_succ_succ]
41+
simp only [CharP.cast_eq_zero, neg_zero, Icc_self, zero_add, Int.reduceNeg, union_insert,
42+
union_singleton, mem_insert, reduceCtorEq, mem_singleton, neg_eq_zero, one_ne_zero, or_self,
43+
not_false_eq_true, prod_insert, prod_singleton]
44+
grind
45+
· rw [Icc_succ_succ, prod_union (by simp)]
46+
grind
47+
48+
end Finset

Mathlib/Algebra/Order/Ring/Defs.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,4 +233,8 @@ lemma one_sub_le_one_add_mul_one_sub (h : c + b * c ≤ a + b) : 1 - a ≤ (1 +
233233
rw [mul_one_sub, one_add_mul, sub_le_sub_iff, add_assoc, add_comm b]
234234
gcongr
235235

236+
instance [Nontrivial R] : NoMaxOrder R := ⟨fun a ↦ ⟨a + 1, by simp⟩⟩
237+
238+
instance [Nontrivial R] : NoMinOrder R := ⟨fun a ↦ ⟨a - 1, by simp⟩⟩
239+
236240
end OrderedRing

Mathlib/Data/Int/Interval.lean

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,31 @@ theorem image_Ico_emod (n a : ℤ) (h : 0 ≤ a) : (Ico n (n + a)).image (· % a
164164
· rw [Int.add_mul_emod_self_left, Int.emod_eq_of_lt hia.left hia.right]
165165

166166
end Int
167+
168+
section Nat
169+
170+
lemma Finset.Icc_succ_succ (m n : ℕ) :
171+
Icc (-(m + 1) : ℤ) (n + 1) = Icc (-m : ℤ) n ∪ {(-(m + 1) : ℤ), (n + 1 : ℤ)} := by
172+
ext
173+
simp only [mem_Icc, union_insert, union_singleton, mem_insert]
174+
omega
175+
176+
lemma Finset.Ico_succ_succ (m n : ℕ) :
177+
Ico (-(m + 1) : ℤ) (n + 1) = Ico (-m : ℤ) n ∪ {(-(m + 1) : ℤ), (n : ℤ)} := by
178+
ext
179+
simp only [mem_Ico, union_insert, union_singleton, mem_insert]
180+
omega
181+
182+
lemma Finset.Ioc_succ_succ (m n : ℕ) :
183+
Ioc (-(m + 1) : ℤ) (n + 1) = Ioc (-m : ℤ) n ∪ {-(m : ℤ), (n + 1 : ℤ)} := by
184+
ext
185+
simp only [mem_Ioc, union_insert, union_singleton, mem_insert]
186+
omega
187+
188+
lemma Finset.Ioo_succ_succ (m n : ℕ) :
189+
Ioo (-(m + 1) : ℤ) (n + 1) = Ioo (-m : ℤ) n ∪ {-(m : ℤ), (n : ℤ)} := by
190+
ext
191+
simp only [mem_Ioo, union_insert, union_singleton, mem_insert]
192+
omega
193+
194+
end Nat

Mathlib/Order/Filter/AtTopBot/Finset.lean

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Johannes Hölzl, Jeremy Avigad, Yury Kudryashov, Patrick Massot
55
-/
66
import Mathlib.Data.Finset.Order
7-
import Mathlib.Data.Finset.Preimage
8-
import Mathlib.Order.Filter.AtTopBot.Tendsto
97
import Mathlib.Order.Filter.AtTopBot.Basic
108
import Mathlib.Order.Filter.Finite
119
import Mathlib.Order.Interval.Finset.Defs
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/-
2+
Copyright (c) 2025 Chris Birkbeck. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Chris Birkbeck, David Loeffler
5+
-/
6+
7+
import Mathlib.Order.Filter.AtTopBot.Archimedean
8+
import Mathlib.Order.Filter.Prod
9+
import Mathlib.Order.Interval.Finset.Defs
10+
11+
/-!
12+
# Limits of intervals along filters
13+
14+
This file contains some lemmas about how filters `Ixx` behave as the endpoints tend to `±∞`.
15+
16+
-/
17+
18+
namespace Finset
19+
20+
open Filter
21+
22+
section Asymmetric
23+
24+
variable {α : Type*} [Preorder α] [LocallyFiniteOrder α]
25+
26+
lemma tendsto_Icc_atBot_prod_atTop :
27+
Tendsto (fun p : α × α ↦ Icc p.1 p.2) (atBot ×ˢ atTop) atTop := by
28+
simpa [tendsto_atTop, ← coe_subset, Set.subset_def, -eventually_and]
29+
using fun b i _ ↦ (eventually_le_atBot i).prod_mk (eventually_ge_atTop i)
30+
31+
lemma tendsto_Ioc_atBot_prod_atTop [NoBotOrder α] :
32+
Tendsto (fun p : α × α ↦ Ioc p.1 p.2) (atBot ×ˢ atTop) atTop := by
33+
simpa [tendsto_atTop, ← coe_subset, Set.subset_def, -eventually_and]
34+
using fun b i _ ↦ (eventually_lt_atBot i).prod_mk (eventually_ge_atTop i)
35+
36+
lemma tendsto_Ico_atBot_prod_atTop [NoTopOrder α] :
37+
Tendsto (fun p : α × α ↦ Finset.Ico p.1 p.2) (atBot ×ˢ atTop) atTop := by
38+
simpa [tendsto_atTop, ← coe_subset, Set.subset_def, -eventually_and]
39+
using fun b i _ ↦ (eventually_le_atBot i).prod_mk (eventually_gt_atTop i)
40+
41+
lemma tendsto_Ioo_atBot_prod_atTop [NoBotOrder α] [NoTopOrder α] :
42+
Tendsto (fun p : α × α ↦ Finset.Ioo p.1 p.2) (atBot ×ˢ atTop) atTop := by
43+
simpa [tendsto_atTop, ← coe_subset, Set.subset_def, -eventually_and]
44+
using fun b i _ ↦ (eventually_lt_atBot i).prod_mk (eventually_gt_atTop i)
45+
46+
end Asymmetric
47+
48+
section Symmetric
49+
50+
variable {α : Type*} [AddCommGroup α] [PartialOrder α] [IsOrderedAddMonoid α]
51+
[LocallyFiniteOrder α]
52+
53+
lemma tendsto_Icc_neg_atTop_atTop :
54+
Tendsto (fun a : α ↦ Icc (-a) a) atTop atTop :=
55+
tendsto_Icc_atBot_prod_atTop.comp (tendsto_neg_atTop_atBot.prodMk tendsto_id)
56+
57+
lemma tendsto_Ioc_neg_atTop_atTop [NoBotOrder α] :
58+
Tendsto (fun a : α ↦ Ioc (-a) a) atTop atTop :=
59+
tendsto_Ioc_atBot_prod_atTop.comp (tendsto_neg_atTop_atBot.prodMk tendsto_id)
60+
61+
lemma tendsto_Ico_neg_atTop_atTop [NoTopOrder α] :
62+
Tendsto (fun a : α ↦ Ico (-a) a) atTop atTop :=
63+
tendsto_Ico_atBot_prod_atTop.comp (tendsto_neg_atTop_atBot.prodMk tendsto_id)
64+
65+
lemma tendsto_Ioo_neg_atTop_atTop [NoBotOrder α] [NoTopOrder α] :
66+
Tendsto (fun a : α ↦ Ioo (-a) a) atTop atTop :=
67+
tendsto_Ioo_atBot_prod_atTop.comp (tendsto_neg_atTop_atBot.prodMk tendsto_id)
68+
69+
end Symmetric
70+
71+
section NatCast
72+
73+
variable {R : Type*} [Ring R] [PartialOrder R] [IsOrderedRing R] [LocallyFiniteOrder R]
74+
[Archimedean R]
75+
76+
lemma tendsto_Icc_neg :
77+
Tendsto (fun n : ℕ ↦ Icc (-n : R) n) atTop atTop :=
78+
tendsto_Icc_neg_atTop_atTop.comp tendsto_natCast_atTop_atTop
79+
80+
variable [Nontrivial R]
81+
82+
lemma tendsto_Ioc_neg : Tendsto (fun n : ℕ ↦ Ioc (-n : R) n) atTop atTop :=
83+
tendsto_Ioc_neg_atTop_atTop.comp tendsto_natCast_atTop_atTop
84+
85+
lemma tendsto_Ico_neg : Tendsto (fun n : ℕ ↦ Ico (-n : R) n) atTop atTop :=
86+
tendsto_Ico_neg_atTop_atTop.comp tendsto_natCast_atTop_atTop
87+
88+
lemma tendsto_Ioo_neg : Tendsto (fun n : ℕ ↦ Ioo (-n : R) n) atTop atTop :=
89+
tendsto_Ioo_neg_atTop_atTop.comp tendsto_natCast_atTop_atTop
90+
91+
end NatCast
92+
93+
end Finset
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/-
2+
Copyright (c) 2025 Chris Birkbeck. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Chris Birkbeck
5+
-/
6+
7+
import Mathlib.Algebra.BigOperators.Group.Finset.Interval
8+
import Mathlib.Algebra.Order.Ring.Star
9+
import Mathlib.Order.Filter.AtTopBot.Interval
10+
import Mathlib.Topology.Algebra.InfiniteSum.Defs
11+
import Mathlib.Topology.Algebra.Monoid.Defs
12+
import Mathlib.Tactic.FinCases
13+
14+
15+
/-!
16+
# Sums over symmetric integer intervals
17+
18+
This file contains some lemmas about sums over symmetric integer intervals `Ixx -N N` used, for
19+
example in the definition of the Eisenstein series `E2`.
20+
In particular we define `symmetricIcc`, `symmetricIco`, `symmetricIoc` and `symmetricIoo` as
21+
`SummationFilter`s corresponding to the intervals `Icc -N N`, `Ico -N N`, `Ioc -N N` respectively.
22+
We also prove that these filters are all `NeBot` and `LeAtTop`.
23+
24+
-/
25+
26+
open Finset Topology Function Filter SummationFilter
27+
28+
namespace SummationFilter
29+
30+
section IntervalFilters
31+
32+
variable (G : Type*) [Neg G] [Preorder G] [LocallyFiniteOrder G]
33+
34+
/-- The SummationFilter on a locally finite order `G` corresponding to the symmetric
35+
intervals `Icc (-N) N`· -/
36+
@[simps]
37+
def symmetricIcc : SummationFilter G where
38+
filter := atTop.map (fun g ↦ Icc (-g) g)
39+
40+
/-- The SummationFilter on a locally finite order `G` corresponding to the symmetric
41+
intervals `Ioo (-N) N`· Note that for `G = ℤ` this coincides with
42+
`symmetricIcc` so one should use that. See `symmetricIcc_eq_symmetricIoo_int`. -/
43+
@[simps]
44+
def symmetricIoo : SummationFilter G where
45+
filter := atTop.map (fun g ↦ Ioo (-g) g)
46+
47+
/-- The SummationFilter on a locally finite order `G` corresponding to the symmetric
48+
intervals `Ico (-N) N`· -/
49+
@[simps]
50+
def symmetricIco : SummationFilter G where
51+
filter := atTop.map (fun N ↦ Ico (-N) N)
52+
53+
/-- The SummationFilter on a locally finite order `G` corresponding to the symmetric
54+
intervals `Ioc (-N) N`· -/
55+
@[simps]
56+
def symmetricIoc : SummationFilter G where
57+
filter := atTop.map (fun N ↦ Ioc (-N) N)
58+
59+
variable [(atTop : Filter G).NeBot]
60+
61+
instance : (symmetricIcc G).NeBot where
62+
ne_bot := by simp [symmetricIcc, Filter.NeBot.map]
63+
64+
instance : (symmetricIco G).NeBot where
65+
ne_bot := by simp [symmetricIco, Filter.NeBot.map]
66+
67+
instance : (symmetricIoc G).NeBot where
68+
ne_bot := by simp [symmetricIoc, Filter.NeBot.map]
69+
70+
instance : (symmetricIoo G).NeBot where
71+
ne_bot := by simp [symmetricIoo, Filter.NeBot.map]
72+
73+
section LeAtTop
74+
75+
variable {G : Type*} [AddCommGroup G] [PartialOrder G] [IsOrderedAddMonoid G] [LocallyFiniteOrder G]
76+
77+
lemma symmetricIcc_le_Conditional :
78+
(symmetricIcc G).filter ≤ (conditional G).filter :=
79+
Filter.map_mono (tendsto_neg_atTop_atBot.prodMk tendsto_id)
80+
81+
instance : (symmetricIcc G).LeAtTop where
82+
le_atTop := le_trans symmetricIcc_le_Conditional (conditional G).le_atTop
83+
84+
variable [NoTopOrder G] [NoBotOrder G]
85+
86+
instance : (symmetricIco G).LeAtTop where
87+
le_atTop := by
88+
rw [symmetricIco, map_le_iff_le_comap, ← @tendsto_iff_comap]
89+
exact tendsto_Ico_neg_atTop_atTop
90+
91+
instance : (symmetricIoc G).LeAtTop where
92+
le_atTop := by
93+
rw [symmetricIoc, map_le_iff_le_comap, ← @tendsto_iff_comap]
94+
exact tendsto_Ioc_neg_atTop_atTop
95+
96+
instance : (symmetricIoo G).LeAtTop where
97+
le_atTop := by
98+
rw [symmetricIoo, map_le_iff_le_comap, ← @tendsto_iff_comap]
99+
exact tendsto_Ioo_neg_atTop_atTop
100+
101+
end LeAtTop
102+
103+
end IntervalFilters
104+
section Int
105+
106+
variable {α : Type*} {f : ℤ → α} [CommGroup α] [TopologicalSpace α] [ContinuousMul α]
107+
108+
lemma symmetricIcc_eq_map_Icc_nat :
109+
(symmetricIcc ℤ).filter = atTop.map (fun N : ℕ ↦ Icc (-(N : ℤ)) N) := by
110+
simp [← Nat.map_cast_int_atTop, Function.comp_def]
111+
112+
lemma symmetricIcc_eq_symmetricIoo_int : symmetricIcc ℤ = symmetricIoo ℤ := by
113+
simp only [symmetricIcc, symmetricIoo, mk.injEq]
114+
ext s
115+
simp only [← Nat.map_cast_int_atTop, Filter.map_map, Filter.mem_map, mem_atTop_sets, ge_iff_le,
116+
Set.mem_preimage, comp_apply]
117+
refine ⟨fun ⟨a, ha⟩ ↦ ⟨a + 1, fun b hb ↦ ?_⟩, fun ⟨a, ha⟩ ↦ ⟨a - 1, fun b hb ↦ ?_⟩⟩ <;>
118+
[ convert ha (b - 1) (by grind) using 1; convert ha (b + 1) (by grind) using 1 ] <;>
119+
simpa [Finset.ext_iff] using by grind
120+
121+
@[to_additive]
122+
lemma HasProd.hasProd_symmetricIco_of_hasProd_symmetricIcc {a : α}
123+
(hf : HasProd f a (symmetricIcc ℤ)) (hf2 : Tendsto (fun N : ℕ ↦ (f N)⁻¹) atTop (𝓝 1)) :
124+
HasProd f a (symmetricIco ℤ) := by
125+
simp only [HasProd, tendsto_map'_iff, symmetricIcc_eq_map_Icc_nat,
126+
← Nat.map_cast_int_atTop, symmetricIco] at *
127+
apply tendsto_of_div_tendsto_one _ hf
128+
simpa [Pi.div_def, fun N : ℕ ↦ prod_Icc_eq_prod_Ico_mul f (show (-N : ℤ) ≤ N by omega)]
129+
using hf2
130+
131+
@[to_additive]
132+
lemma multipliable_symmetricIco_of_multiplible_symmetricIcc
133+
(hf : Multipliable f (symmetricIcc ℤ)) (hf2 : Tendsto (fun N : ℕ ↦ (f N)⁻¹) atTop (𝓝 1)) :
134+
Multipliable f (symmetricIco ℤ) :=
135+
(hf.hasProd.hasProd_symmetricIco_of_hasProd_symmetricIcc hf2).multipliable
136+
137+
@[to_additive]
138+
lemma tprod_symmetricIcc_eq_tprod_symmetricIco [T2Space α]
139+
(hf : Multipliable f (symmetricIcc ℤ)) (hf2 : Tendsto (fun N : ℕ ↦ (f N)⁻¹) atTop (𝓝 1)) :
140+
∏'[symmetricIco ℤ] b, f b = ∏'[symmetricIcc ℤ] b, f b :=
141+
(hf.hasProd.hasProd_symmetricIco_of_hasProd_symmetricIcc hf2).tprod_eq
142+
143+
@[to_additive]
144+
lemma hasProd_symmetricIcc_iff {α : Type*} [CommMonoid α] [TopologicalSpace α]
145+
{f : ℤ → α} {a : α} : HasProd f a (symmetricIcc ℤ) ↔
146+
Tendsto (fun N : ℕ ↦ ∏ n ∈ Icc (-(N : ℤ)) N, f n) atTop (𝓝 a) := by
147+
simp [HasProd, symmetricIcc, ← Nat.map_cast_int_atTop, comp_def]
148+
149+
@[to_additive]
150+
lemma hasProd_symmetricIco_int_iff {α : Type*} [CommMonoid α] [TopologicalSpace α]
151+
{f : ℤ → α} {a : α} : HasProd f a (symmetricIco ℤ) ↔
152+
Tendsto (fun N : ℕ ↦ ∏ n ∈ Ico (-(N : ℤ)) (N : ℤ), f n) atTop (𝓝 a) := by
153+
simp [HasProd, symmetricIco, ← Nat.map_cast_int_atTop, comp_def]
154+
155+
@[to_additive]
156+
lemma hasProd_symmetricIoc_int_iff {α : Type*} [CommMonoid α] [TopologicalSpace α]
157+
{f : ℤ → α} {a : α} : HasProd f a (symmetricIoc ℤ) ↔
158+
Tendsto (fun N : ℕ ↦ ∏ n ∈ Ioc (-(N : ℤ)) (N : ℤ), f n) atTop (𝓝 a) := by
159+
simp [HasProd, symmetricIoc, ← Nat.map_cast_int_atTop, comp_def]
160+
161+
end Int
162+
163+
end SummationFilter

Mathlib/Topology/Algebra/InfiniteSum/Defs.lean

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,4 +334,14 @@ theorem Multipliable.hasProd_iff (h : Multipliable f L) :
334334
HasProd f a L ↔ ∏'[L] b, f b = a :=
335335
Iff.intro HasProd.tprod_eq fun eq ↦ eq ▸ h.hasProd
336336

337+
@[to_additive]
338+
theorem tprod_eq_of_filter_le {L₁ L₂ : SummationFilter β} [L₁.NeBot]
339+
(h : L₁.filter ≤ L₂.filter) (hf : Multipliable f L₂) : ∏'[L₁] b, f b = ∏'[L₂] b, f b :=
340+
(hf.mono_filter h).hasProd_iff.mp (hf.hasProd.mono_left h)
341+
342+
@[to_additive]
343+
theorem tprod_eq_of_multipliable_unconditional [L.LeAtTop] (hf : Multipliable f) :
344+
∏'[L] b, f b = ∏' b, f b :=
345+
tprod_eq_of_filter_le L.le_atTop hf
346+
337347
end HasProd

0 commit comments

Comments
 (0)