Current task: —

← Session 27 — ii′-5c/5d: Davenport disc + FE-reflection bounds

#1419 assistant 2026-08-23 08:55:37.608 UTC · 800→3061 tok open ⤢
thinking (7747 chars)
`harmonic_le_one_add_log (n : ℕ) : (↑(harmonic n) : ℝ) ≤ 1 + Real.log n` — with the ℚ→ℝ cast (the statement shows `harmonic n ≤ 1 + Real.log n` where harmonic n : ℚ is coerced to ℝ by the ≤ on ℝ... the statement `harmonic n ≤ 1 + Real.log n` — since Real.log n : ℝ, the harmonic n is coerced: (↑(harmonic n) : ℝ) ≤ ... ✓ via Rat.cast). harmonic def: ∑ i ∈ range n, (↑(i+1))⁻¹ : ℚ. So H_m (as ℝ) = ↑(harmonic m) = ∑ i ∈ range m, ((i+1 : ℚ)⁻¹ : ℝ)-cast — via Rat.cast_sum/inv/natCast simp lemmas (as used in the proof). My sums have the form ∑ 1/(i+1 : ℝ): bridge: ∑ i ∈ range m, (1:ℝ)/(i+1) = ↑(harmonic m): ``` have hharm : (∑ i ∈ Finset.range m, (1 : ℝ) / ((i : ℝ) + 1)) = (harmonic m : ℝ) := by rw [harmonic] -- unfold: ∑ i ∈ range m, (↑(i+1))⁻¹ in ℚ then cast rw [Rat.cast_sum] -- ↑(∑ ...) = ∑ ↑(...) apply Finset.sum_congr rfl intro i _ simp [Rat.cast_inv, Rat.cast_natCast, one_div] -- ↑((↑(i+1))⁻¹) = ((↑i+1:ℝ))⁻¹ = 1/(↑i+1) ``` something like that — adapt at build. `sum_range_sub'` — not found by grep (to_additive generated from prod_range_div'? probably). The telescope: I'll use `Finset.sum_range_sub'` — generated from prod_range_div' via to_additive (like sum_sdiff from journal-024). Assume it exists: `Finset.sum_range_sub' (f : ℕ → M) (n : ℕ) : ∑ i ∈ range n, (f i − f (i+1)) = f 0 − f n` — hmm wait that's `sum_range_sub'`? or `sum_range_sub : ∑ (f (i+1) − f i) = f n − f 0`? Both exist (sub and sub'). I'll use sum_range_sub' and adjust. Now let me write §1 + §2 of LiDigammaLeft.lean. Actually, let me reconsider scope once more — this file is getting big. Let me prioritize for a green boundary: §1 telescope + §2 (B). Then §3 (C) + §4 (A) + §5 (G) as a second chunk. Writing now. For (B), the detailed plan: ``` theorem norm_digamma_le_of_two_le_re {w : ℂ} (hwre : 2 ≤ w.re) (hwim : |w.im| ≤ 5) : ‖Complex.digamma w‖ ≤ 20 * Real.log (2 + ‖w‖) := by -- w off the integers? cases: w = ↑m for some m : ℤ or not by_cases hwint : ∃ m : ℤ, (m : ℂ) = w · -- integer case: w = ↑m, m ≥ 2 (re ≥ 2, im = 0) obtain ⟨m, hm⟩ := hwint -- m ≥ 2: re w = ↑m ≥ 2 (as reals): m ≥ 2 as int have hmre : w.re = (m : ℝ) := by rw [← hm]; simp have hm2 : 2 ≤ m := by by_contra h push Not at h -- m < 2 ⟹ m ≤ 1 have : (m : ℝ) ≤ 1 := by exact_mod_cast (by omega : m ≤ 1) linarith [hwre, hmre, this] -- w = ↑m with m ≥ 2: m as nat: m = ↑(m.toNat) with m.toNat ≥ 2 set n := m.toNat with hn_def have hmn : (m : ℂ) = (n : ℂ) := by rw [hn_def]; exact_mod_cast (Int.toNat_of_nonneg (by omega : 0 ≤ m)).symm -- hmm: (↑(m.toNat) : ℂ) = ↑m: Int.toNat_of_nonneg: ↑(m.toNat) = m for 0 ≤ m: `Int.toNat_of_nonneg (h : 0 ≤ m) : ↑(m.toNat) = m`? the cast: ((m.toNat : ℕ) : ℤ) = m: Int.toNat_of_nonneg ✓ — so ((n:ℂ)) = ((m.toNat:ℕ):ℂ) = ((m.toNat:ℤ):ℂ) [Nat.cast] = ↑m [Int.toNat_of_nonneg]: push_cast + the lemma: `by rw [hn_def]; push_cast [Int.toNat_of_nonneg (show (0:ℤ) ≤ m by omega)]` — direction: goal (↑m : ℂ) = (↑n : ℂ): rw [hn_def]: goal ↑m = ↑(m.toNat): norm_num? Let me: have : ((m.toNat : ℕ) : ℂ) = (m : ℂ) := by exact_mod_cast Int.toNat_of_nonneg (show (0:ℤ) ≤ m by omega) — exact_mod_cast handles the double cast ℕ→ℤ→ℂ vs ℤ→ℂ ✓ probably. Then rw [← hm, this]... -- ψ(↑n) = −γ + H_{n−1}: the identity via digamma_one + digamma_apply_add_one induction: have hpsi : Complex.digamma (n : ℂ) = -(Real.eulerMascheroniConstant : ℂ) + (harmonic (n - 1) : ℝ) := by -- induction from digamma_one: ψ(1) = −γ; ψ(k+1) = ψ(k) + 1/k; H_k = H_{k−1} + 1/k ... ``` Hmm — the digamma-at-nat identity needs its own induction (~30 lines). Is there a Mathlib lemma `Complex.digamma_natCast`? Let me grep quickly. If not, the induction: ``` have hdig1 : Complex.digamma 1 = -(Real.eulerMascheroniConstant : ℂ) := by -- ψ(1) = −γ: from digamma_apply_add_one at 1/2? no — is there digamma_one in Mathlib? The Digamma.lean had digamma_one_half. digamma_one: ψ(1) = −γ — maybe `Complex.digamma_one : digamma 1 = -eulerMascheroniConstant`? check at build; else derive: ψ(1) = ψ(1/2 + 1/2)?? no. From digamma_apply_add_one (1/2): ψ(3/2) = ψ(1/2) + 2 — doesn't give ψ(1). Hmm — ψ(1) = −γ needs the series or the definition limit. If not in Mathlib: ψ(1) = −γ via the digamma_series at z = 1?? 1 ∈ integerComplement? NO — 1 is an integer. Ugh. Via logGammaSeq?? The Mathlib def of digamma: deriv Gamma/Gamma — Gamma(1) = 1, Gamma'(1) = −γ — `Complex.deriv_Gamma_one : deriv Complex.Gamma 1 = -γ`? hmm — there's `Complex.Gamma_one_deriv`? Not sure. This is a rabbit hole. ``` ALTERNATIVE: avoid the integer case entirely by perturbing the (B) hypothesis: 5e-v needs the bound at specific points w' — which could be positive integers only in the corner case R = 4k+3 exactly (the endpoint). I can just RESTRICT 5e-i's radius to the OPEN-ish sub-window [4k+2.5, 4k+2.75]?? — no wait the issue was R = 4k+3 ⟹ (1+R)/2 = 2k+2 integer. If R ∈ [4k+2.5, 4k+3): still could hit... (1+R)/2 integer ⟺ R = 2m−1: R ∈ [4k+2.5, 4k+3): 2m−1 < 4k+3: m ≤ 2k+1: 2m−1 ≤ 4k+1 < 4k+2.5 — NO! R ≥ 4k+2.5 ⟹ 2m−1 ≥ 4k+2.5 ⟹ m ≥ 2k+1.75 ⟹ m ≥ 2k+2 ⟹ R = 2m−1 ≥ 4k+3 — excluded by R < 4k+3?? but 5e-i gives R ≤ 4k+3 inclusive. Hmm — so with R ≤ 4k+3, R = 4k+3 possible ⟹ (1+R)/2 = 2k+2 integer possible. BUT — the pigeonhole's R is any point in the window; I can just take R ≠ 4k+3... no — the existence statement gives me an R I don't control beyond the window. Wait — actually: does (B)'s application at w' = (1+R)/2 with R = 4k+3 even arise? The point s = −R (left real crossing): logDeriv ΓR(1−s) at 1−s = 1+R = 4k+4 (EVEN positive integer): w' = (1+R)/2 = 2k+2: ψ(2k+2) — fine value. The issue is ONLY the digamma_series hypothesis. So handle w' ∈ ℤ via the harmonic identity OR... hmm, actually simplest: is ψ continuous at 2k+2? YES. So I can EXTEND (B) to integers by continuity: prove (B) for w ∉ ℤ, then for w = ↑m (m ≥ 2): take w_j → ↑m non-integer... continuity + the bound on the sequence: ‖ψ(↑m)‖ = lim ‖ψ(w_j)‖ ≤ 20 log(2+‖w_j‖) → 20 log(2+m) — needs ψ continuous at ↑m (analyticity: ψ = logDeriv Gamma: Gamma analytic nonzero at ↑m (m ≥ 1: Gamma_ne_zero via ∀ k, ↑m ≠ −k ✓) ⟹ ψ continuous) and the bound closed: `le_of_tendsto`... This is ~20 lines of topology. OR the harmonic identity (needs digamma_one). Let me check what exists for digamma at 1/nat first. Actually — hmm, hold on: simpler! The 5e-v application at the LEFT real point s = −R: logDeriv ΓR(s) needs ψ(s/2) = ψ(−R/2): −R/2 ∈ [−2k−1.5, −2k−1.25]: never an integer ✓ (fractional part ≥ 1/4) — the dist condition ✓. And logDeriv ΓR(1−s) at 1+R: ψ((1+R)/2): (1+R)/2 ∈ [2k+1.75, 2k+2]: the endpoint 2k+2 (integer) only when R = 4k+3. The (B) bound at that exact point: could I just... the 5e-v circle bound needs |F| on the whole circle INCLUDING the two real crossings ±R. At s = −R with R = 4k+3: everything is finite (the point −(4k+3) is not a trivial zero — those are at EVEN negatives; ΓR(−R) = ΓR(−(4k+3)): zeros at −2n: −(4k+3) odd ⟹ ΓR ≠ 0 ✓; ψ(−R/2): −R/2 = −(2k+1.5): half-integer ✓ fine; ψ((1+R)/2) = ψ(2k+2) fine). The (B) bound at the integer point: needed. OK let me just check for digamma_one/digamma_natCast in Mathlib and the continuity fallback otherwise. Actually — you know what, the CLEANEST: prove (B) for non-integer w via the series, and handle the integer case by the recurrence REDUCTION to a half-integer!! ψ(m) = ψ(m − 1/2) − ... no: ψ(m) = ψ(m−1) + 1/(m−1) — the recurrence relates integers to integers. ψ(m) = ψ(1/2) + Σ... no: ψ(1/2 + 1) = ψ(1/2) + 2: so ψ(3/2) known; ψ(2) = ψ(1) + 1... — all integer values hang off ψ(1) = −γ. No half-integer shortcut for integers. Check Mathlib for digamma_one now. And I'll write §1 + §2 with the integer handling via whichever route pans out.
Checking for digamma values at positive integers (needed for the boundary case in B).
tool: Grep ok
input
{
  "pattern": "digamma_one|digamma_natCast|digamma_nat",
  "path": "D:\\Python\\Quantum\\zeta-23-lean\\.lake\\packages\\mathlib\\Mathlib\\Analysis\\SpecialFunctions\\Gamma",
  "output_mode": "content",
  "head_limit": 10
}
result 2026-08-23 08:55:37Z → 2026-08-23 08:55:37Z
mode='content' num_files=0 filenames=[] content='Mathlib\\Analysis\\SpecialFunctions\\Gamma\\Digamma.lean:47:theorem digamma_one : digamma 1 = - Real.eulerMascheroniConstant := by\nMathlib\\Analysis\\SpecialFunctions\\Gamma\\Digamma.lean:50:theorem digamma_one_half : digamma (1 / 2) = - 2 * log 2 - Real.eulerMascheroniConstant := by' num_lines=2 num_matches=None applied_limit=None applied_offset=None
raw content_json (database row)
[{"type":"thinking","thinking":"`harmonic_le_one_add_log (n : ℕ) : (↑(harmonic n) : ℝ) ≤ 1 + Real.log n` — with the ℚ→ℝ cast (the statement shows `harmonic n ≤ 1 + Real.log n` where harmonic n : ℚ is coerced to ℝ by the ≤ on ℝ... the statement `harmonic n ≤ 1 + Real.log n` — since Real.log n : ℝ, the harmonic n is coerced: (↑(harmonic n) : ℝ) ≤ ... ✓ via Rat.cast).\n\nharmonic def: ∑ i ∈ range n, (↑(i+1))⁻¹ : ℚ. So H_m (as ℝ) = ↑(harmonic m) = ∑ i ∈ range m, ((i+1 : ℚ)⁻¹ : ℝ)-cast — via Rat.cast_sum/inv/natCast simp lemmas (as used in the proof). My sums have the form ∑ 1/(i+1 : ℝ): bridge: ∑ i ∈ range m, (1:ℝ)/(i+1) = ↑(harmonic m): \n```\nhave hharm : (∑ i ∈ Finset.range m, (1 : ℝ) / ((i : ℝ) + 1)) = (harmonic m : ℝ) := by\n  rw [harmonic]  -- unfold: ∑ i ∈ range m, (↑(i+1))⁻¹ in ℚ then cast\n  rw [Rat.cast_sum]  -- ↑(∑ ...) = ∑ ↑(...)\n  apply Finset.sum_congr rfl\n  intro i _\n  simp [Rat.cast_inv, Rat.cast_natCast, one_div]  -- ↑((↑(i+1))⁻¹) = ((↑i+1:ℝ))⁻¹ = 1/(↑i+1)\n```\nsomething like that — adapt at build.\n\n`sum_range_sub'` — not found by grep (to_additive generated from prod_range_div'? probably). The telescope: I'll use `Finset.sum_range_sub'` — generated from prod_range_div' via to_additive (like sum_sdiff from journal-024). Assume it exists: `Finset.sum_range_sub' (f : ℕ → M) (n : ℕ) : ∑ i ∈ range n, (f i − f (i+1)) = f 0 − f n` — hmm wait that's `sum_range_sub'`? or `sum_range_sub : ∑ (f (i+1) − f i) = f n − f 0`? Both exist (sub and sub'). I'll use sum_range_sub' and adjust.\n\nNow let me write §1 + §2 of LiDigammaLeft.lean. Actually, let me reconsider scope once more — this file is getting big. Let me prioritize for a green boundary: §1 telescope + §2 (B). Then §3 (C) + §4 (A) + §5 (G) as a second chunk.\n\nWriting now. For (B), the detailed plan:\n\n```\ntheorem norm_digamma_le_of_two_le_re {w : ℂ} (hwre : 2 ≤ w.re) (hwim : |w.im| ≤ 5) :\n    ‖Complex.digamma w‖ ≤ 20 * Real.log (2 + ‖w‖) := by\n  -- w off the integers? cases: w = ↑m for some m : ℤ or not\n  by_cases hwint : ∃ m : ℤ, (m : ℂ) = w\n  · -- integer case: w = ↑m, m ≥ 2 (re ≥ 2, im = 0)\n    obtain ⟨m, hm⟩ := hwint\n    -- m ≥ 2: re w = ↑m ≥ 2 (as reals): m ≥ 2 as int\n    have hmre : w.re = (m : ℝ) := by rw [← hm]; simp\n    have hm2 : 2 ≤ m := by\n      by_contra h\n      push Not at h  -- m < 2 ⟹ m ≤ 1\n      have : (m : ℝ) ≤ 1 := by exact_mod_cast (by omega : m ≤ 1)\n      linarith [hwre, hmre, this]\n    -- w = ↑m with m ≥ 2: m as nat: m = ↑(m.toNat) with m.toNat ≥ 2\n    set n := m.toNat with hn_def\n    have hmn : (m : ℂ) = (n : ℂ) := by rw [hn_def]; exact_mod_cast (Int.toNat_of_nonneg (by omega : 0 ≤ m)).symm -- hmm: (↑(m.toNat) : ℂ) = ↑m: Int.toNat_of_nonneg: ↑(m.toNat) = m for 0 ≤ m: `Int.toNat_of_nonneg (h : 0 ≤ m) : ↑(m.toNat) = m`? the cast: ((m.toNat : ℕ) : ℤ) = m: Int.toNat_of_nonneg ✓ — so ((n:ℂ)) = ((m.toNat:ℕ):ℂ) = ((m.toNat:ℤ):ℂ) [Nat.cast] = ↑m [Int.toNat_of_nonneg]: push_cast + the lemma: `by rw [hn_def]; push_cast [Int.toNat_of_nonneg (show (0:ℤ) ≤ m by omega)]` — direction: goal (↑m : ℂ) = (↑n : ℂ): rw [hn_def]: goal ↑m = ↑(m.toNat): norm_num? Let me: have : ((m.toNat : ℕ) : ℂ) = (m : ℂ) := by exact_mod_cast Int.toNat_of_nonneg (show (0:ℤ) ≤ m by omega) — exact_mod_cast handles the double cast ℕ→ℤ→ℂ vs ℤ→ℂ ✓ probably. Then rw [← hm, this]...\n    -- ψ(↑n) = −γ + H_{n−1}: the identity via digamma_one + digamma_apply_add_one induction:\n    have hpsi : Complex.digamma (n : ℂ) = -(Real.eulerMascheroniConstant : ℂ) + (harmonic (n - 1) : ℝ) := by\n      -- induction from digamma_one: ψ(1) = −γ; ψ(k+1) = ψ(k) + 1/k; H_k = H_{k−1} + 1/k\n      ...\n```\nHmm — the digamma-at-nat identity needs its own induction (~30 lines). Is there a Mathlib lemma `Complex.digamma_natCast`? Let me grep quickly. If not, the induction:\n```\n    have hdig1 : Complex.digamma 1 = -(Real.eulerMascheroniConstant : ℂ) := by\n      -- ψ(1) = −γ: from digamma_apply_add_one at 1/2? no — is there digamma_one in Mathlib? The Digamma.lean had digamma_one_half. digamma_one: ψ(1) = −γ — maybe `Complex.digamma_one : digamma 1 = -eulerMascheroniConstant`? check at build; else derive: ψ(1) = ψ(1/2 + 1/2)?? no. From digamma_apply_add_one (1/2): ψ(3/2) = ψ(1/2) + 2 — doesn't give ψ(1). Hmm — ψ(1) = −γ needs the series or the definition limit. If not in Mathlib: ψ(1) = −γ via the digamma_series at z = 1?? 1 ∈ integerComplement? NO — 1 is an integer. Ugh. Via logGammaSeq?? The Mathlib def of digamma: deriv Gamma/Gamma — Gamma(1) = 1, Gamma'(1) = −γ — `Complex.deriv_Gamma_one : deriv Complex.Gamma 1 = -γ`? hmm — there's `Complex.Gamma_one_deriv`? Not sure. This is a rabbit hole. \n```\nALTERNATIVE: avoid the integer case entirely by perturbing the (B) hypothesis: 5e-v needs the bound at specific points w' — which could be positive integers only in the corner case R = 4k+3 exactly (the endpoint). I can just RESTRICT 5e-i's radius to the OPEN-ish sub-window [4k+2.5, 4k+2.75]?? — no wait the issue was R = 4k+3 ⟹ (1+R)/2 = 2k+2 integer. If R ∈ [4k+2.5, 4k+3): still could hit... (1+R)/2 integer ⟺ R = 2m−1: R ∈ [4k+2.5, 4k+3): 2m−1 < 4k+3: m ≤ 2k+1: 2m−1 ≤ 4k+1 < 4k+2.5 — NO! R ≥ 4k+2.5 ⟹ 2m−1 ≥ 4k+2.5 ⟹ m ≥ 2k+1.75 ⟹ m ≥ 2k+2 ⟹ R = 2m−1 ≥ 4k+3 — excluded by R < 4k+3?? but 5e-i gives R ≤ 4k+3 inclusive. Hmm — so with R ≤ 4k+3, R = 4k+3 possible ⟹ (1+R)/2 = 2k+2 integer possible. BUT — the pigeonhole's R is any point in the window; I can just take R ≠ 4k+3... no — the existence statement gives me an R I don't control beyond the window. \n\n   Wait — actually: does (B)'s application at w' = (1+R)/2 with R = 4k+3 even arise? The point s = −R (left real crossing): logDeriv ΓR(1−s) at 1−s = 1+R = 4k+4 (EVEN positive integer): w' = (1+R)/2 = 2k+2: ψ(2k+2) — fine value. The issue is ONLY the digamma_series hypothesis. So handle w' ∈ ℤ via the harmonic identity OR... hmm, actually simplest: is ψ continuous at 2k+2? YES. So I can EXTEND (B) to integers by continuity: prove (B) for w ∉ ℤ, then for w = ↑m (m ≥ 2): take w_j → ↑m non-integer... continuity + the bound on the sequence: ‖ψ(↑m)‖ = lim ‖ψ(w_j)‖ ≤ 20 log(2+‖w_j‖) → 20 log(2+m) — needs ψ continuous at ↑m (analyticity: ψ = logDeriv Gamma: Gamma analytic nonzero at ↑m (m ≥ 1: Gamma_ne_zero via ∀ k, ↑m ≠ −k ✓) ⟹ ψ continuous) and the bound closed: `le_of_tendsto`... This is ~20 lines of topology. OR the harmonic identity (needs digamma_one). Let me check what exists for digamma at 1/nat first.\n\nActually — hmm, hold on: simpler! The 5e-v application at the LEFT real point s = −R: logDeriv ΓR(s) needs ψ(s/2) = ψ(−R/2): −R/2 ∈ [−2k−1.5, −2k−1.25]: never an integer ✓ (fractional part ≥ 1/4) — the dist condition ✓. And logDeriv ΓR(1−s) at 1+R: ψ((1+R)/2): (1+R)/2 ∈ [2k+1.75, 2k+2]: the endpoint 2k+2 (integer) only when R = 4k+3. The (B) bound at that exact point: could I just... the 5e-v circle bound needs |F| on the whole circle INCLUDING the two real crossings ±R. At s = −R with R = 4k+3: everything is finite (the point −(4k+3) is not a trivial zero — those are at EVEN negatives; ΓR(−R) = ΓR(−(4k+3)): zeros at −2n: −(4k+3) odd ⟹ ΓR ≠ 0 ✓; ψ(−R/2): −R/2 = −(2k+1.5): half-integer ✓ fine; ψ((1+R)/2) = ψ(2k+2) fine). The (B) bound at the integer point: needed. \n\nOK let me just check for digamma_one/digamma_natCast in Mathlib and the continuity fallback otherwise. Actually — you know what, the CLEANEST: prove (B) for non-integer w via the series, and handle the integer case by the recurrence REDUCTION to a half-integer!! ψ(m) = ψ(m − 1/2) − ... no: ψ(m) = ψ(m−1) + 1/(m−1) — the recurrence relates integers to integers. ψ(m) = ψ(1/2) + Σ... no: ψ(1/2 + 1) = ψ(1/2) + 2: so ψ(3/2) known; ψ(2) = ψ(1) + 1... — all integer values hang off ψ(1) = −γ. No half-integer shortcut for integers.\n\nCheck Mathlib for digamma_one now. And I'll write §1 + §2 with the integer handling via whichever route pans out.","signature":""},{"type":"text","text":"Checking for digamma values at positive integers (needed for the boundary case in B)."},{"type":"tool_use","id":"Grep_257","name":"Grep","input":{"pattern":"digamma_one|digamma_natCast|digamma_nat","path":"D:\\Python\\Quantum\\zeta-23-lean\\.lake\\packages\\mathlib\\Mathlib\\Analysis\\SpecialFunctions\\Gamma","output_mode":"content","head_limit":10},"extra_content":null}]