Current task: —

← Session 28 — ii′-5e: partial-fraction identity (zero series + F entire)

#1469 assistant 2026-08-23 13:49:06.775 UTC · 858→4587 tok open ⤢
thinking (11971 chars)
Excellent — Mathlib has: - `riemannZetaZeros := riemannZeta ⁻¹' {0}`, `isClosed_riemannZetaZeros`, `isDiscrete_riemannZetaZeros`, `IsCompact.inter_riemannZetaZeros_finite`, AND `riemannZeta_one_ne_zero` (so ζ(1) ≠ 0 in Mathlib — junk value is nonzero, good: the s₀=1 case goes through the ζ ≠ 0 continuity route... but wait, is ζ continuous at 1? ζ has a pole at 1, so not continuous. `riemannZeta_one_ne_zero` just says the value is nonzero. For the ball-avoidance at s₀ = 1, continuity at 1 fails (pole). But zetaA route: ζ(z) = zetaA(z)/(z−1) near 1, zetaA(1) = 1 ≠ 0, zetaA continuous ⟹ ‖zetaA‖ ≥ 1/2 on a ball ⟹ ‖ζ(z)‖ ≥ (1/2)/‖z−1‖ → ∞ ⟹ no zeros in punctured ball. So: s₀ = 1 → zetaA route ✓; s₀ ≠ 1, ζ s₀ ≠ 0 → differentiableAt_riemannZeta ⟹ continuousAt ⟹ ball with ζ ≠ 0 ✓; s₀ ≠ 1, ζ s₀ = 0 → NF ✓. Also `isDiscrete_riemannZetaZeros` gives isolation for zeros directly! IsDiscrete: every point of the set has a punctured neighborhood avoiding the set. For ρ₀ a nontrivial zero (hence ∈ riemannZetaZeros): ∃ ball, riemannZetaZeros ∩ ball = {ρ₀}... Actually IsDiscrete in Mathlib: `IsDiscrete s := sᶜ ∈ codiscreteWithin...`? There's `IsDiscrete` meaning ∀ x ∈ s, ∃ t ∈ 𝓝 x, t ∩ s = {x}? Something like `isDiscrete_iff...`. For the isolation at ρ₀ (part iii) I can use isDiscrete_riemannZetaZeros to get a ball where the only zero is ρ₀. Let me check what API exists for IsDiscrete: `IsDiscrete.mem_nhds...`? Let me grep. Also `tendsto_riemannZetaZeros_cofinite_cocompact` is interesting — the zeros' cofinite filter tends to cocompact — that directly gives finiteness of {ρ : ‖ρ‖ < R} in the FULL zero subtype. But I'm working with the nontrivial-zero subtype; the map {nontrivial} → {zeros} inclusion... finiteness via the LiSkeleton pattern is already banked; I'll reuse it. Now the plan is solid. Deliverables for LiSeries.lean: ```lean /- §0 defs -/ def seriesTerm (s : ℂ) (ρ : {ρ : ℂ // IsNontrivialZero ρ}) : ℂ := (zeroMult ρ : ℂ) * (1 / (s - ρ) + 1 / ρ) def seriesFun (s : ℂ) : ℂ := ∑' ρ : {ρ : ℂ // IsNontrivialZero ρ}, seriesTerm s ρ /- §1 the comparison + tail bound -/ lemma normSq_gammaOf_le' : for nontrivial ρ with 2 ≤ ‖ρ‖: 1 + normSq (gammaOf ρ) ≤ 17/12 ‖ρ‖² -- wait, direction: I need 1/‖ρ‖² ≤ C/(1+‖γ‖²), i.e. 1+‖γ‖² ≤ C‖ρ‖² ✓ 17/12. lemma seriesTerm_norm_le (s) (ρ) (h2 : 2 ≤ ‖ρ‖) (hs : 2‖s‖ ≤ ‖ρ‖) : ‖seriesTerm s ρ‖ ≤ (17/6)·‖s‖·mult/(1+‖γ‖²)... -- careful: ‖1/(s−ρ)+1/ρ‖ ≤ 2‖s‖/‖ρ‖² needs ρ ≠ 0 (re > 0 ✓) and the algebra -- 1/(s−ρ)+1/ρ = s/(ρ(s−ρ)): field_simp with s−ρ ≠ 0 (‖s−ρ‖ ≥ ‖ρ‖/2 > 0 ✓). /- §2 summability for all s (D-trick clone) -/ theorem seriesSummable (s : ℂ) : Summable (seriesTerm s) /- §3 finiteness of the subtype ball (shared) -/ lemma finite_norm_lt (R : ℝ) : {ρ : {ρ // IsNontrivialZero ρ} | ‖(ρ:ℂ)‖ < R}.Finite -- hmm — need the subtype-set finiteness; the liSummable proof did the inline version. -- Actually for the M-test cofinite argument I need: {ρ | ‖ρ‖ < R} ∈ cofinite... -- complement finite. Set.Finite.compl_mem_cofinite? Filter: sᶜ.Finite → s ∈ cofinite: -- `Filter.mem_cofinite : s ∈ cofinite ↔ sᶜ.Finite`? or `Set.Finite.compl_mem_cofinite`. /- §4 analyticity on U = {¬IsNontrivialZero} -/ lemma exists_ball_avoid (s₀ : ℂ) (hs₀ : ¬ IsNontrivialZero s₀) : ∃ δ > 0, Metric.ball s₀ δ ⊆ {s | ¬ IsNontrivialZero s} -- via case split lemma seriesFun_analyticAt_of_not_zero {s₀} (hs₀ : ¬ IsNontrivialZero s₀) : AnalyticAt ℂ seriesFun s₀ -- M-test on ball(s₀, δ/2)?? uniform bound on closedBall ⊆ ball; use of_norm_le_summable_eventually -- on the open ball with R₀ = max 4 (2(‖s₀‖+δ)); differentiableOn via partial sums; analyticOnNhd; -- then AnalyticAt from analyticOnNhd on the open ball containing s₀. theorem seriesFun_analyticOnNhd : AnalyticOnNhd ℂ seriesFun {s | ¬ IsNontrivialZero s} -- from pointwise: analyticOnNhd_iff...? check Mathlib: `AnalyticOnNhd` def. /- §5 isolation + reduced series -/ theorem exists_isolation (ρ₀) : ∃ δ > 0, ∀ ρ₁ ≠ ρ₀, δ ≤ ‖ρ₁ - ρ₀‖ -- from isDiscrete or finite-min def seriesTermSub (ρ₀) (s) (ρ) := if ρ = ρ₀ then 0 else seriesTerm s ρ def seriesFunSub (ρ₀) (s) := ∑' ρ, seriesTermSub ρ₀ s ρ lemma seriesFunSub_analyticAt (ρ₀) : AnalyticAt ℂ (seriesFunSub ρ₀) ρ₀ -- M-test on ball(ρ₀, δ/2): terms ρ₁ ≠ ρ₀: ‖s−ρ₁‖ ≥ δ/2; ρ₀-term zero. -- uniform bound eventually via tail; head terms fine. lemma seriesFun_sub_eq (ρ₀) : ∀ s near ρ₀... seriesFun s = seriesFunSub ρ₀ s + seriesTerm s ρ₀ -- via Summable.tsum_add? seriesTerm s ρ = seriesTermSub + if-eq term; tsum splits. theorem seriesFun_sub_term_analyticAt (ρ₀) : AnalyticAt ℂ (fun s => seriesFun s - (zeroMult ρ₀:ℂ)/(s - ρ₀)) ρ₀ -- = seriesFunSub ρ₀ s + mult/ρ₀ near ρ₀... need EventualEq then AnalyticAt.congr. ``` Details for §4's M-test on ball(s₀, δ) (avoiding nontrivial zeros): - R₀ := 2·(‖s₀‖+δ) + 4 (say). For ρ with R₀ ≤ ‖ρ‖: 2 ≤ ‖ρ‖ ✓ and for s ∈ ball: ‖s‖ ≤ ‖s₀‖+δ =: M; 2‖s‖ ≤ 2M ≤ R₀ ≤ ‖ρ‖ ✓. So ‖term s ρ‖ ≤ (17/6)·M... wait the bound has ‖s‖ varying: (17/6)‖s‖·mult/(1+‖γ‖²) ≤ (17/6)·M·mult/(1+‖γ‖²) ✓ monotone. So u ρ := (17/6)·M·mult/(1+normSq(γ_ρ)) summable ✓. - cofinite: {ρ | R₀ ≤ ‖ρ‖}ᶜ = {ρ | ‖ρ‖ < R₀} finite ⟹ ∈ cofinite: `Set.Finite.compl_mem_cofinite`? Actually direction: finite set's complement is in cofinite filter: `Set.Finite.compl_mem_cofinite (h : s.Finite) : sᶜ ∈ cofinite`. I want {ρ | R₀ ≤ ‖ρ‖} ∈ cofinite = {ρ | ¬(‖ρ‖ < R₀)}... ‖ρ‖ < R₀ complement is ‖ρ‖ ≥ R₀ ✓. So `{ρ | ‖ρ‖ < R₀}.compl_mem_cofinite` gives {ρ | R₀ ≤ ‖ρ‖} ∈ cofinite after compl. Fine. - `of_norm_le_summable_eventually hu hfu` gives HasSumUniformlyOn (fun ρ => fun s => seriesTerm s ρ) (fun s => ∑' ρ, seriesTerm s ρ) (ball s₀ δ) — the limit function is defeq to seriesFun restricted... `fun s => ∑' ρ, seriesTerm s ρ` — is this syntactically `seriesFun`? seriesFun s := ∑' ρ, seriesTerm s ρ — yes if I state things right. - Then `hasSumUniformlyOn_iff_tendstoUniformlyOn.mp` → TendstoUniformlyOn → `.tendstoLocallyUniformlyOn` → `.differentiableOn (eventually partial sums differentiableOn) (isOpen_ball)`. Partial sums: fun s => ∑ ρ ∈ t, seriesTerm s ρ; differentiable on the ball: each term: fun s => mult·(1/(s−ρ)+1/ρ): needs s − ρ ≠ 0 on the ball: ball avoids nontrivial zeros ✓ (ρ nontrivial ⟹ ρ ∉ ball ⟹ s ≠ ρ... s ∈ ball, ρ ∉ ball ⟹ s ≠ ρ ✓); ρ ≠ 0 ✓ (re > 0). DifferentiableAt.div etc. - `.analyticOnNhd isOpen_ball` — wait the DifferentiableOn.analyticOnNhd signature: `(h : DifferentiableOn ℂ f s) (hs : IsOpen s) : AnalyticOnNhd ℂ f s`? In LiDigamma: `dpsiTermC_tsum_differentiableOn.analyticOnNhd dpsiDomain_isOpen` ✓ same pattern. - AnalyticOnNhd on ball(s₀,δ), s₀ ∈ ball ⟹ AnalyticAt: `AnalyticOnNhd.analyticAt (h) (mem)` — check name: `AnalyticOnNhd.analyticAt (hf : AnalyticOnNhd 𝕜 f s) (hx : s ∈ 𝓝 x) : AnalyticAt 𝕜 f x`? Something like that — grep when writing. Or via DifferentiableAt directly: differentiableOn at interior point ⟹ DifferentiableWithinAt ⟹ DifferentiableAt (ball is nhds of s₀): `(hd s₀ (mem)).differentiableAt (ball_mem_nhds s₀ hδ)` then `DifferentiableAt.analyticAt` — banked gotcha from session 026: "DifferentiableAt.analyticAt does NOT exist (use fun_prop)". Hmm! Session-026 banked: DifferentiableAt.analyticAt does NOT exist. But there must be a way: over ℂ, differentiable ⟹ analytic: Mathlib `DifferentiableOn.analyticOnNhd` exists (used in LiDigamma). So: get DifferentiableOn on the ball, then `.analyticOnNhd isOpen_ball` gives AnalyticOnNhd on the ball, then AnalyticOnNhd s ∈ 𝓝 s₀ ⟹ AnalyticAt: lemma `AnalyticOnNhd.analyticAt`? Let me grep Mathlib for it when writing. There's `AnalyticOnNhd.analyticAt (h : AnalyticOnNhd 𝕜 f s) (hx : s ∈ 𝓝 x)`? I recall `AnalyticOnNhd.analyticAt` exists... or `AnalyticAt` via `analyticAt_of_...`. I'll check. For §5's M-test on ball(ρ₀, δ/2) for seriesTermSub: - Terms: if ρ = ρ₀ then 0 else seriesTerm s ρ. For ρ₁ ≠ ρ₀: isolation ‖ρ₁ − ρ₀‖ ≥ δ ⟹ for s ∈ ball(ρ₀, δ/2): ‖s − ρ₁‖ ≥ δ/2 > 0 ✓ differentiable ✓. - Uniform bound: split: ρ with ‖ρ‖ ≥ R₀: same tail bound (the if-zero term is ≤ since 0 ≤ anything ✓ — need care: ‖if ρ = ρ₀ then 0 else term‖ ≤ u ρ for the tail: if ρ = ρ₀: 0 ≤ u ρ₀ ✓ (u nonneg); else the bound ✓). Head terms: fine (each differentiable on the ball). And the equality: seriesFun s =ᶠ near ρ₀... actually for ALL s: seriesTerm s ρ = seriesTermSub ρ₀ s ρ + (if ρ = ρ₀ then seriesTerm s ρ else 0). Pointwise in ρ ✓. tsum: Summable (seriesTermSub ρ₀ s)? From the M-test on the ball for s ∈ ball; and Summable (if ρ = ρ₀ then seriesTerm s ρ₀... single-support function: `summable_of_hasFiniteSupport` with support ⊆ {ρ₀} ✓. Then `Summable.hasSum.add`... I need tsum f = tsum g + tsum h where f = g + h pointwise: `Summable.tsum_add : tsum (g + h) = tsum g + tsum h` — need f = g + h as functions: funext: seriesTerm s ρ = seriesTermSub ρ₀ s ρ + (if ρ = ρ₀ then seriesTerm s ρ else 0) ✓ by by_cases. And tsum of the single-support: `tsum_eq_single`? `tsum_ite_eq`? There's `tsum_eq_single (f) (a) (h : ∀ b ≠ a, f b = 0) : tsum f = f a`? `tsum_eq_single` exists I think (tsum_eq_single : ∑' x, f x = f a if ∀ x ∉ {a}...). I'll find it. So near ρ₀ (in fact everywhere): seriesFun s − mult·(1/(s−ρ₀)+1/ρ₀) = seriesFunSub ρ₀ s. Then seriesFun s − mult/(s−ρ₀) = seriesFunSub ρ₀ s + mult/ρ₀. Hmm — for the analyticAt statement, cleanest target: `AnalyticAt ℂ (fun s => seriesFun s - (zeroMult (ρ₀:ℂ)... wait zeroMult ρ₀ where ρ₀ : subtype — zeroMult takes ℂ: zeroMult (ρ₀ : ℂ) — in liSummand it's `(zeroMult ρ : ℂ)` with ρ : subtype coerced automatically? `(zeroMult ρ : ℂ)` with ρ the subtype — zeroMult ρ means zeroMult ↑ρ ✓. Target (5e-iv will consume): for each nontrivial zero ρ₀ (as a ℂ point with h : IsNontrivialZero ρ₀): `AnalyticAt ℂ (fun s => seriesFun s - (zeroMult ρ₀ : ℂ) * (1/(s - ρ₀))) ρ₀`? Or with the +1/ρ₀ kept — cleaner to keep the whole term: the function fun s => seriesFun s − seriesTerm s ρ₀ equals seriesFunSub ρ₀ everywhere ✓ analytic at ρ₀ ✓. 5e-iv can then adjust by the constant mult/ρ₀. Even better: state exactly `theorem seriesFun_sub_self_term_analyticAt (ρ₀ : {ρ // IsNontrivialZero ρ}) : AnalyticAt ℂ (fun s => seriesFun s - seriesTerm s ρ₀) ρ₀` and let 5e-iv rearrange. Also maybe the form with just the polar part: `AnalyticAt ℂ (fun s => seriesFun s - (zeroMult ρ₀ : ℂ)/(s - ρ₀)) ρ₀` — since the difference between the two is the constant mult·(1/ρ₀) — analytic. I'll prove the seriesTermSub one and derive the polar one. One subtlety in seriesFun s − seriesTerm s ρ₀ = seriesFunSub ρ₀ s: this requires Summable (seriesTerm s) (have it ∀ s ✓) and Summable (seriesTermSub ρ₀ s) — for s in the ball ✓ but I want the equality near ρ₀ only — restrict to the ball where both summable ✓ (eventually). For the analyticAt: AnalyticAt.congr with the EventuallyEq on the ball ✓. Alright — also for §4 I realize I should double check `differentiableAt_riemannZeta` name. In LiSides: `analyticAt_riemannZeta hρ` — with hρ : ρ ≠ 1. ✓. And continuity route: `(analyticAt_riemannZeta hs₀).continuousAt` — AnalyticAt.continuousAt exists? AnalyticAt ⟹ ContinuousAt: `AnalyticAt.continuousAt` ✓ probably. Also for the ζ s₀ ≠ 0 case: continuousAt.eventually_ne gives ζ ≠ 0 in a ball? `ContinuousAt.eventually_ne (h : f x₀ ≠ 0) : ∀ᶠ y in 𝓝 x₀, f y ≠ 0` ✓ then eventually-ball: metric.eventually_nhds_iff_ball: ∀ᶠ y in 𝓝 x, P y ↔ ∃ ε > 0, ∀ y ∈ ball x ε, P y ✓. For the NF case (ζ s₀ = 0, s₀ ≠ 1): hfh : ζ =ᶠ[𝓝 s₀] (z−s₀)^m • h z; hh0 : h s₀ ≠ 0, hh continuous ⟹ h ≠ 0 on a ball B(s₀, ε₁); hfh on B(s₀, ε₂); take min: on punctured ball: ζ z = (z−s₀)^m·h z ≠ 0 ✓. So zeros of ζ in ball ⊆ {s₀}; s₀ not nontrivial ✓. For s₀ = 1: zetaA facts: from LiResidue: `zetaA` def, `zetaA_apply (hw : w ≠ 1) : zetaA w = (w−1)·ζ w`? Let me check LiResidue for exact names: "zetaA/hLi analytic at 1", "zetaA_one". Grep quickly. Also `riemannZeta_one_ne_zero` (Mathlib, used in ZetaZeros.lean) — so at s₀ = 1, ζ 1 ≠ 0 junk-wise. But continuity at 1 fails, so I still use zetaA. Let me now check LiResidue names for zetaA.
The infrastructure is all banked. Let me check the zetaA names in LiResidue and the `AnalyticOnNhd`/`IsDiscrete` API entry points I'll need.
tool: Grep
input
{
  "pattern": "def zetaA|lemma zetaA|theorem zetaA|zetaA_one|zetaA_apply|zetaA_analytic",
  "path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiResidue.lean",
  "output_mode": "content",
  "-n": true,
  "head_limit": 25
}
tool: Bash
input
{
  "command": "cd D:/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem AnalyticOnNhd.analyticAt\\b\\|lemma AnalyticOnNhd.analyticAt\\b\\|def AnalyticOnNhd\\b\" Mathlib/Analysis/Analytic/*.lean | head -5; grep -rn \"analyticOnNhd_iff_analyticAt\\|AnalyticOnNhd.*\u2194.*AnalyticAt\" Mathlib/Analysis/Analytic/*.lean | head -5; grep -rn \"theorem.*IsDiscrete.*ball\\|IsDiscrete.mem\\|isDiscrete_iff\" Mathlib/Topology/*.lean Mathlib/Topology/**/*.lean 2>/dev/null | head -8",
  "description": "Check AnalyticOnNhd and IsDiscrete API"
}
raw content_json (database row)
[{"type":"thinking","thinking":"Excellent — Mathlib has:\n- `riemannZetaZeros := riemannZeta ⁻¹' {0}`, `isClosed_riemannZetaZeros`, `isDiscrete_riemannZetaZeros`, `IsCompact.inter_riemannZetaZeros_finite`, AND `riemannZeta_one_ne_zero` (so ζ(1) ≠ 0 in Mathlib — junk value is nonzero, good: the s₀=1 case goes through the ζ ≠ 0 continuity route... but wait, is ζ continuous at 1? ζ has a pole at 1, so not continuous. `riemannZeta_one_ne_zero` just says the value is nonzero. For the ball-avoidance at s₀ = 1, continuity at 1 fails (pole). But zetaA route: ζ(z) = zetaA(z)/(z−1) near 1, zetaA(1) = 1 ≠ 0, zetaA continuous ⟹ ‖zetaA‖ ≥ 1/2 on a ball ⟹ ‖ζ(z)‖ ≥ (1/2)/‖z−1‖ → ∞ ⟹ no zeros in punctured ball. So: s₀ = 1 → zetaA route ✓; s₀ ≠ 1, ζ s₀ ≠ 0 → differentiableAt_riemannZeta ⟹ continuousAt ⟹ ball with ζ ≠ 0 ✓; s₀ ≠ 1, ζ s₀ = 0 → NF ✓.\n\nAlso `isDiscrete_riemannZetaZeros` gives isolation for zeros directly! IsDiscrete: every point of the set has a punctured neighborhood avoiding the set. For ρ₀ a nontrivial zero (hence ∈ riemannZetaZeros): ∃ ball, riemannZetaZeros ∩ ball = {ρ₀}... Actually IsDiscrete in Mathlib: `IsDiscrete s := sᶜ ∈ codiscreteWithin...`? There's `IsDiscrete` meaning ∀ x ∈ s, ∃ t ∈ 𝓝 x, t ∩ s = {x}? Something like `isDiscrete_iff...`. For the isolation at ρ₀ (part iii) I can use isDiscrete_riemannZetaZeros to get a ball where the only zero is ρ₀. \n\nLet me check what API exists for IsDiscrete: `IsDiscrete.mem_nhds...`? Let me grep. Also `tendsto_riemannZetaZeros_cofinite_cocompact` is interesting — the zeros' cofinite filter tends to cocompact — that directly gives finiteness of {ρ : ‖ρ‖ < R} in the FULL zero subtype. But I'm working with the nontrivial-zero subtype; the map {nontrivial} → {zeros} inclusion... finiteness via the LiSkeleton pattern is already banked; I'll reuse it.\n\nNow the plan is solid. Deliverables for LiSeries.lean:\n\n```lean\n/- §0 defs -/\ndef seriesTerm (s : ℂ) (ρ : {ρ : ℂ // IsNontrivialZero ρ}) : ℂ :=\n  (zeroMult ρ : ℂ) * (1 / (s - ρ) + 1 / ρ)\n\ndef seriesFun (s : ℂ) : ℂ := ∑' ρ : {ρ : ℂ // IsNontrivialZero ρ}, seriesTerm s ρ\n\n/- §1 the comparison + tail bound -/\nlemma normSq_gammaOf_le' : for nontrivial ρ with 2 ≤ ‖ρ‖: 1 + normSq (gammaOf ρ) ≤ 17/12 ‖ρ‖²\n  -- wait, direction: I need 1/‖ρ‖² ≤ C/(1+‖γ‖²), i.e. 1+‖γ‖² ≤ C‖ρ‖² ✓ 17/12.\n\nlemma seriesTerm_norm_le (s) (ρ) (h2 : 2 ≤ ‖ρ‖) (hs : 2‖s‖ ≤ ‖ρ‖) :\n    ‖seriesTerm s ρ‖ ≤ (17/6)·‖s‖·mult/(1+‖γ‖²)... \n    -- careful: ‖1/(s−ρ)+1/ρ‖ ≤ 2‖s‖/‖ρ‖² needs ρ ≠ 0 (re > 0 ✓) and the algebra\n    -- 1/(s−ρ)+1/ρ = s/(ρ(s−ρ)): field_simp with s−ρ ≠ 0 (‖s−ρ‖ ≥ ‖ρ‖/2 > 0 ✓).\n\n/- §2 summability for all s (D-trick clone) -/\ntheorem seriesSummable (s : ℂ) : Summable (seriesTerm s)\n\n/- §3 finiteness of the subtype ball (shared) -/\nlemma finite_norm_lt (R : ℝ) : {ρ : {ρ // IsNontrivialZero ρ} | ‖(ρ:ℂ)‖ < R}.Finite\n  -- hmm — need the subtype-set finiteness; the liSummable proof did the inline version.\n  -- Actually for the M-test cofinite argument I need: {ρ | ‖ρ‖ < R} ∈ cofinite... \n  -- complement finite. Set.Finite.compl_mem_cofinite? Filter: sᶜ.Finite → s ∈ cofinite:\n  -- `Filter.mem_cofinite : s ∈ cofinite ↔ sᶜ.Finite`? or `Set.Finite.compl_mem_cofinite`.\n\n/- §4 analyticity on U = {¬IsNontrivialZero} -/\nlemma exists_ball_avoid (s₀ : ℂ) (hs₀ : ¬ IsNontrivialZero s₀) :\n    ∃ δ > 0, Metric.ball s₀ δ ⊆ {s | ¬ IsNontrivialZero s}  -- via case split\n\nlemma seriesFun_analyticAt_of_not_zero {s₀} (hs₀ : ¬ IsNontrivialZero s₀) :\n    AnalyticAt ℂ seriesFun s₀\n  -- M-test on ball(s₀, δ/2)?? uniform bound on closedBall ⊆ ball; use of_norm_le_summable_eventually\n  -- on the open ball with R₀ = max 4 (2(‖s₀‖+δ)); differentiableOn via partial sums; analyticOnNhd;\n  -- then AnalyticAt from analyticOnNhd on the open ball containing s₀.\n\ntheorem seriesFun_analyticOnNhd : AnalyticOnNhd ℂ seriesFun {s | ¬ IsNontrivialZero s}\n  -- from pointwise: analyticOnNhd_iff...? check Mathlib: `AnalyticOnNhd` def.\n\n/- §5 isolation + reduced series -/\ntheorem exists_isolation (ρ₀) : ∃ δ > 0, ∀ ρ₁ ≠ ρ₀, δ ≤ ‖ρ₁ - ρ₀‖  -- from isDiscrete or finite-min\n\ndef seriesTermSub (ρ₀) (s) (ρ) := if ρ = ρ₀ then 0 else seriesTerm s ρ\ndef seriesFunSub (ρ₀) (s) := ∑' ρ, seriesTermSub ρ₀ s ρ\n\nlemma seriesFunSub_analyticAt (ρ₀) : AnalyticAt ℂ (seriesFunSub ρ₀) ρ₀\n  -- M-test on ball(ρ₀, δ/2): terms ρ₁ ≠ ρ₀: ‖s−ρ₁‖ ≥ δ/2; ρ₀-term zero.\n  -- uniform bound eventually via tail; head terms fine.\n\nlemma seriesFun_sub_eq (ρ₀) : ∀ s near ρ₀... \n    seriesFun s = seriesFunSub ρ₀ s + seriesTerm s ρ₀\n  -- via Summable.tsum_add? seriesTerm s ρ = seriesTermSub + if-eq term; tsum splits.\n\ntheorem seriesFun_sub_term_analyticAt (ρ₀) :\n    AnalyticAt ℂ (fun s => seriesFun s - (zeroMult ρ₀:ℂ)/(s - ρ₀)) ρ₀\n  -- = seriesFunSub ρ₀ s + mult/ρ₀ near ρ₀... need EventualEq then AnalyticAt.congr.\n```\n\nDetails for §4's M-test on ball(s₀, δ) (avoiding nontrivial zeros):\n- R₀ := 2·(‖s₀‖+δ) + 4 (say). For ρ with R₀ ≤ ‖ρ‖: 2 ≤ ‖ρ‖ ✓ and for s ∈ ball: ‖s‖ ≤ ‖s₀‖+δ =: M; 2‖s‖ ≤ 2M ≤ R₀ ≤ ‖ρ‖ ✓. So ‖term s ρ‖ ≤ (17/6)·M... wait the bound has ‖s‖ varying: (17/6)‖s‖·mult/(1+‖γ‖²) ≤ (17/6)·M·mult/(1+‖γ‖²) ✓ monotone. So u ρ := (17/6)·M·mult/(1+normSq(γ_ρ)) summable ✓.\n- cofinite: {ρ | R₀ ≤ ‖ρ‖}ᶜ = {ρ | ‖ρ‖ < R₀} finite ⟹ ∈ cofinite: `Set.Finite.compl_mem_cofinite`? Actually direction: finite set's complement is in cofinite filter: `Set.Finite.compl_mem_cofinite (h : s.Finite) : sᶜ ∈ cofinite`. I want {ρ | R₀ ≤ ‖ρ‖} ∈ cofinite = {ρ | ¬(‖ρ‖ < R₀)}... ‖ρ‖ < R₀ complement is ‖ρ‖ ≥ R₀ ✓. So `{ρ | ‖ρ‖ < R₀}.compl_mem_cofinite` gives {ρ | R₀ ≤ ‖ρ‖} ∈ cofinite after compl. Fine.\n- `of_norm_le_summable_eventually hu hfu` gives HasSumUniformlyOn (fun ρ => fun s => seriesTerm s ρ) (fun s => ∑' ρ, seriesTerm s ρ) (ball s₀ δ) — the limit function is defeq to seriesFun restricted... `fun s => ∑' ρ, seriesTerm s ρ` — is this syntactically `seriesFun`? seriesFun s := ∑' ρ, seriesTerm s ρ — yes if I state things right.\n- Then `hasSumUniformlyOn_iff_tendstoUniformlyOn.mp` → TendstoUniformlyOn → `.tendstoLocallyUniformlyOn` → `.differentiableOn (eventually partial sums differentiableOn) (isOpen_ball)`. Partial sums: fun s => ∑ ρ ∈ t, seriesTerm s ρ; differentiable on the ball: each term: fun s => mult·(1/(s−ρ)+1/ρ): needs s − ρ ≠ 0 on the ball: ball avoids nontrivial zeros ✓ (ρ nontrivial ⟹ ρ ∉ ball ⟹ s ≠ ρ... s ∈ ball, ρ ∉ ball ⟹ s ≠ ρ ✓); ρ ≠ 0 ✓ (re > 0). DifferentiableAt.div etc.\n- `.analyticOnNhd isOpen_ball` — wait the DifferentiableOn.analyticOnNhd signature: `(h : DifferentiableOn ℂ f s) (hs : IsOpen s) : AnalyticOnNhd ℂ f s`? In LiDigamma: `dpsiTermC_tsum_differentiableOn.analyticOnNhd dpsiDomain_isOpen` ✓ same pattern.\n- AnalyticOnNhd on ball(s₀,δ), s₀ ∈ ball ⟹ AnalyticAt: `AnalyticOnNhd.analyticAt (h) (mem)` — check name: `AnalyticOnNhd.analyticAt (hf : AnalyticOnNhd 𝕜 f s) (hx : s ∈ 𝓝 x) : AnalyticAt 𝕜 f x`? Something like that — grep when writing. Or via DifferentiableAt directly: differentiableOn at interior point ⟹ DifferentiableWithinAt ⟹ DifferentiableAt (ball is nhds of s₀): `(hd s₀ (mem)).differentiableAt (ball_mem_nhds s₀ hδ)` then `DifferentiableAt.analyticAt` — banked gotcha from session 026: \"DifferentiableAt.analyticAt does NOT exist (use fun_prop)\". Hmm! Session-026 banked: DifferentiableAt.analyticAt does NOT exist. But there must be a way: over ℂ, differentiable ⟹ analytic: Mathlib `DifferentiableOn.analyticOnNhd` exists (used in LiDigamma). So: get DifferentiableOn on the ball, then `.analyticOnNhd isOpen_ball` gives AnalyticOnNhd on the ball, then AnalyticOnNhd s ∈ 𝓝 s₀ ⟹ AnalyticAt: lemma `AnalyticOnNhd.analyticAt`? Let me grep Mathlib for it when writing. There's `AnalyticOnNhd.analyticAt (h : AnalyticOnNhd 𝕜 f s) (hx : s ∈ 𝓝 x)`? I recall `AnalyticOnNhd.analyticAt` exists... or `AnalyticAt` via `analyticAt_of_...`. I'll check.\n\nFor §5's M-test on ball(ρ₀, δ/2) for seriesTermSub:\n- Terms: if ρ = ρ₀ then 0 else seriesTerm s ρ. For ρ₁ ≠ ρ₀: isolation ‖ρ₁ − ρ₀‖ ≥ δ ⟹ for s ∈ ball(ρ₀, δ/2): ‖s − ρ₁‖ ≥ δ/2 > 0 ✓ differentiable ✓.\n- Uniform bound: split: ρ with ‖ρ‖ ≥ R₀: same tail bound (the if-zero term is ≤ since 0 ≤ anything ✓ — need care: ‖if ρ = ρ₀ then 0 else term‖ ≤ u ρ for the tail: if ρ = ρ₀: 0 ≤ u ρ₀ ✓ (u nonneg); else the bound ✓). Head terms: fine (each differentiable on the ball).\n\nAnd the equality: seriesFun s =ᶠ near ρ₀... actually for ALL s: seriesTerm s ρ = seriesTermSub ρ₀ s ρ + (if ρ = ρ₀ then seriesTerm s ρ else 0). Pointwise in ρ ✓. tsum: Summable (seriesTermSub ρ₀ s)? From the M-test on the ball for s ∈ ball; and Summable (if ρ = ρ₀ then seriesTerm s ρ₀... single-support function: `summable_of_hasFiniteSupport` with support ⊆ {ρ₀} ✓. Then `Summable.hasSum.add`... I need tsum f = tsum g + tsum h where f = g + h pointwise: `Summable.tsum_add : tsum (g + h) = tsum g + tsum h` — need f = g + h as functions: funext: seriesTerm s ρ = seriesTermSub ρ₀ s ρ + (if ρ = ρ₀ then seriesTerm s ρ else 0) ✓ by by_cases. And tsum of the single-support: `tsum_eq_single`? `tsum_ite_eq`? There's `tsum_eq_single (f) (a) (h : ∀ b ≠ a, f b = 0) : tsum f = f a`? `tsum_eq_single` exists I think (tsum_eq_single : ∑' x, f x = f a if ∀ x ∉ {a}...). I'll find it.\n\nSo near ρ₀ (in fact everywhere): seriesFun s − mult·(1/(s−ρ₀)+1/ρ₀) = seriesFunSub ρ₀ s. Then seriesFun s − mult/(s−ρ₀) = seriesFunSub ρ₀ s + mult/ρ₀. Hmm — for the analyticAt statement, cleanest target:\n\n`AnalyticAt ℂ (fun s => seriesFun s - (zeroMult (ρ₀:ℂ)... wait zeroMult ρ₀ where ρ₀ : subtype — zeroMult takes ℂ: zeroMult (ρ₀ : ℂ) — in liSummand it's `(zeroMult ρ : ℂ)` with ρ : subtype coerced automatically? `(zeroMult ρ : ℂ)` with ρ the subtype — zeroMult ρ means zeroMult ↑ρ ✓.\n\nTarget (5e-iv will consume): for each nontrivial zero ρ₀ (as a ℂ point with h : IsNontrivialZero ρ₀):\n`AnalyticAt ℂ (fun s => seriesFun s - (zeroMult ρ₀ : ℂ) * (1/(s - ρ₀))) ρ₀`? Or with the +1/ρ₀ kept — cleaner to keep the whole term: the function fun s => seriesFun s − seriesTerm s ρ₀ equals seriesFunSub ρ₀ everywhere ✓ analytic at ρ₀ ✓. 5e-iv can then adjust by the constant mult/ρ₀. Even better: state exactly\n\n`theorem seriesFun_sub_self_term_analyticAt (ρ₀ : {ρ // IsNontrivialZero ρ}) : AnalyticAt ℂ (fun s => seriesFun s - seriesTerm s ρ₀) ρ₀`\n\nand let 5e-iv rearrange. Also maybe the form with just the polar part:\n`AnalyticAt ℂ (fun s => seriesFun s - (zeroMult ρ₀ : ℂ)/(s - ρ₀)) ρ₀` — since the difference between the two is the constant mult·(1/ρ₀) — analytic. I'll prove the seriesTermSub one and derive the polar one.\n\nOne subtlety in seriesFun s − seriesTerm s ρ₀ = seriesFunSub ρ₀ s: this requires Summable (seriesTerm s) (have it ∀ s ✓) and Summable (seriesTermSub ρ₀ s) — for s in the ball ✓ but I want the equality near ρ₀ only — restrict to the ball where both summable ✓ (eventually). For the analyticAt: AnalyticAt.congr with the EventuallyEq on the ball ✓.\n\nAlright — also for §4 I realize I should double check `differentiableAt_riemannZeta` name. In LiSides: `analyticAt_riemannZeta hρ` — with hρ : ρ ≠ 1. ✓. And continuity route: `(analyticAt_riemannZeta hs₀).continuousAt` — AnalyticAt.continuousAt exists? AnalyticAt ⟹ ContinuousAt: `AnalyticAt.continuousAt` ✓ probably.\n\nAlso for the ζ s₀ ≠ 0 case: continuousAt.eventually_ne gives ζ ≠ 0 in a ball? `ContinuousAt.eventually_ne (h : f x₀ ≠ 0) : ∀ᶠ y in 𝓝 x₀, f y ≠ 0` ✓ then eventually-ball: metric.eventually_nhds_iff_ball: ∀ᶠ y in 𝓝 x, P y ↔ ∃ ε > 0, ∀ y ∈ ball x ε, P y ✓.\n\nFor the NF case (ζ s₀ = 0, s₀ ≠ 1): hfh : ζ =ᶠ[𝓝 s₀] (z−s₀)^m • h z; hh0 : h s₀ ≠ 0, hh continuous ⟹ h ≠ 0 on a ball B(s₀, ε₁); hfh on B(s₀, ε₂); take min: on punctured ball: ζ z = (z−s₀)^m·h z ≠ 0 ✓. So zeros of ζ in ball ⊆ {s₀}; s₀ not nontrivial ✓.\n\nFor s₀ = 1: zetaA facts: from LiResidue: `zetaA` def, `zetaA_apply (hw : w ≠ 1) : zetaA w = (w−1)·ζ w`? Let me check LiResidue for exact names: \"zetaA/hLi analytic at 1\", \"zetaA_one\". Grep quickly.\n\nAlso `riemannZeta_one_ne_zero` (Mathlib, used in ZetaZeros.lean) — so at s₀ = 1, ζ 1 ≠ 0 junk-wise. But continuity at 1 fails, so I still use zetaA.\n\nLet me now check LiResidue names for zetaA.","signature":""},{"type":"text","text":"The infrastructure is all banked. Let me check the zetaA names in LiResidue and the `AnalyticOnNhd`/`IsDiscrete` API entry points I'll need."},{"type":"tool_use","id":"Grep_26","name":"Grep","input":{"pattern":"def zetaA|lemma zetaA|theorem zetaA|zetaA_one|zetaA_apply|zetaA_analytic","path":"D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiResidue.lean","output_mode":"content","-n":true,"head_limit":25},"extra_content":null},{"type":"tool_use","id":"Bash_27","name":"Bash","input":{"command":"cd D:/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem AnalyticOnNhd.analyticAt\\b\\|lemma AnalyticOnNhd.analyticAt\\b\\|def AnalyticOnNhd\\b\" Mathlib/Analysis/Analytic/*.lean | head -5; grep -rn \"analyticOnNhd_iff_analyticAt\\|AnalyticOnNhd.*↔.*AnalyticAt\" Mathlib/Analysis/Analytic/*.lean | head -5; grep -rn \"theorem.*IsDiscrete.*ball\\|IsDiscrete.mem\\|isDiscrete_iff\" Mathlib/Topology/*.lean Mathlib/Topology/**/*.lean 2>/dev/null | head -8","description":"Check AnalyticOnNhd and IsDiscrete API"},"extra_content":null}]