Current task: —

← Session 29 — ii′-5e-v: circle bound (far-tail + series bounds)

#1637 assistant 2026-08-24 02:16:31.568 UTC · 787→4911 tok open ⤢
thinking (12814 chars)
`Complex.differentiableAt_Gamma (s) (hs : ∀ m : ℕ, s ≠ -m)` exists — but only DifferentiableAt, not AnalyticAt. Hmm. But wait — DifferentiableAt on an OPEN SET gives AnalyticAt? In Mathlib: `DifferentiableOn.analyticOnNhd`? or `DifferentiableOn.analyticOn` — for complex functions: differentiable on an open set ⟹ analytic there (`DifferentiableOn.analyticOn (hd : DifferentiableOn ℂ f s) (hs : IsOpen s) : AnalyticOn ℂ f s` — yes! Complex differentiability on an open set implies analyticity — Goursat's theorem is in Mathlib via `DifferentiableOn.analyticOn`). So for the continuity at s₀ = −R: Gammaℝ is differentiable on the open set U := {s | ∀ m, s/2 ≠ −(m:ℂ)} (the pole complement — hmm is it open? {s : s/2 ∈ −ℕ} = 2·(−ℕ) as a set of ℂ points: {−2m : m ∈ ℕ} — discrete: its complement is open: the set {s : ∃ m, s/2 = −m} is closed (discrete set of points — closed because it has no limit point: `Set.isClosed_of_discrete`? or via: the set is locally finite... There might be a slicker path: I only need differentiability in a NEIGHBORHOOD of s₀: take the ball B := ball s₀ (1/8): for s ∈ B: s/2 ∈ ball(s₀/2, 1/16): s₀/2 = −R/2 with dist(R/2,ℤ) ≥ 1/4: for s/2 = −m: |R/2 − m| < 1/16 + |s₀/2 − ... hmm: s/2 = −m ⟹ m = −s/2: |R/2 − m| = |R/2 + s/2| hmm: |s₀/2 − s/2| < 1/16 ⟹ |R/2 − m| ≤ |s₀/2 − s/2| + ... s₀/2 = −R/2: R/2 − m = −(s₀/2) − m = −(s₀/2 + m) = −(s₀/2 − s/2 + s/2 + m) = −(s₀/2 − s/2) − (s/2 + m) = −(s₀/2 − s/2) (since s/2 = −m): |R/2 − m| = |s₀/2 − s/2| < 1/16 < 1/4 — CONTRADICTION with hgapInt (m : ℤ) — wait m : ℕ, hgapInt (m : ℤ): |R/2 − (m:ℝ)| ≥ 1/4 ✓ contradiction. So on ball s₀ (1/8), Gammaℝ = π^{−s/2}Γ(s/2) with Γ(s/2) differentiable (s/2 avoids −ℕ ✓): differentiable ON the ball ⟹ analytic ON the ball (DifferentiableOn.analyticOn isOpen_ball) ⟹ AnalyticAt at s₀ (analyticOnNhd: AnalyticOn ball → AnalyticOnNhd at interior points — AnalyticOn is the on-Nhd version in current Mathlib?? The API: `DifferentiableOn.analyticOn : DifferentiableOn ℂ f s → IsOpen s → AnalyticOn ℂ f s` — AnalyticOn in current Mathlib means analytic on nhds of each point? (AnalyticOn got renamed: AnalyticOnNhd vs AnalyticOn — in recent Mathlib, AnalyticOnNhd s = ∀ x ∈ s, AnalyticAt, and AnalyticOn s = AnalyticOnNhd on the set... ugh naming. There's `DifferentiableOn.analyticOnNhd`? Let me just grep for the exact name when I get there.) Then logDeriv ΓR continuous at s₀: analyticAt_f.deriv.div analyticAt_f hnonzero → analyticAt → continuousAt ✓. And digamma continuous at s₀/2: analyticAt_digamma (LiFEntire, needs ∀ m, s₀/2 ≠ −(m:ℂ) ✓ from the dist argument) ✓. OK. So the im = 0 extension of (G) at s₀ (with pole-avoidance): ``` theorem logDeriv_Gammaℝ_eq_of_im_eq_zero {s₀ : ℂ} (hpoles : ∀ m : ℕ, s₀ / 2 ≠ -(m : ℂ)) : logDeriv Complex.Gammaℝ s₀ = -(Real.log Real.pi : ℂ) / 2 + (1 / 2 : ℂ) * Complex.digamma (s₀ / 2) := by -- both sides continuous at s₀; equal on the dense set {im ≠ 0} -- via tendsto uniqueness on 𝓝[≠] s₀ ``` Continuity of the pieces: - hGcont : ContinuousAt (logDeriv Complex.Gammaℝ) s₀: from analyticAt on the ball (as above) — needs the dist-to-poles at s₀/2, which I have as hpoles — but the ball argument needs a QUANTITATIVE distance: dist(s₀/2, −ℕ) > 0: from hpoles (∀ m, s₀/2 ≠ −m): the set −ℕ is closed discrete ⟹ positive distance... For s₀ = −R I have dist(R/2,ℤ) ≥ 1/4 — quantitative ✓. But the lemma as stated (hpoles only) doesn't give a quantitative distance — the ball-radius existence: {s₀/2}ᶜ ... −ℕ ∪ ... the set P := {s : ∃ m, s/2 = −(m:ℂ)} = (2·−ℕ): closed: its complement open: s₀ ∈ complement ⟹ ball. Closedness of (2·−ℕ) as a subset of ℂ: the image of −ℕ under ×2 — −ℕ ⊆ ℂ is closed (integers are closed: isClosed_intCast hmm: Set of negative integers: `Set.isClosed_intCast`? or (Set.range fun m : ℕ => −(m:ℂ)): closed via `Set.Finite.isClosed`? not finite. `isClosed_of_locallyFinite`? There IS a clean way: integers in ℂ form a closed set (Complex.isClosed_intCast? `Int.cast` closed: `isClosed_intCast` hmm — there's `Complex.isClosed_intCast`? or `Set.isClosed_range_intCast`?). This is getting heavy. ALTERNATIVE: the quantitative hypothesis: state the lemma with (hdist : ∃ c > 0, ∀ m : ℕ, c ≤ ‖s₀/2 + (m:ℂ)‖) — I HAVE that for s₀ = −R (c = 1/4-ish from hgapInt: ‖s₀/2 + m‖ = |R/2 − m|·... s₀ = −R: s₀/2 + m = m − R/2: ‖·‖ = |m − R/2| = |R/2 − m| ≥ 1/4 ✓ — well ‖(m:ℂ) − R/2·ofReal‖: m − R/2 as complex: norm = |m − R/2| ✓). So c = 1/4 works for s₀ = −R directly, no ℤ-clearance halving needed for the POLE distance (only for the (A)-application with the moving re(s/2)). So state: `logDeriv_Gammaℝ_eq_of_forall_dist {s₀ : ℂ} {c : ℝ} (hc : 0 < c) (hdist : ∀ m : ℕ, c ≤ ‖s₀ / 2 + (m : ℂ)‖) : ...`. Then ball(s₀, c): for s ∈ ball: s/2 + m: ‖s₀/2 − s/2‖ < c/2... wait: if s/2 = −m: ‖s₀/2 + m‖ = ‖s₀/2 − s/2‖ = ‖s₀ − s‖/2 < c/2 < c — contradiction with hdist. So ball(s₀, 2c)-ish avoids poles: take ball(s₀, 2c): ‖s₀ − s‖ < 2c ⟹ ‖s₀/2 − s/2‖ < c ⟹ s/2 ≠ −m ∀m (else ‖s₀/2 + m‖ < c ✗). So Gammaℝ differentiable on ball(s₀, 2c) ⟹ analytic on it ⟹ analyticAt at s₀. And digamma at s₀/2: analyticAt_digamma (hpoles from hdist: ∀ m, s₀/2 ≠ −(m:ℂ): from c ≤ ‖s₀/2 + m‖: if = −m: norm 0 < c ✗) ✓ continuous. The dense-equality: on {im ≠ 0}: (G) applies (needs s.im ≠ 0 only — logDeriv_Gammaℝ_eq's sole hypothesis ✓). So f =ᶠ[𝓝[≠] s₀] g: the set {s | s.im ≠ 0} ∈ 𝓝[≠] s₀: via: {s | s.im = 0}ᶜ: the real-line complement: dense open: membership in 𝓝[≠] s₀: `mem_nhdsWithin_of_mem_nhds`? no — 𝓝[≠] s₀ membership: s ∈ 𝓝[≠] s₀ ↔ s ∪ {s₀} ∈ 𝓝 s₀ (nhdsWithin_union_singleton?). {im ≠ 0} ∪ {s₀}: open? complement is {im = 0} ∖ {s₀} = the real line minus s₀ — closed? Hmm: {im = 0} is closed (preimage of {0} under continuous im); removing a point keeps it... {im = 0} ∖ {s₀}: closed iff... real line minus a point IS closed in ℂ (its complement {im ≠ 0} ∪ {s₀} is open? at s₀: any ball around s₀ contains im ≠ 0 points ✓ contained in the set {im≠0}∪{s₀} ✓ so s₀ is interior ✓; other points obviously interior ✓). So {im ≠ 0} ∪ {s₀} is open ∋ s₀ ⟹ ∈ 𝓝 s₀ ⟹ {im ≠ 0} ∈ 𝓝[≠] s₀ (`nhdsWithin_mem_iff`? the exact lemma: `mem_nhdsWithin_compl_iff` or `nhdsWithin_compl`... There's: `mem_nhdsWithin_iff_eventually`? Simplest: show {im ≠ 0} ∈ 𝓝[≠] s₀ via `mem_nhdsWithin_of_mem_nhds`?? no. Via the definition: 𝓝[≠] s₀ = 𝓝 s₀ ⊓ 𝓟 ({s₀}ᶜ): membership: A ∈ 𝓝[≠] s₀ iff ∃ U ∈ 𝓝 s₀, U ∩ ({s₀}ᶜ) ⊆ A: take U := {im ≠ 0} ∪ {s₀} (∈ 𝓝 s₀ as open ∋ s₀): U ∖ {s₀} = {im ≠ 0} ∩ ... ⊆ A ✓. Lemma: `mem_nhdsWithin_iff_exists_mem_nhds_inter` — used in LiDigamma:654 above ✓ same pattern.) Then: f s₀ = g s₀: tendsto_nhds_unique: both ContinuousAt: Tendsto f (𝓝[≠] s₀) (𝓝 (f s₀)) := hGcont.tendsto_nhdsWithin... (ContinuousAt → Tendsto on nhdsWithin: `(ContinuousAt.tendsto_nhdsWithin)`? or hcont.continuousWithinAt.tendsto: ContinuousAt.continuousWithinAt : ContinuousWithinAt f s s₀: ContinuousWithinAt.tendsto : Tendsto f (𝓝[s] f s₀) hmm: ContinuousWithinAt f u s₀ := Tendsto f (𝓝[u] s₀) (𝓝 (f s₀)) ✓. So hGcont.continuousWithinAt (u := {s₀}ᶜ). With the EventuallyEq f =ᶠ[𝓝[≠] s₀] g ⟹ Tendsto f (𝓝[≠] s₀) (𝓝 (f s₀)) ∧ Tendsto g (𝓝[≠] s₀) (𝓝 (g s₀)) ⟹ f s₀ = g s₀ (tendsto_nhds_unique (neBot)). `Filter.EventuallyEq.tendsto_iff`? or `tendsto_congr'`: Tendsto.congr' (h : f₁ =ᶠ[l] f₂) : Tendsto f₁ l a ↔ Tendsto f₂ l a ✓. Then tendsto_nhds_unique hnebot (h1.congr' heq) h2 — hmm tendsto_nhds_unique (hl : NeBot l) (h1 : Tendsto f l (𝓝 a)) (h2 : Tendsto f l (𝓝 b)) : a = b ✓. OK — this is all doable but it's ~80-100 lines for the extension. Hmm. Let me reconsider ONE more time whether I can avoid (G) at s = −R entirely. The ONLY place (G) at a real point is needed: case (iii)'s bracket at s = −R. The bracket: logDeriv ΓR(−R) + logDeriv ΓR(1+R). For the FE identity (logDeriv_zeta_fe) at s = −R I need differentiableAt Gammaℝ at −R and 1+R (fine via the new differentiableAt_Gammaℝ_of... hmm — wait, actually — I need AnalyticAt for the logDeriv continuity... no: logDeriv_zeta_fe's hypotheses are (hd : DifferentiableAt ℂ Complex.Gammaℝ s) — just differentiable! My new `differentiableAt_Gammaℝ_of_not_neg_nat` (cloned from the im≠0 proof with hhalf from hdist) discharges those at −R and 1+R ✓. So the remaining need: EVALUATE/BOUND ‖logDeriv ΓR(−R) + logDeriv ΓR(1+R)‖. What if I bound it via the m-shift recurrence instead of (G)? 5d's `logDeriv_Gammaℝ_shift` — what does it say exactly? From STATE session 025: "the ΓR +4 shift logDeriv_Gammaℝ_shift (Gammaℝ_def + Gamma_add_one twice + exp-form cpow arithmetic) putting both digamma arguments in re > 0". Its statement: probably logDeriv ΓR s = logDeriv ΓR (s+4) − (digamma-shift terms)... and then the bracket bound in 5d used StirlingVert's digamma_stirling on the SHIFTED arguments. For s = −R: logDeriv ΓR(−R) = logDeriv ΓR(4−R) − T(s): still needs evaluating logDeriv ΓR at the real point 4−R. Same issue one level down. The 5e-ii (G) proof itself: `logDeriv_Gammaℝ_eq` via "the m-fold shift + 5d's EventuallyEq machinery" — the proof shifts s by 2m to re > 0 and computes logDeriv via Gammaℝ_def directly at the SHIFTED point: logDeriv ΓR(s+2m) = −(logπ)/2 + ½ψ((s+2m)/2) — evaluating at s+2m with re(s+2m)/2 > 0: how does THAT evaluation avoid (G)-circularity? It uses Gammaℝ_def + Complex.logDeriv... at a point with s/2 having re > 0: Γ(s/2) differentiable + the digamma definition (logDeriv Γ = digamma by definition? Complex.digamma IS defined as deriv Γ / Γ = logDeriv Γ ✓ by definition: `Complex.digamma_def : digamma = logDeriv Gamma`? or digamma s := deriv Gamma s / Gamma s — there must be a def lemma). So at s₀ = −R: logDeriv ΓR(−R) = −(logπ)/2 + ½·(logDeriv Γ)(−R/2)·... = −(logπ)/2 + ½ψ(−R/2) — the direct computation via Gammaℝ_def: logDeriv ΓR s₀ = logDeriv (fun s => π^{−s/2}·Γ(s/2)) s₀ = deriv(π^{−s/2}Γ(s/2))/(π^{−s₀/2}Γ(s₀/2)) — computable: deriv of the product at s₀: (π^{−s/2})' = −(logπ)/2·π^{−s/2}; (Γ(s/2))' = ½·digamma(s/2)·Γ(s/2) (via deriv.comp + the digamma def). So: logDeriv ΓR s₀ = [−(logπ)/2·π^{−s₀/2}·Γ(s₀/2) + π^{−s₀/2}·½·digamma(s₀/2)·Γ(s₀/2)] / (π^{−s₀/2}Γ(s₀/2)) = −(logπ)/2 + ½ψ(s₀/2). That's a DIRECT ~40-line computation with NO continuity argument! Needs: - DifferentiableAt (fun s => (π:ℂ)^(−s/2)) s₀ ✓ (as in the im≠0 proof). - DifferentiableAt (fun s => Γ(s/2)) s₀: (Complex.differentiableAt_Gamma _ hhalf).comp ✓ (hhalf from hdist). - The derivative values: HasDerivAt (π^{−s/2}) (−(logπ)/2·π^{−s₀/2}) s₀: const_cpow hasDerivAt: `HasDerivAt.const_cpow`? and HasDerivAt (Γ(s/2)) (digamma(s₀/2)·Γ(s₀/2)·(1/2)): deriv Γ(s/2) = (deriv Γ)(s₀/2)·(1/2) = digamma(s₀/2)·Γ(s₀/2)·½ — via Complex.deriv_Gamma?? hmm: deriv Γ = digamma·Γ: `Complex.deriv_Gamma`? there should be `Complex.deriv_Gamma : deriv Gamma s = digamma s * Gamma s`?? Hmm — digamma is DEFINED as logDeriv Gamma (logDeriv Γ s = deriv Γ s / Γ s) so deriv Γ s = digamma s · Γ s — from the definition + Γ(s) ≠ 0: `Complex.digamma_def`? Let me check Complex.digamma's definition in Mathlib. Actually — logDeriv f s = deriv f s / f s BY DEFINITION (logDeriv_def). And Complex.digamma s := logDeriv Complex.Gamma s (I believe digamma is DEFINED as logDeriv Gamma in Mathlib — `Complex.digamma : ℂ → ℂ := fun s => logDeriv Gamma s`? or via the Weierstrass form... In Mathlib: `Complex.digamma (s : ℂ) : ℂ := deriv Gamma s / Gamma s`?? Let me grep.) Then logDeriv ΓR s₀ computation: ``` have hdef : Complex.Gammaℝ = fun z : ℂ => (Real.pi : ℂ) ^ (-z / 2) * Complex.Gamma (z / 2) := funext Complex.Gammaℝ_def rw [hdef] rw [logDeriv_apply, ((h1.hasDerivAt).mul (h2.hasDerivAt)).deriv] -- deriv of product -- then field_simp with the nonvanishing: π^{−s₀/2}·Γ(s₀/2) ≠ 0 ``` Hmm — the deriv of the product: (f·g)' = f'·g + f·g' (HasDerivAt.mul.deriv? `HasDerivAt.mul (hf : HasDerivAt f f' x) (hg : HasDerivAt g g' x) : HasDerivAt (f·g) (f'·g x + f x·g') x` — .deriv gives the deriv form ✓). And the pieces: f := fun z => (π:ℂ)^(−z/2): f' : HasDerivAt f (−(log π)/2·π^{−s₀/2}·(1/2)?? — const_cpow: d/dz π^{−z/2} = π^{−z/2}·log π·(−1/2): HasDerivAt.const_cpow (hf : HasDerivAt f f' x) (h : ...) : HasDerivAt (fun x => c^(f x)) (c^(f x)·log c·f') x — the Mathlib form: `HasDerivAt.const_cpow (hf : HasDerivAt f f' x) (hc : c ≠ 0 ∨ ...)`: in Mathlib: `HasDerivAt.const_cpow (hf : HasDerivAt f f' x) (h : a ≠ 0 ∨ f x ≠ 0) : HasDerivAt (fun x => a ^ f x) (a ^ f x * (Complex.log a * f')) x`? something like that. Used in 5d's gammaR_shift_four proof region — there are cpow computations in LiReflect already. And g := fun z => Γ(z/2): HasDerivAt Γ(z/2) (digamma(s₀/2)·Γ(s₀/2)·(1/2)): HasDerivAt.comp: (hasDerivAt_Gamma?). Is there `Complex.hasDerivAt_Gamma (s) (hs) : HasDerivAt Gamma (digamma s * Gamma s) s`?? digamma is DEFINED as deriv Γ/Γ so deriv Γ s = digamma s·Γ s — if digamma is defined as the logDeriv: `Complex.digamma_def : digamma = logDeriv Gamma`? hmm. Let me grep Complex.digamma's definition.
Check how `Complex.digamma` is defined in this Mathlib (logDeriv of Gamma?) and the cpow/Gamma deriv API.
tool: Bash
input
{
  "command": "cd \"D:/Python/Quantum/research/lean/NguyenRH1\" && grep -rn \"def digamma\\|digamma_def\\|noncomputable def digamma\" ../../../zeta-23-lean/.lake/packages/mathlib/Mathlib/ 2>/dev/null | head -8",
  "description": "Find digamma definition"
}
raw content_json (database row)
[{"type":"thinking","thinking":"`Complex.differentiableAt_Gamma (s) (hs : ∀ m : ℕ, s ≠ -m)` exists — but only DifferentiableAt, not AnalyticAt. Hmm. But wait — DifferentiableAt on an OPEN SET gives AnalyticAt? In Mathlib: `DifferentiableOn.analyticOnNhd`? or `DifferentiableOn.analyticOn` — for complex functions: differentiable on an open set ⟹ analytic there (`DifferentiableOn.analyticOn (hd : DifferentiableOn ℂ f s) (hs : IsOpen s) : AnalyticOn ℂ f s` — yes! Complex differentiability on an open set implies analyticity — Goursat's theorem is in Mathlib via `DifferentiableOn.analyticOn`).\n\nSo for the continuity at s₀ = −R: Gammaℝ is differentiable on the open set U := {s | ∀ m, s/2 ≠ −(m:ℂ)} (the pole complement — hmm is it open? {s : s/2 ∈ −ℕ} = 2·(−ℕ) as a set of ℂ points: {−2m : m ∈ ℕ} — discrete: its complement is open: the set {s : ∃ m, s/2 = −m} is closed (discrete set of points — closed because it has no limit point: `Set.isClosed_of_discrete`? or via: the set is locally finite... There might be a slicker path: I only need differentiability in a NEIGHBORHOOD of s₀: take the ball B := ball s₀ (1/8): for s ∈ B: s/2 ∈ ball(s₀/2, 1/16): s₀/2 = −R/2 with dist(R/2,ℤ) ≥ 1/4: for s/2 = −m: |R/2 − m| < 1/16 + |s₀/2 − ... hmm: s/2 = −m ⟹ m = −s/2: |R/2 − m| = |R/2 + s/2| hmm: |s₀/2 − s/2| < 1/16 ⟹ |R/2 − m| ≤ |s₀/2 − s/2| + ... s₀/2 = −R/2: R/2 − m = −(s₀/2) − m = −(s₀/2 + m) = −(s₀/2 − s/2 + s/2 + m) = −(s₀/2 − s/2) − (s/2 + m) = −(s₀/2 − s/2) (since s/2 = −m): |R/2 − m| = |s₀/2 − s/2| < 1/16 < 1/4 — CONTRADICTION with hgapInt (m : ℤ) — wait m : ℕ, hgapInt (m : ℤ): |R/2 − (m:ℝ)| ≥ 1/4 ✓ contradiction. So on ball s₀ (1/8), Gammaℝ = π^{−s/2}Γ(s/2) with Γ(s/2) differentiable (s/2 avoids −ℕ ✓): differentiable ON the ball ⟹ analytic ON the ball (DifferentiableOn.analyticOn isOpen_ball) ⟹ AnalyticAt at s₀ (analyticOnNhd: AnalyticOn ball → AnalyticOnNhd at interior points — AnalyticOn is the on-Nhd version in current Mathlib?? The API: `DifferentiableOn.analyticOn : DifferentiableOn ℂ f s → IsOpen s → AnalyticOn ℂ f s` — AnalyticOn in current Mathlib means analytic on nhds of each point? (AnalyticOn got renamed: AnalyticOnNhd vs AnalyticOn — in recent Mathlib, AnalyticOnNhd s = ∀ x ∈ s, AnalyticAt, and AnalyticOn s = AnalyticOnNhd on the set... ugh naming. There's `DifferentiableOn.analyticOnNhd`? Let me just grep for the exact name when I get there.)\n\nThen logDeriv ΓR continuous at s₀: analyticAt_f.deriv.div analyticAt_f hnonzero → analyticAt → continuousAt ✓.\n\nAnd digamma continuous at s₀/2: analyticAt_digamma (LiFEntire, needs ∀ m, s₀/2 ≠ −(m:ℂ) ✓ from the dist argument) ✓.\n\nOK. So the im = 0 extension of (G) at s₀ (with pole-avoidance): \n```\ntheorem logDeriv_Gammaℝ_eq_of_im_eq_zero {s₀ : ℂ} (hpoles : ∀ m : ℕ, s₀ / 2 ≠ -(m : ℂ)) :\n    logDeriv Complex.Gammaℝ s₀ = -(Real.log Real.pi : ℂ) / 2 + (1 / 2 : ℂ) * Complex.digamma (s₀ / 2) := by\n  -- both sides continuous at s₀; equal on the dense set {im ≠ 0}\n  -- via tendsto uniqueness on 𝓝[≠] s₀\n```\nContinuity of the pieces:\n- hGcont : ContinuousAt (logDeriv Complex.Gammaℝ) s₀: from analyticAt on the ball (as above) — needs the dist-to-poles at s₀/2, which I have as hpoles — but the ball argument needs a QUANTITATIVE distance: dist(s₀/2, −ℕ) > 0: from hpoles (∀ m, s₀/2 ≠ −m): the set −ℕ is closed discrete ⟹ positive distance... For s₀ = −R I have dist(R/2,ℤ) ≥ 1/4 — quantitative ✓. But the lemma as stated (hpoles only) doesn't give a quantitative distance — the ball-radius existence: {s₀/2}ᶜ ... −ℕ ∪ ... the set P := {s : ∃ m, s/2 = −(m:ℂ)} = (2·−ℕ): closed: its complement open: s₀ ∈ complement ⟹ ball. Closedness of (2·−ℕ) as a subset of ℂ: the image of −ℕ under ×2 — −ℕ ⊆ ℂ is closed (integers are closed: isClosed_intCast hmm: Set of negative integers: `Set.isClosed_intCast`? or (Set.range fun m : ℕ => −(m:ℂ)): closed via `Set.Finite.isClosed`? not finite. `isClosed_of_locallyFinite`? There IS a clean way: integers in ℂ form a closed set (Complex.isClosed_intCast? `Int.cast` closed: `isClosed_intCast` hmm — there's `Complex.isClosed_intCast`? or `Set.isClosed_range_intCast`?). This is getting heavy. ALTERNATIVE: the quantitative hypothesis: state the lemma with (hdist : ∃ c > 0, ∀ m : ℕ, c ≤ ‖s₀/2 + (m:ℂ)‖) — I HAVE that for s₀ = −R (c = 1/4-ish from hgapInt: ‖s₀/2 + m‖ = |R/2 − m|·... s₀ = −R: s₀/2 + m = m − R/2: ‖·‖ = |m − R/2| = |R/2 − m| ≥ 1/4 ✓ — well ‖(m:ℂ) − R/2·ofReal‖: m − R/2 as complex: norm = |m − R/2| ✓). So c = 1/4 works for s₀ = −R directly, no ℤ-clearance halving needed for the POLE distance (only for the (A)-application with the moving re(s/2)).\n  So state: `logDeriv_Gammaℝ_eq_of_forall_dist {s₀ : ℂ} {c : ℝ} (hc : 0 < c) (hdist : ∀ m : ℕ, c ≤ ‖s₀ / 2 + (m : ℂ)‖) : ...`.\n  Then ball(s₀, c): for s ∈ ball: s/2 + m: ‖s₀/2 − s/2‖ < c/2... wait: if s/2 = −m: ‖s₀/2 + m‖ = ‖s₀/2 − s/2‖ = ‖s₀ − s‖/2 < c/2 < c — contradiction with hdist. So ball(s₀, 2c)-ish avoids poles: take ball(s₀, 2c): ‖s₀ − s‖ < 2c ⟹ ‖s₀/2 − s/2‖ < c ⟹ s/2 ≠ −m ∀m (else ‖s₀/2 + m‖ < c ✗). So Gammaℝ differentiable on ball(s₀, 2c) ⟹ analytic on it ⟹ analyticAt at s₀.\n  And digamma at s₀/2: analyticAt_digamma (hpoles from hdist: ∀ m, s₀/2 ≠ −(m:ℂ): from c ≤ ‖s₀/2 + m‖: if = −m: norm 0 < c ✗) ✓ continuous.\n  The dense-equality: on {im ≠ 0}: (G) applies (needs s.im ≠ 0 only — logDeriv_Gammaℝ_eq's sole hypothesis ✓). So f =ᶠ[𝓝[≠] s₀] g: the set {s | s.im ≠ 0} ∈ 𝓝[≠] s₀: via: {s | s.im = 0}ᶜ: the real-line complement: dense open: membership in 𝓝[≠] s₀: `mem_nhdsWithin_of_mem_nhds`? no — 𝓝[≠] s₀ membership: s ∈ 𝓝[≠] s₀ ↔ s ∪ {s₀} ∈ 𝓝 s₀ (nhdsWithin_union_singleton?). {im ≠ 0} ∪ {s₀}: open? complement is {im = 0} ∖ {s₀} = the real line minus s₀ — closed? Hmm: {im = 0} is closed (preimage of {0} under continuous im); removing a point keeps it... {im = 0} ∖ {s₀}: closed iff... real line minus a point IS closed in ℂ (its complement {im ≠ 0} ∪ {s₀} is open? at s₀: any ball around s₀ contains im ≠ 0 points ✓ contained in the set {im≠0}∪{s₀} ✓ so s₀ is interior ✓; other points obviously interior ✓). So {im ≠ 0} ∪ {s₀} is open ∋ s₀ ⟹ ∈ 𝓝 s₀ ⟹ {im ≠ 0} ∈ 𝓝[≠] s₀ (`nhdsWithin_mem_iff`? the exact lemma: `mem_nhdsWithin_compl_iff` or `nhdsWithin_compl`... There's: `mem_nhdsWithin_iff_eventually`? Simplest: show {im ≠ 0} ∈ 𝓝[≠] s₀ via `mem_nhdsWithin_of_mem_nhds`?? no. Via the definition: 𝓝[≠] s₀ = 𝓝 s₀ ⊓ 𝓟 ({s₀}ᶜ): membership: A ∈ 𝓝[≠] s₀ iff ∃ U ∈ 𝓝 s₀, U ∩ ({s₀}ᶜ) ⊆ A: take U := {im ≠ 0} ∪ {s₀} (∈ 𝓝 s₀ as open ∋ s₀): U ∖ {s₀} = {im ≠ 0} ∩ ... ⊆ A ✓. Lemma: `mem_nhdsWithin_iff_exists_mem_nhds_inter` — used in LiDigamma:654 above ✓ same pattern.)\n  Then: f s₀ = g s₀: tendsto_nhds_unique: both ContinuousAt: Tendsto f (𝓝[≠] s₀) (𝓝 (f s₀)) := hGcont.tendsto_nhdsWithin... (ContinuousAt → Tendsto on nhdsWithin: `(ContinuousAt.tendsto_nhdsWithin)`? or hcont.continuousWithinAt.tendsto: ContinuousAt.continuousWithinAt : ContinuousWithinAt f s s₀: ContinuousWithinAt.tendsto : Tendsto f (𝓝[s] f s₀) hmm: ContinuousWithinAt f u s₀ := Tendsto f (𝓝[u] s₀) (𝓝 (f s₀)) ✓. So hGcont.continuousWithinAt (u := {s₀}ᶜ). With the EventuallyEq f =ᶠ[𝓝[≠] s₀] g ⟹ Tendsto f (𝓝[≠] s₀) (𝓝 (f s₀)) ∧ Tendsto g (𝓝[≠] s₀) (𝓝 (g s₀)) ⟹ f s₀ = g s₀ (tendsto_nhds_unique (neBot)). `Filter.EventuallyEq.tendsto_iff`? or `tendsto_congr'`: Tendsto.congr' (h : f₁ =ᶠ[l] f₂) : Tendsto f₁ l a ↔ Tendsto f₂ l a ✓. Then tendsto_nhds_unique hnebot (h1.congr' heq) h2 — hmm tendsto_nhds_unique (hl : NeBot l) (h1 : Tendsto f l (𝓝 a)) (h2 : Tendsto f l (𝓝 b)) : a = b ✓.\n\nOK — this is all doable but it's ~80-100 lines for the extension. Hmm. Let me reconsider ONE more time whether I can avoid (G) at s = −R entirely.\n\nThe ONLY place (G) at a real point is needed: case (iii)'s bracket at s = −R. The bracket: logDeriv ΓR(−R) + logDeriv ΓR(1+R). For the FE identity (logDeriv_zeta_fe) at s = −R I need differentiableAt Gammaℝ at −R and 1+R (fine via the new differentiableAt_Gammaℝ_of... hmm — wait, actually — I need AnalyticAt for the logDeriv continuity... no: logDeriv_zeta_fe's hypotheses are (hd : DifferentiableAt ℂ Complex.Gammaℝ s) — just differentiable! My new `differentiableAt_Gammaℝ_of_not_neg_nat` (cloned from the im≠0 proof with hhalf from hdist) discharges those at −R and 1+R ✓.\n\nSo the remaining need: EVALUATE/BOUND ‖logDeriv ΓR(−R) + logDeriv ΓR(1+R)‖. What if I bound it via the m-shift recurrence instead of (G)? 5d's `logDeriv_Gammaℝ_shift` — what does it say exactly? From STATE session 025: \"the ΓR +4 shift logDeriv_Gammaℝ_shift (Gammaℝ_def + Gamma_add_one twice + exp-form cpow arithmetic) putting both digamma arguments in re > 0\". Its statement: probably logDeriv ΓR s = logDeriv ΓR (s+4) − (digamma-shift terms)... and then the bracket bound in 5d used StirlingVert's digamma_stirling on the SHIFTED arguments. For s = −R: logDeriv ΓR(−R) = logDeriv ΓR(4−R) − T(s): still needs evaluating logDeriv ΓR at the real point 4−R. Same issue one level down.\n\nThe 5e-ii (G) proof itself: `logDeriv_Gammaℝ_eq` via \"the m-fold shift + 5d's EventuallyEq machinery\" — the proof shifts s by 2m to re > 0 and computes logDeriv via Gammaℝ_def directly at the SHIFTED point: logDeriv ΓR(s+2m) = −(logπ)/2 + ½ψ((s+2m)/2) — evaluating at s+2m with re(s+2m)/2 > 0: how does THAT evaluation avoid (G)-circularity? It uses Gammaℝ_def + Complex.logDeriv... at a point with s/2 having re > 0: Γ(s/2) differentiable + the digamma definition (logDeriv Γ = digamma by definition? Complex.digamma IS defined as deriv Γ / Γ = logDeriv Γ ✓ by definition: `Complex.digamma_def : digamma = logDeriv Gamma`? or digamma s := deriv Gamma s / Gamma s — there must be a def lemma). So at s₀ = −R: logDeriv ΓR(−R) = −(logπ)/2 + ½·(logDeriv Γ)(−R/2)·... = −(logπ)/2 + ½ψ(−R/2) — the direct computation via Gammaℝ_def: logDeriv ΓR s₀ = logDeriv (fun s => π^{−s/2}·Γ(s/2)) s₀ = deriv(π^{−s/2}Γ(s/2))/(π^{−s₀/2}Γ(s₀/2)) — computable: deriv of the product at s₀: (π^{−s/2})' = −(logπ)/2·π^{−s/2}; (Γ(s/2))' = ½·digamma(s/2)·Γ(s/2) (via deriv.comp + the digamma def). So:\nlogDeriv ΓR s₀ = [−(logπ)/2·π^{−s₀/2}·Γ(s₀/2) + π^{−s₀/2}·½·digamma(s₀/2)·Γ(s₀/2)] / (π^{−s₀/2}Γ(s₀/2)) = −(logπ)/2 + ½ψ(s₀/2).\nThat's a DIRECT ~40-line computation with NO continuity argument! Needs:\n- DifferentiableAt (fun s => (π:ℂ)^(−s/2)) s₀ ✓ (as in the im≠0 proof).\n- DifferentiableAt (fun s => Γ(s/2)) s₀: (Complex.differentiableAt_Gamma _ hhalf).comp ✓ (hhalf from hdist).\n- The derivative values: HasDerivAt (π^{−s/2}) (−(logπ)/2·π^{−s₀/2}) s₀: const_cpow hasDerivAt: `HasDerivAt.const_cpow`? and HasDerivAt (Γ(s/2)) (digamma(s₀/2)·Γ(s₀/2)·(1/2)): deriv Γ(s/2) = (deriv Γ)(s₀/2)·(1/2) = digamma(s₀/2)·Γ(s₀/2)·½ — via Complex.deriv_Gamma?? hmm: deriv Γ = digamma·Γ: `Complex.deriv_Gamma`? there should be `Complex.deriv_Gamma : deriv Gamma s = digamma s * Gamma s`?? Hmm — digamma is DEFINED as logDeriv Gamma (logDeriv Γ s = deriv Γ s / Γ s) so deriv Γ s = digamma s · Γ s — from the definition + Γ(s) ≠ 0: `Complex.digamma_def`? Let me check Complex.digamma's definition in Mathlib.\n\nActually — logDeriv f s = deriv f s / f s BY DEFINITION (logDeriv_def). And Complex.digamma s := logDeriv Complex.Gamma s (I believe digamma is DEFINED as logDeriv Gamma in Mathlib — `Complex.digamma : ℂ → ℂ := fun s => logDeriv Gamma s`? or via the Weierstrass form... In Mathlib: `Complex.digamma (s : ℂ) : ℂ := deriv Gamma s / Gamma s`?? Let me grep.)\n\nThen logDeriv ΓR s₀ computation:\n```\nhave hdef : Complex.Gammaℝ = fun z : ℂ => (Real.pi : ℂ) ^ (-z / 2) * Complex.Gamma (z / 2) := funext Complex.Gammaℝ_def\nrw [hdef]\nrw [logDeriv_apply, ((h1.hasDerivAt).mul (h2.hasDerivAt)).deriv] -- deriv of product\n-- then field_simp with the nonvanishing: π^{−s₀/2}·Γ(s₀/2) ≠ 0\n```\nHmm — the deriv of the product: (f·g)' = f'·g + f·g' (HasDerivAt.mul.deriv? `HasDerivAt.mul (hf : HasDerivAt f f' x) (hg : HasDerivAt g g' x) : HasDerivAt (f·g) (f'·g x + f x·g') x` — .deriv gives the deriv form ✓).\nAnd the pieces: f := fun z => (π:ℂ)^(−z/2): f' : HasDerivAt f (−(log π)/2·π^{−s₀/2}·(1/2)?? — const_cpow: d/dz π^{−z/2} = π^{−z/2}·log π·(−1/2): HasDerivAt.const_cpow (hf : HasDerivAt f f' x) (h : ...) : HasDerivAt (fun x => c^(f x)) (c^(f x)·log c·f') x — the Mathlib form: `HasDerivAt.const_cpow (hf : HasDerivAt f f' x) (hc : c ≠ 0 ∨ ...)`: in Mathlib: `HasDerivAt.const_cpow (hf : HasDerivAt f f' x) (h : a ≠ 0 ∨ f x ≠ 0) : HasDerivAt (fun x => a ^ f x) (a ^ f x * (Complex.log a * f')) x`? something like that. Used in 5d's gammaR_shift_four proof region — there are cpow computations in LiReflect already. And g := fun z => Γ(z/2): HasDerivAt Γ(z/2) (digamma(s₀/2)·Γ(s₀/2)·(1/2)): HasDerivAt.comp: (hasDerivAt_Gamma?). Is there `Complex.hasDerivAt_Gamma (s) (hs) : HasDerivAt Gamma (digamma s * Gamma s) s`?? digamma is DEFINED as deriv Γ/Γ so deriv Γ s = digamma s·Γ s — if digamma is defined as the logDeriv: `Complex.digamma_def : digamma = logDeriv Gamma`? hmm.\n\nLet me grep Complex.digamma's definition.","signature":""},{"type":"text","text":"Check how `Complex.digamma` is defined in this Mathlib (logDeriv of Gamma?) and the cpow/Gamma deriv API."},{"type":"tool_use","id":"Bash_153","name":"Bash","input":{"command":"cd \"D:/Python/Quantum/research/lean/NguyenRH1\" && grep -rn \"def digamma\\|digamma_def\\|noncomputable def digamma\" ../../../zeta-23-lean/.lake/packages/mathlib/Mathlib/ 2>/dev/null | head -8","description":"Find digamma definition"},"extra_content":null}]