Skip to content

Commit 05b7159

Browse files
committed
feat: canonical decomposition of complex-meromorphic functions on disks (#37477)
Establish the Finite Canonical Decomposition of meromorphic functions, where a complex-meromorphic function `f` on a disk is written as a product of an analytic function without zeros and poles, and canonical factors that take only values of norm one on the boundary of the disk. A future PR will extend this theorem to handle zeros/poles on the boundary of the disk.
1 parent 258731d commit 05b7159

8 files changed

Lines changed: 355 additions & 12 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,6 +2090,7 @@ public import Mathlib.Analysis.Meromorphic.FactorizedRational
20902090
public import Mathlib.Analysis.Meromorphic.IsolatedZeros
20912091
public import Mathlib.Analysis.Meromorphic.NormalForm
20922092
public import Mathlib.Analysis.Meromorphic.Order
2093+
public import Mathlib.Analysis.Meromorphic.RCLike
20932094
public import Mathlib.Analysis.Meromorphic.TrailingCoefficient
20942095
public import Mathlib.Analysis.Normed.Affine.AddTorsor
20952096
public import Mathlib.Analysis.Normed.Affine.AddTorsorBases

Mathlib/Algebra/Order/WithTop/Untop0.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ lemma untop₀_add [AddZeroClass α] {a b : WithTop α} (ha : a ≠ ⊤) (hb : b
7171
@[simp]
7272
lemma untop₀_natCast [AddMonoidWithOne α] (n : ℕ) : untop₀ (n : WithTop α) = n := rfl
7373

74+
@[simp]
75+
theorem untop₀_one {α : Type*} [AddMonoidWithOne α] :
76+
(1 : WithTop α).untop₀ = 1 := by
77+
convert WithTop.untop₀_natCast 1
78+
all_goals exact Nat.cast_one.symm
79+
7480
@[simp]
7581
lemma untop₀_ofNat [AddMonoidWithOne α] (n : ℕ) [n.AtLeastTwo] :
7682
untop₀ (ofNat(n) : WithTop α) = ofNat(n) := rfl

Mathlib/Analysis/Complex/CanonicalDecomposition.lean

Lines changed: 244 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,40 @@ Authors: Stefan Kebekus
66
module
77

88
public import Mathlib.Analysis.Meromorphic.FactorizedRational
9+
public import Mathlib.Analysis.Meromorphic.RCLike
910

1011
/-!
1112
# Canonical Decomposition
1213
1314
If a function `f` is meromorphic on a compact set `U`, then it has only finitely many zeros and
1415
poles on the disk, and the theorem `MeromorphicOn.extract_zeros_poles` can be used to re-write `f`
1516
as `(∏ᶠ u, (· - u) ^ divisor f U u) • g`, where `g` is analytic without zeros on `U`. In case where
16-
`U` is a disk, one consider a similar decomposition, called *Canonical Decomposition* or *Blaschke
17-
Product* that replaces the factors `(· - u)` by canonical factors that take only values of norm
18-
one on the boundary of the circle. This file introduces the canonical factors.
17+
`U` is a disk, one consider a similar decomposition, called *Finite Canonical Decomposition* or
18+
*Finite Blaschke Product* that replaces the factors `(· - u)` by canonical factors that take only
19+
values of norm one on the boundary of the disk. This file introduces the canonical factors and
20+
provides API for the canonical decomposition.
1921
2022
See Page 160f of [Lang, *Introduction to Complex Hyperbolic Spaces*][MR886677] for a detailed
2123
discussion.
2224
23-
TODO: Formulate the canonical decomposition.
25+
TODO: Formulate a refined version of the canonical decomposition that takes zeros on poles on the
26+
boundary of the ball into account.
2427
-/
2528

2629
@[expose] public section
2730

2831
namespace Complex
2932

30-
open ComplexConjugate Metric Real
33+
open ComplexConjugate Filter Function MeromorphicOn Metric Real Set
3134

3235
variable {R : ℝ} {w : ℂ}
3336

3437
/-!
3538
## Canonical Factors
3639
37-
Given `R : ℝ` and `w : ℂ`, the Blaschke factor `Blaschke R w : ℂ → ℂ` is meromorphic in normal form,
38-
has a single pole at `w`, no zeros, and takes values of norm one on the circle of radius `R`.
40+
Given `R : ℝ` and `w : ℂ`, the canonical factor `canonical R w : ℂ → ℂ` is meromorphic function in
41+
normal form that has a single pole at `w`, no zeros, and takes values of norm one on the circle of
42+
radius `R`.
3943
-/
4044

4145
/--
@@ -67,8 +71,8 @@ variable (R w) in
6771
/--
6872
Canonical factors are meromorphic.
6973
-/
70-
theorem meromorphicOn_canonicalFactor : MeromorphicOn (canonicalFactor R w) Set.univ := by
71-
intro x hx
74+
theorem meromorphic_canonicalFactor : Meromorphic (canonicalFactor R w) := by
75+
intro x
7276
unfold canonicalFactor
7377
fun_prop
7478

@@ -113,7 +117,7 @@ theorem meromorphicNFOn_canonicalFactor (h : w ∈ ball 0 R) :
113117
obtain (rfl | h₁) := eq_or_ne z w
114118
· rw [meromorphicNFAt_iff_analyticAt_or]
115119
right
116-
refine ⟨meromorphicOn_canonicalFactor R z z (Set.mem_univ z), ?_, by simp⟩
120+
refine ⟨meromorphic_canonicalFactor R z z, ?_, by simp⟩
117121
simpa [meromorphicOrderAt_canonicalFactor h] using WithTop.coe_lt_zero.mpr (by lia : -1 < 0)
118122
apply (analyticOnNhd_canonicalFactor R w z h₁).meromorphicNFAt
119123

@@ -138,6 +142,16 @@ theorem canonicalFactor_ne_zero {z : ℂ} (hw : w ∈ ball 0 R) (h₁z : z ∈ c
138142
rw [canonicalFactor_apply]
139143
positivity
140144

145+
/--
146+
The function `CanonicalFactor R w` vanishes only at `w`.
147+
-/
148+
theorem canonicalFactor_eq_zero_iff {z : ℂ} (hw : w ∈ ball 0 R) (hz : z ∈ ball 0 R) :
149+
canonicalFactor R w z = 0 ↔ z = w := by
150+
constructor
151+
· contrapose
152+
exact canonicalFactor_ne_zero hw (ball_subset_closedBall hz)
153+
· simp_all
154+
141155
open scoped ComplexOrder in
142156
/--
143157
The canonical factor `CanonicalFactor R w` takes values of norm one on `sphere 0 R`.
@@ -151,4 +165,224 @@ theorem norm_canonicalFactor_eval_circle_eq_one {z : ℂ} (hw : w ∈ ball 0 R)
151165
rw [← ofReal_pow, ← normSq_eq_norm_sq, normSq_eq_conj_mul_self, ← sub_mul, mul_comm _ z]
152166
simp [← map_sub]
153167

168+
/-!
169+
### Orders and Divisors
170+
-/
171+
172+
/--
173+
Canonical factors are nowhere locally constant zero.
174+
-/
175+
theorem meromorphicOrderAt_canonicalFactor_ne_top {z : ℂ} {R : ℝ} (w : ℂ) (hR : 0 < R) :
176+
meromorphicOrderAt (canonicalFactor R w) z ≠ ⊤ := by
177+
apply (meromorphic_canonicalFactor R w).exists_meromorphicOrderAt_ne_top_iff_forall.1
178+
use 0
179+
by_cases hw : w = 0
180+
· simp_all [meromorphicOrderAt_canonicalFactor (mem_ball_self hR)]
181+
suffices meromorphicOrderAt (canonicalFactor R w) 0 = 0 by simp_all
182+
rw [MeromorphicNFAt.meromorphicOrderAt_eq_zero_iff]
183+
· simp_all [canonicalFactor, ne_of_gt hR]
184+
· apply AnalyticAt.meromorphicNFAt
185+
apply analyticOnNhd_canonicalFactor
186+
grind
187+
188+
/--
189+
The divisor of `CanonicalFactor R w` is `-w`. In other words, the divisor function takes the value
190+
-1 at `w` and is zero elsewhere.
191+
-/
192+
theorem divisor_canonicalFactor (hw : w ∈ ball 0 R) :
193+
MeromorphicOn.divisor (canonicalFactor R w) (ball 0 R)
194+
= -(Function.locallyFinsuppWithin.single w 1).restrict (Set.subset_univ (ball 0 R)) := by
195+
ext z
196+
by_cases hz : z ∈ ball 0 R
197+
· rw [MeromorphicOn.divisor_apply
198+
(fun z hz ↦ meromorphic_canonicalFactor R w z) hz]
199+
obtain (rfl | h₂z) := eq_or_ne z w
200+
· rw [meromorphicOrderAt_canonicalFactor hz]
201+
simp_all [Function.locallyFinsuppWithin.restrict_apply]
202+
· have : meromorphicOrderAt (canonicalFactor R w) z = 0 := by
203+
rw [(meromorphicNFOn_canonicalFactor hw (Set.mem_univ z)).meromorphicOrderAt_eq_zero_iff]
204+
exact canonicalFactor_ne_zero hw (ball_subset_closedBall hz) h₂z
205+
simp [this, h₂z, Function.locallyFinsuppWithin.restrict_apply, hz]
206+
· simp_all
207+
208+
/-!
209+
## Canonical Decomposition
210+
211+
The canonical decomposition theorem shows that a meromorphic function `f` on a disk is equal, up to
212+
modification over a discrete set, to a product of canonical factors and a meromorphic function `g`
213+
without zeros or poles in the interior of the disk.
214+
215+
To simplify notation and avoid repetition, we introduce a structure, `CanonicalDecomp`, that bundles
216+
the conclusions of the decomposition theorem.
217+
-/
218+
219+
variable
220+
{E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E]
221+
{R : ℝ} {c w : ℂ}
222+
{f : ℂ → E}
223+
224+
/--
225+
Given functions `f`, `g` and a real number `R`, the following convenience structure packs the
226+
information relevant in the canonical decomposition. The condition "`g` is without zeros or poles"
227+
is formulated by saying that `g` is meromorphic in normal form and `g ≠ 0`.
228+
-/
229+
structure CanonicalDecomp (f g : ℂ → E) (R : ℝ) : Prop where
230+
/-- A proof that `f` is meromorphic on `closedBall 0 R`. -/
231+
meromorphicOn : MeromorphicOn f (closedBall 0 R)
232+
233+
/-- A proof that `g` is meromorphic in normal form on `closedBall 0 R`. -/
234+
meromorphicNFOn : MeromorphicNFOn g (closedBall 0 R)
235+
236+
/-- A proof that `g` does not vanish in the interior of the ball. -/
237+
ne_zero : ∀ u ∈ (ball 0 R), g u ≠ 0
238+
239+
/--
240+
A proof that `f` is equal, up to modification over a discrete set, to a product of `g` and
241+
canonical factors prescribed by the divisor of `f`.
242+
-/
243+
eventuallyEq : f =ᶠ[codiscreteWithin (closedBall 0 R)]
244+
(∏ᶠ u, (canonicalFactor R u) ^ (-MeromorphicOn.divisor f (ball 0 R) u)) • g
245+
246+
-- Auxiliary lemma for the proof of the canonical decomposition theorem: The factor in the canonical
247+
-- decomposition is meromorphic in normal form.
248+
private lemma canonicalDecomposition_aux₁ (F : locallyFinsuppWithin (ball (0 : ℂ) R) ℤ) :
249+
MeromorphicNFOn (∏ᶠ u, (canonicalFactor R u) ^ (F u)) (ball (0 : ℂ) R) := by
250+
classical
251+
refine meromorphicNFOn_finprod (fun w ↦ ?_) fun z hz a ha b hb ↦ ?_
252+
· by_cases hw : w ∈ ball 0 R
253+
· exact fun _ _ ↦ (meromorphicNFOn_canonicalFactor hw).zpow (by trivial)
254+
· simp only [hw, not_false_eq_true, locallyFinsuppWithin.apply_eq_zero_of_notMem, zpow_zero]
255+
exact analyticOnNhd_const.meromorphicNFOn
256+
· have ⟨h₂a, h₂b⟩ : a ∈ ball 0 R ∧ b ∈ ball 0 R := by constructor <;> (by_contra; aesop)
257+
grind [eq_zero_of_zpow_eq_zero hb, eq_zero_of_zpow_eq_zero ha,
258+
canonicalFactor_eq_zero_iff h₂b hz, canonicalFactor_eq_zero_iff h₂a hz]
259+
260+
-- Auxiliary lemma for the proof of the canonical decomposition theorem: Write a function with
261+
-- finite support as a linear combination of singleton indicator functions.
262+
open Function.locallyFinsuppWithin in
263+
private lemma sum_apply_smul_single_eq_self
264+
{X : Type*} [TopologicalSpace X] [DecidableEq X] {U : Set X}
265+
{F : Function.locallyFinsuppWithin U ℤ} (h : F.support.Finite) :
266+
∑ x ∈ h.toFinset, (F x) • ((single x (1 : ℤ)).restrict (subset_univ U)) = F := by
267+
ext z
268+
by_cases hz : z ∉ U
269+
· aesop
270+
simp only [coe_sum, coe_zsmul, zsmul_eq_mul, Finset.sum_apply, Pi.mul_apply, Pi.intCast_apply,
271+
Int.cast_eq, Function.locallyFinsuppWithin.restrict_apply]
272+
by_cases hz : z ∈ F.support
273+
· rw [← Finset.add_sum_erase _ _ (by aesop : z ∈ h.toFinset), Finset.sum_eq_zero (by aesop)]
274+
aesop
275+
· aesop
276+
277+
-- Auxiliary lemma for the proof of the canonical decomposition theorem: Exhibit the divisor of the
278+
-- factor in the canonical decomposition as the negative of the divisor of `f`.
279+
private lemma canonicalDecomposition_aux₂ (h₁f : MeromorphicOn f (closedBall 0 R)) :
280+
divisor (∏ᶠ u, (canonicalFactor R u) ^ (divisor f (ball 0 R) u)) (ball 0 R)
281+
= -(divisor f (ball 0 R)) := by
282+
have η₀ : (-divisor f (ball 0 R)).support.Finite := by simp [h₁f.divisor_ball_support_finite]
283+
rw [finprod_eq_prod_of_mulSupport_subset_of_finite _ (by aesop) η₀, divisor_prod]
284+
· simp_rw [divisor_zpow (fun z hz ↦ meromorphic_canonicalFactor R _ z)]
285+
conv_rhs => rw [← sum_apply_smul_single_eq_self η₀]
286+
apply Finset.sum_congr rfl fun x hx ↦ ?_
287+
rw [divisor_canonicalFactor, smul_neg, locallyFinsuppWithin.coe_neg, Pi.neg_apply, neg_smul]
288+
by_contra
289+
simp_all
290+
· intro z hz
291+
apply zpow (fun x hx ↦ meromorphic_canonicalFactor R z x)
292+
· intro z hz x hx
293+
rw [meromorphicOrderAt_zpow (meromorphic_canonicalFactor R z x)]
294+
lift (meromorphicOrderAt (canonicalFactor R z) x) to ℤ using
295+
(meromorphicOrderAt_canonicalFactor_ne_top z (pos_of_mem_ball hx)) with
296+
simp [← WithTop.coe_mul]
297+
298+
-- Auxiliary lemma for the proof of the canonical decomposition theorem: The (inverse of the) factor
299+
-- in the canonical decomposition does not vanish identically.
300+
private lemma canonicalDecomposition_aux₃ {z : ℂ} (hR : 0 < R) :
301+
meromorphicOrderAt (∏ᶠ (c : ℂ), canonicalFactor R c ^ (divisor f (ball 0 R)) c) z ≠ ⊤ := by
302+
apply meromorphicOrderAt_finprod_ne_top
303+
(fun _ ↦ MeromorphicAt.zpow (meromorphic_canonicalFactor _ _ _) _)
304+
intro c
305+
rw [meromorphicOrderAt_zpow (meromorphic_canonicalFactor R c z)]
306+
lift meromorphicOrderAt (canonicalFactor R c) z to ℤ using
307+
(meromorphicOrderAt_canonicalFactor_ne_top c hR) with
308+
simp [← WithTop.coe_mul]
309+
310+
/--
311+
**Canonical decomposition:** A meromorphic function `f` on a disk is equal, up to modification over
312+
a discrete set, to a product of canonical factors and a meromorphic function `g` without zeros or
313+
poles in the interior of the disk.
314+
-/
315+
theorem _root_.MeromorphicOn.exists_canonicalDecomp
316+
(h₁f : MeromorphicOn f (closedBall 0 R))
317+
(h₂f : ∀ u : (closedBall (0 : ℂ) R), meromorphicOrderAt f u ≠ ⊤) :
318+
∃ g : ℂ → E, CanonicalDecomp f g R := by
319+
-- Trivial case: If `R` is non-positive, then the ball is empty.
320+
by_cases hR : R ≤ 0
321+
· use fun _ ↦ f 0
322+
exact {
323+
meromorphicOn := h₁f
324+
meromorphicNFOn := fun z hz ↦ AnalyticAt.meromorphicNFAt analyticAt_const
325+
ne_zero := by simp [ball_eq_empty.2 hR]
326+
eventuallyEq := by
327+
filter_upwards [self_mem_codiscreteWithin (closedBall 0 R)] with a ha
328+
have : R = 0 := by grind [nonneg_of_mem_closedBall ha]
329+
aesop
330+
}
331+
rw [not_le] at hR
332+
-- General case: The requirement that `f =ᶠ[…] (something) • g` implies that `g` must equal
333+
-- `(something)⁻¹ • g`, converted to a meromorphic function in normal form. The next lines define
334+
-- `g` in this way and establish basic properties.
335+
let φ := (∏ᶠ c, canonicalFactor R c ^ (divisor f (ball 0 R)) c) • f
336+
have hφ : MeromorphicOn φ (closedBall 0 R) := by
337+
apply smul (MeromorphicOn.finprod _) h₁f
338+
exact fun z ↦ zpow (fun z₁ hz₁ ↦ meromorphic_canonicalFactor _ _ _) _
339+
let g := toMeromorphicNFOn φ (closedBall 0 R)
340+
have h₃g : divisor g (ball 0 R) = 0 := by
341+
rw [divisor_congr_codiscreteWithin
342+
((toMeromorphicNFOn_eqOn_codiscrete hφ).symm.filter_mono
343+
(codiscreteWithin_mono ball_subset_closedBall)) isOpen_ball,
344+
divisor_smul _ (fun x hx ↦ h₁f x (ball_subset_closedBall hx))
345+
(fun z _ ↦ canonicalDecomposition_aux₃ hR)
346+
(fun z hz ↦ h₂f ⟨z, ball_subset_closedBall hz⟩),
347+
canonicalDecomposition_aux₂ h₁f, neg_add_cancel]
348+
apply (canonicalDecomposition_aux₁ _).meromorphicOn
349+
have h₂g : MeromorphicNFOn g (closedBall 0 R) :=
350+
meromorphicNFOn_toMeromorphicNFOn φ (closedBall 0 R)
351+
have h₄g {z : ℂ} (hz : z ∈ closedBall 0 R) : meromorphicOrderAt g z ≠ ⊤ := by
352+
rw [meromorphicOrderAt_toMeromorphicNFOn hφ hz, meromorphicOrderAt_smul _ (h₁f z hz)]
353+
· simpa [h₂f ⟨z, hz⟩] using canonicalDecomposition_aux₃ hR
354+
· apply MeromorphicAt.finprod (fun x ↦ (meromorphic_canonicalFactor R x z).zpow _)
355+
-- Use the function `g` defined above and establish the required properties
356+
use g
357+
have η₀ : (-divisor f (ball 0 R)).support.Finite := by simp [h₁f.divisor_ball_support_finite]
358+
exact {
359+
meromorphicOn := h₁f
360+
meromorphicNFOn := meromorphicNFOn_toMeromorphicNFOn φ (closedBall 0 R)
361+
ne_zero := by
362+
intro z hz
363+
rw [← MeromorphicNFAt.meromorphicOrderAt_eq_zero_iff (h₂g (ball_subset_closedBall hz))]
364+
have : divisor g (ball 0 R) z = 0 := by simp [h₃g]
365+
rw [divisor_apply (fun x hx ↦ (h₂g (ball_subset_closedBall hx)).meromorphicAt) hz] at this
366+
simpa [h₄g (ball_subset_closedBall hz)] using this
367+
eventuallyEq := by
368+
trans (∏ i ∈ η₀.toFinset, canonicalFactor R i ^ (-(divisor f (ball 0 R)) i)) • φ
369+
· unfold φ
370+
rw [finprod_eq_prod_of_mulSupport_subset_of_finite _ (by aesop) η₀]
371+
· filter_upwards [codiscreteWithin_mono (by tauto) η₀.compl_mem_codiscrete,
372+
self_mem_codiscreteWithin (closedBall 0 R)] with a ha h₂a
373+
simp only [Pi.smul_apply', Finset.prod_apply, Pi.pow_apply]
374+
rw [← smul_assoc, ← Finset.prod_smul, Finset.prod_eq_one, one_smul]
375+
intro x hx
376+
rw [smul_eq_mul, ← zpow_add', neg_add_cancel, zpow_zero]
377+
simp_all only [ne_eq, Subtype.forall, mem_closedBall, dist_zero_right,
378+
locallyFinsuppWithin.support_neg, mem_compl_iff, mem_support, Decidable.not_not,
379+
Finite.mem_toFinset, neg_add_cancel, not_true_eq_false, neg_eq_zero, and_self, or_self,
380+
or_false]
381+
apply canonicalFactor_ne_zero _ (by simp_all) (by grind)
382+
by_contra h
383+
simp_all
384+
· rw [finprod_eq_prod_of_mulSupport_subset_of_finite _ (by aesop) η₀]
385+
filter_upwards [toMeromorphicNFOn_eqOn_codiscrete hφ] using by simp_all [g]
386+
}
387+
154388
end Complex

Mathlib/Analysis/Meromorphic/Divisor.lean

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,40 @@ lemma AnalyticOnNhd.divisor_apply {f : 𝕜 → E} (hf : AnalyticOnNhd 𝕜 f U)
7272
divisor f U z = ((analyticOrderAt f z).map (↑)).untop₀ := by
7373
rw [hf.meromorphicOn.divisor_apply hz, (hf z hz).meromorphicOrderAt_eq]
7474

75+
/-!
76+
## Support Properties
77+
-/
78+
79+
/--
80+
Special case of `Function.locallyFinsuppWithin.finiteSupport` that frequently shows in complex
81+
analysis: Divisors on spheres have finite support.
82+
-/
83+
lemma _root_.divisor_sphere_support_finite [ProperSpace 𝕜] {f : 𝕜 → E} {R : ℝ} {c : 𝕜} :
84+
(divisor f (Metric.sphere c R)).support.Finite :=
85+
(divisor f (Metric.sphere c R)).finiteSupport (isCompact_sphere c R)
86+
87+
/--
88+
If `f` is meromorphic on a compact set `U` and `V ⊆ U`, then the divisor of `f` on `V` has finite
89+
support.
90+
-/
91+
lemma divisor_support_finite_of_subset {f : 𝕜 → E} {V : Set 𝕜} (hf : MeromorphicOn f U)
92+
(hU : IsCompact U) (hV : V ⊆ U) :
93+
(divisor f V).support.Finite := by
94+
apply ((divisor f U).finiteSupport hU).subset
95+
intro b hb
96+
rw [Function.mem_support, ne_eq, divisor_apply hf (hV ((divisor f V).supportWithinDomain hb))]
97+
rwa [Function.mem_support, ne_eq, divisor_apply (fun x hx ↦ hf x (hV hx))
98+
((divisor f V).supportWithinDomain hb)] at hb
99+
100+
/--
101+
Special case of `MeromorphicOn.divisor_subset_finiteSupport` that frequently shows in complex
102+
analysis, where `U` is a closed ball and `V` is its interior.
103+
-/
104+
lemma divisor_ball_support_finite [ProperSpace 𝕜] {f : 𝕜 → E} {R : ℝ} {c : 𝕜}
105+
(hf : MeromorphicOn f (Metric.closedBall c R)) :
106+
(divisor f (Metric.ball c R)).support.Finite :=
107+
hf.divisor_support_finite_of_subset (isCompact_closedBall c R) Metric.ball_subset_closedBall
108+
75109
/-!
76110
## Congruence Lemmas
77111
-/

0 commit comments

Comments
 (0)