Current task: —

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

#1499 assistant 2026-08-23 15:36:13.649 UTC · 234→11134 tok open ⤢
thinking (26019 chars)
§0–§4 compile clean (zero errors, zero warnings). Now §5–§9. Let me write the remaining sections: §5: digammaSeriesPart + analyticity on ball(0, 1/2) + the s=0 witness. §6: digammaSeriesPartSub + analyticity on ball(−n, 1/2) + the split + the −2n witness. §7: nontrivial-zero witness. §8: generic analyticity + badPoint-free balls. §9: Gentire + capstone. Let me draft these carefully. §5: ```lean /-! ## 5. The digamma series part and the witness at s = 0 -/ /-- The series part of the digamma partial-fraction expansion: Σ'_j (1/(j+1) − 1/(w+j+1)); analytic on ball(0, 1/2). -/ def digammaSeriesPart (w : ℂ) : ℂ := ∑' j : ℕ, (1 / ((j : ℂ) + 1) - 1 / (w + j + 1)) lemma digammaSeriesTerm_eq {w : ℂ} {j : ℕ} (hj : (j : ℂ) + 1 ≠ 0) (hw : w + j + 1 ≠ 0) : 1 / ((j : ℂ) + 1) - 1 / (w + j + 1) = w / (((j : ℂ) + 1) * (w + j + 1)) := by field_simp ring ``` Hmm: 1/a − 1/b = (b − a)/(ab): b − a = w+j+1 − (j+1) = w ✓: field_simp + ring ✓ (banked pattern). ```lean lemma digammaSeriesPart_analyticOn : AnalyticOnNhd ℂ digammaSeriesPart (Metric.ball 0 (1 / 2)) := by have hsum : Summable (fun j : ℕ => (1 : ℝ) / ((j : ℝ) + 1) ^ 2) := summable_div_add_one_sq 1 have hu : HasSumUniformlyOn (fun j => fun w : ℂ => 1 / ((j : ℂ) + 1) - 1 / (w + j + 1)) digammaSeriesPart (Metric.ball 0 (1 / 2)) := by apply HasSumUniformlyOn.of_norm_le_summable hsum intro j w hw -- w ∈ ball(0, 1/2): ‖w‖ < 1/2 have hwn : ‖w‖ < 1 / 2 := by have := Metric.mem_ball.mp hw rw [dist_zero_right] at this exact this have hj1 : (0 : ℝ) < (j : ℝ) + 1 := by positivity have hwj : w + (j : ℂ) + 1 ≠ 0 := by intro h have : ‖w + (j : ℂ) + 1‖ = 0 := by rw [h]; exact norm_zero have hge : (j : ℝ) + 1 - ‖w‖ ≤ ‖w + (j : ℂ) + 1‖ := by have h1 : (w + (j : ℂ) + 1).re = w.re + (j : ℝ) + 1 := by simp [Complex.add_re, Complex.one_re, Complex.natCast_re] -- natCast_re: (↑j).re = j: `Complex.natCast_re : (↑n).re = n`? there's `Complex.natCast_re` ✓ or `RCLike.natCast_re`... hmm: (↑j : ℂ).re = (j : ℝ): `Complex.natCast_re : ((n : ℂ)).re = n`? I think `Complex.natCast_re` exists (or `RCLike.natCast_re`). Let me use `Complex.natCast_re` and adjust if error. have h2 : (w + (j : ℂ) + 1).re ≤ ‖w + (j : ℂ) + 1‖ := Complex.re_le_norm _ have h3 : w.re ≥ -‖w‖ := neg_norm_le_re w -- `neg_norm_le_re : -‖z‖ ≤ z.re`? `Complex.neg_norm_le_re`? hmm: `neg_norm_le.re`? The lemma: `Complex.neg_norm_le_re (z : ℂ) : -‖z‖ ≤ z.re`? or `Complex.re_le_norm` + `Complex.neg_le_norm`? There's `Complex.neg_norm_le_re`? If unsure: from abs_re_le_norm: |w.re| ≤ ‖w‖ ⟹ −‖w‖ ≤ w.re via abs_le. linarith [h1, h2, h3] -- wait hge : (j:ℝ)+1 − ‖w‖ ≤ ‖w+j+1‖: from h2: w.re + j + 1 ≤ ‖·‖ and w.re ≥ −‖w‖: j + 1 − ‖w‖ ≤ w.re + j + 1 ≤ ‖·‖ ✓ rw [this] at hge linarith [hwn, hj1] -- (j+1) − ‖w‖ ≤ 0 with ‖w‖ < 1/2 ≤ j+1: contra ✓ have hj0 : ((j : ℂ) + 1) ≠ 0 := by intro h have := congrArg Complex.re h simp at this -- (j+1).re = j+1 = 0: j + 1 > 0: `Complex.add_re, natCast_re, one_re`: this : (j:ℝ) + 1 = 0: positivity false: linarith? simp at this leaves ↑j + 1 = 0: then `have : (0:ℝ) < (j:ℝ)+1 := by positivity; linarith`. Hmm simp at this might close the goal if it reduces to False: (↑(j)+1 : ℝ) = 0 — simp knows Nat.cast_nonneg? `simp at this` with positivity facts... safer: have h1 : ((j : ℂ) + 1).re = 0 := by rw [h]; simp simp [Complex.add_re] at h1 -- (j:ℝ) + 1 = 0 have h2 : (0 : ℝ) < (j : ℝ) + 1 := by positivity linarith rw [digammaSeriesTerm_eq hj0 hwj, norm_div, norm_mul] -- ‖w‖ / ((j+1) * ‖w+j+1‖) ≤ 1 / (j+1)² have hnorm_ge : ((j : ℝ) + 1) * ((j : ℝ) + 1) / 2 ≤ ‖((j : ℂ) + 1) * (w + j + 1)‖ := by rw [norm_mul] have h1 : ‖((j : ℂ) + 1 : ℂ)‖ = (j : ℝ) + 1 := by rw [show ((j : ℂ) + 1) = ((j + 1 : ℕ) : ℂ) by push_cast; ring, Complex.norm_natCast] -- hmm: (↑j + 1 : ℂ) = ↑(j+1): push_cast; ring ✓; Complex.norm_natCast : ‖↑(j+1)‖ = ↑(j+1) — wait Complex.norm_natCast vs RCLike.norm_natCast ∀-form (journal-028 gotcha: ∀-form — use rw)... in rw position fine. -- then ↑(j+1) = ↑j + 1: push_cast ... ``` This is getting heavy. Simplify the norm estimates: ‖(j:ℂ)+1‖ = (j:ℝ)+1: ```lean have h1 : ‖(j : ℂ) + 1‖ = (j : ℝ) + 1 := by have e : ((j : ℂ) + 1) = ((j + 1 : ℕ) : ℂ) := by push_cast; ring rw [e, RCLike.norm_natCast] -- ∀-form in rw ✓ push_cast -- goal ↑(j+1) = ↑j + 1: push_cast closes? push_cast : ↑(j+1) = ↑j + 1 ✓ simp form: rw [Nat.cast_add, Nat.cast_one] -- safer: rw [Nat.cast_add, Nat.cast_one] ``` and ‖w + j + 1‖ ≥ ((j:ℝ)+1)/2: from re: (w + j + 1).re = w.re + j + 1 ≥ −‖w‖ + j + 1 > −1/2 + j + 1 = (j+1)/2 + j/2 ≥ (j+1)/2 — and ‖·‖ ≥ re: so ‖w+j+1‖ ≥ re(...) ≥ (j+1) − ‖w‖ > (j+1) − 1/2 ≥ (j+1)/2 ✓. Then ‖w‖/((j+1)·‖w+j+1‖) ≤ (1/2)/((j+1)·(j+1)/2) = 1/(j+1)² via div_le_div_iff₀-style juggling: ```lean have hbig : ‖w‖ / (‖(j:ℂ)+1‖ * ‖w + j + 1‖) ≤ 1 / ((j:ℝ)+1)^2 := by rw [h1] -- denominator (j+1) * ‖w+j+1‖ have hwj2 : ((j : ℝ) + 1) / 2 ≤ ‖w + (j : ℂ) + 1‖ := by have h2 : (w + (j : ℂ) + 1).re ≤ ‖w + (j : ℂ) + 1‖ := Complex.re_le_norm _ have h3 : (w + (j : ℂ) + 1).re = w.re + (j : ℝ) + 1 := by simp [Complex.add_re, Complex.one_re, Complex.natCast_re] -- hmm the re of ↑j + ... : build explicitly: ... ``` Honestly the re-computation: (w + ↑j + 1).re = w.re + (↑j).re + (1:ℂ).re = w.re + j + 1: `simp [Complex.add_re]` should give w.re + (↑j).re + 1 and (↑j).re: simp lemma `Complex.natCast_re : (↑n).re = ↑n`? I believe `Complex.natCast_re` exists as simp. To be safe: `have h3 : (w + (j:ℂ) + 1).re = w.re + j + 1 := by simp [Complex.add_re]` and if simp leaves (↑j).re, add Complex.natCast_re to the simp set. I'll write `simp [Complex.add_re, Complex.natCast_re, Complex.one_re]`. Then: −‖w‖ ≤ w.re: `neg_norm_le_re`? For ℂ: `Complex.neg_norm_le_re (z : ℂ) : -‖z‖ ≤ z.re`? — I used `abs_re_le_norm` earlier (LiDigamma used Complex.abs_re_le_norm ✓): from |w.re| ≤ ‖w‖: abs_le.mp gives both ✓: `(abs_le.mp (Complex.abs_re_le_norm w)).1 : -‖w‖ ≤ w.re` ✓. OK the estimates: let A := (j:ℝ)+1 > 0. ‖denom‖ = A·‖w+j+1‖ ≥ A·(A/2) = A²/2. ‖w‖/denom ≤ (1/2)/(A²/2) = 1/A²: ```lean rw [div_le_div_iff₀ hden0 hA20] -- ‖w‖·A² ≤ 1·(A·‖w+j+1‖) -- from ‖w‖ ≤ 1/2 (hwn.le) and A·‖w+j+1‖ ≥ A²/2: ‖w‖·A² ≤ (1/2)A² ≤ A·‖w+j+1‖?? need (1/2)A² ≤ A·‖w+j+1‖ ⟺ A/2 ≤ ‖w+j+1‖ ✓ hwj2 times A ≥ 0: nlinarith [hwn.le, hwj2, hj1, ...] ``` Let me write: goal after div_le_div_iff₀: ‖w‖ * (A^2) ≤ 1 * (A * ‖w+j+1‖): nlinarith [hwn.le, hwj2, hj1]: from A/2 ≤ ‖w+j+1‖: A·‖w+j+1‖ ≥ A²/2 (nlinarith product A·(...) with A ≥ 0); ‖w‖·A² ≤ (1/2)·A² (product (1/2 − ‖w‖)≥0 · A² ≥ 0 — nlinarith needs A² ≥ 0: sq_nonneg): 1*(A*‖..‖) = A·‖..‖ ✓. So nlinarith [hwn.le, hwj2, hj1, sq_nonneg A]? pass the pieces: `nlinarith [hwn.le, hwj2, hj1.le, sq_nonneg ((j:ℝ)+1)]` — hmm nlinarith multiplies hypotheses pairwise automatically ✓. OK — and then TendstoLocallyUniformlyOn → differentiableOn (partial sums: each term 1/(j+1) − 1/(w+j+1) differentiable on the ball: w+j+1 ≠ 0 ✓ hwj-style for all w ∈ ball — note hwj above is per-w; inside the differentiability proof I need ∀ w ∈ ball, w + j + 1 ≠ 0 — same proof (extract a standalone lemma `add_nat_add_one_ne_zero_of_mem_ball`). Let me factor a helper: ```lean lemma add_nat_add_one_ne_zero_of_mem_ball {w : ℂ} (hw : w ∈ Metric.ball 0 (1/2)) (j : ℕ) : w + (j : ℂ) + 1 ≠ 0 := by have hwn : ‖w‖ < 1 / 2 := by have h := Metric.mem_ball.mp hw rwa [dist_zero_right] at this intro h have hre : (w + (j : ℂ) + 1).re ≤ ‖w + (j : ℂ) + 1‖ := Complex.re_le_norm _ rw [h, norm_zero] at hre... ``` hmm: rw [h] at hre: (0:ℂ).re ≤ ‖0‖: hre : (0).re ≤ 0... then hre computes: need (w+↑j+1).re = w.re + j + 1: ```lean have h1 : (w + (j : ℂ) + 1).re = w.re + (j : ℝ) + 1 := by simp [Complex.add_re, Complex.natCast_re, Complex.one_re] rw [h] at h1 -- h1 : (0:ℂ).re = ... : simp: h1 : 0 = w.re + j + 1: hmm (0:ℂ).re simp to 0: `simp at h1` gives 0 = w.re + ↑j + 1 simp at h1 -- 0 = w.re + ↑j + 1 have h2 : -‖w‖ ≤ w.re := (abs_le.mp (Complex.abs_re_le_norm w)).1 have hj0 : (0 : ℝ) ≤ (j : ℝ) := Nat.cast_nonneg j linarith -- 0 = w.re + j + 1 ≥ −1/2 + 0 + 1 = 1/2 > 0 contra ✓ ``` OK. Rather than fully elaborating every step in my head, let me write the sections and let the compiler guide. Write §5+§6 now (the digamma splits + the 0 and −2n witnesses), compile, then §7–§9. For §6 the −n ball version: ball(−(n:ℂ), 1/2): - pole avoidance: w + j + 1 ≠ 0 for j ≠ n−1: w = −(j+1) ⟹ ‖w − (−n)‖ = |n − (j+1)| ≥ 1 (j+1 ≠ n) but ‖w+n‖ < 1/2 contra ✓: ```lean lemma add_nat_add_one_ne_zero_of_mem_ball_neg {n : ℕ} (hn : 1 ≤ n) {w : ℂ} (hw : w ∈ Metric.ball (-(n : ℂ)) (1/2)) {j : ℕ} (hj : j ≠ n - 1) : w + (j : ℂ) + 1 ≠ 0 := by intro h -- w = −(j+1): then ‖(−n) − (−(j+1))‖ = |j+1−n| ≥ 1 have h1 : w = -((j : ℂ) + 1) := by linear_combination h -- from h: w + j + 1 = 0 have h2 : dist w (-(n : ℂ)) < 1 / 2 := Metric.mem_ball.mp hw rw [h1] at h2 -- dist (−(j+1)) (−n) = ‖(j+1) − n‖ = |((j:ℝ)+1) − n| rw [Complex.dist_eq] at h2 -- ‖−(j+1) − −n‖ = ‖(n:ℂ) − (j+1)‖: have h3 : (-((j : ℂ) + 1)) - (-(n : ℂ)) = ((n : ℂ) - ((j : ℂ) + 1)) := by ring rw [h3] at h2 -- hmm rw at h2 with h3: the pattern (−(↑j+1)) − (−↑n) ✓ -- ‖(n:ℂ) − (↑j+1)‖ = |(n:ℝ) − (j+1)|: via norm of real cast: (n:ℂ) − (↑j+1) = ↑((n:ℝ) − (j+1)): ofReal_sub... have h4 : ‖((n : ℂ) - ((j : ℂ) + 1))‖ = |(n : ℝ) - ((j : ℝ) + 1)| := by rw [show (n : ℂ) - ((j : ℂ) + 1) = ((n - (j + 1) : ℕ) : ℂ)?? — no: n vs j+1 in ℕ-sub is wrong when j+1 > n. Use ℝ: ((n:ℝ) − ((j:ℝ)+1) : ℂ)? the ofReal cast: ((x : ℝ) : ℂ): `Complex.ofReal_sub`... (n:ℂ) − (↑j + 1) = ↑((n:ℝ) − (↑j + 1)): push_cast backwards: `by push_cast; ring`?? then norm of ofReal: `Complex.norm_ofReal`? `RCLike.norm_ofReal` ∀-form (LiSkeleton used RCLike.norm_ofReal ✓): rw [show ..., RCLike.norm_ofReal]: gives ‖(x:ℝ)‖ = |x|? RCLike.norm_ofReal : ‖(x : 𝕜)‖ = |x|?? For ℂ: ‖(x:ℂ-of-real)‖ = |x| — `Complex.norm_ofReal` : ‖(r : ℂ)‖ = |r| ✓ exists (or RCLike.norm_ofReal y = |y| ✓). rw [show (n : ℂ) - ((j : ℂ) + 1) = (((n : ℝ) - ((j : ℝ) + 1)) : ℂ) by push_cast; ring, Complex.norm_ofReal] rw [h4] at h2 -- |(n:ℝ) − (j+1)| ≥ 1 since n ≠ j+1 (integers) have h5 : (1 : ℝ) ≤ |(n : ℝ) - ((j : ℝ) + 1)| := by have hne : n ≠ j + 1 := by intro hc apply hj omega -- j ≠ n − 1 with n ≥ 1: j + 1 = n ⟺ j = n − 1 ✓ omega handles? hne goal: n ≠ j+1; hj : j ≠ n − 1; from hc : n = j + 1: j = n − 1 in ℕ: omega ✓ (with hn : 1 ≤ n in context? omega sees hn ✓ since hn is a hypothesis... hn : 1 ≤ n is in scope ✓). -- |n − (j+1)| ≥ 1 for distinct naturals rcases lt_or_gt_of_ne hne with hlt | hgt · -- n < j+1: (j+1) − n ≥ 1 have h6 : (n : ℝ) + 1 ≤ (j : ℝ) + 1 := by exact_mod_cast Nat.succ_le_of_lt... hmm: n < j+1 ⟹ n+1 ≤ j+1: exact_mod_cast (Nat.succ_le_iff.mpr hlt)?? n+1 ≤ j+1 ⟺ n < j+1 ✓: `Nat.succ_le_of_lt hlt : n + 1 ≤ j + 1` — wait Nat.succ_le_of_lt : a < b → a+1 ≤ b: n < j+1 ⟹ n+1 ≤ j+1 ✓. Then (n:ℝ)+1 ≤ (j:ℝ)+1 via exact_mod_cast ✓. rw [abs_of_neg (by linarith : (n:ℝ) − (j+1) < 0)]; linarith. · -- n > j+1 have h6 : (j : ℝ) + 1 + 1 ≤ (n : ℝ) := by exact_mod_cast Nat.succ_le_of_lt hgt -- j+1+1 ≤ n rw [abs_of_pos (by linarith : 0 < (n:ℝ) − (j+1))]; linarith linarith ``` Hmm wait — h3 rewrite direction: h2 : ‖−(↑j+1) − −↑n‖ < 1/2: rw [h3] at h2 ✓. But careful Complex.dist_eq : dist a b = ‖a − b‖ ✓. OK this is doable. The M-test for the sub-series: eventually-form with u j := 6n/(j+1)² for j ≥ 2n+1... wait earlier I computed with ‖w‖ ≤ 3n/2: hmm ‖w‖ ≤ ‖w+n‖... no: w ∈ ball(−n, 1/2): ‖w‖ ≤ ‖w − (−n)‖ + ‖−n‖ < 1/2 + n. So ‖w‖ < n + 1/2 ≤ 3n/2 (n ≥ 1 ✓). For j ≥ 2n+1 (so j+1 ≥ 2n+2): ‖w+j+1‖ ≥ (j+1) − ‖w‖ > (j+1) − (n+1/2) ≥ (j+1) − (j+1)/2 = (j+1)/2 ✓ ((j+1)/2 ≥ n+1 > n+1/2 ✓ since j+1 ≥ 2n+2 ⟹ (j+1)/2 ≥ n+1 ✓). So ‖term‖ = ‖w‖/((j+1)‖w+j+1‖) ≤ (n+1/2)·2/(j+1)² = (2n+1)/(j+1)² ✓. u j := (2n+1)/((j:ℝ)+1)^2 — summable via summable_div_add_one_sq (2n+1) ✓. The cofinite eventuality: {j | ¬ (2n+1 ≤ j)} = {j | j < 2n+1} = finite (Finset.range / Set.finite_lt...): `Set.finite_lt_nat`? {j : ℕ | j < k}.Finite: `Set.finite_Iio`? or `Set.Finite.subset (Finset.finite_toSet (Finset.range ...))`: there's `Set.finite_lt_nat (k) : {j | j < k}.Finite`? I'll use `(Set.finite_lt_nat _)`. Hmm — safer: `Set.Finite.subset (Finset.finite_range ...)`: {j | j < 2n+1} = ↑(Finset.range (2n+1)): `Finset.coe_range : ↑(range k) = {j | j < k}`? `Finset.coe_range : ↑(Finset.range k) = Set.Iio k` ✓ and Set.Iio k finite: `Set.finite_Iio` ✓ exists for locally finite orders. So (Set.finite_Iio (2*n+1)).subset (fun j hj => hj) with membership defeq ✓. Then eventually_cofinite.mpr — wait direction: eventually_cofinite : (∀ᶠ x in cofinite, p x) ↔ {x | ¬p x}.Finite: rw [eventually_cofinite]; apply (Set.finite_Iio ...).subset; intro j hj; show j < 2n+1?? — {j | ¬P j} ⊆ {j | j < 2n+1}: intro j hj (hj : ¬P j); goal j ∈ {j | j < 2n+1} defeq j < 2n+1: by_contra; push Not → 2n+1 ≤ j; then prove P j contra hj ✓. Hmm wait — for the sub-series M-test I need: for j ≥ 2n+1: ∀ w ∈ ball, ‖subterm j w‖ ≤ u j. subterm j w = if j = n−1 then 0 else full-term. j ≥ 2n+1 ⟹ j ≠ n−1 (2n+1 > n−1 ⟺ n > −2 ✓) ⟹ = full term: bound ✓ as computed. But also — pole avoidance hwj for ALL j ≠ n−1 on the ball (needed for differentiability of partial sums AND for the term algebra at each w): add_nat_add_one_ne_zero_of_mem_ball_neg ✓. And the summability of the sub-series at each w ∈ ball — from the uniform convergence (pointwise). How to extract pointwise HasSum from HasSumUniformlyOn? There should be `HasSumUniformlyOn.hasSum (h) (hw : w ∈ s)`? Let me not need it: for the SPLIT identity I need Summable (sub at w) — get it by comparison with the FULL series at w (‖sub‖ ≤ ‖full‖ pointwise via if-zero; full summable at w ∈ integerComplement via Zeta23 summable_digamma_series). ✓ no pointwise-extraction needed. But wait — the M-test conclusion gives HasSumUniformlyOn of sub → its limit = ∑' sub = digammaSeriesPartSub — fine, no pointwise summability needed from it. Hmm, actually — is the eventual M-test (of_norm_le_summable_eventually) applicable with the if-term? The bound holds eventually ✓; the head terms unconstrained ✓. Conclusion: HasSumUniformlyOn sub (fun w => ∑' j, sub j w) ball ✓ = digammaSeriesPartSub ✓ (defeq). Then differentiability of partial sums of sub on the ball: term j: if j = n−1 then 0 else full-term: full-term differentiable at w ∈ ball: 1/(j+1) const ✓; 1/(w+j+1): w+j+1 ≠ 0 (pole avoidance, j ≠ n−1 ✓; for j = n−1 the if gives 0 ✓ const). The single-split: for w ∈ ball(−n,1/2), w ≠ −n: digammaSeriesPart w = digammaSeriesPartSub n w + (1/(n:ℂ) − 1/(w+n)): - pointwise: full j = sub j + single j where single j := if j = n−1 then (1/(j+1) − 1/(w+j+1)) else 0 ✓ by_cases simp. - Summable full at w: w ∈ integerComplement: w = (k:ℤ) with ‖w+n‖ < 1/2 ⟹ |k + n| < 1/2... k integer, n nat: |k+n| < 1/2 ⟹ k = −n ⟹ w = −n excluded ✓. So w ∈ integerComplement ⟹ summable_digamma_series gives Summable (fun j => 1/(j+1) − 1/(w+j+1)) — its exact summand form must match — check: `summable_digamma_series (hz : z ∈ integerComplement) : Summable fun n => ...` (line 298) — presumably exactly the digamma_series summand ✓. - Summable sub at w: of_norm_bounded (full.norm) (‖sub‖ ≤ ‖full‖ pointwise: if-zero ≤ ✓). - Summable single: finite support ✓. - tsum: full = sub + single via Summable.tsum_add (sub) (single) reversed: ∑' (sub + single) = ... with pointwise eq full = sub + single: tsum_congr. - single tsum = 1/n − 1/(w+n): tsum_eq_single (n−1): ∀ j ≠ n−1: single j = 0 ✓ if_neg; value at n−1: if_pos: 1/((n−1:ℂ)+1) − 1/(w+(n−1)+1) = 1/n − 1/(w+n): casts: (n−1 : ℕ) as ℂ + 1: (↑(n−1) : ℂ) + 1 = ↑n: Nat.cast_sub (hn : 1 ≤ n)... `(↑(n − 1) : ℂ) + 1 = ↑n`: Nat.cast_sub hn gives ↑(n−1) = ↑n − ↑1 = ↑n − 1: so LHS = ↑n − 1 + 1 = ↑n ✓ via push_cast/ring with the cast_sub rewrite: `rw [Nat.cast_sub hn]; push_cast; ring`? Nat.cast_sub (hn : 1 ≤ n) : ↑(n − 1) = ↑n − ↑1: then ring ✓. Handle carefully. Then H_n w := −γ − 1/w + digammaSeriesPartSub n w + 1/(n:ℂ): analytic at −n: pieces: const ✓; 1/w at −n ≠ 0 ✓ (n ≥ 1); digammaSeriesPartSub analytic on the ball (M-test) ⟹ at −n (center ✓); 1/n const ✓. digamma w = −1/(w+n) + H_n w for w ∈ ball, w ≠ −n: digamma w = −γ − 1/w + full w (digamma_series at w ∈ integerComplement ✓) = −γ − 1/w + sub w + (1/n − 1/(w+n)) [the split] = −1/(w+n) + H_n w ✓ ring. Then the −2n witness: W := fun s => Wtriv s − seriesFun s + 1/s + 1/(s−1) − c + H_n(s/2)/2 where Wtriv from logDeriv_zeta_sub_mult_div_eventually at ρ₀ = −2n: (hζ : riemannZeta (−2n) = 0) — need! ζ(−2n) = 0 for n ≥ 1: from zeroMult_neg_two_mul: zeroMult(−2n) = (analyticOrderAt ζ (−2n)).toNat = 1: analyticOrderAt = some 1 ≠ 0 ⟹ ζ(−2n) = 0: analyticOrderAt_eq_zero ↔ f x ≠ 0 (hh.analyticOrderAt_eq_zero.mpr used earlier in LiSides: `(....analyticOrderAt_eq_zero).mpr (by rw [zetaA_one]; norm_num)` ✓ so analyticOrderAt_eq_zero : order = 0 ↔ f x ≠ 0 — the iff for analytic f: `AnalyticAt.analyticOrderAt_eq_zero : analyticOrderAt f x = 0 ↔ f x ≠ 0`? So contrapositive: order.toNat = 1 ≠ 0 ⟹ order ≠ 0 ⟹ ¬ f x ≠ 0 ⟹ f x = 0 ✓: ```lean have hζtriv : riemannZeta (-2 * (n : ℂ)) = 0 := by by_contra h have hord := zeroMult_neg_two_mul (n) hn -- check signature: zeroMult_neg_two_mul {n : ℕ} (hn : 1 ≤ n) : zeroMult (-2 * n) = 1? — check LiTrivialZeros exact statement -- zeroMult = (analyticOrderAt ζ _).toNat; analyticOrderAt ≠ 0 (toNat = 1) have h0 : analyticOrderAt riemannZeta (-2 * (n : ℂ)) = 0 := (analyticAt_riemannZeta (by ... : -2*n ≠ 1)).analyticOrderAt_eq_zero.mpr h rw [h0] at hord -- zeroMult = (0).toNat = 0 ≠ 1 simp [zeroMult] at hord ``` Check zeroMult_neg_two_mul's exact form/signature from LiTrivialZeros — need to grep. Also its s-form: `zeroMult (-2 * ↑n) = 1`? - Wtriv analytic at −2n ✓ from the lemma + punctured: logDeriv ζ s − zeroMult(−2n)/(s−(−2n)) = Wtriv s: with zeroMult = 1 and s − (−2n) = s + 2n. - Fexpr s = W s punctured: Fexpr s = logDerivζ s − series + 1/s + 1/(s−1) − c + ψ(s/2)/2; for s near −2n, s ≠ −2n: logDerivζ s = Wtriv s + 1/(s+2n) (from the witness + zeroMult = 1) and ψ(s/2)/2 = −1/(s+2n) + H_n(s/2)/2 (from the digamma split at w = s/2 — need s/2 ∈ ball(−n, 1/2) ⟺ s ∈ ball(−2n, 1) ✓ take the s-ball radius min(1, ...)/2 etc; and s/2 ≠ −n ⟺ s ≠ −2n ✓): Fexpr s = [Wtriv s + 1/(s+2n)] − series + 1/s + 1/(s−1) − c + [−1/(s+2n) + H_n(s/2)/2] = Wtriv s − series + 1/s + 1/(s−1) − c + H_n(s/2)/2 ✓ ring. - W analytic at −2n: Wtriv ✓; seriesFun: ¬IsNontrivialZero (−2n): re = −2n < 0: `.2.1 : 0 < re` contra ✓; 1/s: −2n ≠ 0 (n ≥ 1) ✓; 1/(s−1): −2n − 1 ≠ 0 ✓; H_n(s/2)/2: H_n analytic at −n ✓ comp with s/2 (value at −2n is −n ✓) then /2 ✓. §7 nontrivial witness: ```lean lemma Fexpr_eventually_zero_of_nontrivial {ρ₀ : ℂ} (hρ : IsNontrivialZero ρ₀) : ∃ W, AnalyticAt ℂ W ρ₀ ∧ ∀ᶠ s in 𝓝[≠] ρ₀, Fexpr s = W s := by obtain ⟨W0, hW0, hW0eq⟩ := logDeriv_zeta_sub_mult_div_eventually hρ.1 (by intro h; rw [h] at hρ... : ρ₀ ≠ 1: re ρ₀ < 1: if ρ₀ = 1: re = 1 contra: `fun h => absurd (h ▸ hρ.2.2) (by simp)`? h : ρ₀ = 1: hρ.2.2 : ρ₀.re < 1: h ▸ : (1:ℂ).re < 1: simp ⟹ False: `exact fun h => by rw [h, Complex.one_re] at hρ; exact lt_irrefl 1 hρ.2.2` — careful: rw [h] at hρ rewrites everywhere incl hρ.2.2: then hρ.2.2 : (1:ℂ).re < 1?? hρ is a term of And-type: rw [h] at hρ rewrites ρ₀ → 1 in hρ's type ✓ then have hlt := hρ.2.2; rw [Complex.one_re] at hlt; exact lt_irrefl _ hlt ✓.) -- series part obtain ⟨ρ₀', rfl⟩?? — seriesFun_sub_polar_analyticAt takes ρ₀ : {ρ // IsNontrivialZero ρ} (subtype). Here ρ₀ : ℂ with hρ : IsNontrivialZero ρ₀: use ⟨ρ₀, hρ⟩ : the subtype. seriesFun_sub_polar_analyticAt ⟨ρ₀, hρ⟩ : AnalyticAt ℂ (fun s => seriesFun s − (zeroMult (⟨ρ₀,hρ⟩:ℂ)... hmm (zeroMult (↑⟨ρ₀,hρ⟩) : ℂ)/(s − ↑⟨ρ₀,hρ⟩)) ↑⟨ρ₀,hρ⟩ — coercions reduce: ↑⟨ρ₀, hρ⟩ = ρ₀ ✓ rfl. So: AnalyticAt ℂ (fun s => seriesFun s − (zeroMult ρ₀:ℂ)/(s − ρ₀)) ρ₀ ✓ after defeq coercion — may need `show` to manage the coe display. W := fun s => W0 s − (seriesFun s − m/(s−ρ₀)) + 1/s + 1/(s−1) − c + ψ(s/2)/2 — wait the Fexpr assembly: Fexpr s = logDerivζ − series + elems; logDerivζ = W0 + m/(s−ρ₀) punctured; series = (series − m/(s−ρ₀)) + m/(s−ρ₀) — trivially: Fexpr s = W0 s + m/(s−ρ₀) − seriesFun s + 1/s + 1/(s−1) − c + ψ/2 = W0 s − (seriesFun s − m/(s−ρ₀)) + 1/s + 1/(s−1) − c + ψ/2 ✓ ring (punctured). W := fun s => W0 s - (seriesFun s - (zeroMult ρ₀:ℂ)/(s - ρ₀)) + 1/s + 1/(s-1) - c + digamma(s/2)/2 analytic: W0 ✓; series-minus-polar ✓ (5e-iii); 1/s: ρ₀ ≠ 0 (re > 0 ✓); 1/(s−1): ρ₀ ≠ 1 ✓; digamma(s/2)/2: ∀ m, ρ₀/2 ≠ −↑m: re(ρ₀/2) = re ρ₀/2 > 0 ≥ ... −↑m's re = −m ≤ 0 contra ✓. punctured: filter_upwards [hW0eq] with s hs; show-unfold Fexpr; rw [hs]; ring ✓ (m/(s−ρ₀) atoms cancel). ``` §8 generic + good balls: ```lean lemma Fexpr_analyticAt_of_not_bad {s : ℂ} (hs : ¬ badPoint s) : AnalyticAt ℂ Fexpr s := by -- ζ s ≠ 0 have hζ : riemannZeta s ≠ 0 := by intro hz apply hs rcases zeta_zero_classification hz with h | h | ⟨n, hn, h⟩ · exact Or.inl h · exact Or.inr (Or.inl h) · exact Or.inr (Or.inr (Or.inr ⟨n, hn, h⟩)) have hs1 : s ≠ 1 := fun h => hs (Or.inr (Or.inr (Or.inl h))) have hs0 : s ≠ 0 := fun h => hs (Or.inr (Or.inl h)) have hlog : AnalyticAt ℂ (logDeriv riemannZeta) s := ((analyticAt_riemannZeta hs1).deriv).div (analyticAt_riemannZeta hs1) hζ have hser : AnalyticAt ℂ seriesFun s := seriesFun_analyticAt (fun h => hs (Or.inl h)) have hinv : AnalyticAt ℂ (fun s : ℂ => 1 / s) s := analyticAt_const.div analyticAt_id hs0 have hinv1 : AnalyticAt ℂ (fun s : ℂ => 1 / (s - 1)) s := analyticAt_const.div (analyticAt_id.sub analyticAt_const) (sub_ne_zero.mpr hs1) -- hmm: the g function: fun s => s − 1: analyticAt_id.sub analyticAt_const : AnalyticAt (id − const)... the lambda form again: (analyticAt_id.sub analyticAt_const) : AnalyticAt ℂ (id − fun _ => 1) s: Pi-sub vs fun s => s − 1: use apply AnalyticAt.div analyticAt_const _ ...: `apply AnalyticAt.div analyticAt_const _ (sub_ne_zero.mpr hs1)` leaves goal AnalyticAt ℂ (fun x => x − 1)?? the div unification: goal AnalyticAt (fun s => 1/(s−1)) s: apply AnalyticAt.div: pattern fun x => f x / g x: f := 1, g := fun s => s − 1 ✓ then hg0 : g s ≠ 0: (fun s => s−1) s ≠ 0 — beta: s − 1 ≠ 0 ✓ sub_ne_zero.mpr hs1 : s − 1 ≠ 0 — exact defeq ✓ might need show. Then remaining goal AnalyticAt ℂ (fun s => s − 1) s: analyticAt_id.sub analyticAt_const : AnalyticAt ℂ (id − fun _ => 1)?? — defeq id s − 1 = s − 1: exact should accept? Pi-sub again — risk. Use fun_prop? AnalyticAt fun_prop support: try `by fun_prop`. If fun_prop fails, the show-bridge. I'll write explicit term with apply and hope, else adjust. have hdig : AnalyticAt ℂ (fun s => Complex.digamma (s / 2) / 2) s := by apply analyticAt_digamma_div_two intro m h -- s/2 = −↑m ⟹ s = −2m: bad apply hs have h2 : s = -2 * (m : ℂ) := by linear_combination 2 * h -- s/2 = −m ⟹ s = −2m: h : s/2 = −↑m: 2*h: s = −2↑m ✓ linear_combination 2*h? goal s = -2*↑m: linear_combination (2 * h): LHS−RHS − 2*(hLHS−hRHS) = 0: s − (−2↑m) − 2*(s/2 − (−↑m)) = s + 2↑m − s + ... let me verify: 2*(s/2 + ↑m) = s + 2↑m: goal s + 2↑m = 0?? goal is s = −2↑m i.e. s + 2↑m = 0 ✓ linear_combination 2*h: proves (s) − (−2↑m) = 2*(s/2 − (−↑m)) ✓: s + 2↑m = 2(s/2) + 2↑m = s + 2↑m ✓. rcases Nat.eq_zero_or_pos m with hm0 | hm · subst hm0; simp at h2; exact Or.inr (Or.inl h2) -- s = 0: h2 : s = -2*↑0 = 0: simp at h2 : s = 0 · exact Or.inr (Or.inr (Or.inr ⟨m, hm, h2⟩)) have hconst : AnalyticAt ℂ (fun _ : ℂ => (Real.log Real.pi : ℂ) / 2) s := analyticAt_const -- assemble: Fexpr = (((logDerivζ − series) + 1/s) + 1/(s−1) − c) + ψ/2 — the def order: -- Fexpr s := logDeriv ζ s - seriesFun s + 1/s + 1/(s-1) - c + digamma(s/2)/2 show AnalyticAt ℂ (fun s => logDeriv riemannZeta s - seriesFun s + 1/s + 1/(s-1) - c + digamma(s/2)/2) s exact ((((hlog.sub hser).add hinv).add hinv1).sub hconst).add hdig ``` The show: Fexpr s unfolds ✓ defeq. The final assembly: the association order in Fexpr: ((((logDeriv − series) + 1/s) + 1/(s−1)) − c) + ψ/2 — my term: ((((hlog.sub hser).add hinv).add hinv1).sub hconst).add hdig : AnalyticAt ℂ (((((logDeriv ζ − seriesFun) + 1/s-lambda) + 1/(s−1)-lambda) − const) + dig-lambda) s — with Pi-ops vs the show-lambda: defeq ✓ hopefully exact accepts. If not: convert using 1 + funext simp [Pi...]. I'll handle if error. §9 the good-ball lemma: ```lean lemma exists_ball_good_of_not_bad {s : ℂ} (hs : ¬ badPoint s) : ∃ δ : ℝ, 0 < δ ∧ ∀ y ∈ Metric.ball s δ, ¬ badPoint y := by -- ζ ≠ 0 ball have hζ : riemannZeta s ≠ 0 := ... (as in §8) have hs1 : s ≠ 1 := ... obtain ⟨ε₁, hε₁, hball₁⟩ := Metric.eventually_nhds_iff_ball.mp ((analyticAt_riemannZeta hs1).continuousAt.eventually_ne hζ) -- avoid {0, 1} have hs0 : s ≠ 0 := ... set δ₀ := min (‖s‖ / 2) (‖s - 1‖ / 2)?? hmm — need δ₀ > 0 with ball(s, δ₀) avoiding {0,1}: δ₀ := min ‖s‖ ‖s−1‖ /2... ‖s‖ > 0 (s ≠ 0), ‖s−1‖ > 0 (s ≠ 1): δ₀ := min ‖s‖ ‖s−1‖ > 0... wait but if ‖s‖ huge it's fine. Take δ := min ε₁ (min ‖s‖ ‖s−1‖)/2... just δ := min ε₁ ((min ‖s‖ ‖s−1‖)/2) — positivity: min ‖s‖ ‖s−1‖ > 0 (both pos via norm_pos_iff) /2 ✓. -- every y in ball: ζ y ≠ 0 ⟹ y not nontrivial (∈ zeros contra), not −2n (ζ(−2n) = 0), and ‖y‖ ≤ ‖s‖/... y ≠ 0: ‖y − s‖ < δ ≤ ‖s‖/2 ⟹ ‖y‖ ≥ ‖s‖/2 > 0 ✓; y ≠ 1: ‖y−s‖ < ‖s−1‖/2 ⟹ ‖y−1‖ ≥ ‖s−1‖/2 > 0 ✓. ... -- y badPoint cases: nontrivial: ζ y = 0 contra hball₁; y = 0: norm contra; y = 1: contra; y = −2n: ζ(−2n) = 0 contra hball₁ — needs ζ(−2n) = 0! ``` ζ(−2n) = 0: as discussed from zeroMult_neg_two_mul — let me make a standalone lemma `riemannZeta_neg_two_mul (hn : 1 ≤ n) : riemannZeta (−2 * (n:ℂ)) = 0` (also used in §6's Wtriv). Form: what's the exact statement of zeroMult_neg_two_mul? Check LiTrivialZeros.
§0–§4 compile clean. Before writing §5–§9, let me check `zeroMult_neg_two_mul`'s exact form and the `summable_digamma_series` summand shape.
tool: Bash
input
{
  "command": "grep -n \"theorem zeroMult_neg_two_mul\\|lemma zeroMult_neg_two_mul\" -A 4 D:/Python/Quantum/research/lean/NguyenRH1/NguyenRH1/LiTrivialZeros.lean | head -8; cd D:/Python/Quantum/zeta-23-lean && sed -n '296,320p' Zeta23/GammaFacts/Series.lean",
  "description": "zeroMult_neg_two_mul signature and summable_digamma_series"
}
raw content_json (database row)
[{"type":"thinking","thinking":"§0–§4 compile clean (zero errors, zero warnings). Now §5–§9. Let me write the remaining sections:\n\n§5: digammaSeriesPart + analyticity on ball(0, 1/2) + the s=0 witness.\n§6: digammaSeriesPartSub + analyticity on ball(−n, 1/2) + the split + the −2n witness.\n§7: nontrivial-zero witness.\n§8: generic analyticity + badPoint-free balls.\n§9: Gentire + capstone.\n\nLet me draft these carefully.\n\n§5:\n```lean\n/-! ## 5. The digamma series part and the witness at s = 0 -/\n\n/-- The series part of the digamma partial-fraction expansion:\nΣ'_j (1/(j+1) − 1/(w+j+1)); analytic on ball(0, 1/2). -/\ndef digammaSeriesPart (w : ℂ) : ℂ :=\n  ∑' j : ℕ, (1 / ((j : ℂ) + 1) - 1 / (w + j + 1))\n\nlemma digammaSeriesTerm_eq {w : ℂ} {j : ℕ} (hj : (j : ℂ) + 1 ≠ 0) (hw : w + j + 1 ≠ 0) :\n    1 / ((j : ℂ) + 1) - 1 / (w + j + 1) = w / (((j : ℂ) + 1) * (w + j + 1)) := by\n  field_simp\n  ring\n```\nHmm: 1/a − 1/b = (b − a)/(ab): b − a = w+j+1 − (j+1) = w ✓: field_simp + ring ✓ (banked pattern).\n\n```lean\nlemma digammaSeriesPart_analyticOn :\n    AnalyticOnNhd ℂ digammaSeriesPart (Metric.ball 0 (1 / 2)) := by\n  have hsum : Summable (fun j : ℕ => (1 : ℝ) / ((j : ℝ) + 1) ^ 2) := summable_div_add_one_sq 1\n  have hu : HasSumUniformlyOn (fun j => fun w : ℂ => 1 / ((j : ℂ) + 1) - 1 / (w + j + 1))\n      digammaSeriesPart (Metric.ball 0 (1 / 2)) := by\n    apply HasSumUniformlyOn.of_norm_le_summable hsum\n    intro j w hw\n    -- w ∈ ball(0, 1/2): ‖w‖ < 1/2\n    have hwn : ‖w‖ < 1 / 2 := by\n      have := Metric.mem_ball.mp hw\n      rw [dist_zero_right] at this\n      exact this\n    have hj1 : (0 : ℝ) < (j : ℝ) + 1 := by positivity\n    have hwj : w + (j : ℂ) + 1 ≠ 0 := by\n      intro h\n      have : ‖w + (j : ℂ) + 1‖ = 0 := by rw [h]; exact norm_zero\n      have hge : (j : ℝ) + 1 - ‖w‖ ≤ ‖w + (j : ℂ) + 1‖ := by\n        have h1 : (w + (j : ℂ) + 1).re = w.re + (j : ℝ) + 1 := by\n          simp [Complex.add_re, Complex.one_re, Complex.natCast_re]  -- natCast_re: (↑j).re = j: `Complex.natCast_re : (↑n).re = n`? there's `Complex.natCast_re` ✓ or `RCLike.natCast_re`... hmm: (↑j : ℂ).re = (j : ℝ): `Complex.natCast_re : ((n : ℂ)).re = n`? I think `Complex.natCast_re` exists (or `RCLike.natCast_re`). Let me use `Complex.natCast_re` and adjust if error.\n        have h2 : (w + (j : ℂ) + 1).re ≤ ‖w + (j : ℂ) + 1‖ := Complex.re_le_norm _\n        have h3 : w.re ≥ -‖w‖ := neg_norm_le_re w  -- `neg_norm_le_re : -‖z‖ ≤ z.re`? `Complex.neg_norm_le_re`? hmm: `neg_norm_le.re`? The lemma: `Complex.neg_norm_le_re (z : ℂ) : -‖z‖ ≤ z.re`? or `Complex.re_le_norm` + `Complex.neg_le_norm`? There's `Complex.neg_norm_le_re`? If unsure: from abs_re_le_norm: |w.re| ≤ ‖w‖ ⟹ −‖w‖ ≤ w.re via abs_le. \n        linarith [h1, h2, h3]  -- wait hge : (j:ℝ)+1 − ‖w‖ ≤ ‖w+j+1‖: from h2: w.re + j + 1 ≤ ‖·‖ and w.re ≥ −‖w‖: j + 1 − ‖w‖ ≤ w.re + j + 1 ≤ ‖·‖ ✓\n      rw [this] at hge\n      linarith [hwn, hj1]  -- (j+1) − ‖w‖ ≤ 0 with ‖w‖ < 1/2 ≤ j+1: contra ✓\n    have hj0 : ((j : ℂ) + 1) ≠ 0 := by\n      intro h\n      have := congrArg Complex.re h\n      simp at this  -- (j+1).re = j+1 = 0: j + 1 > 0: `Complex.add_re, natCast_re, one_re`: this : (j:ℝ) + 1 = 0: positivity false: linarith? simp at this leaves ↑j + 1 = 0: then `have : (0:ℝ) < (j:ℝ)+1 := by positivity; linarith`. Hmm simp at this might close the goal if it reduces to False: (↑(j)+1 : ℝ) = 0 — simp knows Nat.cast_nonneg? `simp at this` with positivity facts... safer:\n      have h1 : ((j : ℂ) + 1).re = 0 := by rw [h]; simp\n      simp [Complex.add_re] at h1  -- (j:ℝ) + 1 = 0\n      have h2 : (0 : ℝ) < (j : ℝ) + 1 := by positivity\n      linarith\n    rw [digammaSeriesTerm_eq hj0 hwj, norm_div, norm_mul]\n    -- ‖w‖ / ((j+1) * ‖w+j+1‖) ≤ 1 / (j+1)²\n    have hnorm_ge : ((j : ℝ) + 1) * ((j : ℝ) + 1) / 2 ≤ ‖((j : ℂ) + 1) * (w + j + 1)‖ := by\n      rw [norm_mul]\n      have h1 : ‖((j : ℂ) + 1 : ℂ)‖ = (j : ℝ) + 1 := by\n        rw [show ((j : ℂ) + 1) = ((j + 1 : ℕ) : ℂ) by push_cast; ring, Complex.norm_natCast]  -- hmm: (↑j + 1 : ℂ) = ↑(j+1): push_cast; ring ✓; Complex.norm_natCast : ‖↑(j+1)‖ = ↑(j+1) — wait Complex.norm_natCast vs RCLike.norm_natCast ∀-form (journal-028 gotcha: ∀-form — use rw)... in rw position fine.\n        -- then ↑(j+1) = ↑j + 1: push_cast\n      ...\n```\nThis is getting heavy. Simplify the norm estimates: ‖(j:ℂ)+1‖ = (j:ℝ)+1: \n```lean\n      have h1 : ‖(j : ℂ) + 1‖ = (j : ℝ) + 1 := by\n        have e : ((j : ℂ) + 1) = ((j + 1 : ℕ) : ℂ) := by push_cast; ring\n        rw [e, RCLike.norm_natCast]  -- ∀-form in rw ✓\n        push_cast  -- goal ↑(j+1) = ↑j + 1: push_cast closes? push_cast : ↑(j+1) = ↑j + 1 ✓ simp form: rw [Nat.cast_add, Nat.cast_one]\n        -- safer: rw [Nat.cast_add, Nat.cast_one]\n```\nand ‖w + j + 1‖ ≥ ((j:ℝ)+1)/2: from re: (w + j + 1).re = w.re + j + 1 ≥ −‖w‖ + j + 1 > −1/2 + j + 1 = (j+1)/2 + j/2 ≥ (j+1)/2 — and ‖·‖ ≥ re: so ‖w+j+1‖ ≥ re(...) ≥ (j+1) − ‖w‖ > (j+1) − 1/2 ≥ (j+1)/2 ✓.\nThen ‖w‖/((j+1)·‖w+j+1‖) ≤ (1/2)/((j+1)·(j+1)/2) = 1/(j+1)² via div_le_div_iff₀-style juggling: \n```lean\n    have hbig : ‖w‖ / (‖(j:ℂ)+1‖ * ‖w + j + 1‖) ≤ 1 / ((j:ℝ)+1)^2 := by\n      rw [h1]  -- denominator (j+1) * ‖w+j+1‖\n      have hwj2 : ((j : ℝ) + 1) / 2 ≤ ‖w + (j : ℂ) + 1‖ := by\n        have h2 : (w + (j : ℂ) + 1).re ≤ ‖w + (j : ℂ) + 1‖ := Complex.re_le_norm _\n        have h3 : (w + (j : ℂ) + 1).re = w.re + (j : ℝ) + 1 := by\n          simp [Complex.add_re, Complex.one_re, Complex.natCast_re]  -- hmm the re of ↑j + ... : build explicitly:\n        ...\n```\nHonestly the re-computation: (w + ↑j + 1).re = w.re + (↑j).re + (1:ℂ).re = w.re + j + 1: `simp [Complex.add_re]` should give w.re + (↑j).re + 1 and (↑j).re: simp lemma `Complex.natCast_re : (↑n).re = ↑n`? I believe `Complex.natCast_re` exists as simp. To be safe: `have h3 : (w + (j:ℂ) + 1).re = w.re + j + 1 := by simp [Complex.add_re]` and if simp leaves (↑j).re, add Complex.natCast_re to the simp set. I'll write `simp [Complex.add_re, Complex.natCast_re, Complex.one_re]`.\n\nThen: −‖w‖ ≤ w.re: `neg_norm_le_re`? For ℂ: `Complex.neg_norm_le_re (z : ℂ) : -‖z‖ ≤ z.re`? — I used `abs_re_le_norm` earlier (LiDigamma used Complex.abs_re_le_norm ✓): from |w.re| ≤ ‖w‖: abs_le.mp gives both ✓: `(abs_le.mp (Complex.abs_re_le_norm w)).1 : -‖w‖ ≤ w.re` ✓.\n\nOK the estimates: let A := (j:ℝ)+1 > 0. ‖denom‖ = A·‖w+j+1‖ ≥ A·(A/2) = A²/2. ‖w‖/denom ≤ (1/2)/(A²/2) = 1/A²:\n```lean\n      rw [div_le_div_iff₀ hden0 hA20]  -- ‖w‖·A² ≤ 1·(A·‖w+j+1‖)\n      -- from ‖w‖ ≤ 1/2 (hwn.le) and A·‖w+j+1‖ ≥ A²/2: ‖w‖·A² ≤ (1/2)A² ≤ A·‖w+j+1‖?? need (1/2)A² ≤ A·‖w+j+1‖ ⟺ A/2 ≤ ‖w+j+1‖ ✓ hwj2 times A ≥ 0:\n      nlinarith [hwn.le, hwj2, hj1, ...]\n```\nLet me write: goal after div_le_div_iff₀: ‖w‖ * (A^2) ≤ 1 * (A * ‖w+j+1‖): nlinarith [hwn.le, hwj2, hj1]: from A/2 ≤ ‖w+j+1‖: A·‖w+j+1‖ ≥ A²/2 (nlinarith product A·(...) with A ≥ 0); ‖w‖·A² ≤ (1/2)·A² (product (1/2 − ‖w‖)≥0 · A² ≥ 0 — nlinarith needs A² ≥ 0: sq_nonneg): 1*(A*‖..‖) = A·‖..‖ ✓. So nlinarith [hwn.le, hwj2, hj1, sq_nonneg A]? pass the pieces: `nlinarith [hwn.le, hwj2, hj1.le, sq_nonneg ((j:ℝ)+1)]` — hmm nlinarith multiplies hypotheses pairwise automatically ✓.\n\nOK — and then TendstoLocallyUniformlyOn → differentiableOn (partial sums: each term 1/(j+1) − 1/(w+j+1) differentiable on the ball: w+j+1 ≠ 0 ✓ hwj-style for all w ∈ ball — note hwj above is per-w; inside the differentiability proof I need ∀ w ∈ ball, w + j + 1 ≠ 0 — same proof (extract a standalone lemma `add_nat_add_one_ne_zero_of_mem_ball`).\n\nLet me factor a helper:\n```lean\nlemma add_nat_add_one_ne_zero_of_mem_ball {w : ℂ} (hw : w ∈ Metric.ball 0 (1/2)) (j : ℕ) :\n    w + (j : ℂ) + 1 ≠ 0 := by\n  have hwn : ‖w‖ < 1 / 2 := by\n    have h := Metric.mem_ball.mp hw\n    rwa [dist_zero_right] at this\n  intro h\n  have hre : (w + (j : ℂ) + 1).re ≤ ‖w + (j : ℂ) + 1‖ := Complex.re_le_norm _\n  rw [h, norm_zero] at hre... \n```\nhmm: rw [h] at hre: (0:ℂ).re ≤ ‖0‖: hre : (0).re ≤ 0... then hre computes: need (w+↑j+1).re = w.re + j + 1: \n```lean\n  have h1 : (w + (j : ℂ) + 1).re = w.re + (j : ℝ) + 1 := by\n    simp [Complex.add_re, Complex.natCast_re, Complex.one_re]\n  rw [h] at h1  -- h1 : (0:ℂ).re = ... : simp: h1 : 0 = w.re + j + 1: hmm (0:ℂ).re simp to 0: `simp at h1` gives 0 = w.re + ↑j + 1\n  simp at h1  -- 0 = w.re + ↑j + 1\n  have h2 : -‖w‖ ≤ w.re := (abs_le.mp (Complex.abs_re_le_norm w)).1\n  have hj0 : (0 : ℝ) ≤ (j : ℝ) := Nat.cast_nonneg j\n  linarith  -- 0 = w.re + j + 1 ≥ −1/2 + 0 + 1 = 1/2 > 0 contra ✓\n```\n\nOK. Rather than fully elaborating every step in my head, let me write the sections and let the compiler guide. Write §5+§6 now (the digamma splits + the 0 and −2n witnesses), compile, then §7–§9.\n\nFor §6 the −n ball version: ball(−(n:ℂ), 1/2):\n- pole avoidance: w + j + 1 ≠ 0 for j ≠ n−1: w = −(j+1) ⟹ ‖w − (−n)‖ = |n − (j+1)| ≥ 1 (j+1 ≠ n) but ‖w+n‖ < 1/2 contra ✓:\n```lean\nlemma add_nat_add_one_ne_zero_of_mem_ball_neg {n : ℕ} (hn : 1 ≤ n) {w : ℂ}\n    (hw : w ∈ Metric.ball (-(n : ℂ)) (1/2)) {j : ℕ} (hj : j ≠ n - 1) :\n    w + (j : ℂ) + 1 ≠ 0 := by\n  intro h\n  -- w = −(j+1): then ‖(−n) − (−(j+1))‖ = |j+1−n| ≥ 1\n  have h1 : w = -((j : ℂ) + 1) := by linear_combination h  -- from h: w + j + 1 = 0\n  have h2 : dist w (-(n : ℂ)) < 1 / 2 := Metric.mem_ball.mp hw\n  rw [h1] at h2\n  -- dist (−(j+1)) (−n) = ‖(j+1) − n‖ = |((j:ℝ)+1) − n|\n  rw [Complex.dist_eq] at h2  -- ‖−(j+1) − −n‖ = ‖(n:ℂ) − (j+1)‖: \n  have h3 : (-((j : ℂ) + 1)) - (-(n : ℂ)) = ((n : ℂ) - ((j : ℂ) + 1)) := by ring\n  rw [h3] at h2  -- hmm rw at h2 with h3: the pattern (−(↑j+1)) − (−↑n) ✓\n  -- ‖(n:ℂ) − (↑j+1)‖ = |(n:ℝ) − (j+1)|: via norm of real cast: (n:ℂ) − (↑j+1) = ↑((n:ℝ) − (j+1)): ofReal_sub... \n  have h4 : ‖((n : ℂ) - ((j : ℂ) + 1))‖ = |(n : ℝ) - ((j : ℝ) + 1)| := by\n    rw [show (n : ℂ) - ((j : ℂ) + 1) = ((n - (j + 1) : ℕ) : ℂ)?? — no: n vs j+1 in ℕ-sub is wrong when j+1 > n. Use ℝ: ((n:ℝ) − ((j:ℝ)+1) : ℂ)? the ofReal cast: ((x : ℝ) : ℂ): `Complex.ofReal_sub`... (n:ℂ) − (↑j + 1) = ↑((n:ℝ) − (↑j + 1)): push_cast backwards: `by push_cast; ring`?? then norm of ofReal: `Complex.norm_ofReal`? `RCLike.norm_ofReal` ∀-form (LiSkeleton used RCLike.norm_ofReal ✓): rw [show ..., RCLike.norm_ofReal]: gives ‖(x:ℝ)‖ = |x|? RCLike.norm_ofReal : ‖(x : 𝕜)‖ = |x|?? For ℂ: ‖(x:ℂ-of-real)‖ = |x| — `Complex.norm_ofReal` : ‖(r : ℂ)‖ = |r| ✓ exists (or RCLike.norm_ofReal y = |y| ✓).\n    rw [show (n : ℂ) - ((j : ℂ) + 1) = (((n : ℝ) - ((j : ℝ) + 1)) : ℂ) by push_cast; ring, Complex.norm_ofReal]\n  rw [h4] at h2\n  -- |(n:ℝ) − (j+1)| ≥ 1 since n ≠ j+1 (integers)\n  have h5 : (1 : ℝ) ≤ |(n : ℝ) - ((j : ℝ) + 1)| := by\n    have hne : n ≠ j + 1 := by\n      intro hc\n      apply hj\n      omega  -- j ≠ n − 1 with n ≥ 1: j + 1 = n ⟺ j = n − 1 ✓ omega handles? hne goal: n ≠ j+1; hj : j ≠ n − 1; from hc : n = j + 1: j = n − 1 in ℕ: omega ✓ (with hn : 1 ≤ n in context? omega sees hn ✓ since hn is a hypothesis... hn : 1 ≤ n is in scope ✓).\n    -- |n − (j+1)| ≥ 1 for distinct naturals\n    rcases lt_or_gt_of_ne hne with hlt | hgt\n    · -- n < j+1: (j+1) − n ≥ 1\n      have h6 : (n : ℝ) + 1 ≤ (j : ℝ) + 1 := by exact_mod_cast Nat.succ_le_of_lt... hmm: n < j+1 ⟹ n+1 ≤ j+1: exact_mod_cast (Nat.succ_le_iff.mpr hlt)?? n+1 ≤ j+1 ⟺ n < j+1 ✓: `Nat.succ_le_of_lt hlt : n + 1 ≤ j + 1` — wait Nat.succ_le_of_lt : a < b → a+1 ≤ b: n < j+1 ⟹ n+1 ≤ j+1 ✓. Then (n:ℝ)+1 ≤ (j:ℝ)+1 via exact_mod_cast ✓. rw [abs_of_neg (by linarith : (n:ℝ) − (j+1) < 0)]; linarith.\n    · -- n > j+1\n      have h6 : (j : ℝ) + 1 + 1 ≤ (n : ℝ) := by exact_mod_cast Nat.succ_le_of_lt hgt  -- j+1+1 ≤ n\n      rw [abs_of_pos (by linarith : 0 < (n:ℝ) − (j+1))]; linarith\n  linarith\n```\nHmm wait — h3 rewrite direction: h2 : ‖−(↑j+1) − −↑n‖ < 1/2: rw [h3] at h2 ✓. But careful Complex.dist_eq : dist a b = ‖a − b‖ ✓.\n\nOK this is doable. The M-test for the sub-series: eventually-form with u j := 6n/(j+1)² for j ≥ 2n+1... wait earlier I computed with ‖w‖ ≤ 3n/2: hmm ‖w‖ ≤ ‖w+n‖... no: w ∈ ball(−n, 1/2): ‖w‖ ≤ ‖w − (−n)‖ + ‖−n‖ < 1/2 + n. So ‖w‖ < n + 1/2 ≤ 3n/2 (n ≥ 1 ✓). For j ≥ 2n+1 (so j+1 ≥ 2n+2): ‖w+j+1‖ ≥ (j+1) − ‖w‖ > (j+1) − (n+1/2) ≥ (j+1) − (j+1)/2 = (j+1)/2 ✓ ((j+1)/2 ≥ n+1 > n+1/2 ✓ since j+1 ≥ 2n+2 ⟹ (j+1)/2 ≥ n+1 ✓). So ‖term‖ = ‖w‖/((j+1)‖w+j+1‖) ≤ (n+1/2)·2/(j+1)² = (2n+1)/(j+1)² ✓. u j := (2n+1)/((j:ℝ)+1)^2 — summable via summable_div_add_one_sq (2n+1) ✓.\n\nThe cofinite eventuality: {j | ¬ (2n+1 ≤ j)} = {j | j < 2n+1} = finite (Finset.range / Set.finite_lt...): `Set.finite_lt_nat`? {j : ℕ | j < k}.Finite: `Set.finite_Iio`? or `Set.Finite.subset (Finset.finite_toSet (Finset.range ...))`: there's `Set.finite_lt_nat (k) : {j | j < k}.Finite`? I'll use `(Set.finite_lt_nat _)`. Hmm — safer: `Set.Finite.subset (Finset.finite_range ...)`: {j | j < 2n+1} = ↑(Finset.range (2n+1)): `Finset.coe_range : ↑(range k) = {j | j < k}`? `Finset.coe_range : ↑(Finset.range k) = Set.Iio k` ✓ and Set.Iio k finite: `Set.finite_Iio` ✓ exists for locally finite orders. So (Set.finite_Iio (2*n+1)).subset (fun j hj => hj) with membership defeq ✓. Then eventually_cofinite.mpr — wait direction: eventually_cofinite : (∀ᶠ x in cofinite, p x) ↔ {x | ¬p x}.Finite: rw [eventually_cofinite]; apply (Set.finite_Iio ...).subset; intro j hj; show j < 2n+1?? — {j | ¬P j} ⊆ {j | j < 2n+1}: intro j hj (hj : ¬P j); goal j ∈ {j | j < 2n+1} defeq j < 2n+1: by_contra; push Not → 2n+1 ≤ j; then prove P j contra hj ✓.\n\nHmm wait — for the sub-series M-test I need: for j ≥ 2n+1: ∀ w ∈ ball, ‖subterm j w‖ ≤ u j. subterm j w = if j = n−1 then 0 else full-term. j ≥ 2n+1 ⟹ j ≠ n−1 (2n+1 > n−1 ⟺ n > −2 ✓) ⟹ = full term: bound ✓ as computed.\n\nBut also — pole avoidance hwj for ALL j ≠ n−1 on the ball (needed for differentiability of partial sums AND for the term algebra at each w): add_nat_add_one_ne_zero_of_mem_ball_neg ✓.\n\nAnd the summability of the sub-series at each w ∈ ball — from the uniform convergence (pointwise). How to extract pointwise HasSum from HasSumUniformlyOn? There should be `HasSumUniformlyOn.hasSum (h) (hw : w ∈ s)`? Let me not need it: for the SPLIT identity I need Summable (sub at w) — get it by comparison with the FULL series at w (‖sub‖ ≤ ‖full‖ pointwise via if-zero; full summable at w ∈ integerComplement via Zeta23 summable_digamma_series). ✓ no pointwise-extraction needed. But wait — the M-test conclusion gives HasSumUniformlyOn of sub → its limit = ∑' sub = digammaSeriesPartSub — fine, no pointwise summability needed from it.\n\nHmm, actually — is the eventual M-test (of_norm_le_summable_eventually) applicable with the if-term? The bound holds eventually ✓; the head terms unconstrained ✓. Conclusion: HasSumUniformlyOn sub (fun w => ∑' j, sub j w) ball ✓ = digammaSeriesPartSub ✓ (defeq).\n\nThen differentiability of partial sums of sub on the ball: term j: if j = n−1 then 0 else full-term: full-term differentiable at w ∈ ball: 1/(j+1) const ✓; 1/(w+j+1): w+j+1 ≠ 0 (pole avoidance, j ≠ n−1 ✓; for j = n−1 the if gives 0 ✓ const).\n\nThe single-split: for w ∈ ball(−n,1/2), w ≠ −n: \ndigammaSeriesPart w = digammaSeriesPartSub n w + (1/(n:ℂ) − 1/(w+n)):\n- pointwise: full j = sub j + single j where single j := if j = n−1 then (1/(j+1) − 1/(w+j+1)) else 0 ✓ by_cases simp.\n- Summable full at w: w ∈ integerComplement: w = (k:ℤ) with ‖w+n‖ < 1/2 ⟹ |k + n| < 1/2... k integer, n nat: |k+n| < 1/2 ⟹ k = −n ⟹ w = −n excluded ✓. So w ∈ integerComplement ⟹ summable_digamma_series gives Summable (fun j => 1/(j+1) − 1/(w+j+1)) — its exact summand form must match — check: `summable_digamma_series (hz : z ∈ integerComplement) : Summable fun n => ...` (line 298) — presumably exactly the digamma_series summand ✓.\n- Summable sub at w: of_norm_bounded (full.norm) (‖sub‖ ≤ ‖full‖ pointwise: if-zero ≤ ✓).\n- Summable single: finite support ✓.\n- tsum: full = sub + single via Summable.tsum_add (sub) (single) reversed: ∑' (sub + single) = ... with pointwise eq full = sub + single: tsum_congr.\n- single tsum = 1/n − 1/(w+n): tsum_eq_single (n−1): ∀ j ≠ n−1: single j = 0 ✓ if_neg; value at n−1: if_pos: 1/((n−1:ℂ)+1) − 1/(w+(n−1)+1) = 1/n − 1/(w+n): casts: (n−1 : ℕ) as ℂ + 1: (↑(n−1) : ℂ) + 1 = ↑n: Nat.cast_sub (hn : 1 ≤ n)... `(↑(n − 1) : ℂ) + 1 = ↑n`: Nat.cast_sub hn gives ↑(n−1) = ↑n − ↑1 = ↑n − 1: so LHS = ↑n − 1 + 1 = ↑n ✓ via push_cast/ring with the cast_sub rewrite: `rw [Nat.cast_sub hn]; push_cast; ring`? Nat.cast_sub (hn : 1 ≤ n) : ↑(n − 1) = ↑n − ↑1: then ring ✓. Handle carefully.\n\nThen H_n w := −γ − 1/w + digammaSeriesPartSub n w + 1/(n:ℂ): analytic at −n: pieces: const ✓; 1/w at −n ≠ 0 ✓ (n ≥ 1); digammaSeriesPartSub analytic on the ball (M-test) ⟹ at −n (center ✓); 1/n const ✓.\ndigamma w = −1/(w+n) + H_n w for w ∈ ball, w ≠ −n:\ndigamma w = −γ − 1/w + full w (digamma_series at w ∈ integerComplement ✓)\n        = −γ − 1/w + sub w + (1/n − 1/(w+n))  [the split]\n        = −1/(w+n) + H_n w ✓ ring.\n\nThen the −2n witness:\nW := fun s => Wtriv s − seriesFun s + 1/s + 1/(s−1) − c + H_n(s/2)/2\nwhere Wtriv from logDeriv_zeta_sub_mult_div_eventually at ρ₀ = −2n: (hζ : riemannZeta (−2n) = 0) — need! ζ(−2n) = 0 for n ≥ 1: from zeroMult_neg_two_mul: zeroMult(−2n) = (analyticOrderAt ζ (−2n)).toNat = 1: analyticOrderAt = some 1 ≠ 0 ⟹ ζ(−2n) = 0: analyticOrderAt_eq_zero ↔ f x ≠ 0 (hh.analyticOrderAt_eq_zero.mpr used earlier in LiSides: `(....analyticOrderAt_eq_zero).mpr (by rw [zetaA_one]; norm_num)` ✓ so analyticOrderAt_eq_zero : order = 0 ↔ f x ≠ 0 — the iff for analytic f: `AnalyticAt.analyticOrderAt_eq_zero : analyticOrderAt f x = 0 ↔ f x ≠ 0`? So contrapositive: order.toNat = 1 ≠ 0 ⟹ order ≠ 0 ⟹ ¬ f x ≠ 0 ⟹ f x = 0 ✓:\n```lean\n  have hζtriv : riemannZeta (-2 * (n : ℂ)) = 0 := by\n    by_contra h\n    have hord := zeroMult_neg_two_mul (n) hn  -- check signature: zeroMult_neg_two_mul {n : ℕ} (hn : 1 ≤ n) : zeroMult (-2 * n) = 1? — check LiTrivialZeros exact statement\n    -- zeroMult = (analyticOrderAt ζ _).toNat; analyticOrderAt ≠ 0 (toNat = 1)\n    have h0 : analyticOrderAt riemannZeta (-2 * (n : ℂ)) = 0 :=\n      (analyticAt_riemannZeta (by ... : -2*n ≠ 1)).analyticOrderAt_eq_zero.mpr h\n    rw [h0] at hord  -- zeroMult = (0).toNat = 0 ≠ 1\n    simp [zeroMult] at hord\n```\nCheck zeroMult_neg_two_mul's exact form/signature from LiTrivialZeros — need to grep. Also its s-form: `zeroMult (-2 * ↑n) = 1`?\n\n- Wtriv analytic at −2n ✓ from the lemma + punctured: logDeriv ζ s − zeroMult(−2n)/(s−(−2n)) = Wtriv s: with zeroMult = 1 and s − (−2n) = s + 2n.\n- Fexpr s = W s punctured: Fexpr s = logDerivζ s − series + 1/s + 1/(s−1) − c + ψ(s/2)/2; for s near −2n, s ≠ −2n: logDerivζ s = Wtriv s + 1/(s+2n) (from the witness + zeroMult = 1) and ψ(s/2)/2 = −1/(s+2n) + H_n(s/2)/2 (from the digamma split at w = s/2 — need s/2 ∈ ball(−n, 1/2) ⟺ s ∈ ball(−2n, 1) ✓ take the s-ball radius min(1, ...)/2 etc; and s/2 ≠ −n ⟺ s ≠ −2n ✓):\n  Fexpr s = [Wtriv s + 1/(s+2n)] − series + 1/s + 1/(s−1) − c + [−1/(s+2n) + H_n(s/2)/2] = Wtriv s − series + 1/s + 1/(s−1) − c + H_n(s/2)/2 ✓ ring.\n- W analytic at −2n: Wtriv ✓; seriesFun: ¬IsNontrivialZero (−2n): re = −2n < 0: `.2.1 : 0 < re` contra ✓; 1/s: −2n ≠ 0 (n ≥ 1) ✓; 1/(s−1): −2n − 1 ≠ 0 ✓; H_n(s/2)/2: H_n analytic at −n ✓ comp with s/2 (value at −2n is −n ✓) then /2 ✓.\n\n§7 nontrivial witness:\n```lean\nlemma Fexpr_eventually_zero_of_nontrivial {ρ₀ : ℂ} (hρ : IsNontrivialZero ρ₀) :\n    ∃ W, AnalyticAt ℂ W ρ₀ ∧ ∀ᶠ s in 𝓝[≠] ρ₀, Fexpr s = W s := by\n  obtain ⟨W0, hW0, hW0eq⟩ := logDeriv_zeta_sub_mult_div_eventually hρ.1 (by\n    intro h; rw [h] at hρ... : ρ₀ ≠ 1: re ρ₀ < 1: if ρ₀ = 1: re = 1 contra: `fun h => absurd (h ▸ hρ.2.2) (by simp)`? h : ρ₀ = 1: hρ.2.2 : ρ₀.re < 1: h ▸ : (1:ℂ).re < 1: simp ⟹ False: `exact fun h => by rw [h, Complex.one_re] at hρ; exact lt_irrefl 1 hρ.2.2` — careful: rw [h] at hρ rewrites everywhere incl hρ.2.2: then hρ.2.2 : (1:ℂ).re < 1?? hρ is a term of And-type: rw [h] at hρ rewrites ρ₀ → 1 in hρ's type ✓ then have hlt := hρ.2.2; rw [Complex.one_re] at hlt; exact lt_irrefl _ hlt ✓.)\n  -- series part\n  obtain ⟨ρ₀', rfl⟩?? — seriesFun_sub_polar_analyticAt takes ρ₀ : {ρ // IsNontrivialZero ρ} (subtype). Here ρ₀ : ℂ with hρ : IsNontrivialZero ρ₀: use ⟨ρ₀, hρ⟩ : the subtype. seriesFun_sub_polar_analyticAt ⟨ρ₀, hρ⟩ : AnalyticAt ℂ (fun s => seriesFun s − (zeroMult (⟨ρ₀,hρ⟩:ℂ)... hmm (zeroMult (↑⟨ρ₀,hρ⟩) : ℂ)/(s − ↑⟨ρ₀,hρ⟩)) ↑⟨ρ₀,hρ⟩ — coercions reduce: ↑⟨ρ₀, hρ⟩ = ρ₀ ✓ rfl. So: AnalyticAt ℂ (fun s => seriesFun s − (zeroMult ρ₀:ℂ)/(s − ρ₀)) ρ₀ ✓ after defeq coercion — may need `show` to manage the coe display.\n  W := fun s => W0 s − (seriesFun s − m/(s−ρ₀)) + 1/s + 1/(s−1) − c + ψ(s/2)/2 — wait the Fexpr assembly: Fexpr s = logDerivζ − series + elems; logDerivζ = W0 + m/(s−ρ₀) punctured; series = (series − m/(s−ρ₀)) + m/(s−ρ₀) — trivially: Fexpr s = W0 s + m/(s−ρ₀) − seriesFun s + 1/s + 1/(s−1) − c + ψ/2 = W0 s − (seriesFun s − m/(s−ρ₀)) + 1/s + 1/(s−1) − c + ψ/2 ✓ ring (punctured).\n  W := fun s => W0 s - (seriesFun s - (zeroMult ρ₀:ℂ)/(s - ρ₀)) + 1/s + 1/(s-1) - c + digamma(s/2)/2\n  analytic: W0 ✓; series-minus-polar ✓ (5e-iii); 1/s: ρ₀ ≠ 0 (re > 0 ✓); 1/(s−1): ρ₀ ≠ 1 ✓; digamma(s/2)/2: ∀ m, ρ₀/2 ≠ −↑m: re(ρ₀/2) = re ρ₀/2 > 0 ≥ ... −↑m's re = −m ≤ 0 contra ✓.\n  punctured: filter_upwards [hW0eq] with s hs; show-unfold Fexpr; rw [hs]; ring ✓ (m/(s−ρ₀) atoms cancel).\n```\n\n§8 generic + good balls:\n```lean\nlemma Fexpr_analyticAt_of_not_bad {s : ℂ} (hs : ¬ badPoint s) : AnalyticAt ℂ Fexpr s := by\n  -- ζ s ≠ 0\n  have hζ : riemannZeta s ≠ 0 := by\n    intro hz\n    apply hs\n    rcases zeta_zero_classification hz with h | h | ⟨n, hn, h⟩\n    · exact Or.inl h\n    · exact Or.inr (Or.inl h)\n    · exact Or.inr (Or.inr (Or.inr ⟨n, hn, h⟩))\n  have hs1 : s ≠ 1 := fun h => hs (Or.inr (Or.inr (Or.inl h)))\n  have hs0 : s ≠ 0 := fun h => hs (Or.inr (Or.inl h))\n  have hlog : AnalyticAt ℂ (logDeriv riemannZeta) s :=\n    ((analyticAt_riemannZeta hs1).deriv).div (analyticAt_riemannZeta hs1) hζ\n  have hser : AnalyticAt ℂ seriesFun s := seriesFun_analyticAt (fun h => hs (Or.inl h))\n  have hinv : AnalyticAt ℂ (fun s : ℂ => 1 / s) s := analyticAt_const.div analyticAt_id hs0\n  have hinv1 : AnalyticAt ℂ (fun s : ℂ => 1 / (s - 1)) s :=\n    analyticAt_const.div (analyticAt_id.sub analyticAt_const) (sub_ne_zero.mpr hs1)  -- hmm: the g function: fun s => s − 1: analyticAt_id.sub analyticAt_const : AnalyticAt (id − const)... the lambda form again: (analyticAt_id.sub analyticAt_const) : AnalyticAt ℂ (id − fun _ => 1) s: Pi-sub vs fun s => s − 1: use apply AnalyticAt.div analyticAt_const _ ...: `apply AnalyticAt.div analyticAt_const _ (sub_ne_zero.mpr hs1)` leaves goal AnalyticAt ℂ (fun x => x − 1)?? the div unification: goal AnalyticAt (fun s => 1/(s−1)) s: apply AnalyticAt.div: pattern fun x => f x / g x: f := 1, g := fun s => s − 1 ✓ then hg0 : g s ≠ 0: (fun s => s−1) s ≠ 0 — beta: s − 1 ≠ 0 ✓ sub_ne_zero.mpr hs1 : s − 1 ≠ 0 — exact defeq ✓ might need show. Then remaining goal AnalyticAt ℂ (fun s => s − 1) s: analyticAt_id.sub analyticAt_const : AnalyticAt ℂ (id − fun _ => 1)?? — defeq id s − 1 = s − 1: exact should accept? Pi-sub again — risk. Use fun_prop? AnalyticAt fun_prop support: try `by fun_prop`. If fun_prop fails, the show-bridge. I'll write explicit term with apply and hope, else adjust.\n  have hdig : AnalyticAt ℂ (fun s => Complex.digamma (s / 2) / 2) s := by\n    apply analyticAt_digamma_div_two\n    intro m h\n    -- s/2 = −↑m ⟹ s = −2m: bad\n    apply hs\n    have h2 : s = -2 * (m : ℂ) := by linear_combination 2 * h  -- s/2 = −m ⟹ s = −2m: h : s/2 = −↑m: 2*h: s = −2↑m ✓ linear_combination 2*h? goal s = -2*↑m: linear_combination (2 * h): LHS−RHS − 2*(hLHS−hRHS) = 0: s − (−2↑m) − 2*(s/2 − (−↑m)) = s + 2↑m − s + ... let me verify: 2*(s/2 + ↑m) = s + 2↑m: goal s + 2↑m = 0?? goal is s = −2↑m i.e. s + 2↑m = 0 ✓ linear_combination 2*h: proves (s) − (−2↑m) = 2*(s/2 − (−↑m)) ✓: s + 2↑m = 2(s/2) + 2↑m = s + 2↑m ✓.\n    rcases Nat.eq_zero_or_pos m with hm0 | hm\n    · subst hm0; simp at h2; exact Or.inr (Or.inl h2)  -- s = 0: h2 : s = -2*↑0 = 0: simp at h2 : s = 0\n    · exact Or.inr (Or.inr (Or.inr ⟨m, hm, h2⟩))\n  have hconst : AnalyticAt ℂ (fun _ : ℂ => (Real.log Real.pi : ℂ) / 2) s := analyticAt_const\n  -- assemble: Fexpr = (((logDerivζ − series) + 1/s) + 1/(s−1) − c) + ψ/2 — the def order:\n  -- Fexpr s := logDeriv ζ s - seriesFun s + 1/s + 1/(s-1) - c + digamma(s/2)/2\n  show AnalyticAt ℂ (fun s => logDeriv riemannZeta s - seriesFun s + 1/s + 1/(s-1) - c + digamma(s/2)/2) s\n  exact ((((hlog.sub hser).add hinv).add hinv1).sub hconst).add hdig\n```\nThe show: Fexpr s unfolds ✓ defeq. The final assembly: the association order in Fexpr: ((((logDeriv − series) + 1/s) + 1/(s−1)) − c) + ψ/2 — my term: ((((hlog.sub hser).add hinv).add hinv1).sub hconst).add hdig : AnalyticAt ℂ (((((logDeriv ζ − seriesFun) + 1/s-lambda) + 1/(s−1)-lambda) − const) + dig-lambda) s — with Pi-ops vs the show-lambda: defeq ✓ hopefully exact accepts. If not: convert using 1 + funext simp [Pi...]. I'll handle if error.\n\n§9 the good-ball lemma:\n```lean\nlemma exists_ball_good_of_not_bad {s : ℂ} (hs : ¬ badPoint s) :\n    ∃ δ : ℝ, 0 < δ ∧ ∀ y ∈ Metric.ball s δ, ¬ badPoint y := by\n  -- ζ ≠ 0 ball\n  have hζ : riemannZeta s ≠ 0 := ... (as in §8)\n  have hs1 : s ≠ 1 := ...\n  obtain ⟨ε₁, hε₁, hball₁⟩ := Metric.eventually_nhds_iff_ball.mp\n    ((analyticAt_riemannZeta hs1).continuousAt.eventually_ne hζ)\n  -- avoid {0, 1}\n  have hs0 : s ≠ 0 := ...\n  set δ₀ := min (‖s‖ / 2) (‖s - 1‖ / 2)?? hmm — need δ₀ > 0 with ball(s, δ₀) avoiding {0,1}: δ₀ := min ‖s‖ ‖s−1‖ /2... ‖s‖ > 0 (s ≠ 0), ‖s−1‖ > 0 (s ≠ 1): δ₀ := min ‖s‖ ‖s−1‖ > 0... wait but if ‖s‖ huge it's fine. Take δ := min ε₁ (min ‖s‖ ‖s−1‖)/2... just δ := min ε₁ ((min ‖s‖ ‖s−1‖)/2) — positivity: min ‖s‖ ‖s−1‖ > 0 (both pos via norm_pos_iff) /2 ✓.\n  -- every y in ball: ζ y ≠ 0 ⟹ y not nontrivial (∈ zeros contra), not −2n (ζ(−2n) = 0), and ‖y‖ ≤ ‖s‖/... y ≠ 0: ‖y − s‖ < δ ≤ ‖s‖/2 ⟹ ‖y‖ ≥ ‖s‖/2 > 0 ✓; y ≠ 1: ‖y−s‖ < ‖s−1‖/2 ⟹ ‖y−1‖ ≥ ‖s−1‖/2 > 0 ✓.\n  ...\n  -- y badPoint cases: nontrivial: ζ y = 0 contra hball₁; y = 0: norm contra; y = 1: contra; y = −2n: ζ(−2n) = 0 contra hball₁ — needs ζ(−2n) = 0!\n```\nζ(−2n) = 0: as discussed from zeroMult_neg_two_mul — let me make a standalone lemma `riemannZeta_neg_two_mul (hn : 1 ≤ n) : riemannZeta (−2 * (n:ℂ)) = 0` (also used in §6's Wtriv).\n\nForm: what's the exact statement of zeroMult_neg_two_mul? Check LiTrivialZeros.","signature":""},{"type":"text","text":"§0–§4 compile clean. Before writing §5–§9, let me check `zeroMult_neg_two_mul`'s exact form and the `summable_digamma_series` summand shape."},{"type":"tool_use","id":"Bash_132","name":"Bash","input":{"command":"grep -n \"theorem zeroMult_neg_two_mul\\|lemma zeroMult_neg_two_mul\" -A 4 D:/Python/Quantum/research/lean/NguyenRH1/NguyenRH1/LiTrivialZeros.lean | head -8; cd D:/Python/Quantum/zeta-23-lean && sed -n '296,320p' Zeta23/GammaFacts/Series.lean","description":"zeroMult_neg_two_mul signature and summable_digamma_series"},"extra_content":null}]