Current task: —

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

#1472 assistant 2026-08-23 14:08:01.546 UTC · 513→22493 tok open ⤢
thinking (58788 chars)
All confirmed. Now write LiSeries.lean. Let me draft the full file carefully. ```lean /- NguyenRH1/LiSeries.lean — tier ii′ sub-stage ii′-5e-iii (D-068 §3): the zero-side partial-fraction series seriesFun s := ∑' ρ : {ρ // IsNontrivialZero ρ}, (zeroMult ρ : ℂ)·(1/(s−ρ) + 1/ρ) and its three structural properties: (§1–2) ABSOLUTE SUMMABILITY at every s (`seriesSummable`): the tail bound ‖1/(s−ρ) + 1/ρ‖ ≤ 2‖s‖/‖ρ‖² (‖ρ‖ ≥ 2‖s‖, ‖ρ‖ ≥ 2) feeds the ii′-1a dominator chain (comparison 1 + ‖γ_ρ‖² ≤ (17/12)‖ρ‖² → Zeta23 `WeilEF.zero_sum_inv_sq`); the finite head is a finite subtype sum. (§3–4) ANALYTICITY off the zeros (`seriesFun_analyticOnNhd`): around any s₀ that is not a nontrivial zero there is a ball avoiding the nontrivial zeros (continuity of ζ where ζ s₀ ≠ 0; the order normal form where ζ s₀ = 0, s₀ ≠ 1; the zetaA factorization at s₀ = 1), and on that ball the series converges UNIFORMLY (Weierstrass M-test, `HasSumUniformlyOn.of_norm_le_summable_eventually`) with analytic partial sums. (§5) ISOLATION (`nontrivialZero_isolated`) and the reduced series `seriesFunSub ρ₀` (the ρ₀-term zeroed out): analytic AT ρ₀ (`seriesFunSub_analyticAt`), so the polar subtraction s ↦ seriesFun s − mult/(s−ρ₀) is analytic at ρ₀ (`seriesFun_sub_polar_analyticAt`) — the input 5e-iv needs for the residue cancellation at the nontrivial zeros. Archive references: D-068 §3, journal-020/021 (the locally-uniform ⟹ analytic pattern), journal-015 (the ii′-1a dominator chain). -/ import Mathlib import Zeta23.WeilEF.ZeroSummability import Zeta23.Statement.SeamClosed import NguyenRH1.LiSides open Zeta23 Complex Filter Topology noncomputable section namespace NguyenRH1 ``` Wait — check LiSides namespace: decls like zeta_order_ne_top_of_ne are in NguyenRH1 namespace (used unqualified in LiDisc which is also NguyenRH1). ✓. Now §0: ```lean /-! ## 0. The series -/ /-- The zero-series summand: mult(ρ)·(1/(s−ρ) + 1/ρ) over the nontrivial zero subtype (the ii′-1a encoding; D-068 §3). -/ def seriesTerm (s : ℂ) (ρ : {ρ : ℂ // IsNontrivialZero ρ}) : ℂ := (zeroMult ρ : ℂ) * (1 / (s - (ρ : ℂ)) + 1 / (ρ : ℂ)) /-- The zero-side partial-fraction series. Summable at every s (`seriesSummable`), analytic off the nontrivial zeros (`seriesFun_analyticOnNhd`). -/ def seriesFun (s : ℂ) : ℂ := ∑' ρ : {ρ : ℂ // IsNontrivialZero ρ}, seriesTerm s ρ ``` §1: ```lean /-! ## 1. The norm comparison and the tail bound -/ /-- For a nontrivial zero with 2 ≤ ‖ρ‖: 1 + ‖γ_ρ‖² ≤ (17/12)·‖ρ‖² (the γ-vs-‖·‖ comparison of the ii′-1a chain, with the constant for the ‖ρ‖ ≥ 2 range: ‖γ‖² = im² + (1/2−re)² ≤ im² + 1/4 and im² ≥ ‖ρ‖² − 1 ≥ 3). -/ lemma one_add_normSq_gammaOf_le (ρ : {ρ : ℂ // IsNontrivialZero ρ}) (hρ : (2 : ℝ) ≤ ‖(ρ : ℂ)‖) : 1 + Complex.normSq (gammaOf (ρ : ℂ)) ≤ 17 / 12 * ‖(ρ : ℂ)‖ ^ 2 := by have hz := ρ.2 have hre0 : 0 < (ρ : ℂ).re := hz.2.1 have hre1 : (ρ : ℂ).re < 1 := hz.2.2 have hnorm : ‖(ρ : ℂ)‖ ^ 2 = (ρ : ℂ).re ^ 2 + (ρ : ℂ).im ^ 2 := by rw [← Complex.normSq_eq_norm_sq, Complex.normSq_apply] ring have hgam : Complex.normSq (gammaOf (ρ : ℂ)) = (ρ : ℂ).im ^ 2 + (1 / 2 - (ρ : ℂ).re) ^ 2 := by rw [Complex.normSq_apply, WeilEF.gammaOf_re, WeilEF.gammaOf_im] ring have hre2 : (ρ : ℂ).re ^ 2 ≤ 1 := by nlinarith [hre0, hre1] have him2 : 3 ≤ (ρ : ℂ).im ^ 2 := by nlinarith [hρ, hnorm, hre2] -- needs 4 ≤ ‖ρ‖²: from hρ: 2 ≤ ‖ρ‖: sq: 4 ≤ ‖ρ‖² — pow_le_pow_left₀ or nlinarith [hρ, norm_nonneg] have hquarter : (1 / 2 - (ρ : ℂ).re) ^ 2 ≤ 1 / 4 := by nlinarith [hre0, hre1] rw [hgam, hnorm] nlinarith [him2, hquarter] ``` Check nlinarith goals: him2: 3 ≤ im²: from ‖ρ‖² = re²+im², ‖ρ‖ ≥ 2 ⟹ ‖ρ‖² ≥ 4 (nlinarith: hρ : 2 ≤ ‖ρ‖, norm_nonneg ‖ρ‖ ≥ 0 ⟹ product (‖ρ‖−2)(‖ρ‖+2) ≥ 0 ⟹ ‖ρ‖² ≥ 4 ✓ nlinarith [hρ, norm_nonneg ‖(ρ:ℂ)‖]); re² ≤ 1 ⟹ im² = ‖ρ‖² − re² ≥ 4 − 1 = 3 ✓ nlinarith should manage with hnorm as an hypothesis (rw first? I rw [hgam, hnorm] at the END — the haves hnorm/hgam are used in nlinarith calls before the rewrite; hnorm is a hypothesis equation so nlinarith [hρ, hnorm, hre2]... but hnorm is in context already, no need to pass. Final goal after rw [hgam, hnorm]: 1 + (im² + (1/2−re)²) ≤ 17/12·(re²+im²). nlinarith [him2, hquarter, hre2...]: LHS ≤ 1 + im² + 1/4; want ≤ 17/12 re² + 17/12 im². From him2: im² ≥ 3. Hmm: 1 + im² + 1/4 ≤ 17/12(re²+im²) ⟺ 5/4 + im² ≤ 17/12 re² + 17/12 im² ⟸ 5/4 + im² ≤ 17/12 im² ⟺ 5/4 ≤ 5/12 im² ⟺ 3 ≤ im² ✓. nlinarith hint: needs (5/12)im² ≥ 5/4 from im² ≥ 3: linear ✓ and re² ≥ 0 (sq_nonneg) ✓. So `nlinarith [him2, hquarter, sq_nonneg (ρ:ℂ).re]`. hquarter: (1/2−re)² ≤ 1/4 ⟺ |1/2−re| ≤ 1/2 ⟺ 0 ≤ re ≤ 1: nlinarith [hre0, hre1]: (1/2−re)² − 1/4 = −re + re² = re(re−1) ≤ 0 since re > 0, re−1 < 0: product re(re−1) < 0: nlinarith product hint: it multiplies hre0·(hre1): re·(re − 1)... nlinarith proves (1/2−re)² ≤ 1/4 ⟺ re² − re + 1/4 ≤ 1/4 ⟺ re² ≤ re ⟺ re(re−1) ≤ 0: from hre0 (0 < re) and hre1 (re < 1): (re)·(1−re) > 0 ⟹ re − re² > 0: nlinarith multiplies hre0 and (1 − re > 0 from hre1) ✓ should find it. hre2: re² ≤ 1: re < 1, re > 0: re·re < 1·re·... nlinarith [hre0, hre1]: re² ≤ 1 ⟸ re² ≤ re (above) and re < 1: nlinarith finds via product (1−re)·re > 0 and re < 1... re² ≤ re < 1... wait need re² ≤ 1: re² ≤ re (from product) and re < 1 ⟹ re² < 1 ✓. nlinarith [hre0, hre1] ✓. Then: ```lean /-- The key algebra: 1/(s−ρ) + 1/ρ = s/(ρ·(s−ρ)). -/ lemma one_div_sub_add_one_div {s ρ : ℂ} (h0 : ρ ≠ 0) (h1 : s - ρ ≠ 0) : 1 / (s - ρ) + 1 / ρ = s / (ρ * (s - ρ)) := by field_simp ring ``` field_simp with h0, h1 in context: goal 1/(s−ρ) + 1/ρ = s/(ρ·(s−ρ)): field_simp clears denominators: needs ρ*(s−ρ) ≠ 0 — mul_ne_zero h0 h1 might need to be in context; field_simp should find h0 h1 and maybe need the product: add `have := mul_ne_zero h0 h1`. After clearing: ρ + (s−ρ) = s? LHS·denom: 1/(s−ρ) = ρ·?/… let me trust field_simp + ring (banked gotcha: "field_simp often closes goals (trailing ring errors)"). ```lean /-- Tail bound: for 2 ≤ ‖ρ‖ and 2‖s‖ ≤ ‖ρ‖, ‖seriesTerm s ρ‖ ≤ (17/6)·‖s‖·mult/(1+‖γ_ρ‖²). -/ lemma seriesTerm_norm_le {s : ℂ} (ρ : {ρ : ℂ // IsNontrivialZero ρ}) (hρ2 : (2 : ℝ) ≤ ‖(ρ : ℂ)‖) (hsρ : 2 * ‖s‖ ≤ ‖(ρ : ℂ)‖) : ‖seriesTerm s ρ‖ ≤ 17 / 6 * ‖s‖ * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ)))) := by have h0 : (ρ : ℂ) ≠ 0 := by intro h; rw [h, norm_zero] at hρ2; linarith -- norm_num at... 2 ≤ 0 false: linarith works: norm_zero: ‖0‖=0: hρ2 : 2 ≤ 0: linarith? norm_num closes: `norm_num at hρ2`. Use that. have hρpos : (0 : ℝ) < ‖(ρ : ℂ)‖ := norm_pos_iff.mpr h0 have hsnorm : ‖s‖ ≤ ‖(ρ : ℂ)‖ / 2 := by linarith have hsr : ‖s - (ρ : ℂ)‖ ≥ ‖(ρ : ℂ)‖ / 2 := by -- use norm_sub_le reversed have h := norm_sub_le_norm_sub... ``` ‖s−ρ‖ ≥ ‖ρ‖ − ‖s‖ (norm_sub_norm_le? `norm_sub_le_norm_sub`? The reverse triangle: `norm_sub_le`? Mathlib: `norm_sub_le_norm_sub`? No: `abs_norm_sub_norm_le : |‖a‖ − ‖b‖| ≤ ‖a − b‖` — so ‖ρ‖ − ‖s‖ ≤ |‖ρ‖−‖s‖| ≤ ‖ρ − s‖ = ‖s − ρ‖ (norm_sub_rev). So: ```lean have hsr : ‖(ρ : ℂ)‖ / 2 ≤ ‖s - (ρ : ℂ)‖ := by have h := abs_norm_sub_norm_le s (ρ : ℂ) -- |‖s‖ − ‖ρ‖| ≤ ‖s − ρ‖ rw [abs_le] at h have h2 := h.1 -- -(‖s‖−‖ρ‖) ≤ ‖s−ρ‖ i.e. ‖ρ‖−‖s‖ ≤ ‖s−ρ‖ linarith ``` Then s − ρ ≠ 0: norm_pos: ‖s−ρ‖ ≥ ‖ρ‖/2 > 0. ```lean have h1 : s - (ρ : ℂ) ≠ 0 := by intro h; rw [h, norm_zero] at hsr; linarith have hcomp := one_add_normSq_gammaOf_le ρ hρ2 have hg0 : (0 : ℝ) < 1 + Complex.normSq (gammaOf (ρ : ℂ)) := by have := Complex.normSq_nonneg (gammaOf (ρ : ℂ)); linarith have halg := one_div_sub_add_one_div h0 h1 rw [seriesTerm, halg, norm_mul, Complex.norm_natCast] -- norm of (mult : ℂ) * (...): norm_mul gives ‖mult‖·‖s/(ρ(s−ρ))‖; Complex.norm_natCast: ‖(mult:ℂ)‖ = (mult:ℝ)... zeroMult ρ is ℕ; (zeroMult ρ : ℂ): norm_natCast: ‖(↑n : ℂ)‖ = ↑n? Complex.norm_natCast : ‖(n : ℂ)‖ = n. Hmm RCLike.norm_natCast was used in LiSkeleton: `RCLike.norm_natCast`. Both may exist. Use RCLike.norm_natCast like LiSkeleton. rw [norm_div, norm_mul] -- goal: (mult:ℝ) * (‖s‖ / (‖ρ‖ * ‖s−ρ‖)) ≤ 17/6 * ‖s‖ * (mult / (1+‖γ‖²)) have hmul0 : (0:ℝ) ≤ (zeroMult ρ : ℝ) := Nat.cast_nonneg _ -- ‖ρ‖·‖s−ρ‖ ≥ ‖ρ‖·(‖ρ‖/2) = ‖ρ‖²/2 have hden : ‖(ρ : ℂ)‖ ^ 2 / 2 ≤ ‖(ρ : ℂ)‖ * ‖s - (ρ : ℂ)‖ := by nlinarith [hsr, hρpos, norm_nonneg (s - (ρ:ℂ))] -- mul_le_mul_of_nonneg_left hsr (le_of_lt hρpos) : ‖ρ‖·(‖ρ‖/2) ≤ ‖ρ‖·‖s−ρ‖; ring_nf -- hence ‖s‖/(‖ρ‖‖s−ρ‖) ≤ ‖s‖/(‖ρ‖²/2) = 2‖s‖/‖ρ‖² have hfrac : ‖s‖ / (‖(ρ : ℂ)‖ * ‖s - (ρ : ℂ)‖) ≤ 2 * ‖s‖ / ‖(ρ : ℂ)‖ ^ 2 := by rw [div_le_div_iff₀ (by positivity...)] ... ``` div_le_div_iff₀ (ha : 0 < a) (hb : 0 < b): a/b ≤ c/d ⟺ ... signature: `div_le_div_iff₀ (hb : 0 < b) (hd : 0 < d) : a / b ≤ c / d ↔ a * d ≤ c * b`. Let me do: ‖s‖/D ≤ 2‖s‖/ρ² ⟺ ‖s‖·ρ² ≤ 2‖s‖·D (D = ‖ρ‖‖s−ρ‖ > 0): from D ≥ ρ²/2: 2‖s‖·D ≥ 2‖s‖·ρ²/2 = ‖s‖·ρ² ✓. positivity for ‖s‖ ≥ 0 fine. Then: ```lean calc (zeroMult ρ : ℝ) * (‖s‖ / (‖(ρ:ℂ)‖ * ‖s - (ρ:ℂ)‖)) ≤ (zeroMult ρ : ℝ) * (2 * ‖s‖ / ‖(ρ:ℂ)‖ ^ 2) := mul_le_mul_of_nonneg_left hfrac hmul0 _ = 2 * ‖s‖ * (zeroMult ρ : ℝ) / ‖(ρ:ℂ)‖ ^ 2 := by ring _ ≤ 17 / 6 * ‖s‖ * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ)))) := by -- ⟺ 2·‖s‖·mult/ρ² ≤ (17/6)‖s‖·mult/(1+γ²) -- ⟸ mult·‖s‖·(2/ρ² ≤ (17/6)/(1+γ²)) ⟸ 2/ρ² ≤ (17/6)/(1+γ²) ⟺ 2(1+γ²) ≤ (17/6)ρ² ⟸ 2·(17/12)ρ² = (17/6)ρ² ✓ rw [div_le_div_iff₀ (by positivity) hg0] -- careful: LHS form A/ρ², RHS B/(1+γ²) ... ``` Let me structure: ```lean have hinv : 2 * ‖s‖ * (zeroMult ρ : ℝ) / ‖(ρ:ℂ)‖ ^ 2 ≤ 17 / 6 * ‖s‖ * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ)))) := by rw [div_le_div_iff₀ (by positivity : (0:ℝ) < ‖(ρ:ℂ)‖ ^ 2) hg0] -- goal: 2‖s‖mult·(1+γ²) ≤ (17/6‖s‖·mult)·ρ² -- hmm RHS form: (17/6 * ‖s‖ * (mult/(1+γ²))) * ρ²... ``` Careful — after div_le_div_iff₀ with a = 2‖s‖mult, b = ρ², c = (17/6)‖s‖·mult... wait RHS is (17/6 * ‖s‖ * (mult/(1+γ²))) — that's not of the form c/d syntactically! It's a product containing a division. div_le_div_iff₀ won't apply. Restructure: show both sides as divisions: RHS = ((17/6)·‖s‖·mult)/(1+γ²) by ring (mul_div_assoc). So: ```lean have hR : 17 / 6 * ‖s‖ * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ)))) = (17 / 6 * ‖s‖ * (zeroMult ρ : ℝ)) / (1 + Complex.normSq (gammaOf (ρ:ℂ))) := by ring rw [hR, div_le_div_iff₀ (by positivity : (0:ℝ) < ‖(ρ:ℂ)‖ ^ 2) hg0] -- goal: 2*‖s‖*mult * (1+γ²) ≤ (17/6*‖s‖*mult) * ρ² have hkey : 2 * (1 + Complex.normSq (gammaOf (ρ:ℂ))) ≤ 17 / 6 * ‖(ρ:ℂ)‖ ^ 2 := by linarith [hcomp] -- hcomp: 1+γ² ≤ 17/12 ρ² ⟹ 2(1+γ²) ≤ 17/6 ρ² ✓ calc 2 * ‖s‖ * (zeroMult ρ:ℝ) * (1 + Complex.normSq (gammaOf (ρ:ℂ))) = (‖s‖ * (zeroMult ρ:ℝ)) * (2 * (1 + Complex.normSq (gammaOf (ρ:ℂ)))) := by ring _ ≤ (‖s‖ * (zeroMult ρ:ℝ)) * (17 / 6 * ‖(ρ:ℂ)‖ ^ 2) := mul_le_mul_of_nonneg_left hkey (by positivity) _ = 17 / 6 * ‖s‖ * (zeroMult ρ:ℝ) * ‖(ρ:ℂ)‖ ^ 2 := by ring ``` positivity for ‖s‖·mult ≥ 0 ✓ (Nat.cast_nonneg & norm_nonneg — positivity handles). Then wrap the calc: LHS of goal is `‖(zeroMult ρ : ℂ)‖ * (‖s‖ / (‖ρ‖ * ‖s−ρ‖))` after the rewrites — hmm actually after `rw [seriesTerm, halg, norm_mul, RCLike.norm_natCast, norm_div, norm_mul]` the goal is `(↑(zeroMult ρ) : ℝ) * (‖s‖ / (‖ρ‖ * ‖s − ρ‖)) ≤ ...`. Note RCLike.norm_natCast gives ‖(n:ℂ)‖ = (n:ℝ)? RCLike.norm_natCast : ‖(n : R)‖ = n where the RHS is (n : ℝ)? For ℂ: ‖(n:ℂ)‖ = ↑n ✓. In liSummand_norm: `rw [liSummand_eq n ρ, norm_mul, RCLike.norm_natCast]` then `RCLike.norm_ofReal` — so RCLike.norm_natCast : ‖(↑n : 𝕜)‖ = ↑n (into ℝ) ✓. Hmm — but wait, does `norm_natCast` match `(zeroMult ρ : ℂ)` where zeroMult ρ : ℕ? The cast is ℕ → ℂ: ‖((zeroMult ρ : ℕ) : ℂ)‖ = ((zeroMult ρ : ℕ) : ℝ) ✓. But hold on: in my calc chain the goal after rw has LHS `(zeroMult ρ : ℝ) * (‖s‖ / (‖ρ‖ * ‖s − ρ‖))` — my calc starts with exactly that ✓. Actually `norm_div` on `‖s / (ρ * (s−ρ))‖` gives ‖s‖ / ‖ρ*(s−ρ)‖ then norm_mul gives ‖ρ‖·‖s−ρ‖ ✓. §2: ```lean /-! ## 2. Summability -/ /-- The subtype elements in a closed ball form a finite set (the ii′-1a compact-finiteness pattern). -/ lemma finite_subtype_norm_lt (R : ℝ) : {ρ : {ρ : ℂ // IsNontrivialZero ρ} | ‖(ρ : ℂ)‖ < R}.Finite := by have hcomp : IsCompact (Metric.closedBall (0 : ℂ) R) := isCompact_closedBall _ _ have hzeros : (Metric.closedBall (0 : ℂ) R) ∩ {ρ : ℂ | IsNontrivialZero ρ} ⊆ (Metric.closedBall (0 : ℂ) R) ∩ riemannZetaZeros := by intro z hz exact ⟨hz.1, hz.2.1⟩ have hfin2 := (hcomp.inter_riemannZetaZeros_finite).subset hzeros have himg : (Subtype.val '' {ρ : {ρ // IsNontrivialZero ρ} | ‖(ρ : ℂ)‖ < R}).Finite := by apply hfin2.subset rintro z ⟨ρ, hρ, rfl⟩ refine ⟨?_, ρ.2⟩ simp only [Metric.mem_closedBall, dist_zero_right] exact le_of_lt hρ exact Set.Finite.of_finite_image himg (Subtype.val_injective.injOn) ``` Wait — in liSummable the set was `{ρ : {ρ // IsNontrivialZero ρ} | ¬ ((2:ℝ)*n ≤ ‖(ρ:ℂ)‖)}` and the image-subset argument used `lt_of_not_ge hρ`. Mine: ‖ρ‖ < R directly ⟹ dist ≤ R: le_of_lt hρ where hρ : ‖ρ‖ < R ✓ — but hρ after rintro: `⟨ρ, hρ, rfl⟩` where hρ : ‖(ρ:ℂ)‖ < R (the set membership). ✓. Also note in liSummable the membership target included `ρ.2` for the {IsNontrivialZero} part ✓ same. Hmm — one difference: liSummable's hfin2/himg used the set-builder on the SUBTYPE with the negated condition; the Set.Finite.of_finite_image with Subtype.val_injective.injOn — wait `Set.Finite.of_finite_image (hs : (f '' s).Finite) (hi : Set.InjOn f s) : s.Finite` ✓. Membership: `hz.2.1` where hz.2 : IsNontrivialZero z — as discussed hz.2.1 : riemannZeta z = 0 — and membership in riemannZetaZeros is .rfl ✓ (liSummable line 312: `exact ⟨hz.1, hz.2.1⟩` ✓ copy). ```lean /-- The series is absolutely summable at every s (the ii′-1a D-trick: dominator (17/6)(‖s‖+1)·mult/(1+‖γ‖²), finite head inside ‖ρ‖ < R₀). -/ theorem seriesSummable (s : ℂ) : Summable (fun ρ : {ρ : ℂ // IsNontrivialZero ρ} => seriesTerm s ρ) := by set R₀ : ℝ := max 2 (2 * ‖s‖) with hR₀ have hR₀2 : (2 : ℝ) ≤ R₀ := le_max_left _ _ have hR₀s : 2 * ‖s‖ ≤ R₀ := le_max_right _ _ set C : ℝ := 17 / 6 * (‖s‖ + 1) with hC have hbase : Summable (fun ρ : {ρ : ℂ // IsNontrivialZero ρ} => C * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ))))) := (WeilEF.zero_sum_inv_sq zetaSeam).mul_left C set D : {ρ : ℂ // IsNontrivialZero ρ} → ℝ := fun ρ => if R₀ ≤ ‖(ρ : ℂ)‖ then C * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ)))) else ‖seriesTerm s ρ‖ with hDdef have hfin : {ρ : {ρ // IsNontrivialZero ρ} | ¬ (R₀ ≤ ‖(ρ : ℂ)‖)}.Finite := by have := finite_subtype_norm_lt R₀ apply this.subset -- hmm: {¬ R₀ ≤ ‖ρ‖} = {‖ρ‖ < R₀}: not_le: ¬(R₀ ≤ x) ↔ x < R₀ — defeq? not_le : ¬ a ≤ b ↔ b < a ✓ defeq? `not_le` is an iff (propext'd) — the SETS are equal by defeq of the membership? {x | ¬ R₀ ≤ ‖x‖} vs {x | ‖x‖ < R₀}: membership x ∈ {x | p x} is p x; p = ¬ R₀ ≤ ‖x‖ vs q = ‖x‖ < R₀: these are defeq (lt is DEFINED as ¬ ≤ in linear orders? x < y := x ≤ y ∧ ¬ y ≤ x in Mathlib's LT for ℝ?? ℝ's <: `lt_iff_le_not_ge`... For ℝ, a < b is defined via the LinearOrder instance — InstLT; Real.lt is defined as a ≤ b ∧ ¬ b ≤ a?? Actually Real's LT is defined directly (Real.lt := ...). Hmm risky. Use Set.Finite.subset with intro: `apply this.subset; intro ρ hρ; exact not_le.mp hρ` — subset direction: {¬ R₀ ≤ ‖ρ‖} ⊆ {‖ρ‖ < R₀}: not_le.mp ✓. ... ``` Cleaner: just call finite_subtype_norm_lt R₀ and subset via not_le. Then hE (D − base summable via finite support), hD, then Summable.of_norm_bounded hD with: ```lean refine Summable.of_norm_bounded D hD (fun ρ => ?_) by_cases hρ : R₀ ≤ ‖(ρ : ℂ)‖ · simp only [D, if_pos hρ] have h2 : (2:ℝ) ≤ ‖(ρ:ℂ)‖ := hR₀2.trans hρ have hs2 : 2 * ‖s‖ ≤ ‖(ρ:ℂ)‖ := hR₀s.trans hρ have h := seriesTerm_norm_le ρ h2 hs2 apply h.trans -- (17/6)‖s‖·mult/(1+γ²) ≤ C·mult/(1+γ²): C = (17/6)(‖s‖+1) rw [hC] -- hmm hC : C = ... set already replaces. With `set`, C is substituted everywhere; use `show`. The dominator in D if_pos branch is C * (mult/(1+γ²)). Goal: 17/6*‖s‖*(mult/(1+γ²)) ≤ C*(mult/(1+γ²)). -- Both as single divisions? D branch: C * (mult/(1+γ²)). seriesTerm_norm_le RHS: 17/6*‖s‖*(mult/(1+γ²)). have hg0 : (0:ℝ) ≤ (zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ))) := by positivity -- 17/6*‖s‖ ≤ 17/6*(‖s‖+1) = C have hC' : 17 / 6 * ‖s‖ ≤ C := by rw [hC]; nlinarith [norm_nonneg s] -- 17/6·‖s‖ ≤ 17/6·(‖s‖+1) -- a * X ≤ b * X with X ≥ 0 calc 17 / 6 * ‖s‖ * ((zeroMult ρ:ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ)))) ≤ C * ((zeroMult ρ:ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ)))) := mul_le_mul_of_nonneg_right hC' hg0 · simp only [D, if_neg hρ, le_refl] ``` Careful with `set` and D's definition matching liSummable: in liSummable they used `set D ... with hDdef` and then `simp only [D, if_pos hρ]` — the set replaces occurrences; the D if-branch has C * (...) — but in liSummable they wrote the explicit constant (9/2)*(n:ℝ)^2 not a variable. With C a set-variable: hbase : Summable fun ρ => C * (...) ✓; hE : Summable fun ρ => D ρ − C*(...) via summable_of_hasFiniteSupport with support ⊆ {¬ R₀ ≤ ‖ρ‖}: for ρ ∉ support... the proof: ```lean have hE : Summable (fun ρ : {ρ // IsNontrivialZero ρ} => D ρ - C * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ))))) := by apply summable_of_hasFiniteSupport apply hfin.subset intro ρ hρ simp only [Function.mem_support, ne_eq] at hρ by_contra hball apply hρ have hball' : R₀ ≤ ‖(ρ : ℂ)‖ := not_not.mp hball simp only [D, if_pos hball'] ring ``` ✓ (mirrors liSummable lines 322–333). hD: ```lean have hD : Summable D := by have hsum := hbase.add hE have heq : (fun ρ : {ρ // IsNontrivialZero ρ} => C * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ)))) + (D ρ - C * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ)))))) = D := by funext ρ ring rw [heq] at hsum exact hsum ``` ✓ mirrors. Hmm wait — in liSummable, `Summable.of_norm_bounded hD (fun ρ => ?_)` — signature: `Summable.of_norm_bounded (hg : Summable g) (h : ∀ i, ‖f i‖ ≤ g i) : Summable f`? Let me double check argument order: liSummable line 344: `refine Summable.of_norm_bounded hD (fun ρ => ?_)` — goal after refine: ∀ ρ... they did `fun ρ => ?_` so signature (f := _) (g := D) (hg : Summable D) (hfg : ∀ i, ‖f i‖ ≤ D i)? Wait: `Summable.of_norm_bounded {f g : ι → α} (hg : Summable g) (hfg : ∀ i, ‖f i‖ ≤ g i) : Summable f`? Hmm but then `refine Summable.of_norm_bounded hD (fun ρ => ?_)` leaves goal `‖seriesTerm s ρ‖ ≤ D ρ` ✓ matches. But there might be a Real requirement: g : ι → ℝ — `Summable.of_norm_bounded` for real g: yes `Summable.of_norm_bounded (hg : Summable g) (h : ∀ i, ‖f i‖ ≤ g i)` requires g real-valued I think (or NormedField). D is ℝ-valued ✓. Also check: in liSummable the goal was Summable (liSummand n) — the def; here Summable (fun ρ => seriesTerm s ρ) — I'll state seriesSummable as Summable (seriesTerm s)?? seriesTerm s : subtype → ℂ ✓ can state `Summable (seriesTerm s)`. Hmm but with `refine Summable.of_norm_bounded hD ...` the f is inferred from goal ✓. §4: ```lean /-! ## 3. Balls avoiding the nontrivial zeros -/ /-- Around any point that is not a nontrivial zero there is a ball containing no nontrivial zero: continuity where ζ s₀ ≠ 0; the order normal form where ζ s₀ = 0, s₀ ≠ 1; the zetaA factorization at s₀ = 1. -/ lemma exists_ball_avoid_nontrivialZeros (s₀ : ℂ) (hs₀ : ¬ IsNontrivialZero s₀) : ∃ δ : ℝ, 0 < δ ∧ ∀ ρ : {ρ : ℂ // IsNontrivialZero ρ}, (ρ : ℂ) ∉ Metric.ball s₀ δ := by by_cases h1 : s₀ = 1 · subst h1 obtain ⟨ε, hε, hball⟩ := Metric.eventually_nhds_iff_ball.mp zetaA_ne_zero_near_one refine ⟨ε, hε, fun ρ hρ => ?_⟩ -- ρ nontrivial zero in ball(1, ε): ρ ≠ 1 (re < 1), zetaA ρ = (ρ−1)ζ ρ = 0 contra hball have hρ1 : (ρ : ℂ) ≠ 1 := by intro h have : (ρ : ℂ).re < 1 := ρ.2.2.2 rw [h] at this simp at this -- this : (1:ℂ).re < 1 → re 1 = 1: 1 < 1 false: `rw [Complex.one_re] at this; exact lt_irrefl _ this`? simp should close: Complex.one_re is simp. Use: rw [h, Complex.one_re] at this; exact lt_irrefl 1 this. have hz := hball (ρ : ℂ) hρ rw [zetaA_apply hρ1] at hz -- zetaA ρ = (ρ−1)·ζ ρ rw [ρ.2.1, mul_zero] at hz -- ζ ρ = 0: ρ.2.1 : riemannZeta ↑ρ = 0 ✓ exact hz rfl · by_cases h0 : riemannZeta s₀ = 0 · -- NF obtain ⟨h, hh, hh0, hfh⟩ := (analyticAt_riemannZeta h1).analyticOrderAt_ne_top.mp (zeta_order_ne_top_of_ne h1) obtain ⟨ε₁, hε₁, hball₁⟩ := Metric.eventually_nhds_iff_ball.mp (hh.continuousAt.eventually_ne hh0) obtain ⟨ε₂, hε₂, hball₂⟩ := Metric.eventually_nhds_iff_ball.mp hfh refine ⟨min ε₁ ε₂, lt_min hε₁ hε₂, fun ρ hρ => ?_⟩ -- ρ ∈ ball s₀ (min ε₁ ε₂): ζ ρ = (ρ−s₀)^m • h ρ have hmem1 : (ρ : ℂ) ∈ Metric.ball s₀ ε₁ := Metric.ball_subset_ball (min_le_left _ _) hρ have hmem2 : (ρ : ℂ) ∈ Metric.ball s₀ ε₂ := Metric.ball_subset_ball (min_le_right _ _) hρ have heq := hball₂ (ρ : ℂ) hmem2 -- ζ ρ = (ρ − s₀)^m • h ρ have hne : h (ρ : ℂ) ≠ 0 := hball₁ (ρ : ℂ) hmem1 have hpow : ((ρ : ℂ) - s₀) ^ analyticOrderNatAt riemannZeta s₀ ≠ 0 ∨ ... -- need: either ρ = s₀ (then contra hs₀) or pow ≠ 0 by_cases hρs : (ρ : ℂ) = s₀ · rw [hρs] at hs₀? no: ρ nontrivial, ρ = s₀ ⟹ IsNontrivialZero s₀: exact hs₀ (hρs ▸ ρ.2) · have hpow : ((ρ : ℂ) - s₀) ^ analyticOrderNatAt riemannZeta s₀ ≠ 0 := pow_ne_zero _ (sub_ne_zero.mpr hρs) have hz : riemannZeta (ρ : ℂ) ≠ 0 := by rw [heq, smul_eq_mul] -- (pow • h ρ): smul_eq_mul exact mul_ne_zero hpow hne exact hz ρ.2.1 · -- continuity obtain ⟨ε, hε, hball⟩ := Metric.eventually_nhds_iff_ball.mp ((analyticAt_riemannZeta h1).continuousAt.eventually_ne h0) refine ⟨ε, hε, fun ρ hρ => ?_⟩ exact hball (ρ : ℂ) hρ ρ.2.1 ``` Check details: - `zetaA_ne_zero_near_one : ∀ᶠ w in 𝓝 (1:ℂ), zetaA w ≠ 0` ✓ (LiResidue line 81). - After subst h1, s₀ replaced by 1 ✓. - ρ.2.2.2 : (ρ:ℂ).re < 1: ρ.2 : ζ ρ = 0 ∧ 0 < re ∧ re < 1: ρ.2.2.2... ρ.2.2 : 0 < re ∧ re < 1? Hmm: And association: a ∧ b ∧ c = a ∧ (b ∧ c): ρ.2.1 : a = ζ ρ = 0; ρ.2.2 : b ∧ c; ρ.2.2.1?? Accessing nested: ρ.2.2.1 = (b ∧ c).1 = b? Wait — .2.2 is (ρ.2).2 : b ∧ c. Then .2.2.1 : b, .2.2.2 : c. Hmm but earlier in liSummand_norm_le: hz.2.1.le : 0 ≤ re where hz = ρ.2 : hz.2 : b ∧ c... hz.2.1 : (b ∧ c).1 = b = 0 < re ✓ .le : 0 ≤ ✓. And hz.2.2.le : re ≤ 1: hz.2.2 : c = re < 1 ✓. So: ρ.2.1 : ζ ρ = 0; ρ.2.2.1 : 0 < re; ρ.2.2.2 : re < 1. In my draft above I wrote `ρ.2.2.2` for re < 1 ✓ and `ρ.2.1` for ζ ρ = 0 ✓. But careful — earlier in finite_subtype_norm_lt I wrote `hz.2.1` for the riemannZetaZeros membership where hz : z ∈ closedBall ∧ IsNontrivialZero z: hz.2 : IsNontrivialZero z; hz.2.1 : ζ z = 0 ✓ consistent. - For `rw [h] at this` where this : (ρ:ℂ).re < 1 and h : (ρ:ℂ) = 1: gives (1:ℂ).re < 1; then `simp at this`: Complex.one_re : (1:ℂ).re = 1 — simp reduces to 1 < 1 = False, closes goal? `simp at this` with this : 1 < 1 → this becomes False → closes any goal ✓ (simp at this with False closes). OK. - `Metric.ball_subset_ball : ε₁ ≤ ε₂ → ball x ε₁ ⊆ ball x ε₂` ✓ exists. Membership: hρ : (ρ:ℂ) ∈ ball s₀ (min ε₁ ε₂); ball_subset_ball (min_le_left ε₁ ε₂) hρ — hρ needs coercion to set membership ✓ fine. - heq : riemannZeta (ρ:ℂ) = ((ρ:ℂ) − s₀) ^ analyticOrderNatAt riemannZeta s₀ • h (ρ:ℂ). hball₂ : ∀ y ∈ ball s₀ ε₂, riemannZeta y = ... ✓ (hfh is =ᶠ[𝓝 s₀]: eventually_nhds_iff_ball.mp gives ∃ ε > 0, ∀ y ∈ ball, f y = g y ✓). - smul_eq_mul ✓. - hρs ▸ ρ.2: ρ.2 : IsNontrivialZero (ρ:ℂ); hρs : (ρ:ℂ) = s₀; hρs ▸ ρ.2 : IsNontrivialZero s₀ ✓ (▸ direction: rewrites (ρ:ℂ) to s₀ in the type ✓). - continuity case: hball : ∀ y ∈ ball s₀ ε, riemannZeta y ≠ 0 ✓; exact hball (ρ:ℂ) hρ ρ.2.1 : hball ... : ζ ρ ≠ 0 applied to ρ.2.1 : ζ ρ = 0 gives False, goal is (ρ:ℂ) ∉ ball — wait! The goal is `(ρ:ℂ) ∉ Metric.ball s₀ δ` and hρ : (ρ:ℂ) ∈ ball... I wrote `fun ρ hρ => ?_` — hρ : (ρ:ℂ) ∈ Metric.ball s₀ δ ✓, goal False? No — goal after intro ρ hρ: the statement ∀ ρ, (ρ:ℂ) ∉ ball — `fun ρ hρ => ?_` with hρ : ∈ ball, then goal is False (∉ unfolds to ¬ ∈ = ∈ → False). ✓ So exact hz ρ.2.1 where hz : ζ ρ ≠ 0, ρ.2.1 : ζ ρ = 0 ⟹ False ✓. In zetaA case: exact hz rfl where hz : zetaA ρ = 0 → False... wait hz := hball ρ hρ : zetaA ρ ≠ 0; after rw [zetaA_apply hρ1, ρ.2.1, mul_zero] at hz: hz : (0:ℂ) ≠ 0; exact hz rfl ✓. Hmm — `rw [ρ.2.1, mul_zero] at hz`: hz : (ρ − 1)·ζ ρ ≠ 0 — rw ρ.2.1 : ζ ρ = 0 at hz: hz : (ρ−1)*0 ≠ 0; rw [mul_zero] at hz: hz : (0:ℂ) ≠ 0 ✓. But wait — after rw [zetaA_apply hρ1] at hz, hz : (ρ−1) * riemannZeta ρ ≠ 0 ✓. Now §4 analyticity: ```lean /-! ## 4. Analyticity off the zeros -/ /-- The M-test majorant on a ball avoiding the zeros. -/ lemma seriesTerm_summable_majorant (M : ℝ) : Summable (fun ρ : {ρ : ℂ // IsNontrivialZero ρ} => 17 / 6 * M * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ))))) := (WeilEF.zero_sum_inv_sq zetaSeam).mul_left _ theorem seriesFun_analyticAt {s₀ : ℂ} (hs₀ : ¬ IsNontrivialZero s₀) : AnalyticAt ℂ seriesFun s₀ := by obtain ⟨δ, hδ, hball⟩ := exists_ball_avoid_nontrivialZeros s₀ hs₀ set M : ℝ := ‖s₀‖ + δ with hM set R₀ : ℝ := max 2 (2 * M) with hR₀ -- the dominator set u : {ρ : ℂ // IsNontrivialZero ρ} → ℝ := fun ρ => 17 / 6 * M * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ)))) with hu have hsum_u : Summable u := seriesTerm_summable_majorant M -- the eventual bound have hfu : ∀ᶠ ρ in cofinite, ∀ s ∈ Metric.ball s₀ δ, ‖seriesTerm s ρ‖ ≤ u ρ := by rw [Filter.mem_cofinite] -- hmm: ∀ᶠ in cofinite ↔ the set of good ρ is cofinite; use Filter.eventually_cofinite: (∀ᶠ x in cofinite, p x) ↔ {x | p x}ᶜ.Finite? There's `Filter.eventually_cofinite : (∀ᶠ x in cofinite, p x) ↔ {x | ¬ p x}.Finite`. Use that. ... ``` `Filter.eventually_cofinite : (∀ᶠ x ∈ cofinite? ...)`: statement `Filter.eventually_cofinite {p : α → Prop} : (∀ᶠ x in cofinite, p x) ↔ {x | ¬p x}.Finite` — exists? I believe yes. Then show {ρ | ¬ ∀ s ∈ ball, ...}.Finite ⊆ {ρ | ‖ρ‖ < R₀} finite: if ‖ρ‖ ≥ R₀ then the bound holds: need ¬(∀...) ⟹ ‖ρ‖ < R₀ — i.e. prove {ρ | ¬P ρ} ⊆ {ρ | ‖ρ‖ < R₀} then .subset. For ρ with R₀ ≤ ‖ρ‖, prove P ρ: ∀ s ∈ ball, ‖seriesTerm s ρ‖ ≤ u ρ: - h2 : 2 ≤ ‖ρ‖ (max_left trans) - s ∈ ball s₀ δ: ‖s‖ ≤ ‖s₀‖ + δ = M: ‖s‖ = ‖(s − s₀) + s₀‖ ≤ ‖s−s₀‖ + ‖s₀‖ < δ + ‖s₀‖: from mem_ball: dist s s₀ < δ: dist_eq_norm: ‖s − s₀‖ < δ ✓; so ‖s‖ < M hence ≤. - 2‖s‖ ≤ 2M ≤ R₀ ≤ ‖ρ‖ ✓ (max_right). - seriesTerm_norm_le ρ h2 hs2 : ‖term‖ ≤ 17/6·‖s‖·mult/(1+γ²). - ≤ 17/6·M·mult/(1+γ²) = u ρ: since ‖s‖ ≤ M and the other factor ≥ 0: 17/6*‖s‖*(mult/(1+γ²)) ≤ 17/6*M*(mult/(1+γ²)): mul_le_mul_of_nonneg_right (by nlinarith/linarith: 17/6·‖s‖ ≤ 17/6·M) (positivity) ✓. - Then: ```lean have hu' : HasSumUniformlyOn (fun ρ => fun s : ℂ => seriesTerm s ρ) (fun s => ∑' ρ, seriesTerm s ρ) (Metric.ball s₀ δ) := HasSumUniformlyOn.of_norm_le_summable_eventually hsum_u hfu have htend : TendstoLocallyUniformlyOn (fun t : Finset {ρ : ℂ // IsNontrivialZero ρ} => fun s => ∑ ρ ∈ t, seriesTerm s ρ) (fun s => ∑' ρ, seriesTerm s ρ) atTop (Metric.ball s₀ δ) := TendstoUniformlyOn.tendstoLocallyUniformlyOn (hasSumUniformlyOn_iff_tendstoUniformlyOn.mp hu') have hdiff : DifferentiableOn ℂ (fun s => ∑' ρ, seriesTerm s ρ) (Metric.ball s₀ δ) := by apply htend.differentiableOn _ isOpen_ball apply Filter.Eventually.of_forall intro t s hs rw [show (fun s => ∑ ρ ∈ t, seriesTerm s ρ) = ∑ ρ ∈ t, (fun s => seriesTerm s ρ) from by funext s; simp [Finset.sum_apply]] apply DifferentiableAt.differentiableWithinAt apply DifferentiableAt.sum intro ρ hρ -- each term differentiable at s: s ≠ ρ (ball avoids zeros), ρ ≠ 0 have hsρ : s - (ρ : ℂ) ≠ 0 := by have hρout : (ρ : ℂ) ∉ Metric.ball s₀ δ := hball ρ intro h apply hρout -- s − ρ = 0 ⟹ ρ = s ∈ ball have : (ρ : ℂ) = s := sub_eq_zero.mp h -- h : s − ρ = 0 ⟹ s = ρ: sub_eq_zero : s − ρ = 0 ↔ s = ρ: gives s = ρ: then ρ = s via .symm rw [← this] -- hmm: want ρ ∈ ball: rw this: ρ ↦ s: goal s ∈ ball: exact hs exact hs -- wait membership: hs : s ∈ ball s₀ δ from DifferentiableOn intro have hρ0 : (ρ : ℂ) ≠ 0 := by intro h have := ρ.2.2.1 -- 0 < (ρ:ℂ).re rw [h] at this simp at this -- (0:ℂ).re < ... : 0 < 0 false have h1 : DifferentiableAt ℂ (fun s : ℂ => 1 / (s - (ρ : ℂ))) s := (differentiableAt_const (1 : ℂ)).div (differentiableAt_id.sub (differentiableAt_const _)) hsρ have h2 : DifferentiableAt ℂ (fun s : ℂ => 1 / (ρ : ℂ)) s := differentiableAt_const _ show DifferentiableAt ℂ (fun s => (zeroMult ρ : ℂ) * (1 / (s - (ρ : ℂ)) + 1 / (ρ : ℂ))) s exact (h1.add h2).const_mul _ ``` Hmm — the goal after `apply DifferentiableAt.sum; intro ρ hρ` is `DifferentiableAt ℂ (fun s => seriesTerm s ρ) s`? Actually DifferentiableAt.sum signature: `DifferentiableAt.sum (h : ∀ i ∈ t, DifferentiableAt ℂ (f i) x) : DifferentiableAt ℂ (∑ i ∈ t, f i) x`? In LiDigamma: `apply DifferentiableAt.sum; intro m hm; ...exact h1.sub h2` where the goal was DifferentiableAt ℂ (fun s => dpsiTermC s m) s and they proved it via pieces with `show` implicit. dpsiTermC was a def — the goal displayed as the def but reducible. For me: goal DifferentiableAt ℂ (fun s => seriesTerm s ρ) s; seriesTerm is a def — `(h1.add h2).const_mul _` has type DifferentiableAt ℂ (fun s => mult * (1/(s−ρ) + 1/ρ))?? `.const_mul : DifferentiableAt ℂ f x → DifferentiableAt ℂ (fun y => c * f y) x` gives fun s => c * (1/(s−ρ)+1/ρ) — with c = (zeroMult ρ : ℂ): matches seriesTerm s ρ up to def-unfolding: need `show DifferentiableAt ℂ (fun s => (zeroMult ρ : ℂ) * (1 / (s - (ρ:ℂ)) + 1 / (ρ:ℂ))) s` first (defeq unfold) ✓. Also `intro t s hs` — the Eventually goal: ∀ᶠ t in atTop, DifferentiableOn ℂ (fun s => ∑ ρ∈t, seriesTerm s ρ) (ball): `Filter.Eventually.of_forall; intro t` then goal DifferentiableOn ...; DifferentiableOn is ∀ s ∈ ball, DifferentiableWithinAt: `intro s hs` ✓ (LiDigamma did `intro t s hs` after of_forall ✓). - Then: ```lean have han : AnalyticOnNhd ℂ (fun s => ∑' ρ, seriesTerm s ρ) (Metric.ball s₀ δ) := hdiff.analyticOnNhd isOpen_ball -- AnalyticAt at s₀: han s₀ (mem_ball_self hδ) : AnalyticAt ℂ (fun s => ∑' ...) s₀ -- and seriesFun = fun s => ∑' ρ, seriesTerm s ρ by rfl exact han s₀ (Metric.mem_ball_self hδ) ``` Wait — AnalyticOnNhd ℂ f s = ∀ x ∈ s, AnalyticAt ℂ f x: `han s₀ (mem)` : AnalyticAt ℂ (fun s => ∑' ρ, seriesTerm s ρ) s₀. Goal: AnalyticAt ℂ seriesFun s₀. seriesFun s₀ := ∑' ρ, seriesTerm s₀ ρ — but AnalyticAt ℂ f x with f = the lambda vs f = seriesFun: these are different functions (seriesFun is a def whose unfolding gives the lambda). AnalyticAt ℂ seriesFun s₀ — the lambda `fun s => ∑' ρ, seriesTerm s ρ` is DEFEQ to seriesFun (funext-free: seriesFun unfolds to fun s => ∑' ρ, seriesTerm s ρ ✓ definitionally). So `exact han s₀ hmem` should typecheck by defeq ✓ (like DinfC in LiDigamma — they did need a funext rw for the Pi.add form, but plain def unfolding is defeq). ```lean /-- The series is analytic on the complement of the nontrivial zeros. -/ theorem seriesFun_analyticOnNhd : AnalyticOnNhd ℂ seriesFun {s : ℂ | ¬ IsNontrivialZero s} := fun s₀ hs₀ => seriesFun_analyticAt hs₀ ``` §5: ```lean /-! ## 5. Isolation and the reduced series -/ /-- Each nontrivial zero is isolated from the others (finiteness in compact balls + minimum distance). -/ theorem nontrivialZero_isolated (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) : ∃ δ : ℝ, 0 < δ ∧ ∀ ρ₁ : {ρ : ℂ // IsNontrivialZero ρ}, ρ₁ ≠ ρ₀ → δ ≤ ‖(ρ₁ : ℂ) - (ρ₀ : ℂ)‖ := by -- the nontrivial zeros in closedBall ρ₀ 1 form a finite set have hcomp : IsCompact (Metric.closedBall (ρ₀ : ℂ) 1) := isCompact_closedBall _ _ have hzeros : (Metric.closedBall (ρ₀ : ℂ) 1) ∩ {ρ : ℂ | IsNontrivialZero ρ} ⊆ (Metric.closedBall (ρ₀ : ℂ) 1) ∩ riemannZetaZeros := by intro z hz exact ⟨hz.1, hz.2.1⟩ have hfin : ((Metric.closedBall (ρ₀ : ℂ) 1) ∩ {ρ : ℂ | IsNontrivialZero ρ}).Finite := (hcomp.inter_riemannZetaZeros_finite).subset hzeros -- as a finset of subtype elements (excluding ρ₀) set S : Set {ρ : ℂ // IsNontrivialZero ρ} := {ρ | (ρ : ℂ) ∈ Metric.closedBall (ρ₀ : ℂ) 1 ∧ ρ ≠ ρ₀} with hS have hSfin : S.Finite := by have himg : (Subtype.val '' S).Finite := by apply hfin.subset rintro z ⟨ρ, ⟨hρ, -⟩, rfl⟩ exact ⟨hρ, ρ.2⟩ exact Set.Finite.of_finite_image himg (Subtype.val_injective.injOn) by_cases hne : S.Nonempty · -- δ = (min distance)/2 set d : Finset ℝ := hSfin.toFinset.image (fun ρ => ‖(ρ : ℂ) - (ρ₀ : ℂ)‖) with hd have hdne : d.Nonempty := by obtain ⟨ρ, hρ⟩ := hne refine ⟨‖(ρ : ℂ) - (ρ₀ : ℂ)‖, ?_⟩ simp only [hd, Finset.mem_image, Set.Finite.mem_toFinset] exact ⟨ρ, hρ, rfl⟩ have hdpos : ∀ x ∈ d, 0 < x := by intro x hx simp only [hd, Finset.mem_image, Set.Finite.mem_toFinset] at hx obtain ⟨ρ, hρ, rfl⟩ := hx have h1 : (ρ : ℂ) ≠ (ρ₀ : ℂ) := fun h => hρ.2 (Subtype.ext h) exact norm_pos_iff.mpr (sub_ne_zero.mpr h1) refine ⟨d.min' hdne / 2, by positivity?, fun ρ₁ hρ₁ => ?_⟩ · positivity needs d.min' hdne > 0: hdpos _ (d.min'_mem hdne): have := hdpos _ (d.min'_mem hdne); positivity? no — positivity can't use hypotheses. `exact half_pos (hdpos _ (Finset.min'_mem _ _))`... half_pos : 0 < a/2? `half_pos (h : 0 < a) : 0 < a / 2` ✓. · by_cases hmem : (ρ₁ : ℂ) ∈ Metric.closedBall (ρ₀ : ℂ) 1 · -- ρ₁ ∈ S ⟹ its distance ∈ d ≥ min' have h1 : ρ₁ ∈ S := ⟨hmem, hρ₁⟩ have h2 : ‖(ρ₁ : ℂ) - (ρ₀ : ℂ)‖ ∈ d := by simp only [hd, Finset.mem_image, Set.Finite.mem_toFinset] exact ⟨ρ₁, h1, rfl⟩ have h3 : d.min' hdne ≤ ‖(ρ₁ : ℂ) - (ρ₀ : ℂ)‖ := Finset.min'_le _ _ h2 linarith [hdpos _ (Finset.min'_mem _ _)] · -- outside the ball: dist ≥ 1 ≥ min'/2 (min' ≤ 1 since distances in the ball ≤ 1) have h4 : 1 ≤ ‖(ρ₁ : ℂ) - (ρ₀ : ℂ)‖ := by have : (1 : ℝ) ≤ dist (ρ₁ : ℂ) (ρ₀ : ℂ) := by by_contra h apply hmem rw [Metric.mem_closedBall] exact le_of_lt (not_le.mp h) rwa [dist_eq_norm] at this -- min' ≤ 1: min' ∈ d comes from a ball element: any element of d is ≤ 1 have h5 : d.min' hdne ≤ 1 := by have hm := Finset.min'_mem d hdne simp only [hd, Finset.mem_image, Set.Finite.mem_toFinset] at hm obtain ⟨ρ, hρ, rfl⟩ := hm rw [Metric.mem_closedBall, dist_eq_norm] at hρ -- hρ.1 : dist ≤ 1 -- hρ : (ρ:ℂ) ∈ closedBall ∧ ρ ≠ ρ₀; hρ.1 : dist (ρ:ℂ) ρ₀ ≤ 1: dist_eq_norm: ‖ρ − ρ₀‖ ≤ 1 ✓ exact hρ.1 linarith · refine ⟨1 / 2, by norm_num, fun ρ₁ hρ₁ => ?_⟩ by_contra h push_neg at h -- h : ‖ρ₁ − ρ₀‖ < 1/2 apply hne -- S nonempty: ρ₁ ∈ S -- ρ₁ ∈ S: dist < 1/2 < 1 ⟹ in closedBall; ≠ ρ₀ ✓ exact ⟨ρ₁, ⟨by rw [Metric.mem_closedBall, dist_eq_norm]; linarith, hρ₁⟩⟩... -- hne : ¬ S.Nonempty: apply hne: goal S.Nonempty: exact ⟨ρ₁, hSmem⟩: Set.Nonempty def: ∃ x, x ∈ S: ⟨ρ₁, ...⟩: S membership is the pair ✓ ``` Careful: `by_contra h` on goal `1/2 ≤ ‖ρ₁ − ρ₀‖`: push_neg gives ‖…‖ < 1/2 ✓. Then S.Nonempty ⟨ρ₁, hmem_pair⟩ where hmem_pair : (ρ₁:ℂ) ∈ closedBall ∧ ρ₁ ≠ ρ₀ ✓; hne : ¬S.Nonempty — apply hne then exact the Nonempty... `exact hne ⟨ρ₁, ...⟩` ✓. Hmm — `Set.Finite.mem_toFinset` needs the set to match hSfin.toFinset: membership ρ ∈ hSfin.toFinset ↔ ρ ∈ S ✓ via Set.Finite.mem_toFinset (hSfin : S.Finite) — as a simp lemma it fires as written? `Set.Finite.mem_toFinset (hs : s.Finite) : x ∈ hs.toFinset ↔ x ∈ s` — in simp only I should write `Set.Finite.mem_toFinset` and it rewrites `x ∈ hSfin.toFinset` to `x ∈ S` — but d was defined with hSfin.toFinset ✓. One concern: `simp only [hd, Finset.mem_image, Set.Finite.mem_toFinset]` — hd is a `set` equation: simp only [hd]?? With `set ... with hd`, hd : d = hSfin.toFinset.image ... — simp only [hd] rewrites d → the image ✓ then mem_image ✓ then mem_toFinset ✓. Wait actually with `set`, occurrences of the image-finset get replaced by d in the goal — the goal has d; simp [hd] rewrites d back. But `set` also abstracts... fine, this pattern works (banked in previous files presumably). Alternative simpler for h2/hmem: `Finset.mem_image.mpr ⟨ρ₁, by rwa [Set.Finite.mem_toFinset], rfl⟩`. I'll use explicit .mpr forms to be safe. - reduced series: ```lean /-- The reduced summand: the ρ₀-term zeroed out. -/ def seriesTermSub (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) (ρ : {ρ : ℂ // IsNontrivialZero ρ}) : ℂ := if ρ = ρ₀ then 0 else seriesTerm s ρ /-- The reduced series (the ρ₀ polar term removed): analytic AT ρ₀. -/ def seriesFunSub (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) : ℂ := ∑' ρ : {ρ : ℂ // IsNontrivialZero ρ}, seriesTermSub ρ₀ s ρ lemma seriesTermSub_norm_le (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) (ρ : {ρ : ℂ // IsNontrivialZero ρ}) : ‖seriesTermSub ρ₀ s ρ‖ ≤ ‖seriesTerm s ρ‖ := by by_cases h : ρ = ρ₀ <;> simp [seriesTermSub, h] theorem seriesTermSub_summable (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) : Summable (seriesTermSub ρ₀ s) := Summable.of_norm_bounded (seriesSummable s) (fun ρ => seriesTermSub_norm_le ρ₀ s ρ) ``` Wait — Summable.of_norm_bounded with g = seriesTerm s (ℂ-valued) — fine (norm_bounded works for any normed g? signature: (hg : Summable g) (h : ∀ i, ‖f i‖ ≤ g i) — hmm if g is ℂ-valued then g i : ℂ but ‖f i‖ : ℝ ≤ g i : ℂ — type error! of_norm_bounded requires g : ι → ℝ. seriesTerm s is ℂ-valued! So this fails. Options: g := fun ρ => ‖seriesTerm s ρ‖: Summable (fun ρ => ‖seriesTerm s ρ‖) — from seriesSummable: `Summable.norm`? `Summable.norm (hf : Summable f) : Summable (fun i => ‖f i‖)` ✓ exists. So: ```lean Summable.of_norm_bounded (seriesSummable s).norm (fun ρ => seriesTermSub_norm_le ρ₀ s ρ) ``` ✓. Then the pointwise split: ```lean lemma seriesTerm_add_single (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) : (fun ρ => seriesTerm s ρ) = (fun ρ => seriesTermSub ρ₀ s ρ) + (fun ρ => if ρ = ρ₀ then seriesTerm s ρ else 0) := by funext ρ by_cases h : ρ = ρ₀ <;> simp [seriesTermSub, h] lemma single_summable (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) : Summable (fun ρ => if ρ = ρ₀ then seriesTerm s ρ else (0 : ℂ)) := by apply summable_of_hasFiniteSupport apply (Set.finite_singleton ρ₀).subset intro ρ hρ simp only [Function.mem_support, ne_eq] at hρ by_contra h apply hρ simp [h] -- ρ = ρ₀? h : ¬ ρ = ρ₀... wait: support membership: f ρ ≠ 0; want ρ ∈ {ρ₀}: by_contra h : ρ ∉ {ρ₀} i.e. ρ ≠ ρ₀ (Set.mem_singleton_iff): then if_neg: f ρ = 0 contra. ``` Hmm: goal after intro ρ hρ: ρ ∈ {ρ₀} (singleton set membership = ρ = ρ₀?). {ρ₀} as Set of the subtype: membership ρ ∈ ({ρ₀} : Set _) ↔ ρ = ρ₀ via Set.mem_singleton_iff — is it defeq? Set.singleton membership: ρ ∈ {ρ₀} is ρ = ρ₀ definitionally? `{a} : Set α := insert a ∅`; membership: insert def: x ∈ insert a s ↔ x = a ∨ x ∈ s... not defeq to equality cleanly. Use: `by_contra h; rw [Set.mem_singleton_iff] at h`? Wait direction: goal ρ ∈ {ρ₀}; by_contra h : ¬ ρ ∈ {ρ₀}; then f ρ = 0: if_neg (fun heq => h (Set.mem_singleton_iff.mpr heq))... let me write: ```lean apply summable_of_hasFiniteSupport ((Set.finite_singleton ρ₀).subset ?_) intro ρ hρ by_contra h rw [Function.mem_support, ne_eq] at hρ apply hρ rw [if_neg (fun he => h (Set.mem_singleton_iff.mpr he))] ``` Hmm — cleaner pattern from liSummable's hE: they did ```lean apply summable_of_hasFiniteSupport apply hfin.subset intro ρ hρ simp only [Function.mem_support, ne_eq] at hρ by_contra hball apply hρ ... ``` where the subset goal was support ⊆ finite-set. So here: subset target: Function.support f ⊆ {ρ₀}: intro ρ hρ (hρ : ρ ∈ support f: f ρ ≠ 0); goal ρ ∈ {ρ₀}: by_contra h; apply hρ; show f ρ = 0: if_neg: needs ρ ≠ ρ₀: from h : ¬ ρ ∈ {ρ₀}: Set.mem_singleton_iff.not...: `fun he => h (Set.mem_singleton_iff.mpr he)` : ρ ≠ ρ₀... wait he : ρ = ρ₀; Set.mem_singleton_iff.mpr he : ρ ∈ {ρ₀} ✓ contra h ✓. Then `simp only [if_neg that]` closes f ρ = 0. ✓. ```lean /-- Pointwise split: seriesFun = seriesFunSub + the ρ₀-term (everywhere). -/ lemma seriesFun_eq_sub_add (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) : seriesFun s = seriesFunSub ρ₀ s + seriesTerm s ρ₀ := by have h1 : seriesFun s = ∑' ρ, (seriesTermSub ρ₀ s ρ + (if ρ = ρ₀ then seriesTerm s ρ else 0)) := by rw [seriesFun] -- unfold; then congr via funext congr 1 -- ∑' congr: tsum_congr? funext: use `tsum_congr (f g) (h : ∀ x, f x = g x)`? Hmm — ∑' over dependent: `tsum_congr : (∀ b, f b = g b) → ∑' f = ∑' g` ✓ exists. But seriesFun s := ∑' ρ, seriesTerm s ρ — unfold seriesFun first: `show ∑' ρ, seriesTerm s ρ = _`: then tsum_congr with the pointwise: by_cases simp. ... ``` Let me write: ```lean show ∑' ρ, seriesTerm s ρ = _ rw [show seriesFunSub ρ₀ s = ∑' ρ, seriesTermSub ρ₀ s ρ from rfl] rw [← Summable.tsum_add (seriesTermSub_summable ρ₀ s) (single_summable ρ₀ s)] -- goal: ∑' ρ, seriesTerm s ρ = ∑' ρ, (seriesTermSub ρ₀ s ρ + if ...) apply tsum_congr intro ρ by_cases h : ρ = ρ₀ <;> simp [seriesTermSub, h] -- single tsum = seriesTerm s ρ₀: tsum_eq_single rw [tsum_eq_single ρ₀ (fun ρ hρ => if_neg hρ)] -- hmm: the if: if ρ = ρ₀ then seriesTerm s ρ else 0: for ρ ≠ ρ₀: if_neg hρ : the if = 0 ✓; tsum_eq_single : ∑' b, f b = f a given ∀ b ≠ a, f b = 0. Then f ρ₀ = if ρ₀ = ρ₀ then ... else 0 = if_pos rfl: seriesTerm s ρ₀ ✓ simp. ``` Ordering: goal after rw [← Summable.tsum_add]: ∑' seriesTerm s = ∑' ρ, (sub ρ + single ρ)? Careful: `Summable.tsum_add (hf : Summable f) (hg : Summable g) : ∑' x, (f x + g x) = ∑' f + ∑' g`? Actually the name: `Summable.tsum_add : ∑' x, (f x + g x) = ...`. Hmm — in recent Mathlib: `Summable.tsum_add (hf : Summable f) (hg : Summable g) : ∑' x, (f x + g x) = ∑' x, f x + ∑' x, g x`. So ← direction rewrites `∑' sub + ∑' single` to `∑' (sub + single)`. My goal chain: goal: seriesFun s = seriesFunSub ρ₀ s + seriesTerm s ρ₀ ⟹ show: ∑' term = ∑' sub + seriesTerm s ρ₀ (unfold seriesFun, seriesFunSub — `show` with both unfolded; seriesFunSub ρ₀ s unfolds to ∑' sub ✓ defeq so `show` accepts) ⟹ rw [tsum_eq_single ρ₀ h]: rewrites `∑' ρ, if ρ = ρ₀ then seriesTerm s ρ else 0` — but the goal has `seriesTerm s ρ₀` not the single-tsum. Go the other way: first convert: have hsingle : ∑' ρ, (if ρ = ρ₀ then seriesTerm s ρ else 0) = seriesTerm s ρ₀ := tsum_eq_single...: ```lean have hsingle : ∑' ρ : {ρ : ℂ // IsNontrivialZero ρ}, (if ρ = ρ₀ then seriesTerm s ρ else (0:ℂ)) = seriesTerm s ρ₀ := by apply tsum_eq_single intro ρ hρ exact if_neg hρ -- after apply tsum_eq_single: remaining goal ∀ b ≠ ρ₀, f b = 0: intro; exact if_neg hρ — wait if_neg : ¬a → (if a then b else c) = c: hρ : ρ ≠ ρ₀ but the condition is ρ = ρ₀: if_neg hρ : (if ρ = ρ₀ then seriesTerm s ρ else 0) = 0 ✓. But tsum_eq_single's f a: after the ∀-goal, remaining: f ρ₀ = seriesTerm s ρ₀?? No: tsum_eq_single ρ₀ h : ∑' f = f ρ₀; the apply unifies ∑' f with the LHS and f ρ₀ with RHS = seriesTerm s ρ₀: f ρ₀ = if ρ₀ = ρ₀ then ... : needs if_pos rfl reduction — apply unification up to defeq should handle (if_pos rfl is defeq ✓)... risky; safer: rw [tsum_eq_single ρ₀ (fun ρ hρ => if_neg hρ)] exact if_pos rfl ``` i.e. prove via rw + exact. Fine. Then: ```lean calc seriesFun s = ∑' ρ, seriesTerm s ρ := rfl _ = ∑' ρ, (seriesTermSub ρ₀ s ρ + (if ρ = ρ₀ then seriesTerm s ρ else 0)) := by apply tsum_congr intro ρ by_cases h : ρ = ρ₀ <;> simp [seriesTermSub, h] _ = ∑' ρ, seriesTermSub ρ₀ s ρ + ∑' ρ, (if ρ = ρ₀ then seriesTerm s ρ else 0) := Summable.tsum_add (seriesTermSub_summable ρ₀ s) (single_summable ρ₀ s) _ = seriesFunSub ρ₀ s + seriesTerm s ρ₀ := by rw [hsingle]; rfl ``` `tsum_congr`: signature `tsum_congr (h : ∀ b, f b = g b) : ∑' f = ∑' g`? It's `theorem tsum_congr (h : ∀ b, f b = g b) : ∑' b, f b = ∑' b, g b` ✓. The by_cases branches: h : ρ = ρ₀: goal seriesTerm s ρ = seriesTermSub ρ₀ s ρ + (if ρ = ρ₀ then seriesTerm s ρ else 0): simp [seriesTermSub, h]: seriesTermSub → if ρ = ρ₀ then 0 else ... with h: simp [h] reduces both ifs: LHS... the goal becomes seriesTerm s ρ = 0 + seriesTerm s ρ?? simp [h]: `if_pos h`... h : ρ = ρ₀: simp [seriesTermSub, h] rewrites if ρ = ρ₀ via h (simp uses h to decide) ⟹ RHS = 0 + seriesTerm s ρ = seriesTerm s ρ ✓ closes by rfl via simp. Neg branch: h : ¬ρ = ρ₀: RHS = seriesTerm s ρ + 0 ✓. The last `_ = seriesFunSub ρ₀ s + seriesTerm s ρ₀`: first summand: ∑' ρ, seriesTermSub ρ₀ s ρ = seriesFunSub ρ₀ s — rfl defeq: `by rw [hsingle]` then goal ∑' sub + seriesTerm s ρ₀ = seriesFunSub ρ₀ s + seriesTerm s ρ₀ — the subs are defeq but not syntactically: rfl closes ✓ (rfl works up to defeq for `exact rfl`? `rfl` tactic: closes a = b if defeq ✓). Hmm — actually to be safe use `show` conversions instead. It'll be fine. Then: ```lean /-- The series minus its ρ₀-term is analytic at ρ₀. -/ theorem seriesFunSub_analyticAt (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) : AnalyticAt ℂ (seriesFunSub ρ₀) (ρ₀ : ℂ) := by obtain ⟨δ, hδ, hiso⟩ := nontrivialZero_isolated ρ₀ set δ' := δ / 2 with hδ' have hδ'0 : 0 < δ' := half_pos hδ set M : ℝ := ‖(ρ₀ : ℂ)‖ + δ' with hM set u : {ρ : ℂ // IsNontrivialZero ρ} → ℝ := fun ρ => 17 / 6 * M * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ)))) with hu have hsum_u : Summable u := seriesTerm_summable_majorant M have hfu : ∀ᶠ ρ in cofinite, ∀ s ∈ Metric.ball (ρ₀ : ℂ) δ', ‖seriesTermSub ρ₀ s ρ‖ ≤ u ρ := by rw [Filter.eventually_cofinite] apply (finite_subtype_norm_lt (max 2 (2 * M))).subset intro ρ hρ simp only [Set.mem_setOf_eq, not_forall] at hρ -- hρ : ∃ s ∈ ball, ¬ ‖sub‖ ≤ u ρ: get s by_contra hball apply hρ -- wait direction: I want: if ‖ρ‖ ≥ R₀ then ∀ s ∈ ball, bound. Contrapositive: ¬(∀...) ⟹ ‖ρ‖ < R₀. intro ρ hρ with hρ : ¬ ∀ s ∈ ball...; goal ρ ∈ {ρ | ‖ρ‖ < R₀}: by_contra hball: ‖ρ‖ ≥ R₀; derive ∀ s ∈ ball bound; contra hρ. ... ``` Let me structure the contrapositive cleanly: ```lean apply (finite_subtype_norm_lt (max 2 (2 * M))).subset intro ρ hρ -- hρ : ρ ∈ {ρ | ¬ ∀ s ∈ ball, ‖sub ρ s‖ ≤ u ρ}; goal: ‖ρ‖ < R₀ by_contra hlt rw [not_lt] at hlt -- R₀ ≤ ‖ρ‖ apply hρ intro s hs -- s ∈ ball(ρ₀, δ'): ‖s‖ < ‖ρ₀‖ + δ' = M ⟹ 2‖s‖ ≤ 2M ≤ R₀ ≤ ‖ρ‖; 2 ≤ R₀ ≤ ‖ρ‖ have hsM : ‖s‖ ≤ M := by have h : ‖s‖ < M := by calc ‖s‖ ≤ ‖s - (ρ₀:ℂ)‖ + ‖(ρ₀:ℂ)‖ := by nth_rewrite 1 [show s = (s - (ρ₀:ℂ)) + (ρ₀:ℂ) from by ring] exact norm_add_le _ _ _ < δ' + ‖(ρ₀:ℂ)‖ := by have := Metric.mem_ball.mp hs -- dist s ρ₀ < δ' rw [dist_eq_norm] at this linarith _ = M := by rw [hM]; ring exact le_of_lt h have h2 : (2:ℝ) ≤ ‖(ρ:ℂ)‖ := (le_max_left _ _).trans hlt have hs2 : 2 * ‖s‖ ≤ ‖(ρ:ℂ)‖ := ((le_max_right _ _) : 2*M ≤ max 2 (2*M)).trans hlt ∘ ... ``` 2‖s‖ ≤ 2M (from hsM) ≤ R₀ (max_right) ≤ ‖ρ‖ (hlt): `exact (by linarith : 2 * ‖s‖ ≤ max 2 (2*M)).trans hlt`? linarith [hsM, le_max_right 2 (2*M)]... do: have h2M : 2*‖s‖ ≤ 2*M := by linarith; exact (h2M.trans (le_max_right _ _)).trans hlt ✓. Then: ```lean by_cases h0 : ρ = ρ₀ · simp [seriesTermSub, h0] -- goal ‖0‖ ≤ u ρ₀: norm_zero; positivity of u: (17/6)*M*(mult/(1+γ²)) ≥ 0: M = ‖ρ₀‖+δ' > 0: positivity with haves... positivity can't use hM's nonneg directly: M = ‖ρ₀‖ + δ' ≥ 0 since both ≥ 0: have hM0 : 0 ≤ M := by rw [hM]; positivity (‖·‖ nonneg + hδ'0.le: linarith [norm_nonneg (ρ₀:ℂ), hδ'0]). Then positivity for the product with hM0 in context? positivity doesn't read hypotheses. Use explicit: mul_nonneg (mul_nonneg (by norm_num : (0:ℝ) ≤ 17/6) hM0) (div_nonneg (Nat.cast_nonneg _) (by linarith [Complex.normSq_nonneg (gammaOf (ρ:ℂ))]))... -- simpler: simp [seriesTermSub, h0]; positivity?? no. Explicit: rw [seriesTermSub, if_pos h0, norm_zero] have hg0 : (0:ℝ) < 1 + Complex.normSq (gammaOf (ρ:ℂ)) := by have := Complex.normSq_nonneg (gammaOf (ρ:ℂ)); linarith have hM0 : (0:ℝ) ≤ M := by rw [hM]; linarith [norm_nonneg (ρ₀:ℂ), hδ'0.le] exact mul_nonneg (mul_nonneg (by norm_num) hM0) (div_nonneg (Nat.cast_nonneg _) hg0.le) · rw [seriesTermSub, if_neg h0] exact (seriesTerm_norm_le ρ h2 hs2).trans (by -- 17/6‖s‖mult/(1+γ²) ≤ 17/6 M mult/(1+γ²) have hg0 : (0:ℝ) ≤ (zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ))) := by have := Complex.normSq_nonneg (gammaOf (ρ:ℂ)) positivity -- hmm positivity: (mult:ℝ)/(1+γ²): mult cast nonneg ✓, 1+γ² > 0 needs normSq_nonneg — positivity knows normSq_nonneg? It's a lemma not marked... positivity extension for Complex.normSq? Unsure. Safer: div_nonneg (Nat.cast_nonneg _) (by linarith [Complex.normSq_nonneg _]). exact mul_le_mul_of_nonneg_right (by nlinarith [hsM, norm_nonneg s] : 17/6*‖s‖ ≤ 17/6*M) hg0) ``` Wait — but u ρ is DEFINED as 17/6 * M * (mult/(1+γ²)) via `set` — the goal after `rw [seriesTermSub, if_neg h0]` is ‖seriesTerm s ρ‖ ≤ u ρ; with set, u ρ is displayed as the lambda applied: u ρ — set introduces u := fun ρ => ... and replaces occurrences; u ρ is a beta-redex?? `set ... := fun ρ => body` then `u ρ` — Lean keeps u as a local def; u ρ beta-reduces to body[ρ] — defeq but not syntactic. The goal `‖seriesTerm s ρ‖ ≤ u ρ`: my `.trans` target: 17/6*M*(...) ≤ u ρ — I must provide the proof term of type ... ≤ u ρ; my calc gives ... ≤ 17/6*M*(...) which is defeq to u ρ: `exact` accepts defeq ✓. But when I write the bound inline `(by ... : 17/6*‖s‖ ≤ 17/6*M)` fine. Hmm — wait, `set u : ... → ℝ := fun ρ => ...` — then occurrences of `fun ρ => 17/6*M*(...)` get folded to u. The application u ρ doesn't auto-unfold in the goal display but defeq holds ✓ exact works. Also — `hs` : s ∈ Metric.ball (ρ₀:ℂ) δ'. Metric.mem_ball.mp hs : dist s ρ₀ < δ' ✓. Then the uniform-convergence + differentiability on ball(ρ₀, δ'): ```lean have hu' : HasSumUniformlyOn (fun ρ => fun s : ℂ => seriesTermSub ρ₀ s ρ) (fun s => ∑' ρ, seriesTermSub ρ₀ s ρ) (Metric.ball (ρ₀ : ℂ) δ') := HasSumUniformlyOn.of_norm_le_summable_eventually hsum_u hfu have htend := TendstoUniformlyOn.tendstoLocallyUniformlyOn (hasSumUniformlyOn_iff_tendstoUniformlyOn.mp hu') have hdiff : DifferentiableOn ℂ (fun s => ∑' ρ, seriesTermSub ρ₀ s ρ) (Metric.ball (ρ₀ : ℂ) δ') := by apply htend.differentiableOn _ isOpen_ball apply Filter.Eventually.of_forall intro t s hs rw [show (fun s => ∑ ρ ∈ t, seriesTermSub ρ₀ s ρ) = ∑ ρ ∈ t, (fun s => seriesTermSub ρ₀ s ρ) from by funext s; simp [Finset.sum_apply]] apply DifferentiableAt.differentiableWithinAt apply DifferentiableAt.sum intro ρ hρt by_cases h0 : ρ = ρ₀ · show DifferentiableAt ℂ (fun s => if ρ = ρ₀ then (0:ℂ) else seriesTerm s ρ) s rw [if_pos h0] exact differentiableAt_const 0 · have hsρ : s - (ρ : ℂ) ≠ 0 := by have hle : δ ≤ ‖(ρ : ℂ) - (ρ₀ : ℂ)‖ := hiso ρ h0 have hlt : ‖s - (ρ₀ : ℂ)‖ < δ' := by have := Metric.mem_ball.mp hs rw [dist_eq_norm] at this exact this intro hzero -- ‖ρ − ρ₀‖ ≤ ‖ρ − s‖ + ‖s − ρ₀‖ < 0 + δ' = δ/2 < δ contra have h1 : ‖(ρ : ℂ) - (ρ₀ : ℂ)‖ ≤ ‖(ρ : ℂ) - s‖ + ‖s - (ρ₀ : ℂ)‖ := by nth_rewrite 1 [show (ρ:ℂ) - (ρ₀:ℂ) = ((ρ:ℂ) - s) + (s - (ρ₀:ℂ)) from by ring] exact norm_add_le _ _ have h2 : ‖(ρ : ℂ) - s‖ = 0 := by have : s = (ρ:ℂ) := sub_eq_zero.mp hzero rw [← this, sub_self, norm_zero] rw [h2] at h1 linarith [hle, hlt, hδ'0] -- δ ≤ 0 + δ' = δ/2 ⟹ δ ≤ δ/2 contra δ > 0 have hρ0 : (ρ : ℂ) ≠ 0 := by intro h have := ρ.2.2.1 rw [h] at this simp at this show DifferentiableAt ℂ (fun s => if ρ = ρ₀ then (0:ℂ) else seriesTerm s ρ) s rw [if_neg h0] show DifferentiableAt ℂ (fun s => (zeroMult ρ : ℂ) * (1 / (s - (ρ:ℂ)) + 1 / (ρ:ℂ))) s exact (((differentiableAt_const (1:ℂ)).div (differentiableAt_id.sub (differentiableAt_const _)) hsρ).add (differentiableAt_const _)).const_mul _ have han := hdiff.analyticOnNhd isOpen_ball exact han (ρ₀:ℂ) (Metric.mem_ball_self hδ'0) ``` Wait the final: goal AnalyticAt ℂ (seriesFunSub ρ₀) (ρ₀:ℂ); han : AnalyticOnNhd ℂ (fun s => ∑' ρ, seriesTermSub ρ₀ s ρ) (ball...) — defeq to seriesFunSub ρ₀ ✓; han (ρ₀:ℂ) (mem_ball_self) : AnalyticAt ℂ (fun s => ...) (ρ₀:ℂ) — exact defeq ✓. hmm hδ'0 in the last linarith: δ ≤ δ/2 with δ > 0: linarith [hle, hlt, hδ] where hδ : 0 < δ: from h1 (with h2 rw'd): ‖ρ−ρ₀‖ ≤ 0 + ‖s−ρ₀‖ — rw [h2] at h1 gives ‖ρ−ρ₀‖ ≤ 0 + ‖s−ρ₀‖... zero_add not auto: linarith handles: ‖ρ−ρ₀‖ ≤ 0 + ‖s−ρ₀‖, ‖s−ρ₀‖ < δ' = δ/2, hle: δ ≤ ‖ρ−ρ₀‖ ⟹ δ < δ/2 ⟹ δ ≤ 0 contra hδ : 0 < δ — but hδ' = δ/2 defeq: δ' is a set-variable: hlt : ‖s−ρ₀‖ < δ' where δ' := δ/2 — linarith sees δ' opaque! Need hδ' : δ' = δ/2 in the linarith list. set ... with hδ' gives hδ' : δ' = δ/2 ✓ include it: linarith [hle, hlt, hδ, hδ'] — wait `set δ' := δ/2 with hδ'` : hδ' : δ' = δ/2 ✓. Also hlt could just reuse hs directly: Metric.mem_ball.mp hs : dist s ρ₀ < δ' ✓ dist_eq_norm ✓. Then the final assembly: ```lean /-- The series with its ρ₀-term subtracted equals the reduced series (everywhere); hence the polar subtraction is analytic at ρ₀. -/ theorem seriesFun_sub_term (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) : seriesFun s - seriesTerm s ρ₀ = seriesFunSub ρ₀ s := by have h := seriesFun_eq_sub_add ρ₀ s linarith?? — ℂ not ordered: use: rw [h]; ring -- h : seriesFun s = seriesFunSub ρ₀ s + seriesTerm s ρ₀: goal seriesFun s − seriesTerm s ρ₀ = seriesFunSub ρ₀ s: rw [h]: (a + b) − b = a: ring ✓ -- actually: conv? `rw [h]; ring` — ring on (x + y) − y = x ✓ ``` Hmm — ring works for ℂ equalities ✓. ```lean theorem seriesFun_sub_self_term_analyticAt (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) : AnalyticAt ℂ (fun s => seriesFun s - seriesTerm s ρ₀) (ρ₀ : ℂ) := by apply AnalyticAt.congr (seriesFunSub_analyticAt ρ₀) filter_upwards with s -- EventualEq: ∀ᶠ s in 𝓝 ρ₀, seriesFunSub ρ₀ s = seriesFun s − seriesTerm s ρ₀ — pointwise true! exact (seriesFun_sub_term ρ₀ s).symm ``` AnalyticAt.congr (hf : AnalyticAt f x) (hg : f =ᶠ[𝓝 x] g) : AnalyticAt g x — so hf = seriesFunSub_analyticAt (f = seriesFunSub ρ₀), g = fun s => seriesFun s − seriesTerm s ρ₀; need seriesFunSub ρ₀ =ᶠ[𝓝 ρ₀] g: Filter.Eventually.of_forall (fun s => (seriesFun_sub_term ρ₀ s).symm) ✓. ```lean /-- The polar subtraction form consumed by 5e-iv: s ↦ seriesFun s − mult(ρ₀)/(s−ρ₀) is analytic at ρ₀. -/ theorem seriesFun_sub_polar_analyticAt (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) : AnalyticAt ℂ (fun s => seriesFun s - (zeroMult (ρ₀:ℂ) : ℂ) / (s - (ρ₀:ℂ))) (ρ₀:ℂ) := by have h := seriesFun_sub_self_term_analyticAt ρ₀ have heq : (fun s => seriesFun s - (zeroMult (ρ₀:ℂ) : ℂ) / (s - (ρ₀:ℂ))) = (fun s => (seriesFun s - seriesTerm s ρ₀) + (zeroMult (ρ₀:ℂ) : ℂ) / (ρ₀:ℂ)) := by funext s rw [seriesTerm] ring rw [heq] exact h.add (differentiableAt_const _).analyticAt ``` Check: seriesTerm s ρ₀ = mult·(1/(s−ρ₀) + 1/ρ₀) = mult/(s−ρ₀) + mult/ρ₀ — as ℂ expressions with div: mult*(1/(s−ρ₀) + 1/ρ₀) = mult/(s−ρ₀) + mult/ρ₀: ring? ring normalizes a/b to a*b⁻¹ ✓ and distributes ✓ (no field_simp needed since no cancellations of inverses). Goal after funext s, rw [seriesTerm]: seriesFun s − mult/(s−ρ₀) = (seriesFun s − mult*(1/(s−ρ₀)+1/ρ₀)) + mult/ρ₀: ring ✓. `DifferentiableAt.analyticAt` — BANKED GOTCHA (session 026): DifferentiableAt.analyticAt does NOT exist! Use: for a constant function: `(differentiableAt_const _).analyticAt` invalid. AnalyticAt of const: `analyticAt_const : AnalyticAt 𝕜 (fun _ => c) x` ✓ exists (I believe). Use analyticAt_const. Let me double-check `analyticAt_const` exists in this Mathlib — Analytic/Basic.lean: `theorem analyticAt_const : AnalyticAt 𝕜 (fun _ => c) x` ✓ standard. Also `(zeroMult (ρ₀:ℂ) : ℂ)` — zeroMult applied to (ρ₀ : ℂ) then cast ℕ→ℂ. In liSummand they wrote `(zeroMult ρ : ℂ)` with ρ : subtype — Lean coerces ρ to ℂ for zeroMult ✓ same here; but to be safe write `(zeroMult (ρ₀ : ℂ) : ℂ)`. Hmm — in seriesTerm the coercion is already there; for consistency in heq rewrite: seriesTerm s ρ₀ = (zeroMult ↑ρ₀ : ℂ) * (...): rw [seriesTerm] exposes the def with (zeroMult ↑ρ₀ : ℂ) — hmm the def is `(zeroMult ρ : ℂ)` with ρ the subtype var — instantiated at ρ₀: `(zeroMult ↑ρ₀ : ℂ)`? zeroMult's argument: ρ₀ coerced: `zeroMult ↑ρ₀`. Fine — ring handles regardless of the exact form ✓. Also for §4's `seriesFun_analyticOnNhd`: AnalyticOnNhd ℂ seriesFun {s | ¬ IsNontrivialZero s} = ∀ x ∈ s, AnalyticAt: `fun s₀ hs₀ => seriesFun_analyticAt hs₀` — hs₀ : s₀ ∈ {s | ¬ ...} = ¬ IsNontrivialZero s₀ (defeq set membership ✓). Now — remaining risk points: 1. `Filter.eventually_cofinite` name/direction. Check: Mathlib Order/Filter/Cofinite.lean: `theorem eventually_cofinite {p : α → Prop} : (∀ᶠ x in cofinite, p x) ↔ {x | ¬p x}.Finite`? Let me verify. 2. `HasSumUniformlyOn.of_norm_le_summable_eventually` hfu form: ∀ᶠ n in cofinite, ∀ x ∈ s, ‖f n x‖ ≤ u n — matches ✓ (from the source above). 3. `Metric.eventually_nhds_iff_ball` ✓ verified. 4. `analyticAt_riemannZeta` — Mathlib: `analyticAt_riemannZeta {s : ℂ} (hs : s ≠ 1) : AnalyticAt ℂ riemannZeta s`? Used in LiSides line 370: `analyticAt_riemannZeta hρ` with hρ : ρ ≠ 1 ✓. 5. `ContinuousAt.eventually_ne` ✓ (used in LiResidue line 82). 6. `AnalyticAt.continuousAt` ✓ used LiResidue 82. 7. `(analyticAt_riemannZeta h1).analyticOrderAt_ne_top.mp` ✓ LiSides pattern. 8. `smul_eq_mul` ✓. 9. In §4 partial sums: `DifferentiableAt.sum` — signature: `(h : ∀ i ∈ t, DifferentiableAt ...)`? LiDigamma: `apply DifferentiableAt.sum; intro m hm` ✓. 10. `htend.differentiableOn _ isOpen_ball` ✓ pattern from LiDigamma (`htend.differentiableOn _ dpsiDomain_isOpen`). 11. `hdiff.analyticOnNhd isOpen_ball` ✓. 12. `Metric.mem_ball_self : 0 < r → x ∈ ball x r` ✓. 13. `Finset.min'_le`, `Finset.min'_mem` ✓ standard. 14. `Set.finite_singleton` ✓; `summable_of_hasFiniteSupport` ✓. 15. `tsum_congr` ✓. 16. `half_pos` ✓. 17. `abs_norm_sub_norm_le : |‖a‖ − ‖b‖| ≤ ‖a − b‖` — check name: Mathlib `abs_norm_sub_norm_le : |‖x‖ − ‖y‖| ≤ ‖x − y‖` ✓ exists (norm_sub_le_norm... no). Actually the name is `abs_norm_sub_norm_le` ✓ I'm fairly confident. Let me verify #1 and #17 and `tsum_congr`, `analyticAt_const`, `DifferentiableAt.sum`, `Finset.min'_le`, `Complex.norm_natCast`/`RCLike.norm_natCast` quickly.
Now verifying the remaining lemma names in one sweep.
tool: Bash
input
{
  "command": "cd D:/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem eventually_cofinite\\b\" Mathlib/Order/Filter/Cofinite.lean | head -2; grep -rn \"theorem abs_norm_sub_norm_le\\b\\|lemma abs_norm_sub_norm_le\\b\" Mathlib/Analysis/ -r | head -2; grep -rn \"theorem tsum_congr\\b\\|lemma tsum_congr\\b\" Mathlib/Topology/Algebra/InfiniteSum/Basic.lean | head -2; grep -rn \"theorem analyticAt_const\\b\" Mathlib/Analysis/Analytic/Basic.lean | head -2; grep -rn \"theorem DifferentiableAt.sum\\b\\|lemma DifferentiableAt.sum\\b\" Mathlib/ -r | head -2; grep -rn \"theorem half_pos\\b\" Mathlib/Algebra/Order/ -r | head -2; grep -rn \"theorem Summable.tsum_add\\b\" Mathlib/ -r | head -2; grep -rn \"theorem Summable.norm\\b\" Mathlib/ -r | head -2; grep -rn \"theorem Metric.ball_subset_ball\\b\" Mathlib/ -r | head -2",
  "description": "Verify lemma names batch"
}
raw content_json (database row)
[{"type":"thinking","thinking":"All confirmed. Now write LiSeries.lean. Let me draft the full file carefully.\n\n```lean\n/-\nNguyenRH1/LiSeries.lean — tier ii′ sub-stage ii′-5e-iii (D-068 §3):\nthe zero-side partial-fraction series\n\n  seriesFun s := ∑' ρ : {ρ // IsNontrivialZero ρ}, (zeroMult ρ : ℂ)·(1/(s−ρ) + 1/ρ)\n\nand its three structural properties:\n(§1–2) ABSOLUTE SUMMABILITY at every s (`seriesSummable`): the tail bound\n  ‖1/(s−ρ) + 1/ρ‖ ≤ 2‖s‖/‖ρ‖² (‖ρ‖ ≥ 2‖s‖, ‖ρ‖ ≥ 2) feeds the ii′-1a\n  dominator chain (comparison 1 + ‖γ_ρ‖² ≤ (17/12)‖ρ‖² → Zeta23\n  `WeilEF.zero_sum_inv_sq`); the finite head is a finite subtype sum.\n(§3–4) ANALYTICITY off the zeros (`seriesFun_analyticOnNhd`): around any\n  s₀ that is not a nontrivial zero there is a ball avoiding the\n  nontrivial zeros (continuity of ζ where ζ s₀ ≠ 0; the order normal\n  form where ζ s₀ = 0, s₀ ≠ 1; the zetaA factorization at s₀ = 1), and\n  on that ball the series converges UNIFORMLY (Weierstrass M-test,\n  `HasSumUniformlyOn.of_norm_le_summable_eventually`) with analytic\n  partial sums.\n(§5) ISOLATION (`nontrivialZero_isolated`) and the reduced series\n  `seriesFunSub ρ₀` (the ρ₀-term zeroed out): analytic AT ρ₀\n  (`seriesFunSub_analyticAt`), so the polar subtraction\n  s ↦ seriesFun s − mult/(s−ρ₀) is analytic at ρ₀\n  (`seriesFun_sub_polar_analyticAt`) — the input 5e-iv needs for the\n  residue cancellation at the nontrivial zeros.\n\nArchive references: D-068 §3, journal-020/021 (the locally-uniform ⟹\nanalytic pattern), journal-015 (the ii′-1a dominator chain).\n-/\nimport Mathlib\nimport Zeta23.WeilEF.ZeroSummability\nimport Zeta23.Statement.SeamClosed\nimport NguyenRH1.LiSides\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n```\n\nWait — check LiSides namespace: decls like zeta_order_ne_top_of_ne are in NguyenRH1 namespace (used unqualified in LiDisc which is also NguyenRH1). ✓.\n\nNow §0:\n\n```lean\n/-! ## 0. The series -/\n\n/-- The zero-series summand: mult(ρ)·(1/(s−ρ) + 1/ρ) over the nontrivial\nzero subtype (the ii′-1a encoding; D-068 §3). -/\ndef seriesTerm (s : ℂ) (ρ : {ρ : ℂ // IsNontrivialZero ρ}) : ℂ :=\n  (zeroMult ρ : ℂ) * (1 / (s - (ρ : ℂ)) + 1 / (ρ : ℂ))\n\n/-- The zero-side partial-fraction series. Summable at every s\n(`seriesSummable`), analytic off the nontrivial zeros\n(`seriesFun_analyticOnNhd`). -/\ndef seriesFun (s : ℂ) : ℂ := ∑' ρ : {ρ : ℂ // IsNontrivialZero ρ}, seriesTerm s ρ\n```\n\n§1:\n\n```lean\n/-! ## 1. The norm comparison and the tail bound -/\n\n/-- For a nontrivial zero with 2 ≤ ‖ρ‖: 1 + ‖γ_ρ‖² ≤ (17/12)·‖ρ‖²\n(the γ-vs-‖·‖ comparison of the ii′-1a chain, with the constant for the\n‖ρ‖ ≥ 2 range: ‖γ‖² = im² + (1/2−re)² ≤ im² + 1/4 and im² ≥ ‖ρ‖² − 1 ≥ 3). -/\nlemma one_add_normSq_gammaOf_le (ρ : {ρ : ℂ // IsNontrivialZero ρ})\n    (hρ : (2 : ℝ) ≤ ‖(ρ : ℂ)‖) :\n    1 + Complex.normSq (gammaOf (ρ : ℂ)) ≤ 17 / 12 * ‖(ρ : ℂ)‖ ^ 2 := by\n  have hz := ρ.2\n  have hre0 : 0 < (ρ : ℂ).re := hz.2.1\n  have hre1 : (ρ : ℂ).re < 1 := hz.2.2\n  have hnorm : ‖(ρ : ℂ)‖ ^ 2 = (ρ : ℂ).re ^ 2 + (ρ : ℂ).im ^ 2 := by\n    rw [← Complex.normSq_eq_norm_sq, Complex.normSq_apply]\n    ring\n  have hgam : Complex.normSq (gammaOf (ρ : ℂ)) = (ρ : ℂ).im ^ 2 + (1 / 2 - (ρ : ℂ).re) ^ 2 := by\n    rw [Complex.normSq_apply, WeilEF.gammaOf_re, WeilEF.gammaOf_im]\n    ring\n  have hre2 : (ρ : ℂ).re ^ 2 ≤ 1 := by nlinarith [hre0, hre1]\n  have him2 : 3 ≤ (ρ : ℂ).im ^ 2 := by nlinarith [hρ, hnorm, hre2]  -- needs 4 ≤ ‖ρ‖²: from hρ: 2 ≤ ‖ρ‖: sq: 4 ≤ ‖ρ‖² — pow_le_pow_left₀ or nlinarith [hρ, norm_nonneg]\n  have hquarter : (1 / 2 - (ρ : ℂ).re) ^ 2 ≤ 1 / 4 := by nlinarith [hre0, hre1]\n  rw [hgam, hnorm]\n  nlinarith [him2, hquarter]\n```\n\nCheck nlinarith goals: him2: 3 ≤ im²: from ‖ρ‖² = re²+im², ‖ρ‖ ≥ 2 ⟹ ‖ρ‖² ≥ 4 (nlinarith: hρ : 2 ≤ ‖ρ‖, norm_nonneg ‖ρ‖ ≥ 0 ⟹ product (‖ρ‖−2)(‖ρ‖+2) ≥ 0 ⟹ ‖ρ‖² ≥ 4 ✓ nlinarith [hρ, norm_nonneg ‖(ρ:ℂ)‖]); re² ≤ 1 ⟹ im² = ‖ρ‖² − re² ≥ 4 − 1 = 3 ✓ nlinarith should manage with hnorm as an hypothesis (rw first? I rw [hgam, hnorm] at the END — the haves hnorm/hgam are used in nlinarith calls before the rewrite; hnorm is a hypothesis equation so nlinarith [hρ, hnorm, hre2]... but hnorm is in context already, no need to pass. Final goal after rw [hgam, hnorm]: 1 + (im² + (1/2−re)²) ≤ 17/12·(re²+im²). nlinarith [him2, hquarter, hre2...]: LHS ≤ 1 + im² + 1/4; want ≤ 17/12 re² + 17/12 im². From him2: im² ≥ 3. Hmm: 1 + im² + 1/4 ≤ 17/12(re²+im²) ⟺ 5/4 + im² ≤ 17/12 re² + 17/12 im² ⟸ 5/4 + im² ≤ 17/12 im² ⟺ 5/4 ≤ 5/12 im² ⟺ 3 ≤ im² ✓. nlinarith hint: needs (5/12)im² ≥ 5/4 from im² ≥ 3: linear ✓ and re² ≥ 0 (sq_nonneg) ✓. So `nlinarith [him2, hquarter, sq_nonneg (ρ:ℂ).re]`.\n\nhquarter: (1/2−re)² ≤ 1/4 ⟺ |1/2−re| ≤ 1/2 ⟺ 0 ≤ re ≤ 1: nlinarith [hre0, hre1]: (1/2−re)² − 1/4 = −re + re² = re(re−1) ≤ 0 since re > 0, re−1 < 0: product re(re−1) < 0: nlinarith product hint: it multiplies hre0·(hre1): re·(re − 1)... nlinarith proves (1/2−re)² ≤ 1/4 ⟺ re² − re + 1/4 ≤ 1/4 ⟺ re² ≤ re ⟺ re(re−1) ≤ 0: from hre0 (0 < re) and hre1 (re < 1): (re)·(1−re) > 0 ⟹ re − re² > 0: nlinarith multiplies hre0 and (1 − re > 0 from hre1) ✓ should find it.\n\nhre2: re² ≤ 1: re < 1, re > 0: re·re < 1·re·... nlinarith [hre0, hre1]: re² ≤ 1 ⟸ re² ≤ re (above) and re < 1: nlinarith finds via product (1−re)·re > 0 and re < 1... re² ≤ re < 1... wait need re² ≤ 1: re² ≤ re (from product) and re < 1 ⟹ re² < 1 ✓. nlinarith [hre0, hre1] ✓.\n\nThen:\n\n```lean\n/-- The key algebra: 1/(s−ρ) + 1/ρ = s/(ρ·(s−ρ)). -/\nlemma one_div_sub_add_one_div {s ρ : ℂ} (h0 : ρ ≠ 0) (h1 : s - ρ ≠ 0) :\n    1 / (s - ρ) + 1 / ρ = s / (ρ * (s - ρ)) := by\n  field_simp\n  ring\n```\n\nfield_simp with h0, h1 in context: goal 1/(s−ρ) + 1/ρ = s/(ρ·(s−ρ)): field_simp clears denominators: needs ρ*(s−ρ) ≠ 0 — mul_ne_zero h0 h1 might need to be in context; field_simp should find h0 h1 and maybe need the product: add `have := mul_ne_zero h0 h1`. After clearing: ρ + (s−ρ) = s? LHS·denom: 1/(s−ρ) = ρ·?/… let me trust field_simp + ring (banked gotcha: \"field_simp often closes goals (trailing ring errors)\").\n\n```lean\n/-- Tail bound: for 2 ≤ ‖ρ‖ and 2‖s‖ ≤ ‖ρ‖,\n‖seriesTerm s ρ‖ ≤ (17/6)·‖s‖·mult/(1+‖γ_ρ‖²). -/\nlemma seriesTerm_norm_le {s : ℂ} (ρ : {ρ : ℂ // IsNontrivialZero ρ})\n    (hρ2 : (2 : ℝ) ≤ ‖(ρ : ℂ)‖) (hsρ : 2 * ‖s‖ ≤ ‖(ρ : ℂ)‖) :\n    ‖seriesTerm s ρ‖ ≤\n      17 / 6 * ‖s‖ * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ)))) := by\n  have h0 : (ρ : ℂ) ≠ 0 := by\n    intro h; rw [h, norm_zero] at hρ2; linarith  -- norm_num at... 2 ≤ 0 false: linarith works: norm_zero: ‖0‖=0: hρ2 : 2 ≤ 0: linarith? norm_num closes: `norm_num at hρ2`. Use that.\n  have hρpos : (0 : ℝ) < ‖(ρ : ℂ)‖ := norm_pos_iff.mpr h0\n  have hsnorm : ‖s‖ ≤ ‖(ρ : ℂ)‖ / 2 := by linarith\n  have hsr : ‖s - (ρ : ℂ)‖ ≥ ‖(ρ : ℂ)‖ / 2 := by  -- use norm_sub_le reversed\n    have h := norm_sub_le_norm_sub... \n```\n\n‖s−ρ‖ ≥ ‖ρ‖ − ‖s‖ (norm_sub_norm_le? `norm_sub_le_norm_sub`? The reverse triangle: `norm_sub_le`? Mathlib: `norm_sub_le_norm_sub`? No: `abs_norm_sub_norm_le : |‖a‖ − ‖b‖| ≤ ‖a − b‖` — so ‖ρ‖ − ‖s‖ ≤ |‖ρ‖−‖s‖| ≤ ‖ρ − s‖ = ‖s − ρ‖ (norm_sub_rev). So:\n```lean\n  have hsr : ‖(ρ : ℂ)‖ / 2 ≤ ‖s - (ρ : ℂ)‖ := by\n    have h := abs_norm_sub_norm_le s (ρ : ℂ)  -- |‖s‖ − ‖ρ‖| ≤ ‖s − ρ‖\n    rw [abs_le] at h\n    have h2 := h.1  -- -(‖s‖−‖ρ‖) ≤ ‖s−ρ‖ i.e. ‖ρ‖−‖s‖ ≤ ‖s−ρ‖\n    linarith\n```\nThen s − ρ ≠ 0: norm_pos: ‖s−ρ‖ ≥ ‖ρ‖/2 > 0.\n\n```lean\n  have h1 : s - (ρ : ℂ) ≠ 0 := by\n    intro h; rw [h, norm_zero] at hsr; linarith\n  have hcomp := one_add_normSq_gammaOf_le ρ hρ2\n  have hg0 : (0 : ℝ) < 1 + Complex.normSq (gammaOf (ρ : ℂ)) := by\n    have := Complex.normSq_nonneg (gammaOf (ρ : ℂ)); linarith\n  have halg := one_div_sub_add_one_div h0 h1\n  rw [seriesTerm, halg, norm_mul, Complex.norm_natCast]  -- norm of (mult : ℂ) * (...): norm_mul gives ‖mult‖·‖s/(ρ(s−ρ))‖; Complex.norm_natCast: ‖(mult:ℂ)‖ = (mult:ℝ)... zeroMult ρ is ℕ; (zeroMult ρ : ℂ): norm_natCast: ‖(↑n : ℂ)‖ = ↑n? Complex.norm_natCast : ‖(n : ℂ)‖ = n. Hmm RCLike.norm_natCast was used in LiSkeleton: `RCLike.norm_natCast`. Both may exist. Use RCLike.norm_natCast like LiSkeleton.\n  rw [norm_div, norm_mul]\n  -- goal: (mult:ℝ) * (‖s‖ / (‖ρ‖ * ‖s−ρ‖)) ≤ 17/6 * ‖s‖ * (mult / (1+‖γ‖²))\n  have hmul0 : (0:ℝ) ≤ (zeroMult ρ : ℝ) := Nat.cast_nonneg _\n  -- ‖ρ‖·‖s−ρ‖ ≥ ‖ρ‖·(‖ρ‖/2) = ‖ρ‖²/2\n  have hden : ‖(ρ : ℂ)‖ ^ 2 / 2 ≤ ‖(ρ : ℂ)‖ * ‖s - (ρ : ℂ)‖ :=\n    by nlinarith [hsr, hρpos, norm_nonneg (s - (ρ:ℂ))]\n    -- mul_le_mul_of_nonneg_left hsr (le_of_lt hρpos) : ‖ρ‖·(‖ρ‖/2) ≤ ‖ρ‖·‖s−ρ‖; ring_nf\n  -- hence ‖s‖/(‖ρ‖‖s−ρ‖) ≤ ‖s‖/(‖ρ‖²/2) = 2‖s‖/‖ρ‖²\n  have hfrac : ‖s‖ / (‖(ρ : ℂ)‖ * ‖s - (ρ : ℂ)‖) ≤ 2 * ‖s‖ / ‖(ρ : ℂ)‖ ^ 2 := by\n    rw [div_le_div_iff₀ (by positivity...)] ...\n```\n\ndiv_le_div_iff₀ (ha : 0 < a) (hb : 0 < b): a/b ≤ c/d ⟺ ... signature: `div_le_div_iff₀ (hb : 0 < b) (hd : 0 < d) : a / b ≤ c / d ↔ a * d ≤ c * b`. Let me do: ‖s‖/D ≤ 2‖s‖/ρ² ⟺ ‖s‖·ρ² ≤ 2‖s‖·D (D = ‖ρ‖‖s−ρ‖ > 0): from D ≥ ρ²/2: 2‖s‖·D ≥ 2‖s‖·ρ²/2 = ‖s‖·ρ² ✓. positivity for ‖s‖ ≥ 0 fine.\n\nThen:\n```lean\n  calc (zeroMult ρ : ℝ) * (‖s‖ / (‖(ρ:ℂ)‖ * ‖s - (ρ:ℂ)‖))\n      ≤ (zeroMult ρ : ℝ) * (2 * ‖s‖ / ‖(ρ:ℂ)‖ ^ 2) := mul_le_mul_of_nonneg_left hfrac hmul0\n    _ = 2 * ‖s‖ * (zeroMult ρ : ℝ) / ‖(ρ:ℂ)‖ ^ 2 := by ring\n    _ ≤ 17 / 6 * ‖s‖ * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ)))) := by\n        -- ⟺ 2·‖s‖·mult/ρ² ≤ (17/6)‖s‖·mult/(1+γ²)\n        -- ⟸ mult·‖s‖·(2/ρ² ≤ (17/6)/(1+γ²)) ⟸ 2/ρ² ≤ (17/6)/(1+γ²) ⟺ 2(1+γ²) ≤ (17/6)ρ² ⟸ 2·(17/12)ρ² = (17/6)ρ² ✓\n        rw [div_le_div_iff₀ (by positivity) hg0]  -- careful: LHS form A/ρ², RHS B/(1+γ²)\n        ...\n```\nLet me structure: \n```lean\n    have hinv : 2 * ‖s‖ * (zeroMult ρ : ℝ) / ‖(ρ:ℂ)‖ ^ 2\n        ≤ 17 / 6 * ‖s‖ * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ)))) := by\n      rw [div_le_div_iff₀ (by positivity : (0:ℝ) < ‖(ρ:ℂ)‖ ^ 2) hg0]\n      -- goal: 2‖s‖mult·(1+γ²) ≤ (17/6‖s‖·mult)·ρ²  -- hmm RHS form: (17/6 * ‖s‖ * (mult/(1+γ²))) * ρ²... \n```\nCareful — after div_le_div_iff₀ with a = 2‖s‖mult, b = ρ², c = (17/6)‖s‖·mult... wait RHS is (17/6 * ‖s‖ * (mult/(1+γ²))) — that's not of the form c/d syntactically! It's a product containing a division. div_le_div_iff₀ won't apply. Restructure: show both sides as divisions: RHS = ((17/6)·‖s‖·mult)/(1+γ²) by ring (mul_div_assoc). So:\n\n```lean\n      have hR : 17 / 6 * ‖s‖ * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ))))\n          = (17 / 6 * ‖s‖ * (zeroMult ρ : ℝ)) / (1 + Complex.normSq (gammaOf (ρ:ℂ))) := by ring\n      rw [hR, div_le_div_iff₀ (by positivity : (0:ℝ) < ‖(ρ:ℂ)‖ ^ 2) hg0]\n      -- goal: 2*‖s‖*mult * (1+γ²) ≤ (17/6*‖s‖*mult) * ρ²\n      have hkey : 2 * (1 + Complex.normSq (gammaOf (ρ:ℂ))) ≤ 17 / 6 * ‖(ρ:ℂ)‖ ^ 2 := by\n        linarith [hcomp]  -- hcomp: 1+γ² ≤ 17/12 ρ² ⟹ 2(1+γ²) ≤ 17/6 ρ² ✓\n      calc 2 * ‖s‖ * (zeroMult ρ:ℝ) * (1 + Complex.normSq (gammaOf (ρ:ℂ)))\n          = (‖s‖ * (zeroMult ρ:ℝ)) * (2 * (1 + Complex.normSq (gammaOf (ρ:ℂ)))) := by ring\n        _ ≤ (‖s‖ * (zeroMult ρ:ℝ)) * (17 / 6 * ‖(ρ:ℂ)‖ ^ 2) :=\n            mul_le_mul_of_nonneg_left hkey (by positivity)\n        _ = 17 / 6 * ‖s‖ * (zeroMult ρ:ℝ) * ‖(ρ:ℂ)‖ ^ 2 := by ring\n```\npositivity for ‖s‖·mult ≥ 0 ✓ (Nat.cast_nonneg & norm_nonneg — positivity handles).\n\nThen wrap the calc: LHS of goal is `‖(zeroMult ρ : ℂ)‖ * (‖s‖ / (‖ρ‖ * ‖s−ρ‖))` after the rewrites — hmm actually after `rw [seriesTerm, halg, norm_mul, RCLike.norm_natCast, norm_div, norm_mul]` the goal is `(↑(zeroMult ρ) : ℝ) * (‖s‖ / (‖ρ‖ * ‖s − ρ‖)) ≤ ...`. Note RCLike.norm_natCast gives ‖(n:ℂ)‖ = (n:ℝ)? RCLike.norm_natCast : ‖(n : R)‖ = n where the RHS is (n : ℝ)? For ℂ: ‖(n:ℂ)‖ = ↑n ✓. In liSummand_norm: `rw [liSummand_eq n ρ, norm_mul, RCLike.norm_natCast]` then `RCLike.norm_ofReal` — so RCLike.norm_natCast : ‖(↑n : 𝕜)‖ = ↑n (into ℝ) ✓.\n\nHmm — but wait, does `norm_natCast` match `(zeroMult ρ : ℂ)` where zeroMult ρ : ℕ? The cast is ℕ → ℂ: ‖((zeroMult ρ : ℕ) : ℂ)‖ = ((zeroMult ρ : ℕ) : ℝ) ✓.\n\nBut hold on: in my calc chain the goal after rw has LHS `(zeroMult ρ : ℝ) * (‖s‖ / (‖ρ‖ * ‖s − ρ‖))` — my calc starts with exactly that ✓. Actually `norm_div` on `‖s / (ρ * (s−ρ))‖` gives ‖s‖ / ‖ρ*(s−ρ)‖ then norm_mul gives ‖ρ‖·‖s−ρ‖ ✓.\n\n§2:\n\n```lean\n/-! ## 2. Summability -/\n\n/-- The subtype elements in a closed ball form a finite set (the ii′-1a\ncompact-finiteness pattern). -/\nlemma finite_subtype_norm_lt (R : ℝ) :\n    {ρ : {ρ : ℂ // IsNontrivialZero ρ} | ‖(ρ : ℂ)‖ < R}.Finite := by\n  have hcomp : IsCompact (Metric.closedBall (0 : ℂ) R) := isCompact_closedBall _ _\n  have hzeros : (Metric.closedBall (0 : ℂ) R) ∩ {ρ : ℂ | IsNontrivialZero ρ}\n      ⊆ (Metric.closedBall (0 : ℂ) R) ∩ riemannZetaZeros := by\n    intro z hz\n    exact ⟨hz.1, hz.2.1⟩\n  have hfin2 := (hcomp.inter_riemannZetaZeros_finite).subset hzeros\n  have himg : (Subtype.val '' {ρ : {ρ // IsNontrivialZero ρ} | ‖(ρ : ℂ)‖ < R}).Finite := by\n    apply hfin2.subset\n    rintro z ⟨ρ, hρ, rfl⟩\n    refine ⟨?_, ρ.2⟩\n    simp only [Metric.mem_closedBall, dist_zero_right]\n    exact le_of_lt hρ\n  exact Set.Finite.of_finite_image himg (Subtype.val_injective.injOn)\n```\n\nWait — in liSummable the set was `{ρ : {ρ // IsNontrivialZero ρ} | ¬ ((2:ℝ)*n ≤ ‖(ρ:ℂ)‖)}` and the image-subset argument used `lt_of_not_ge hρ`. Mine: ‖ρ‖ < R directly ⟹ dist ≤ R: le_of_lt hρ where hρ : ‖ρ‖ < R ✓ — but hρ after rintro: `⟨ρ, hρ, rfl⟩` where hρ : ‖(ρ:ℂ)‖ < R (the set membership). ✓. Also note in liSummable the membership target included `ρ.2` for the {IsNontrivialZero} part ✓ same.\n\nHmm — one difference: liSummable's hfin2/himg used the set-builder on the SUBTYPE with the negated condition; the Set.Finite.of_finite_image with Subtype.val_injective.injOn — wait `Set.Finite.of_finite_image (hs : (f '' s).Finite) (hi : Set.InjOn f s) : s.Finite` ✓.\n\nMembership: `hz.2.1` where hz.2 : IsNontrivialZero z — as discussed hz.2.1 : riemannZeta z = 0 — and membership in riemannZetaZeros is .rfl ✓ (liSummable line 312: `exact ⟨hz.1, hz.2.1⟩` ✓ copy).\n\n```lean\n/-- The series is absolutely summable at every s (the ii′-1a D-trick:\ndominator (17/6)(‖s‖+1)·mult/(1+‖γ‖²), finite head inside ‖ρ‖ < R₀). -/\ntheorem seriesSummable (s : ℂ) :\n    Summable (fun ρ : {ρ : ℂ // IsNontrivialZero ρ} => seriesTerm s ρ) := by\n  set R₀ : ℝ := max 2 (2 * ‖s‖) with hR₀\n  have hR₀2 : (2 : ℝ) ≤ R₀ := le_max_left _ _\n  have hR₀s : 2 * ‖s‖ ≤ R₀ := le_max_right _ _\n  set C : ℝ := 17 / 6 * (‖s‖ + 1) with hC\n  have hbase : Summable (fun ρ : {ρ : ℂ // IsNontrivialZero ρ} =>\n      C * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ))))) :=\n    (WeilEF.zero_sum_inv_sq zetaSeam).mul_left C\n  set D : {ρ : ℂ // IsNontrivialZero ρ} → ℝ := fun ρ =>\n    if R₀ ≤ ‖(ρ : ℂ)‖ then\n      C * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ))))\n    else ‖seriesTerm s ρ‖ with hDdef\n  have hfin : {ρ : {ρ // IsNontrivialZero ρ} | ¬ (R₀ ≤ ‖(ρ : ℂ)‖)}.Finite := by\n    have := finite_subtype_norm_lt R₀\n    apply this.subset  -- hmm: {¬ R₀ ≤ ‖ρ‖} = {‖ρ‖ < R₀}: not_le: ¬(R₀ ≤ x) ↔ x < R₀ — defeq? not_le : ¬ a ≤ b ↔ b < a ✓ defeq? `not_le` is an iff (propext'd) — the SETS are equal by defeq of the membership? {x | ¬ R₀ ≤ ‖x‖} vs {x | ‖x‖ < R₀}: membership x ∈ {x | p x} is p x; p = ¬ R₀ ≤ ‖x‖ vs q = ‖x‖ < R₀: these are defeq (lt is DEFINED as ¬ ≤ in linear orders? x < y := x ≤ y ∧ ¬ y ≤ x in Mathlib's LT for ℝ?? ℝ's <: `lt_iff_le_not_ge`... For ℝ, a < b is defined via the LinearOrder instance — InstLT; Real.lt is defined as a ≤ b ∧ ¬ b ≤ a?? Actually Real's LT is defined directly (Real.lt := ...). Hmm risky. Use Set.Finite.subset with intro: `apply this.subset; intro ρ hρ; exact not_le.mp hρ` — subset direction: {¬ R₀ ≤ ‖ρ‖} ⊆ {‖ρ‖ < R₀}: not_le.mp ✓.\n  ...\n```\nCleaner: just call finite_subtype_norm_lt R₀ and subset via not_le.\n\nThen hE (D − base summable via finite support), hD, then Summable.of_norm_bounded hD with:\n```lean\n  refine Summable.of_norm_bounded D hD (fun ρ => ?_)\n  by_cases hρ : R₀ ≤ ‖(ρ : ℂ)‖\n  · simp only [D, if_pos hρ]\n    have h2 : (2:ℝ) ≤ ‖(ρ:ℂ)‖ := hR₀2.trans hρ\n    have hs2 : 2 * ‖s‖ ≤ ‖(ρ:ℂ)‖ := hR₀s.trans hρ\n    have h := seriesTerm_norm_le ρ h2 hs2\n    apply h.trans\n    -- (17/6)‖s‖·mult/(1+γ²) ≤ C·mult/(1+γ²): C = (17/6)(‖s‖+1)\n    rw [hC]  -- hmm hC : C = ... set already replaces. With `set`, C is substituted everywhere; use `show`. The dominator in D if_pos branch is C * (mult/(1+γ²)). Goal: 17/6*‖s‖*(mult/(1+γ²)) ≤ C*(mult/(1+γ²)).\n    -- Both as single divisions? D branch: C * (mult/(1+γ²)). seriesTerm_norm_le RHS: 17/6*‖s‖*(mult/(1+γ²)).\n    have hg0 : (0:ℝ) ≤ (zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ))) := by positivity\n    -- 17/6*‖s‖ ≤ 17/6*(‖s‖+1) = C\n    have hC' : 17 / 6 * ‖s‖ ≤ C := by rw [hC]; nlinarith [norm_nonneg s]  -- 17/6·‖s‖ ≤ 17/6·(‖s‖+1)\n    -- a * X ≤ b * X with X ≥ 0\n    calc 17 / 6 * ‖s‖ * ((zeroMult ρ:ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ))))\n        ≤ C * ((zeroMult ρ:ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ)))) :=\n          mul_le_mul_of_nonneg_right hC' hg0\n  · simp only [D, if_neg hρ, le_refl]\n```\nCareful with `set` and D's definition matching liSummable: in liSummable they used `set D ... with hDdef` and then `simp only [D, if_pos hρ]` — the set replaces occurrences; the D if-branch has C * (...) — but in liSummable they wrote the explicit constant (9/2)*(n:ℝ)^2 not a variable. With C a set-variable: hbase : Summable fun ρ => C * (...) ✓; hE : Summable fun ρ => D ρ − C*(...) via summable_of_hasFiniteSupport with support ⊆ {¬ R₀ ≤ ‖ρ‖}: for ρ ∉ support... the proof:\n```lean\n  have hE : Summable (fun ρ : {ρ // IsNontrivialZero ρ} =>\n      D ρ - C * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ))))) := by\n    apply summable_of_hasFiniteSupport\n    apply hfin.subset\n    intro ρ hρ\n    simp only [Function.mem_support, ne_eq] at hρ\n    by_contra hball\n    apply hρ\n    have hball' : R₀ ≤ ‖(ρ : ℂ)‖ := not_not.mp hball\n    simp only [D, if_pos hball']\n    ring\n```\n✓ (mirrors liSummable lines 322–333).\n\nhD:\n```lean\n  have hD : Summable D := by\n    have hsum := hbase.add hE\n    have heq : (fun ρ : {ρ // IsNontrivialZero ρ} =>\n        C * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ)))) +\n          (D ρ - C * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ)))))) = D := by\n      funext ρ\n      ring\n    rw [heq] at hsum\n    exact hsum\n```\n✓ mirrors.\n\nHmm wait — in liSummable, `Summable.of_norm_bounded hD (fun ρ => ?_)` — signature: `Summable.of_norm_bounded (hg : Summable g) (h : ∀ i, ‖f i‖ ≤ g i) : Summable f`? Let me double check argument order: liSummable line 344: `refine Summable.of_norm_bounded hD (fun ρ => ?_)` — goal after refine: ∀ ρ... they did `fun ρ => ?_` so signature (f := _) (g := D) (hg : Summable D) (hfg : ∀ i, ‖f i‖ ≤ D i)? Wait: `Summable.of_norm_bounded {f g : ι → α} (hg : Summable g) (hfg : ∀ i, ‖f i‖ ≤ g i) : Summable f`? Hmm but then `refine Summable.of_norm_bounded hD (fun ρ => ?_)` leaves goal `‖seriesTerm s ρ‖ ≤ D ρ` ✓ matches. But there might be a Real requirement: g : ι → ℝ — `Summable.of_norm_bounded` for real g: yes `Summable.of_norm_bounded (hg : Summable g) (h : ∀ i, ‖f i‖ ≤ g i)` requires g real-valued I think (or NormedField). D is ℝ-valued ✓.\n\nAlso check: in liSummable the goal was Summable (liSummand n) — the def; here Summable (fun ρ => seriesTerm s ρ) — I'll state seriesSummable as Summable (seriesTerm s)?? seriesTerm s : subtype → ℂ ✓ can state `Summable (seriesTerm s)`. Hmm but with `refine Summable.of_norm_bounded hD ...` the f is inferred from goal ✓.\n\n§4:\n\n```lean\n/-! ## 3. Balls avoiding the nontrivial zeros -/\n\n/-- Around any point that is not a nontrivial zero there is a ball\ncontaining no nontrivial zero: continuity where ζ s₀ ≠ 0; the order\nnormal form where ζ s₀ = 0, s₀ ≠ 1; the zetaA factorization at s₀ = 1. -/\nlemma exists_ball_avoid_nontrivialZeros (s₀ : ℂ) (hs₀ : ¬ IsNontrivialZero s₀) :\n    ∃ δ : ℝ, 0 < δ ∧ ∀ ρ : {ρ : ℂ // IsNontrivialZero ρ}, (ρ : ℂ) ∉ Metric.ball s₀ δ := by\n  by_cases h1 : s₀ = 1\n  · subst h1\n    obtain ⟨ε, hε, hball⟩ := Metric.eventually_nhds_iff_ball.mp zetaA_ne_zero_near_one\n    refine ⟨ε, hε, fun ρ hρ => ?_⟩\n    -- ρ nontrivial zero in ball(1, ε): ρ ≠ 1 (re < 1), zetaA ρ = (ρ−1)ζ ρ = 0 contra hball\n    have hρ1 : (ρ : ℂ) ≠ 1 := by\n      intro h\n      have : (ρ : ℂ).re < 1 := ρ.2.2.2\n      rw [h] at this\n      simp at this  -- this : (1:ℂ).re < 1 → re 1 = 1: 1 < 1 false: `rw [Complex.one_re] at this; exact lt_irrefl _ this`? simp should close: Complex.one_re is simp. Use: rw [h, Complex.one_re] at this; exact lt_irrefl 1 this.\n    have hz := hball (ρ : ℂ) hρ\n    rw [zetaA_apply hρ1] at hz  -- zetaA ρ = (ρ−1)·ζ ρ\n    rw [ρ.2.1, mul_zero] at hz  -- ζ ρ = 0: ρ.2.1 : riemannZeta ↑ρ = 0 ✓\n    exact hz rfl\n  · by_cases h0 : riemannZeta s₀ = 0\n    · -- NF\n      obtain ⟨h, hh, hh0, hfh⟩ :=\n        (analyticAt_riemannZeta h1).analyticOrderAt_ne_top.mp (zeta_order_ne_top_of_ne h1)\n      obtain ⟨ε₁, hε₁, hball₁⟩ := Metric.eventually_nhds_iff_ball.mp\n        (hh.continuousAt.eventually_ne hh0)\n      obtain ⟨ε₂, hε₂, hball₂⟩ := Metric.eventually_nhds_iff_ball.mp hfh\n      refine ⟨min ε₁ ε₂, lt_min hε₁ hε₂, fun ρ hρ => ?_⟩\n      -- ρ ∈ ball s₀ (min ε₁ ε₂): ζ ρ = (ρ−s₀)^m • h ρ\n      have hmem1 : (ρ : ℂ) ∈ Metric.ball s₀ ε₁ := Metric.ball_subset_ball (min_le_left _ _) hρ\n      have hmem2 : (ρ : ℂ) ∈ Metric.ball s₀ ε₂ := Metric.ball_subset_ball (min_le_right _ _) hρ\n      have heq := hball₂ (ρ : ℂ) hmem2  -- ζ ρ = (ρ − s₀)^m • h ρ\n      have hne : h (ρ : ℂ) ≠ 0 := hball₁ (ρ : ℂ) hmem1\n      have hpow : ((ρ : ℂ) - s₀) ^ analyticOrderNatAt riemannZeta s₀ ≠ 0 ∨ ... \n      -- need: either ρ = s₀ (then contra hs₀) or pow ≠ 0\n      by_cases hρs : (ρ : ℂ) = s₀\n      · rw [hρs] at hs₀? no: ρ nontrivial, ρ = s₀ ⟹ IsNontrivialZero s₀: exact hs₀ (hρs ▸ ρ.2)\n      · have hpow : ((ρ : ℂ) - s₀) ^ analyticOrderNatAt riemannZeta s₀ ≠ 0 :=\n          pow_ne_zero _ (sub_ne_zero.mpr hρs)\n        have hz : riemannZeta (ρ : ℂ) ≠ 0 := by\n          rw [heq, smul_eq_mul]  -- (pow • h ρ): smul_eq_mul\n          exact mul_ne_zero hpow hne\n        exact hz ρ.2.1\n    · -- continuity\n      obtain ⟨ε, hε, hball⟩ := Metric.eventually_nhds_iff_ball.mp\n        ((analyticAt_riemannZeta h1).continuousAt.eventually_ne h0)\n      refine ⟨ε, hε, fun ρ hρ => ?_⟩\n      exact hball (ρ : ℂ) hρ ρ.2.1\n```\n\nCheck details:\n- `zetaA_ne_zero_near_one : ∀ᶠ w in 𝓝 (1:ℂ), zetaA w ≠ 0` ✓ (LiResidue line 81).\n- After subst h1, s₀ replaced by 1 ✓.\n- ρ.2.2.2 : (ρ:ℂ).re < 1: ρ.2 : ζ ρ = 0 ∧ 0 < re ∧ re < 1: ρ.2.2.2... ρ.2.2 : 0 < re ∧ re < 1? Hmm: And association: a ∧ b ∧ c = a ∧ (b ∧ c): ρ.2.1 : a = ζ ρ = 0; ρ.2.2 : b ∧ c; ρ.2.2.1?? Accessing nested: ρ.2.2.1 = (b ∧ c).1 = b? Wait — .2.2 is (ρ.2).2 : b ∧ c. Then .2.2.1 : b, .2.2.2 : c. Hmm but earlier in liSummand_norm_le: hz.2.1.le : 0 ≤ re where hz = ρ.2 : hz.2 : b ∧ c... hz.2.1 : (b ∧ c).1 = b = 0 < re ✓ .le : 0 ≤ ✓. And hz.2.2.le : re ≤ 1: hz.2.2 : c = re < 1 ✓. So: ρ.2.1 : ζ ρ = 0; ρ.2.2.1 : 0 < re; ρ.2.2.2 : re < 1. In my draft above I wrote `ρ.2.2.2` for re < 1 ✓ and `ρ.2.1` for ζ ρ = 0 ✓. But careful — earlier in finite_subtype_norm_lt I wrote `hz.2.1` for the riemannZetaZeros membership where hz : z ∈ closedBall ∧ IsNontrivialZero z: hz.2 : IsNontrivialZero z; hz.2.1 : ζ z = 0 ✓ consistent.\n\n- For `rw [h] at this` where this : (ρ:ℂ).re < 1 and h : (ρ:ℂ) = 1: gives (1:ℂ).re < 1; then `simp at this`: Complex.one_re : (1:ℂ).re = 1 — simp reduces to 1 < 1 = False, closes goal? `simp at this` with this : 1 < 1 → this becomes False → closes any goal ✓ (simp at this with False closes). OK.\n- `Metric.ball_subset_ball : ε₁ ≤ ε₂ → ball x ε₁ ⊆ ball x ε₂` ✓ exists. Membership: hρ : (ρ:ℂ) ∈ ball s₀ (min ε₁ ε₂); ball_subset_ball (min_le_left ε₁ ε₂) hρ — hρ needs coercion to set membership ✓ fine.\n- heq : riemannZeta (ρ:ℂ) = ((ρ:ℂ) − s₀) ^ analyticOrderNatAt riemannZeta s₀ • h (ρ:ℂ). hball₂ : ∀ y ∈ ball s₀ ε₂, riemannZeta y = ... ✓ (hfh is =ᶠ[𝓝 s₀]: eventually_nhds_iff_ball.mp gives ∃ ε > 0, ∀ y ∈ ball, f y = g y ✓).\n- smul_eq_mul ✓.\n- hρs ▸ ρ.2: ρ.2 : IsNontrivialZero (ρ:ℂ); hρs : (ρ:ℂ) = s₀; hρs ▸ ρ.2 : IsNontrivialZero s₀ ✓ (▸ direction: rewrites (ρ:ℂ) to s₀ in the type ✓).\n- continuity case: hball : ∀ y ∈ ball s₀ ε, riemannZeta y ≠ 0 ✓; exact hball (ρ:ℂ) hρ ρ.2.1 : hball ... : ζ ρ ≠ 0 applied to ρ.2.1 : ζ ρ = 0 gives False, goal is (ρ:ℂ) ∉ ball — wait! The goal is `(ρ:ℂ) ∉ Metric.ball s₀ δ` and hρ : (ρ:ℂ) ∈ ball... I wrote `fun ρ hρ => ?_` — hρ : (ρ:ℂ) ∈ Metric.ball s₀ δ ✓, goal False? No — goal after intro ρ hρ: the statement ∀ ρ, (ρ:ℂ) ∉ ball — `fun ρ hρ => ?_` with hρ : ∈ ball, then goal is False (∉ unfolds to ¬ ∈ = ∈ → False). ✓ So exact hz ρ.2.1 where hz : ζ ρ ≠ 0, ρ.2.1 : ζ ρ = 0 ⟹ False ✓. In zetaA case: exact hz rfl where hz : zetaA ρ = 0 → False... wait hz := hball ρ hρ : zetaA ρ ≠ 0; after rw [zetaA_apply hρ1, ρ.2.1, mul_zero] at hz: hz : (0:ℂ) ≠ 0; exact hz rfl ✓.\n\nHmm — `rw [ρ.2.1, mul_zero] at hz`: hz : (ρ − 1)·ζ ρ ≠ 0 — rw ρ.2.1 : ζ ρ = 0 at hz: hz : (ρ−1)*0 ≠ 0; rw [mul_zero] at hz: hz : (0:ℂ) ≠ 0 ✓. But wait — after rw [zetaA_apply hρ1] at hz, hz : (ρ−1) * riemannZeta ρ ≠ 0 ✓.\n\nNow §4 analyticity:\n\n```lean\n/-! ## 4. Analyticity off the zeros -/\n\n/-- The M-test majorant on a ball avoiding the zeros. -/\nlemma seriesTerm_summable_majorant (M : ℝ) :\n    Summable (fun ρ : {ρ : ℂ // IsNontrivialZero ρ} =>\n      17 / 6 * M * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ))))) :=\n  (WeilEF.zero_sum_inv_sq zetaSeam).mul_left _\n\ntheorem seriesFun_analyticAt {s₀ : ℂ} (hs₀ : ¬ IsNontrivialZero s₀) :\n    AnalyticAt ℂ seriesFun s₀ := by\n  obtain ⟨δ, hδ, hball⟩ := exists_ball_avoid_nontrivialZeros s₀ hs₀\n  set M : ℝ := ‖s₀‖ + δ with hM\n  set R₀ : ℝ := max 2 (2 * M) with hR₀\n  -- the dominator\n  set u : {ρ : ℂ // IsNontrivialZero ρ} → ℝ := fun ρ =>\n    17 / 6 * M * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ)))) with hu\n  have hsum_u : Summable u := seriesTerm_summable_majorant M\n  -- the eventual bound\n  have hfu : ∀ᶠ ρ in cofinite, ∀ s ∈ Metric.ball s₀ δ, ‖seriesTerm s ρ‖ ≤ u ρ := by\n    rw [Filter.mem_cofinite]  -- hmm: ∀ᶠ in cofinite ↔ the set of good ρ is cofinite; use Filter.eventually_cofinite: (∀ᶠ x in cofinite, p x) ↔ {x | p x}ᶜ.Finite? There's `Filter.eventually_cofinite : (∀ᶠ x in cofinite, p x) ↔ {x | ¬ p x}.Finite`. Use that.\n    ...\n```\n`Filter.eventually_cofinite : (∀ᶠ x ∈ cofinite? ...)`: statement `Filter.eventually_cofinite {p : α → Prop} : (∀ᶠ x in cofinite, p x) ↔ {x | ¬p x}.Finite` — exists? I believe yes. Then show {ρ | ¬ ∀ s ∈ ball, ...}.Finite ⊆ {ρ | ‖ρ‖ < R₀} finite: if ‖ρ‖ ≥ R₀ then the bound holds: need ¬(∀...) ⟹ ‖ρ‖ < R₀ — i.e. prove {ρ | ¬P ρ} ⊆ {ρ | ‖ρ‖ < R₀} then .subset.\n\nFor ρ with R₀ ≤ ‖ρ‖, prove P ρ: ∀ s ∈ ball, ‖seriesTerm s ρ‖ ≤ u ρ:\n- h2 : 2 ≤ ‖ρ‖ (max_left trans)\n- s ∈ ball s₀ δ: ‖s‖ ≤ ‖s₀‖ + δ = M: ‖s‖ = ‖(s − s₀) + s₀‖ ≤ ‖s−s₀‖ + ‖s₀‖ < δ + ‖s₀‖: from mem_ball: dist s s₀ < δ: dist_eq_norm: ‖s − s₀‖ < δ ✓; so ‖s‖ < M hence ≤.\n- 2‖s‖ ≤ 2M ≤ R₀ ≤ ‖ρ‖ ✓ (max_right).\n- seriesTerm_norm_le ρ h2 hs2 : ‖term‖ ≤ 17/6·‖s‖·mult/(1+γ²).\n- ≤ 17/6·M·mult/(1+γ²) = u ρ: since ‖s‖ ≤ M and the other factor ≥ 0: \n  17/6*‖s‖*(mult/(1+γ²)) ≤ 17/6*M*(mult/(1+γ²)): mul_le_mul_of_nonneg_right (by nlinarith/linarith: 17/6·‖s‖ ≤ 17/6·M) (positivity) ✓.\n\n- Then:\n```lean\n  have hu' : HasSumUniformlyOn (fun ρ => fun s : ℂ => seriesTerm s ρ)\n      (fun s => ∑' ρ, seriesTerm s ρ) (Metric.ball s₀ δ) :=\n    HasSumUniformlyOn.of_norm_le_summable_eventually hsum_u hfu\n  have htend : TendstoLocallyUniformlyOn\n      (fun t : Finset {ρ : ℂ // IsNontrivialZero ρ} => fun s => ∑ ρ ∈ t, seriesTerm s ρ)\n      (fun s => ∑' ρ, seriesTerm s ρ) atTop (Metric.ball s₀ δ) :=\n    TendstoUniformlyOn.tendstoLocallyUniformlyOn\n      (hasSumUniformlyOn_iff_tendstoUniformlyOn.mp hu')\n  have hdiff : DifferentiableOn ℂ (fun s => ∑' ρ, seriesTerm s ρ) (Metric.ball s₀ δ) := by\n    apply htend.differentiableOn _ isOpen_ball\n    apply Filter.Eventually.of_forall\n    intro t s hs\n    rw [show (fun s => ∑ ρ ∈ t, seriesTerm s ρ) = ∑ ρ ∈ t, (fun s => seriesTerm s ρ) from by\n      funext s; simp [Finset.sum_apply]]\n    apply DifferentiableAt.differentiableWithinAt\n    apply DifferentiableAt.sum\n    intro ρ hρ\n    -- each term differentiable at s: s ≠ ρ (ball avoids zeros), ρ ≠ 0\n    have hsρ : s - (ρ : ℂ) ≠ 0 := by\n      have hρout : (ρ : ℂ) ∉ Metric.ball s₀ δ := hball ρ\n      intro h\n      apply hρout\n      -- s − ρ = 0 ⟹ ρ = s ∈ ball\n      have : (ρ : ℂ) = s := sub_eq_zero.mp h  -- h : s − ρ = 0 ⟹ s = ρ: sub_eq_zero : s − ρ = 0 ↔ s = ρ: gives s = ρ: then ρ = s via .symm\n      rw [← this]  -- hmm: want ρ ∈ ball: rw this: ρ ↦ s: goal s ∈ ball: exact hs\n      exact hs  -- wait membership: hs : s ∈ ball s₀ δ from DifferentiableOn intro\n    have hρ0 : (ρ : ℂ) ≠ 0 := by\n      intro h\n      have := ρ.2.2.1  -- 0 < (ρ:ℂ).re\n      rw [h] at this\n      simp at this  -- (0:ℂ).re < ... : 0 < 0 false\n    have h1 : DifferentiableAt ℂ (fun s : ℂ => 1 / (s - (ρ : ℂ))) s :=\n      (differentiableAt_const (1 : ℂ)).div\n        (differentiableAt_id.sub (differentiableAt_const _)) hsρ\n    have h2 : DifferentiableAt ℂ (fun s : ℂ => 1 / (ρ : ℂ)) s := differentiableAt_const _\n    show DifferentiableAt ℂ (fun s => (zeroMult ρ : ℂ) * (1 / (s - (ρ : ℂ)) + 1 / (ρ : ℂ))) s\n    exact (h1.add h2).const_mul _\n```\nHmm — the goal after `apply DifferentiableAt.sum; intro ρ hρ` is `DifferentiableAt ℂ (fun s => seriesTerm s ρ) s`? Actually DifferentiableAt.sum signature: `DifferentiableAt.sum (h : ∀ i ∈ t, DifferentiableAt ℂ (f i) x) : DifferentiableAt ℂ (∑ i ∈ t, f i) x`? In LiDigamma: `apply DifferentiableAt.sum; intro m hm; ...exact h1.sub h2` where the goal was DifferentiableAt ℂ (fun s => dpsiTermC s m) s and they proved it via pieces with `show` implicit. dpsiTermC was a def — the goal displayed as the def but reducible. For me: goal DifferentiableAt ℂ (fun s => seriesTerm s ρ) s; seriesTerm is a def — `(h1.add h2).const_mul _` has type DifferentiableAt ℂ (fun s => mult * (1/(s−ρ) + 1/ρ))?? `.const_mul : DifferentiableAt ℂ f x → DifferentiableAt ℂ (fun y => c * f y) x` gives fun s => c * (1/(s−ρ)+1/ρ) — with c = (zeroMult ρ : ℂ): matches seriesTerm s ρ up to def-unfolding: need `show DifferentiableAt ℂ (fun s => (zeroMult ρ : ℂ) * (1 / (s - (ρ:ℂ)) + 1 / (ρ:ℂ))) s` first (defeq unfold) ✓.\n\nAlso `intro t s hs` — the Eventually goal: ∀ᶠ t in atTop, DifferentiableOn ℂ (fun s => ∑ ρ∈t, seriesTerm s ρ) (ball): `Filter.Eventually.of_forall; intro t` then goal DifferentiableOn ...; DifferentiableOn is ∀ s ∈ ball, DifferentiableWithinAt: `intro s hs` ✓ (LiDigamma did `intro t s hs` after of_forall ✓).\n\n- Then:\n```lean\n  have han : AnalyticOnNhd ℂ (fun s => ∑' ρ, seriesTerm s ρ) (Metric.ball s₀ δ) :=\n    hdiff.analyticOnNhd isOpen_ball\n  -- AnalyticAt at s₀: han s₀ (mem_ball_self hδ) : AnalyticAt ℂ (fun s => ∑' ...) s₀\n  -- and seriesFun = fun s => ∑' ρ, seriesTerm s ρ by rfl\n  exact han s₀ (Metric.mem_ball_self hδ)\n```\nWait — AnalyticOnNhd ℂ f s = ∀ x ∈ s, AnalyticAt ℂ f x: `han s₀ (mem)` : AnalyticAt ℂ (fun s => ∑' ρ, seriesTerm s ρ) s₀. Goal: AnalyticAt ℂ seriesFun s₀. seriesFun s₀ := ∑' ρ, seriesTerm s₀ ρ — but AnalyticAt ℂ f x with f = the lambda vs f = seriesFun: these are different functions (seriesFun is a def whose unfolding gives the lambda). AnalyticAt ℂ seriesFun s₀ — the lambda `fun s => ∑' ρ, seriesTerm s ρ` is DEFEQ to seriesFun (funext-free: seriesFun unfolds to fun s => ∑' ρ, seriesTerm s ρ ✓ definitionally). So `exact han s₀ hmem` should typecheck by defeq ✓ (like DinfC in LiDigamma — they did need a funext rw for the Pi.add form, but plain def unfolding is defeq).\n\n```lean\n/-- The series is analytic on the complement of the nontrivial zeros. -/\ntheorem seriesFun_analyticOnNhd :\n    AnalyticOnNhd ℂ seriesFun {s : ℂ | ¬ IsNontrivialZero s} :=\n  fun s₀ hs₀ => seriesFun_analyticAt hs₀\n```\n\n§5:\n\n```lean\n/-! ## 5. Isolation and the reduced series -/\n\n/-- Each nontrivial zero is isolated from the others (finiteness in\ncompact balls + minimum distance). -/\ntheorem nontrivialZero_isolated (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) :\n    ∃ δ : ℝ, 0 < δ ∧ ∀ ρ₁ : {ρ : ℂ // IsNontrivialZero ρ}, ρ₁ ≠ ρ₀ →\n      δ ≤ ‖(ρ₁ : ℂ) - (ρ₀ : ℂ)‖ := by\n  -- the nontrivial zeros in closedBall ρ₀ 1 form a finite set\n  have hcomp : IsCompact (Metric.closedBall (ρ₀ : ℂ) 1) := isCompact_closedBall _ _\n  have hzeros : (Metric.closedBall (ρ₀ : ℂ) 1) ∩ {ρ : ℂ | IsNontrivialZero ρ}\n      ⊆ (Metric.closedBall (ρ₀ : ℂ) 1) ∩ riemannZetaZeros := by\n    intro z hz\n    exact ⟨hz.1, hz.2.1⟩\n  have hfin : ((Metric.closedBall (ρ₀ : ℂ) 1) ∩ {ρ : ℂ | IsNontrivialZero ρ}).Finite :=\n    (hcomp.inter_riemannZetaZeros_finite).subset hzeros\n  -- as a finset of subtype elements (excluding ρ₀)\n  set S : Set {ρ : ℂ // IsNontrivialZero ρ} :=\n    {ρ | (ρ : ℂ) ∈ Metric.closedBall (ρ₀ : ℂ) 1 ∧ ρ ≠ ρ₀} with hS\n  have hSfin : S.Finite := by\n    have himg : (Subtype.val '' S).Finite := by\n      apply hfin.subset\n      rintro z ⟨ρ, ⟨hρ, -⟩, rfl⟩\n      exact ⟨hρ, ρ.2⟩\n    exact Set.Finite.of_finite_image himg (Subtype.val_injective.injOn)\n  by_cases hne : S.Nonempty\n  · -- δ = (min distance)/2\n    set d : Finset ℝ := hSfin.toFinset.image (fun ρ => ‖(ρ : ℂ) - (ρ₀ : ℂ)‖) with hd\n    have hdne : d.Nonempty := by\n      obtain ⟨ρ, hρ⟩ := hne\n      refine ⟨‖(ρ : ℂ) - (ρ₀ : ℂ)‖, ?_⟩\n      simp only [hd, Finset.mem_image, Set.Finite.mem_toFinset]\n      exact ⟨ρ, hρ, rfl⟩\n    have hdpos : ∀ x ∈ d, 0 < x := by\n      intro x hx\n      simp only [hd, Finset.mem_image, Set.Finite.mem_toFinset] at hx\n      obtain ⟨ρ, hρ, rfl⟩ := hx\n      have h1 : (ρ : ℂ) ≠ (ρ₀ : ℂ) := fun h => hρ.2 (Subtype.ext h)\n      exact norm_pos_iff.mpr (sub_ne_zero.mpr h1)\n    refine ⟨d.min' hdne / 2, by positivity?, fun ρ₁ hρ₁ => ?_⟩\n    · positivity needs d.min' hdne > 0: hdpos _ (d.min'_mem hdne): have := hdpos _ (d.min'_mem hdne); positivity? no — positivity can't use hypotheses. `exact half_pos (hdpos _ (Finset.min'_mem _ _))`... half_pos : 0 < a/2? `half_pos (h : 0 < a) : 0 < a / 2` ✓.\n    · by_cases hmem : (ρ₁ : ℂ) ∈ Metric.closedBall (ρ₀ : ℂ) 1\n      · -- ρ₁ ∈ S ⟹ its distance ∈ d ≥ min'\n        have h1 : ρ₁ ∈ S := ⟨hmem, hρ₁⟩\n        have h2 : ‖(ρ₁ : ℂ) - (ρ₀ : ℂ)‖ ∈ d := by\n          simp only [hd, Finset.mem_image, Set.Finite.mem_toFinset]\n          exact ⟨ρ₁, h1, rfl⟩\n        have h3 : d.min' hdne ≤ ‖(ρ₁ : ℂ) - (ρ₀ : ℂ)‖ := Finset.min'_le _ _ h2\n        linarith [hdpos _ (Finset.min'_mem _ _)]\n      · -- outside the ball: dist ≥ 1 ≥ min'/2 (min' ≤ 1 since distances in the ball ≤ 1)\n        have h4 : 1 ≤ ‖(ρ₁ : ℂ) - (ρ₀ : ℂ)‖ := by\n          have : (1 : ℝ) ≤ dist (ρ₁ : ℂ) (ρ₀ : ℂ) := by\n            by_contra h\n            apply hmem\n            rw [Metric.mem_closedBall]\n            exact le_of_lt (not_le.mp h)\n          rwa [dist_eq_norm] at this\n        -- min' ≤ 1: min' ∈ d comes from a ball element: any element of d is ≤ 1\n        have h5 : d.min' hdne ≤ 1 := by\n          have hm := Finset.min'_mem d hdne\n          simp only [hd, Finset.mem_image, Set.Finite.mem_toFinset] at hm\n          obtain ⟨ρ, hρ, rfl⟩ := hm\n          rw [Metric.mem_closedBall, dist_eq_norm] at hρ  -- hρ.1 : dist ≤ 1\n          -- hρ : (ρ:ℂ) ∈ closedBall ∧ ρ ≠ ρ₀; hρ.1 : dist (ρ:ℂ) ρ₀ ≤ 1: dist_eq_norm: ‖ρ − ρ₀‖ ≤ 1 ✓\n          exact hρ.1\n        linarith\n  · refine ⟨1 / 2, by norm_num, fun ρ₁ hρ₁ => ?_⟩\n    by_contra h\n    push_neg at h  -- h : ‖ρ₁ − ρ₀‖ < 1/2\n    apply hne  -- S nonempty: ρ₁ ∈ S\n    -- ρ₁ ∈ S: dist < 1/2 < 1 ⟹ in closedBall; ≠ ρ₀ ✓\n    exact ⟨ρ₁, ⟨by rw [Metric.mem_closedBall, dist_eq_norm]; linarith, hρ₁⟩⟩... \n    -- hne : ¬ S.Nonempty: apply hne: goal S.Nonempty: exact ⟨ρ₁, hSmem⟩: Set.Nonempty def: ∃ x, x ∈ S: ⟨ρ₁, ...⟩: S membership is the pair ✓\n```\nCareful: `by_contra h` on goal `1/2 ≤ ‖ρ₁ − ρ₀‖`: push_neg gives ‖…‖ < 1/2 ✓. Then S.Nonempty ⟨ρ₁, hmem_pair⟩ where hmem_pair : (ρ₁:ℂ) ∈ closedBall ∧ ρ₁ ≠ ρ₀ ✓; hne : ¬S.Nonempty — apply hne then exact the Nonempty... `exact hne ⟨ρ₁, ...⟩` ✓.\n\nHmm — `Set.Finite.mem_toFinset` needs the set to match hSfin.toFinset: membership ρ ∈ hSfin.toFinset ↔ ρ ∈ S ✓ via Set.Finite.mem_toFinset (hSfin : S.Finite) — as a simp lemma it fires as written? `Set.Finite.mem_toFinset (hs : s.Finite) : x ∈ hs.toFinset ↔ x ∈ s` — in simp only I should write `Set.Finite.mem_toFinset` and it rewrites `x ∈ hSfin.toFinset` to `x ∈ S` — but d was defined with hSfin.toFinset ✓.\n\nOne concern: `simp only [hd, Finset.mem_image, Set.Finite.mem_toFinset]` — hd is a `set` equation: simp only [hd]?? With `set ... with hd`, hd : d = hSfin.toFinset.image ... — simp only [hd] rewrites d → the image ✓ then mem_image ✓ then mem_toFinset ✓. Wait actually with `set`, occurrences of the image-finset get replaced by d in the goal — the goal has d; simp [hd] rewrites d back. But `set` also abstracts... fine, this pattern works (banked in previous files presumably).\n\nAlternative simpler for h2/hmem: `Finset.mem_image.mpr ⟨ρ₁, by rwa [Set.Finite.mem_toFinset], rfl⟩`. I'll use explicit .mpr forms to be safe.\n\n- reduced series:\n```lean\n/-- The reduced summand: the ρ₀-term zeroed out. -/\ndef seriesTermSub (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ)\n    (ρ : {ρ : ℂ // IsNontrivialZero ρ}) : ℂ :=\n  if ρ = ρ₀ then 0 else seriesTerm s ρ\n\n/-- The reduced series (the ρ₀ polar term removed): analytic AT ρ₀. -/\ndef seriesFunSub (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) : ℂ :=\n  ∑' ρ : {ρ : ℂ // IsNontrivialZero ρ}, seriesTermSub ρ₀ s ρ\n\nlemma seriesTermSub_norm_le (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ)\n    (ρ : {ρ : ℂ // IsNontrivialZero ρ}) : ‖seriesTermSub ρ₀ s ρ‖ ≤ ‖seriesTerm s ρ‖ := by\n  by_cases h : ρ = ρ₀ <;> simp [seriesTermSub, h]\n\ntheorem seriesTermSub_summable (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) :\n    Summable (seriesTermSub ρ₀ s) :=\n  Summable.of_norm_bounded (seriesSummable s) (fun ρ => seriesTermSub_norm_le ρ₀ s ρ)\n```\nWait — Summable.of_norm_bounded with g = seriesTerm s (ℂ-valued) — fine (norm_bounded works for any normed g? signature: (hg : Summable g) (h : ∀ i, ‖f i‖ ≤ g i) — hmm if g is ℂ-valued then g i : ℂ but ‖f i‖ : ℝ ≤ g i : ℂ — type error! of_norm_bounded requires g : ι → ℝ. seriesTerm s is ℂ-valued! So this fails. Options: g := fun ρ => ‖seriesTerm s ρ‖: Summable (fun ρ => ‖seriesTerm s ρ‖) — from seriesSummable: `Summable.norm`? `Summable.norm (hf : Summable f) : Summable (fun i => ‖f i‖)` ✓ exists. So:\n```lean\n  Summable.of_norm_bounded (seriesSummable s).norm (fun ρ => seriesTermSub_norm_le ρ₀ s ρ)\n```\n✓.\n\nThen the pointwise split:\n```lean\nlemma seriesTerm_add_single (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) :\n    (fun ρ => seriesTerm s ρ) =\n      (fun ρ => seriesTermSub ρ₀ s ρ) + (fun ρ => if ρ = ρ₀ then seriesTerm s ρ else 0) := by\n  funext ρ\n  by_cases h : ρ = ρ₀ <;> simp [seriesTermSub, h]\n\nlemma single_summable (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) :\n    Summable (fun ρ => if ρ = ρ₀ then seriesTerm s ρ else (0 : ℂ)) := by\n  apply summable_of_hasFiniteSupport\n  apply (Set.finite_singleton ρ₀).subset\n  intro ρ hρ\n  simp only [Function.mem_support, ne_eq] at hρ\n  by_contra h\n  apply hρ\n  simp [h]  -- ρ = ρ₀? h : ¬ ρ = ρ₀... wait: support membership: f ρ ≠ 0; want ρ ∈ {ρ₀}: by_contra h : ρ ∉ {ρ₀} i.e. ρ ≠ ρ₀ (Set.mem_singleton_iff): then if_neg: f ρ = 0 contra.\n```\nHmm: goal after intro ρ hρ: ρ ∈ {ρ₀} (singleton set membership = ρ = ρ₀?). {ρ₀} as Set of the subtype: membership ρ ∈ ({ρ₀} : Set _) ↔ ρ = ρ₀ via Set.mem_singleton_iff — is it defeq? Set.singleton membership: ρ ∈ {ρ₀} is ρ = ρ₀ definitionally? `{a} : Set α := insert a ∅`; membership: insert def: x ∈ insert a s ↔ x = a ∨ x ∈ s... not defeq to equality cleanly. Use: `by_contra h; rw [Set.mem_singleton_iff] at h`? Wait direction: goal ρ ∈ {ρ₀}; by_contra h : ¬ ρ ∈ {ρ₀}; then f ρ = 0: if_neg (fun heq => h (Set.mem_singleton_iff.mpr heq))... let me write:\n```lean\n  apply summable_of_hasFiniteSupport ((Set.finite_singleton ρ₀).subset ?_)\n  intro ρ hρ\n  by_contra h\n  rw [Function.mem_support, ne_eq] at hρ\n  apply hρ\n  rw [if_neg (fun he => h (Set.mem_singleton_iff.mpr he))]\n```\nHmm — cleaner pattern from liSummable's hE: they did\n```lean\n    apply summable_of_hasFiniteSupport\n    apply hfin.subset\n    intro ρ hρ\n    simp only [Function.mem_support, ne_eq] at hρ\n    by_contra hball\n    apply hρ\n    ...\n```\nwhere the subset goal was support ⊆ finite-set. So here: subset target: Function.support f ⊆ {ρ₀}: intro ρ hρ (hρ : ρ ∈ support f: f ρ ≠ 0); goal ρ ∈ {ρ₀}: by_contra h; apply hρ; show f ρ = 0: if_neg: needs ρ ≠ ρ₀: from h : ¬ ρ ∈ {ρ₀}: Set.mem_singleton_iff.not...: `fun he => h (Set.mem_singleton_iff.mpr he)` : ρ ≠ ρ₀... wait he : ρ = ρ₀; Set.mem_singleton_iff.mpr he : ρ ∈ {ρ₀} ✓ contra h ✓. Then `simp only [if_neg that]` closes f ρ = 0. ✓.\n\n```lean\n/-- Pointwise split: seriesFun = seriesFunSub + the ρ₀-term (everywhere). -/\nlemma seriesFun_eq_sub_add (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) :\n    seriesFun s = seriesFunSub ρ₀ s + seriesTerm s ρ₀ := by\n  have h1 : seriesFun s = ∑' ρ, (seriesTermSub ρ₀ s ρ + (if ρ = ρ₀ then seriesTerm s ρ else 0)) := by\n    rw [seriesFun]  -- unfold; then congr via funext\n    congr 1  -- ∑' congr: tsum_congr? funext: use `tsum_congr (f g) (h : ∀ x, f x = g x)`? Hmm — ∑' over dependent: `tsum_congr : (∀ b, f b = g b) → ∑' f = ∑' g` ✓ exists. But seriesFun s := ∑' ρ, seriesTerm s ρ — unfold seriesFun first: `show ∑' ρ, seriesTerm s ρ = _`: then tsum_congr with the pointwise: by_cases simp.\n    ...\n```\nLet me write:\n```lean\n  show ∑' ρ, seriesTerm s ρ = _\n  rw [show seriesFunSub ρ₀ s = ∑' ρ, seriesTermSub ρ₀ s ρ from rfl]\n  rw [← Summable.tsum_add (seriesTermSub_summable ρ₀ s) (single_summable ρ₀ s)]\n  -- goal: ∑' ρ, seriesTerm s ρ = ∑' ρ, (seriesTermSub ρ₀ s ρ + if ...)\n  apply tsum_congr\n  intro ρ\n  by_cases h : ρ = ρ₀ <;> simp [seriesTermSub, h]\n  -- single tsum = seriesTerm s ρ₀: tsum_eq_single\n  rw [tsum_eq_single ρ₀ (fun ρ hρ => if_neg hρ)]  -- hmm: the if: if ρ = ρ₀ then seriesTerm s ρ else 0: for ρ ≠ ρ₀: if_neg hρ : the if = 0 ✓; tsum_eq_single : ∑' b, f b = f a given ∀ b ≠ a, f b = 0. Then f ρ₀ = if ρ₀ = ρ₀ then ... else 0 = if_pos rfl: seriesTerm s ρ₀ ✓ simp.\n```\nOrdering: goal after rw [← Summable.tsum_add]: ∑' seriesTerm s = ∑' ρ, (sub ρ + single ρ)? Careful: `Summable.tsum_add (hf : Summable f) (hg : Summable g) : ∑' x, (f x + g x) = ∑' f + ∑' g`? Actually the name: `Summable.tsum_add : ∑' x, (f x + g x) = ...`. Hmm — in recent Mathlib: `Summable.tsum_add (hf : Summable f) (hg : Summable g) : ∑' x, (f x + g x) = ∑' x, f x + ∑' x, g x`. So ← direction rewrites `∑' sub + ∑' single` to `∑' (sub + single)`. My goal chain:\n\ngoal: seriesFun s = seriesFunSub ρ₀ s + seriesTerm s ρ₀\n⟹ show: ∑' term = ∑' sub + seriesTerm s ρ₀ (unfold seriesFun, seriesFunSub — `show` with both unfolded; seriesFunSub ρ₀ s unfolds to ∑' sub ✓ defeq so `show` accepts)\n⟹ rw [tsum_eq_single ρ₀ h]: rewrites `∑' ρ, if ρ = ρ₀ then seriesTerm s ρ else 0` — but the goal has `seriesTerm s ρ₀` not the single-tsum. Go the other way: first convert: have hsingle : ∑' ρ, (if ρ = ρ₀ then seriesTerm s ρ else 0) = seriesTerm s ρ₀ := tsum_eq_single...: \n```lean\n  have hsingle : ∑' ρ : {ρ : ℂ // IsNontrivialZero ρ},\n      (if ρ = ρ₀ then seriesTerm s ρ else (0:ℂ)) = seriesTerm s ρ₀ := by\n    apply tsum_eq_single\n    intro ρ hρ\n    exact if_neg hρ\n    -- after apply tsum_eq_single: remaining goal ∀ b ≠ ρ₀, f b = 0: intro; exact if_neg hρ — wait if_neg : ¬a → (if a then b else c) = c: hρ : ρ ≠ ρ₀ but the condition is ρ = ρ₀: if_neg hρ : (if ρ = ρ₀ then seriesTerm s ρ else 0) = 0 ✓. But tsum_eq_single's f a: after the ∀-goal, remaining: f ρ₀ = seriesTerm s ρ₀?? No: tsum_eq_single ρ₀ h : ∑' f = f ρ₀; the apply unifies ∑' f with the LHS and f ρ₀ with RHS = seriesTerm s ρ₀: f ρ₀ = if ρ₀ = ρ₀ then ... : needs if_pos rfl reduction — apply unification up to defeq should handle (if_pos rfl is defeq ✓)... risky; safer:\n    rw [tsum_eq_single ρ₀ (fun ρ hρ => if_neg hρ)]\n    exact if_pos rfl\n```\ni.e. prove via rw + exact. Fine.\n\nThen:\n```lean\n  calc seriesFun s = ∑' ρ, seriesTerm s ρ := rfl\n    _ = ∑' ρ, (seriesTermSub ρ₀ s ρ + (if ρ = ρ₀ then seriesTerm s ρ else 0)) := by\n        apply tsum_congr\n        intro ρ\n        by_cases h : ρ = ρ₀ <;> simp [seriesTermSub, h]\n    _ = ∑' ρ, seriesTermSub ρ₀ s ρ + ∑' ρ, (if ρ = ρ₀ then seriesTerm s ρ else 0) :=\n        Summable.tsum_add (seriesTermSub_summable ρ₀ s) (single_summable ρ₀ s)\n    _ = seriesFunSub ρ₀ s + seriesTerm s ρ₀ := by rw [hsingle]; rfl\n```\n`tsum_congr`: signature `tsum_congr (h : ∀ b, f b = g b) : ∑' f = ∑' g`? It's `theorem tsum_congr (h : ∀ b, f b = g b) : ∑' b, f b = ∑' b, g b` ✓. The by_cases branches: h : ρ = ρ₀: goal seriesTerm s ρ = seriesTermSub ρ₀ s ρ + (if ρ = ρ₀ then seriesTerm s ρ else 0): simp [seriesTermSub, h]: seriesTermSub → if ρ = ρ₀ then 0 else ... with h: simp [h] reduces both ifs: LHS... the goal becomes seriesTerm s ρ = 0 + seriesTerm s ρ?? simp [h]: `if_pos h`... h : ρ = ρ₀: simp [seriesTermSub, h] rewrites if ρ = ρ₀ via h (simp uses h to decide) ⟹ RHS = 0 + seriesTerm s ρ = seriesTerm s ρ ✓ closes by rfl via simp. Neg branch: h : ¬ρ = ρ₀: RHS = seriesTerm s ρ + 0 ✓. \n\nThe last `_ = seriesFunSub ρ₀ s + seriesTerm s ρ₀`: first summand: ∑' ρ, seriesTermSub ρ₀ s ρ = seriesFunSub ρ₀ s — rfl defeq: `by rw [hsingle]` then goal ∑' sub + seriesTerm s ρ₀ = seriesFunSub ρ₀ s + seriesTerm s ρ₀ — the subs are defeq but not syntactically: rfl closes ✓ (rfl works up to defeq for `exact rfl`? `rfl` tactic: closes a = b if defeq ✓).\n\nHmm — actually to be safe use `show` conversions instead. It'll be fine.\n\nThen:\n```lean\n/-- The series minus its ρ₀-term is analytic at ρ₀. -/\ntheorem seriesFunSub_analyticAt (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) :\n    AnalyticAt ℂ (seriesFunSub ρ₀) (ρ₀ : ℂ) := by\n  obtain ⟨δ, hδ, hiso⟩ := nontrivialZero_isolated ρ₀\n  set δ' := δ / 2 with hδ'\n  have hδ'0 : 0 < δ' := half_pos hδ\n  set M : ℝ := ‖(ρ₀ : ℂ)‖ + δ' with hM\n  set u : {ρ : ℂ // IsNontrivialZero ρ} → ℝ := fun ρ =>\n    17 / 6 * M * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ)))) with hu\n  have hsum_u : Summable u := seriesTerm_summable_majorant M\n  have hfu : ∀ᶠ ρ in cofinite, ∀ s ∈ Metric.ball (ρ₀ : ℂ) δ', ‖seriesTermSub ρ₀ s ρ‖ ≤ u ρ := by\n    rw [Filter.eventually_cofinite]\n    apply (finite_subtype_norm_lt (max 2 (2 * M))).subset\n    intro ρ hρ\n    simp only [Set.mem_setOf_eq, not_forall] at hρ\n    -- hρ : ∃ s ∈ ball, ¬ ‖sub‖ ≤ u ρ: get s\n    by_contra hball\n    apply hρ  -- wait direction: I want: if ‖ρ‖ ≥ R₀ then ∀ s ∈ ball, bound. Contrapositive: ¬(∀...) ⟹ ‖ρ‖ < R₀. intro ρ hρ with hρ : ¬ ∀ s ∈ ball...; goal ρ ∈ {ρ | ‖ρ‖ < R₀}: by_contra hball: ‖ρ‖ ≥ R₀; derive ∀ s ∈ ball bound; contra hρ.\n    ...\n```\nLet me structure the contrapositive cleanly:\n```lean\n    apply (finite_subtype_norm_lt (max 2 (2 * M))).subset\n    intro ρ hρ\n    -- hρ : ρ ∈ {ρ | ¬ ∀ s ∈ ball, ‖sub ρ s‖ ≤ u ρ}; goal: ‖ρ‖ < R₀\n    by_contra hlt\n    rw [not_lt] at hlt  -- R₀ ≤ ‖ρ‖\n    apply hρ\n    intro s hs\n    -- s ∈ ball(ρ₀, δ'): ‖s‖ < ‖ρ₀‖ + δ' = M ⟹ 2‖s‖ ≤ 2M ≤ R₀ ≤ ‖ρ‖; 2 ≤ R₀ ≤ ‖ρ‖\n    have hsM : ‖s‖ ≤ M := by\n      have h : ‖s‖ < M := by\n        calc ‖s‖ ≤ ‖s - (ρ₀:ℂ)‖ + ‖(ρ₀:ℂ)‖ := by\n              nth_rewrite 1 [show s = (s - (ρ₀:ℂ)) + (ρ₀:ℂ) from by ring]\n              exact norm_add_le _ _\n          _ < δ' + ‖(ρ₀:ℂ)‖ := by\n              have := Metric.mem_ball.mp hs  -- dist s ρ₀ < δ'\n              rw [dist_eq_norm] at this\n              linarith\n          _ = M := by rw [hM]; ring\n      exact le_of_lt h\n    have h2 : (2:ℝ) ≤ ‖(ρ:ℂ)‖ := (le_max_left _ _).trans hlt\n    have hs2 : 2 * ‖s‖ ≤ ‖(ρ:ℂ)‖ := ((le_max_right _ _) : 2*M ≤ max 2 (2*M)).trans hlt ∘ ... \n```\n2‖s‖ ≤ 2M (from hsM) ≤ R₀ (max_right) ≤ ‖ρ‖ (hlt): `exact (by linarith : 2 * ‖s‖ ≤ max 2 (2*M)).trans hlt`? linarith [hsM, le_max_right 2 (2*M)]... do: have h2M : 2*‖s‖ ≤ 2*M := by linarith; exact (h2M.trans (le_max_right _ _)).trans hlt ✓.\n\nThen:\n```lean\n    by_cases h0 : ρ = ρ₀\n    · simp [seriesTermSub, h0]\n      -- goal ‖0‖ ≤ u ρ₀: norm_zero; positivity of u: (17/6)*M*(mult/(1+γ²)) ≥ 0: M = ‖ρ₀‖+δ' > 0: positivity with haves... positivity can't use hM's nonneg directly: M = ‖ρ₀‖ + δ' ≥ 0 since both ≥ 0: have hM0 : 0 ≤ M := by rw [hM]; positivity (‖·‖ nonneg + hδ'0.le: linarith [norm_nonneg (ρ₀:ℂ), hδ'0]). Then positivity for the product with hM0 in context? positivity doesn't read hypotheses. Use explicit: mul_nonneg (mul_nonneg (by norm_num : (0:ℝ) ≤ 17/6) hM0) (div_nonneg (Nat.cast_nonneg _) (by linarith [Complex.normSq_nonneg (gammaOf (ρ:ℂ))]))... \n      -- simpler: simp [seriesTermSub, h0]; positivity?? no. Explicit:\n      rw [seriesTermSub, if_pos h0, norm_zero]\n      have hg0 : (0:ℝ) < 1 + Complex.normSq (gammaOf (ρ:ℂ)) := by\n        have := Complex.normSq_nonneg (gammaOf (ρ:ℂ)); linarith\n      have hM0 : (0:ℝ) ≤ M := by rw [hM]; linarith [norm_nonneg (ρ₀:ℂ), hδ'0.le]\n      exact mul_nonneg (mul_nonneg (by norm_num) hM0)\n        (div_nonneg (Nat.cast_nonneg _) hg0.le)\n    · rw [seriesTermSub, if_neg h0]\n      exact (seriesTerm_norm_le ρ h2 hs2).trans (by\n        -- 17/6‖s‖mult/(1+γ²) ≤ 17/6 M mult/(1+γ²)\n        have hg0 : (0:ℝ) ≤ (zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ:ℂ))) := by\n          have := Complex.normSq_nonneg (gammaOf (ρ:ℂ))\n          positivity  -- hmm positivity: (mult:ℝ)/(1+γ²): mult cast nonneg ✓, 1+γ² > 0 needs normSq_nonneg — positivity knows normSq_nonneg? It's a lemma not marked... positivity extension for Complex.normSq? Unsure. Safer: div_nonneg (Nat.cast_nonneg _) (by linarith [Complex.normSq_nonneg _]).\n        exact mul_le_mul_of_nonneg_right (by nlinarith [hsM, norm_nonneg s] : 17/6*‖s‖ ≤ 17/6*M) hg0)\n```\nWait — but u ρ is DEFINED as 17/6 * M * (mult/(1+γ²)) via `set` — the goal after `rw [seriesTermSub, if_neg h0]` is ‖seriesTerm s ρ‖ ≤ u ρ; with set, u ρ is displayed as the lambda applied: u ρ — set introduces u := fun ρ => ... and replaces occurrences; u ρ is a beta-redex?? `set ... := fun ρ => body` then `u ρ` — Lean keeps u as a local def; u ρ beta-reduces to body[ρ] — defeq but not syntactic. The goal `‖seriesTerm s ρ‖ ≤ u ρ`: my `.trans` target: 17/6*M*(...) ≤ u ρ — I must provide the proof term of type ... ≤ u ρ; my calc gives ... ≤ 17/6*M*(...) which is defeq to u ρ: `exact` accepts defeq ✓. But when I write the bound inline `(by ... : 17/6*‖s‖ ≤ 17/6*M)` fine.\n\nHmm — wait, `set u : ... → ℝ := fun ρ => ...` — then occurrences of `fun ρ => 17/6*M*(...)` get folded to u. The application u ρ doesn't auto-unfold in the goal display but defeq holds ✓ exact works.\n\nAlso — `hs` : s ∈ Metric.ball (ρ₀:ℂ) δ'. Metric.mem_ball.mp hs : dist s ρ₀ < δ' ✓.\n\nThen the uniform-convergence + differentiability on ball(ρ₀, δ'):\n```lean\n  have hu' : HasSumUniformlyOn (fun ρ => fun s : ℂ => seriesTermSub ρ₀ s ρ)\n      (fun s => ∑' ρ, seriesTermSub ρ₀ s ρ) (Metric.ball (ρ₀ : ℂ) δ') :=\n    HasSumUniformlyOn.of_norm_le_summable_eventually hsum_u hfu\n  have htend := TendstoUniformlyOn.tendstoLocallyUniformlyOn\n    (hasSumUniformlyOn_iff_tendstoUniformlyOn.mp hu')\n  have hdiff : DifferentiableOn ℂ (fun s => ∑' ρ, seriesTermSub ρ₀ s ρ)\n      (Metric.ball (ρ₀ : ℂ) δ') := by\n    apply htend.differentiableOn _ isOpen_ball\n    apply Filter.Eventually.of_forall\n    intro t s hs\n    rw [show (fun s => ∑ ρ ∈ t, seriesTermSub ρ₀ s ρ)\n        = ∑ ρ ∈ t, (fun s => seriesTermSub ρ₀ s ρ) from by\n      funext s; simp [Finset.sum_apply]]\n    apply DifferentiableAt.differentiableWithinAt\n    apply DifferentiableAt.sum\n    intro ρ hρt\n    by_cases h0 : ρ = ρ₀\n    · show DifferentiableAt ℂ (fun s => if ρ = ρ₀ then (0:ℂ) else seriesTerm s ρ) s\n      rw [if_pos h0]\n      exact differentiableAt_const 0\n    · have hsρ : s - (ρ : ℂ) ≠ 0 := by\n        have hle : δ ≤ ‖(ρ : ℂ) - (ρ₀ : ℂ)‖ := hiso ρ h0\n        have hlt : ‖s - (ρ₀ : ℂ)‖ < δ' := by\n          have := Metric.mem_ball.mp hs\n          rw [dist_eq_norm] at this\n          exact this\n        intro hzero\n        -- ‖ρ − ρ₀‖ ≤ ‖ρ − s‖ + ‖s − ρ₀‖ < 0 + δ' = δ/2 < δ contra\n        have h1 : ‖(ρ : ℂ) - (ρ₀ : ℂ)‖ ≤ ‖(ρ : ℂ) - s‖ + ‖s - (ρ₀ : ℂ)‖ := by\n          nth_rewrite 1 [show (ρ:ℂ) - (ρ₀:ℂ) = ((ρ:ℂ) - s) + (s - (ρ₀:ℂ)) from by ring]\n          exact norm_add_le _ _\n        have h2 : ‖(ρ : ℂ) - s‖ = 0 := by\n          have : s = (ρ:ℂ) := sub_eq_zero.mp hzero\n          rw [← this, sub_self, norm_zero]\n        rw [h2] at h1\n        linarith [hle, hlt, hδ'0]  -- δ ≤ 0 + δ' = δ/2 ⟹ δ ≤ δ/2 contra δ > 0\n      have hρ0 : (ρ : ℂ) ≠ 0 := by\n        intro h\n        have := ρ.2.2.1\n        rw [h] at this\n        simp at this\n      show DifferentiableAt ℂ (fun s => if ρ = ρ₀ then (0:ℂ) else seriesTerm s ρ) s\n      rw [if_neg h0]\n      show DifferentiableAt ℂ (fun s => (zeroMult ρ : ℂ) * (1 / (s - (ρ:ℂ)) + 1 / (ρ:ℂ))) s\n      exact (((differentiableAt_const (1:ℂ)).div (differentiableAt_id.sub (differentiableAt_const _)) hsρ).add (differentiableAt_const _)).const_mul _\n  have han := hdiff.analyticOnNhd isOpen_ball\n  exact han (ρ₀:ℂ) (Metric.mem_ball_self hδ'0)\n```\nWait the final: goal AnalyticAt ℂ (seriesFunSub ρ₀) (ρ₀:ℂ); han : AnalyticOnNhd ℂ (fun s => ∑' ρ, seriesTermSub ρ₀ s ρ) (ball...) — defeq to seriesFunSub ρ₀ ✓; han (ρ₀:ℂ) (mem_ball_self) : AnalyticAt ℂ (fun s => ...) (ρ₀:ℂ) — exact defeq ✓.\n\nhmm hδ'0 in the last linarith: δ ≤ δ/2 with δ > 0: linarith [hle, hlt, hδ] where hδ : 0 < δ: from h1 (with h2 rw'd): ‖ρ−ρ₀‖ ≤ 0 + ‖s−ρ₀‖ — rw [h2] at h1 gives ‖ρ−ρ₀‖ ≤ 0 + ‖s−ρ₀‖... zero_add not auto: linarith handles: ‖ρ−ρ₀‖ ≤ 0 + ‖s−ρ₀‖, ‖s−ρ₀‖ < δ' = δ/2, hle: δ ≤ ‖ρ−ρ₀‖ ⟹ δ < δ/2 ⟹ δ ≤ 0 contra hδ : 0 < δ — but hδ' = δ/2 defeq: δ' is a set-variable: hlt : ‖s−ρ₀‖ < δ' where δ' := δ/2 — linarith sees δ' opaque! Need hδ' : δ' = δ/2 in the linarith list. set ... with hδ' gives hδ' : δ' = δ/2 ✓ include it: linarith [hle, hlt, hδ, hδ'] — wait `set δ' := δ/2 with hδ'` : hδ' : δ' = δ/2 ✓.\n\nAlso hlt could just reuse hs directly: Metric.mem_ball.mp hs : dist s ρ₀ < δ' ✓ dist_eq_norm ✓.\n\nThen the final assembly:\n```lean\n/-- The series with its ρ₀-term subtracted equals the reduced series\n(everywhere); hence the polar subtraction is analytic at ρ₀. -/\ntheorem seriesFun_sub_term (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) (s : ℂ) :\n    seriesFun s - seriesTerm s ρ₀ = seriesFunSub ρ₀ s := by\n  have h := seriesFun_eq_sub_add ρ₀ s\n  linarith?? — ℂ not ordered: use: rw [h]; ring  -- h : seriesFun s = seriesFunSub ρ₀ s + seriesTerm s ρ₀: goal seriesFun s − seriesTerm s ρ₀ = seriesFunSub ρ₀ s: rw [h]: (a + b) − b = a: ring ✓\n  -- actually: conv? `rw [h]; ring` — ring on (x + y) − y = x ✓\n```\nHmm — ring works for ℂ equalities ✓.\n\n```lean\ntheorem seriesFun_sub_self_term_analyticAt (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) :\n    AnalyticAt ℂ (fun s => seriesFun s - seriesTerm s ρ₀) (ρ₀ : ℂ) := by\n  apply AnalyticAt.congr (seriesFunSub_analyticAt ρ₀)\n  filter_upwards with s  -- EventualEq: ∀ᶠ s in 𝓝 ρ₀, seriesFunSub ρ₀ s = seriesFun s − seriesTerm s ρ₀ — pointwise true!\n  exact (seriesFun_sub_term ρ₀ s).symm\n```\nAnalyticAt.congr (hf : AnalyticAt f x) (hg : f =ᶠ[𝓝 x] g) : AnalyticAt g x — so hf = seriesFunSub_analyticAt (f = seriesFunSub ρ₀), g = fun s => seriesFun s − seriesTerm s ρ₀; need seriesFunSub ρ₀ =ᶠ[𝓝 ρ₀] g: Filter.Eventually.of_forall (fun s => (seriesFun_sub_term ρ₀ s).symm) ✓.\n\n```lean\n/-- The polar subtraction form consumed by 5e-iv: s ↦ seriesFun s −\nmult(ρ₀)/(s−ρ₀) is analytic at ρ₀. -/\ntheorem seriesFun_sub_polar_analyticAt (ρ₀ : {ρ : ℂ // IsNontrivialZero ρ}) :\n    AnalyticAt ℂ (fun s => seriesFun s - (zeroMult (ρ₀:ℂ) : ℂ) / (s - (ρ₀:ℂ))) (ρ₀:ℂ) := by\n  have h := seriesFun_sub_self_term_analyticAt ρ₀\n  have heq : (fun s => seriesFun s - (zeroMult (ρ₀:ℂ) : ℂ) / (s - (ρ₀:ℂ)))\n      = (fun s => (seriesFun s - seriesTerm s ρ₀) + (zeroMult (ρ₀:ℂ) : ℂ) / (ρ₀:ℂ)) := by\n    funext s\n    rw [seriesTerm]\n    ring\n  rw [heq]\n  exact h.add (differentiableAt_const _).analyticAt\n```\nCheck: seriesTerm s ρ₀ = mult·(1/(s−ρ₀) + 1/ρ₀) = mult/(s−ρ₀) + mult/ρ₀ — as ℂ expressions with div: mult*(1/(s−ρ₀) + 1/ρ₀) = mult/(s−ρ₀) + mult/ρ₀: ring? ring normalizes a/b to a*b⁻¹ ✓ and distributes ✓ (no field_simp needed since no cancellations of inverses). Goal after funext s, rw [seriesTerm]: seriesFun s − mult/(s−ρ₀) = (seriesFun s − mult*(1/(s−ρ₀)+1/ρ₀)) + mult/ρ₀: ring ✓.\n\n`DifferentiableAt.analyticAt` — BANKED GOTCHA (session 026): DifferentiableAt.analyticAt does NOT exist! Use: for a constant function: `(differentiableAt_const _).analyticAt` invalid. AnalyticAt of const: `analyticAt_const : AnalyticAt 𝕜 (fun _ => c) x` ✓ exists (I believe). Use analyticAt_const.\n\nLet me double-check `analyticAt_const` exists in this Mathlib — Analytic/Basic.lean: `theorem analyticAt_const : AnalyticAt 𝕜 (fun _ => c) x` ✓ standard.\n\nAlso `(zeroMult (ρ₀:ℂ) : ℂ)` — zeroMult applied to (ρ₀ : ℂ) then cast ℕ→ℂ. In liSummand they wrote `(zeroMult ρ : ℂ)` with ρ : subtype — Lean coerces ρ to ℂ for zeroMult ✓ same here; but to be safe write `(zeroMult (ρ₀ : ℂ) : ℂ)`. Hmm — in seriesTerm the coercion is already there; for consistency in heq rewrite: seriesTerm s ρ₀ = (zeroMult ↑ρ₀ : ℂ) * (...): rw [seriesTerm] exposes the def with (zeroMult ↑ρ₀ : ℂ) — hmm the def is `(zeroMult ρ : ℂ)` with ρ the subtype var — instantiated at ρ₀: `(zeroMult ↑ρ₀ : ℂ)`? zeroMult's argument: ρ₀ coerced: `zeroMult ↑ρ₀`. Fine — ring handles regardless of the exact form ✓.\n\nAlso for §4's `seriesFun_analyticOnNhd`: AnalyticOnNhd ℂ seriesFun {s | ¬ IsNontrivialZero s} = ∀ x ∈ s, AnalyticAt: `fun s₀ hs₀ => seriesFun_analyticAt hs₀` — hs₀ : s₀ ∈ {s | ¬ ...} = ¬ IsNontrivialZero s₀ (defeq set membership ✓).\n\nNow — remaining risk points:\n1. `Filter.eventually_cofinite` name/direction. Check: Mathlib Order/Filter/Cofinite.lean: `theorem eventually_cofinite {p : α → Prop} : (∀ᶠ x in cofinite, p x) ↔ {x | ¬p x}.Finite`? Let me verify.\n2. `HasSumUniformlyOn.of_norm_le_summable_eventually` hfu form: ∀ᶠ n in cofinite, ∀ x ∈ s, ‖f n x‖ ≤ u n — matches ✓ (from the source above).\n3. `Metric.eventually_nhds_iff_ball` ✓ verified.\n4. `analyticAt_riemannZeta` — Mathlib: `analyticAt_riemannZeta {s : ℂ} (hs : s ≠ 1) : AnalyticAt ℂ riemannZeta s`? Used in LiSides line 370: `analyticAt_riemannZeta hρ` with hρ : ρ ≠ 1 ✓.\n5. `ContinuousAt.eventually_ne` ✓ (used in LiResidue line 82).\n6. `AnalyticAt.continuousAt` ✓ used LiResidue 82.\n7. `(analyticAt_riemannZeta h1).analyticOrderAt_ne_top.mp` ✓ LiSides pattern.\n8. `smul_eq_mul` ✓.\n9. In §4 partial sums: `DifferentiableAt.sum` — signature: `(h : ∀ i ∈ t, DifferentiableAt ...)`? LiDigamma: `apply DifferentiableAt.sum; intro m hm` ✓.\n10. `htend.differentiableOn _ isOpen_ball` ✓ pattern from LiDigamma (`htend.differentiableOn _ dpsiDomain_isOpen`).\n11. `hdiff.analyticOnNhd isOpen_ball` ✓.\n12. `Metric.mem_ball_self : 0 < r → x ∈ ball x r` ✓.\n13. `Finset.min'_le`, `Finset.min'_mem` ✓ standard.\n14. `Set.finite_singleton` ✓; `summable_of_hasFiniteSupport` ✓.\n15. `tsum_congr` ✓.\n16. `half_pos` ✓.\n17. `abs_norm_sub_norm_le : |‖a‖ − ‖b‖| ≤ ‖a − b‖` — check name: Mathlib `abs_norm_sub_norm_le : |‖x‖ − ‖y‖| ≤ ‖x − y‖` ✓ exists (norm_sub_le_norm... no). Actually the name is `abs_norm_sub_norm_le` ✓ I'm fairly confident.\n\nLet me verify #1 and #17 and `tsum_congr`, `analyticAt_const`, `DifferentiableAt.sum`, `Finset.min'_le`, `Complex.norm_natCast`/`RCLike.norm_natCast` quickly.","signature":""},{"type":"text","text":"Now verifying the remaining lemma names in one sweep."},{"type":"tool_use","id":"Bash_37","name":"Bash","input":{"command":"cd D:/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem eventually_cofinite\\b\" Mathlib/Order/Filter/Cofinite.lean | head -2; grep -rn \"theorem abs_norm_sub_norm_le\\b\\|lemma abs_norm_sub_norm_le\\b\" Mathlib/Analysis/ -r | head -2; grep -rn \"theorem tsum_congr\\b\\|lemma tsum_congr\\b\" Mathlib/Topology/Algebra/InfiniteSum/Basic.lean | head -2; grep -rn \"theorem analyticAt_const\\b\" Mathlib/Analysis/Analytic/Basic.lean | head -2; grep -rn \"theorem DifferentiableAt.sum\\b\\|lemma DifferentiableAt.sum\\b\" Mathlib/ -r | head -2; grep -rn \"theorem half_pos\\b\" Mathlib/Algebra/Order/ -r | head -2; grep -rn \"theorem Summable.tsum_add\\b\" Mathlib/ -r | head -2; grep -rn \"theorem Summable.norm\\b\" Mathlib/ -r | head -2; grep -rn \"theorem Metric.ball_subset_ball\\b\" Mathlib/ -r | head -2","description":"Verify lemma names batch"},"extra_content":null}]