← Session 28 — ii′-5e: partial-fraction identity (zero series + F entire)
thinking (13346 chars)
Let me check a couple more things for the Ncount bridge:
1. `zerosIn_finite` (Zeta23) — used in LiContour's zeroWindow_finite ✓.
2. The Ncount window additivity: Ncount a c = Ncount a b + Ncount b c for a ≤ b ≤ c — from zerosIn disjoint union. zerosIn T₁ T₂ := {ρ | IsNontrivialZero ρ ∧ T₁ < ρ.im ∧ ρ.im ≤ T₂}. zerosIn a c = zerosIn a b ∪ zerosIn b c when a ≤ b ≤ c ✓ disjoint (im ≤ b vs b < im) ✓. finsum over union: `finsum_union (hd : Disjoint s t) (hs : s.Finite) (ht : t.Finite) : ∑ᶠ x ∈ s ∪ t, f x = ∑ᶠ x ∈ s, f x + ∑ᶠ x ∈ t, f x` ✓ should exist.
Let me draft LiCircleBound.lean §0–§2 now.
§0 conj:
```lean
lemma isNontrivialZero_conj {ρ : ℂ} (hρ : IsNontrivialZero ρ) :
IsNontrivialZero ((starRingEnd ℂ) ρ) := by
refine ⟨?_, ?_, ?_⟩
· rw [riemannZeta_conj, hρ.1]... wait riemannZeta_conj : ζ (conj s) = conj (ζ s): conj is starRingEnd ℂ: rw [riemannZeta_conj, hρ.1, map_zero] — hmm riemannZeta_conj's LHS form: `riemannZeta (conj s)` where conj = starRingEnd ℂ s ✓: goal riemannZeta ((starRingEnd ℂ) ρ) = 0: rw [riemannZeta_conj, hρ.1, map_zero] — riemannZeta_conj s : riemannZeta (conj s) = conj (riemannZeta s) — the pattern (conj s) = (starRingEnd ℂ) s ✓ same.
· rw [Complex.conj_re]; exact hρ.2.1
· rw [Complex.conj_re]; exact hρ.2.2
```
And the ordinate: (starRingEnd ℂ ρ).im = −ρ.im : Complex.conj_im ✓.
§1 the count bridges:
```lean
/-- The local-count constant (Zeta23's RvM local count, [Tit86 Thm 9.2];
mult-weighted, two-sided, ALL t — no perimeter). -/
def A0count : ℝ := Classical.choose Zeta23.RvM.zeta_local_zero_count
lemma A0count_ge : (1 : ℝ) ≤ A0count := (Classical.choose_spec Zeta23.RvM.zeta_local_zero_count).1
lemma Ncount_window_le (t : ℝ) :
(Zeta23.Ncount t (t + 1) : ℝ) ≤ A0count * Real.log (|t| + 3) :=
(Classical.choose_spec Zeta23.RvM.zeta_local_zero_count).2 t
```
Wait — Ncount's namespace: `Zeta23.Ncount`? It's defined in Zeta23/Statement.lean line 49: `def Ncount (T₁ T₂ : ℝ) : ℕ := ∑ᶠ ρ ∈ zerosIn T₁ T₂, zeroMult ρ` — inside namespace Zeta23? The Statement.lean — check the namespace. The zeta_local_zero_count statement uses bare Ncount inside `namespace Zeta23.RvM`? — the theorem is Zeta23.RvM.zeta_local_zero_count and its statement says `(Ncount t (t + 1) : ℝ)` — Ncount resolves to Zeta23.Ncount presumably (open Zeta23 inside?). I'll use Zeta23.Ncount and adjust.
Window additivity lemma:
```lean
lemma Ncount_add_of_le {a b c : ℝ} (hab : a ≤ b) (hbc : b ≤ c) :
Zeta23.Ncount a c = Zeta23.Ncount a b + Zeta23.Ncount b c := by
rw [Zeta23.Ncount, Zeta23.Ncount, Zeta23.Ncount] -- unfold? Ncount is a def: rw [Ncount]?? — use `show` or simp only [Zeta23.Ncount]?? hmm — the def is Zeta23.Ncount: `unfold Zeta23.Ncount`? or `simp only [Zeta23.Ncount]`? The zerosIn union split:
have hunion : zerosIn a c = zerosIn a b ∪ zerosIn b c := by
ext ρ
simp [zerosIn] -- membership: IsNontrivialZero ∧ a < im ∧ im ≤ c ↔ ...
constructor
· rintro ⟨hρ, ha, hc⟩
rcases le_or_lt ρ.im b with h | h
· exact Or.inl ⟨hρ, ha, h⟩
· exact Or.inr ⟨hρ, h, hc⟩
· rintro (⟨hρ, ha, hb⟩ | ⟨hρ, hb, hc⟩)
· exact ⟨hρ, ha, hb.trans hbc⟩?? wait zerosIn a b: b-bound is ρ.im ≤ b: zerosIn a c needs ≤ c: hb : ρ.im ≤ b ≤ c ✓ ⟨hρ, ha, le_trans hb hbc⟩
· exact ⟨hρ, lt_of_le_of_lt hab?? hb.1 : b < ρ.im with a ≤ b: a < ρ.im ✓ lt_of_le_of_lt hab hb.1 — wait hab : a ≤ b, hb.1 : b < ρ.im ⟹ a < ρ.im: lt_of_le_of_lt hab hb.1 ✓, hc⟩
rw [hunion]
exact finsum_union (disjoint: zerosIn a b ∩ zerosIn b c = ∅ — disjoint_iff: ρ in both: im ≤ b ∧ b < im — contra) (zerosIn_finite a b) (zerosIn_finite b c)
```
Check `finsum_union` signature: `finsum_union (hs : s.Finite) (ht : t.Finite) (h : Disjoint s t)? : ∑ᶠ x ∈ (s ∪ t), f x = ...` — argument order varies; check. And zerosIn_finite is in Zeta23 namespace (used in LiContour: `zerosIn_finite (a-1) (a+1)` unqualified with open Zeta23 ✓).
Then:
```lean
lemma Ncount_le_of_interval {a b : ℝ} (hab : a ≤ b) :
(Zeta23.Ncount a b : ℝ) ≤ A0count * (b - a + 2) * Real.log (max |a| |b| + 3) := by
-- split into unit windows (a, a+1], ..., (a+N−1, a+N], (a+N, b]
-- N := ⌊b − a⌋₊ windows + last partial; count N+1 ≤ b−a+2? if b−a < 1: N = 0: single partial window (a, b]: Ncount a b ≤ Ncount a (a+1) (subset) ≤ A₀ log(|a|+3)... hmm — b could be < a+1: Ncount a b ≤ Ncount a (a+1) ✓ subset (zerosIn a b ⊆ zerosIn a (a+1) since b ≤ a+1) via finsum-le: `finsum_le_finsum`?? or toFinset card... The cleanest: prove by strong induction on ⌊b−a⌋₊? OR simpler: directly bound by unit windows with the Finset cover:
```
Hmm — let me think about the cleanest form. Actually simpler: I'll bound Ncount a b by covering with ≤ ⌈b−a⌉₊+1 unit windows. Induction-free approach:
zerosIn a b ⊆ zerosIn a (a + (N+1)) where N := ⌊b−a⌋₊... this still needs additivity to split. Let me just do the induction on N with the additivity lemma:
```lean
lemma Ncount_le_of_interval_aux (N : ℕ) (a : ℝ) :
(Zeta23.Ncount a (a + N) : ℝ) ≤ A0count * (N + 1) * Real.log (|a| + N + 3) := by
induction N with
| zero =>
simp -- Ncount a a = 0 (zerosIn a a = ∅: a < im ≤ a impossible)
-- need: zerosIn a a = ∅: `zerosIn a a`: T₁ < im ≤ T₁ impossible: finsum over ∅ = 0:
| succ N ih =>
rw [show a + (N+1 : ℕ) = (a + N) + 1 by push_cast; ring]
-- hmm: a + ↑(N+1) = (a + ↑N) + 1: push_cast ring ✓
rw [Ncount_add_of_le (by linarith) (by linarith)] -- Ncount a (a+N+1) = Ncount a (a+N) + Ncount (a+N) (a+N+1)
push_cast
rw [Nat.cast_add, ...]
-- ≤ A₀(N+1)log(|a|+N+3) + A₀ log(|a+N|+3) ≤ A₀(N+2)log(|a|+N+1+3)
have h1 := ih
have h2 := Ncount_window_le (a + N)
-- log(|a+N|+3) ≤ log(|a|+N+3): |a+N| ≤ |a|+N ✓
...
```
The base: Ncount a a: zerosIn a a = ∅ ⟹ finsum = 0: zerosIn a a: {ρ | nontriv ∧ a < im ∧ im ≤ a} = ∅: Set.eq_empty: ... then finsum_mem_empty... `finsum_empty`? For ∑ᶠ ρ ∈ ∅: finsum_mem_empty : ∑ᶠ x ∈ (∅ : Set α), f x = 0 ✓. So Ncount a a = 0: unfold zerosIn: ext/simp. Then 0 ≤ anything ✓.
Then the general interval: Ncount a b with N := ⌈b − a⌉₊: zerosIn a b ⊆ zerosIn a (a + N) (since b ≤ a + ⌈b−a⌉₊ ✓ Nat.le_ceil) ⟹ Ncount a b ≤ Ncount a (a+N) (subset monotonicity: finsum_le_finsum of nonneg...: `finsum_le_finsum (h : ∀ x ∈ t, f x ≤ g x)?? no — subset version: for f ≥ 0: ∑ᶠ x ∈ s, f ≤ ∑ᶠ x ∈ t, f for s ⊆ t: `finsum_le_finsum_of_subset`? hmm — via toFinset: ∑ᶠ = ∑ toFinset; toFinset-subset: `Set.Finite.toFinset_subset_toFinset`... + Finset.sum_le_sum_of_subset_of_nonneg ✓ (zeroMult nonneg cast). ~20 lines bridge.
Then: Ncount a b ≤ Ncount a (a+N) ≤ A₀(N+1)·log(|a|+N+3) with N = ⌈b−a⌉₊ ≤ b−a+1 (for b−a ≥ 0: ⌈x⌉₊ ≤ x+1 ✓ Nat.ceil_le... `Nat.ceil_le : ⌈x⌉₊ ≤ ...`? Nat.ceil_lt_add_one gives < x+1 ⟹ ≤ b−a+1 when b−a ≥ 0? Nat.ceil_lt_add_one (h : 0 ≤ x) : ⌈x⌉₊ < x + 1 — as naturals: ⌈x⌉₊ ≤ ⌊...⌋: (⌈x⌉₊ : ℝ) < x+1 ⟹ (⌈x⌉₊:ℝ) ≤ b−a+1... < is fine) and |a|+N+3 ≤ max(|a|,|b|)+... |a| + (b−a+1) + 3 ≤ ... ≤ 2·max(|a|,|b|) + 4 — meh constants. Let me simplify the final form: Ncount a b ≤ A₀·(b−a+2)·log(2·max|a||b| + 4)?? Ugh the log argument. Cleaner: since a ≤ b and I mostly use [a, b] with a ≥ 2 (heights) or symmetric ±: use |a| ≤ |b|... Hmm — actually in my applications the intervals are [L, 2L] etc. with a ≥ 1: then |a| + N + 3 ≤ b + (b−a+1) + 3 ≤ 2b + 4: log ≤ log(2b+4). Let me just state the aux with its natural form and the final interval lemma as:
`Ncount_le_of_interval {a b} (h2 : 2 ≤ a) (hab : a ≤ b) : (Ncount a b : ℝ) ≤ A0count * (b - a + 2) * Real.log (2 * b + 4)`
(the h2 condition lets me drop |·|: a ≥ 2 ⟹ positive heights; the lower-side windows come via the conj symmetry or... wait — my shells use |γ| ∈ [2^j, 2^{j+1}] — both signs: zeros with γ ∈ [a,b] and γ ∈ [−b,−a] — the negative side: Ncount (−b) (−a) ≤ A₀(b−a+2)·log(|−b|+3) via the direct application ✓ (Ncount covers all t ✓) — with |−b| = b ✓. So state two-sided: Ncount a b ≤ A₀(b−a+2)·log(|b|+3) for 0 ≤ a ≤ b? For a ≥ 0: t ∈ [a, b]: |t| ≤ |b| = b ✓. So:
`Ncount_le_of_interval {a b} (ha : 0 ≤ a) (hab : a ≤ b) : (Ncount a b : ℝ) ≤ A0count * (b - a + 2) * Real.log (b + 3)` — hmm but the aux's log argument: |a| + N + 3 with a ≥ 0: = a + N + 3 ≤ a + (b−a+1) + 3 = b + 4: log(b+4) vs log(b+3): fine adjust: use b + 4: whatever — pick log(2*b)+4... Let me not over-polish constants: state with log (b + 4).
Hmm wait — also need the aux base-case form: Ncount a (a + 0) = Ncount a a = 0 ≤ A₀·1·log(...) ✓.
Actually — hold on, let me reconsider: is the unit-step induction giving N+1 windows for length N — off-by-one: (a, a+N] splits into N unit windows (a+j, a+j+1] for j = 0..N−1 — N windows, not N+1! Ncount a (a+N) = Σ_{j<N} Ncount (a+j)(a+j+1) ≤ N·A₀·log(|a|+N−1+3)-ish. With the induction: Ncount a (a+N+1) = Ncount a (a+N) + Ncount (a+N)(a+N+1): ih gives ≤ N·A₀·log(|a|+N+3) (strengthened form!) — let me set the aux form: Ncount a (a+N) ≤ A₀·N·log(|a|+N+3)?? base N = 0: Ncount a a = 0 ≤ 0 ✓ (A₀·0·log = 0 ✓). Step: Ncount a (a+N+1) ≤ A₀N·log(|a|+N+3) + A₀·log(|a+N|+3) ≤ A₀(N+1)·log(|a|+N+1+3): |a+N| ≤ |a|+N ✓ log-mono ✓ and |a|+N+3 ≤ |a|+N+1+3 ✓: linarith ✓. So aux: Ncount a (a+N) ≤ A₀·N·log(|a|+N+3) ✓ N windows ✓.
Then interval: Ncount a b ≤ Ncount a (a+⌈b−a⌉₊) ≤ A₀·⌈b−a⌉₊·log(|a|+⌈b−a⌉₊+3) ≤ A₀·(b−a+1)·log(2b+4)-ish (⌈x⌉₊ ≤ x+1 for x ≥ 0 ✓ (⌈x⌉₊ < x+1 ⟹ ⌈x⌉₊ ≤ ⌈... as reals (⌈b−a⌉₊:ℝ) < (b−a)+1 ⟹ ≤ b−a+1 exactly? < x+1 for naturals means ≤ ⌊x⌋+1... as real: (⌈x⌉₊:ℝ) < x+1 ⟹ (⌈x⌉₊:ℝ) ≤ x+1 (le_of_lt) ✓ good enough).
Fine. §2 the Dirichlet bound:
```lean
/-- The Dirichlet bound: ‖ζ′/ζ s‖ ≤ C₂ for re s ≥ 2, with
C₂ := ∑' n, ‖LSeries.term (fun n => (Λ n : ℂ)) 2 n‖ (the absolutely
summable majorant; −ζ′/ζ = LSeries Λ for re > 1). -/
def dirichletC2 : ℝ := ∑' n : ℕ, ‖LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : ℂ)) 2 n‖
```
Hmm — the Λ form: in Zeta23 they wrote `(fun n ↦ ↑(Λ n))` with Λ := ArithmeticFunction.vonMangoldt (open ArithmeticFunction?). The LSeriesSummable: `ArithmeticFunction.LSeriesSummable_vonMangoldt (hs : 1 < s.re)` ✓ (used in ZetaBounds). The equation: `ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div (hs : 1 < s.re) : L ↗Λ s = -deriv (riemannZeta) s / riemannZeta s`? — from the grep: `LSeries_vonMangoldt_eq_deriv_riemannZeta_div {s} (hs : 1 < s.re)` at Mathlib/NumberTheory/LSeries/Dirichlet.lean:436 — namespace ArithmeticFunction presumably: `LSeries_vonMangoldt_eq_deriv_riemannZeta_div : L ↗Λ s = -deriv (L 1) s / L 1 s`?? no wait line 429: `LSeries_vonMangoldt_eq (hs : 1 < s.re) : L ↗Λ s = - deriv (L 1) s / L 1 s` and 436 `LSeries_vonMangoldt_eq_deriv_riemannZeta_div`: probably `L ↗Λ s = - deriv riemannZeta s / riemannZeta s` ✓. The `L ↗Λ` notation: `ArithmeticFunction.LSeries`? the ↗Λ is the arithmetic-function-to-LSeries coercion: `LSeries (fun n => (Λ n : ℂ)) s`? In ZetaBounds they unfolded `LSeries` after rw — so L ↗Λ s = LSeries (fun n => ↑(Λ n)) s — there must be a rfl/simp bridge (`ArithmeticFunction.LSeries_eq`? or the ↗ notation IS `fun n => (f n : ℂ)`...). The notation `L f` for arithmetic function f is LSeries (fun n => (f n : ℂ)); `↗Λ` is the coercion of vonMangoldt to ℕ → ℂ... I'll handle with the ZetaBounds pattern verbatim: rw [← ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div hs]; unfold LSeries...
The lemma:
```lean
lemma norm_logDeriv_zeta_le_dirichlet {s : ℂ} (hs : 2 ≤ s.re) :
‖logDeriv riemannZeta s‖ ≤ dirichletC2 := by
have hs1 : 1 < s.re := by linarith
have hsum : Summable (fun n => ‖LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : ℂ)) s n‖) := by
rw [summable_norm_iff]?? — from ZetaBounds: `rw [summable_norm_iff]; exact ArithmeticFunction.LSeriesSummable_vonMangoldt hs1` — wait that was for ‖term‖: summable_norm_iff : Summable (fun i => ‖f i‖) ↔ Summable f? no: `summable_norm_iff : Summable (fun x => ‖f x‖) ↔ Summable f`?? that's false in general (needs... for LSeries terms it was used: hmm `summable_norm_iff` exists? In ZetaBounds: `have summable_abs_value : Summable (fun i ↦ ‖LSeries.term ... s₁ i‖) := by rw [summable_norm_iff]; exact ArithmeticFunction.LSeriesSummable_vonMangoldt s₁_re_geq_one` — hmm summable_norm_iff might be LSeries-term-specific... whatever — copy the pattern.
-- main: ‖LSeries Λ s‖ ≤ ∑' ‖term s‖ ≤ ∑' ‖term 2‖
have h1 : -logDeriv riemannZeta s = LSeries (fun n => (ArithmeticFunction.vonMangoldt n : ℂ)) s := by
rw [ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div hs1]
rw [logDeriv_apply] -- logDeriv f s = deriv f s / f s: goal: -(-deriv ζ s/ζ s)?? LSeries_vonMangoldt_eq_deriv_riemannZeta_div : L ↗Λ s = -deriv riemannZeta s / riemannZeta s: so LSeries Λ s = -(deriv ζ/ζ) = -logDeriv ζ:
...
```
Careful with the ↗Λ vs (fun n => ↑(Λ n)) bridge: the ZetaBounds code: `rw [← (ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div s₁_re_geq_one)]; unfold LSeries` — so L ↗Λ s rewrites to LSeries form then unfold LSeries gives the tsum. The `↗Λ` : ArithmeticFunction.vonMangoldt's coercion into (ℕ → ℂ)?? the notation `L ↗Λ`... In the ZetaBounds usage the rewrite target was `LSeries (fun n => (Λ n:ℂ)) s₁`-form after unfold. Hmm — actually the cleanest: I'll prove my lemma using their exact tactic sequence. Let me look at what `L ↗Λ` unfolds to and just mirror. Actually from VerticalLine.lean:91: `-logDeriv riemannZeta ((c:ℂ) + t*I) = LSeries (fun n => (Λ n : ℂ)) ((c:ℂ)+t*I)` — proved somewhere — let me check how.
Let me check how WeilEF/VerticalLine.lean proves the −logDeriv = LSeries identity (to mirror it exactly).
tool: Bash
input
{
"command": "cd D:/Python/Quantum/zeta-23-lean && sed -n '85,100p' Zeta23/WeilEF/VerticalLine.lean && grep -n \"LSeries_vonMangoldt_eq\\|vonMangoldt_eq_logDeriv\\|logDeriv_riemannZeta_eq\" Zeta23/WeilEF/VerticalLine.lean | head -5 && sed -n '425,445p' .lake/packages/mathlib/Mathlib/NumberTheory/LSeries/Dirichlet.lean",
"description": "The \u2212logDeriv = LSeries identity pattern"
}
raw content_json (database row)
[{"type":"thinking","thinking":"Let me check a couple more things for the Ncount bridge:\n1. `zerosIn_finite` (Zeta23) — used in LiContour's zeroWindow_finite ✓.\n2. The Ncount window additivity: Ncount a c = Ncount a b + Ncount b c for a ≤ b ≤ c — from zerosIn disjoint union. zerosIn T₁ T₂ := {ρ | IsNontrivialZero ρ ∧ T₁ < ρ.im ∧ ρ.im ≤ T₂}. zerosIn a c = zerosIn a b ∪ zerosIn b c when a ≤ b ≤ c ✓ disjoint (im ≤ b vs b < im) ✓. finsum over union: `finsum_union (hd : Disjoint s t) (hs : s.Finite) (ht : t.Finite) : ∑ᶠ x ∈ s ∪ t, f x = ∑ᶠ x ∈ s, f x + ∑ᶠ x ∈ t, f x` ✓ should exist.\n\nLet me draft LiCircleBound.lean §0–§2 now.\n\n§0 conj:\n```lean\nlemma isNontrivialZero_conj {ρ : ℂ} (hρ : IsNontrivialZero ρ) :\n IsNontrivialZero ((starRingEnd ℂ) ρ) := by\n refine ⟨?_, ?_, ?_⟩\n · rw [riemannZeta_conj, hρ.1]... wait riemannZeta_conj : ζ (conj s) = conj (ζ s): conj is starRingEnd ℂ: rw [riemannZeta_conj, hρ.1, map_zero] — hmm riemannZeta_conj's LHS form: `riemannZeta (conj s)` where conj = starRingEnd ℂ s ✓: goal riemannZeta ((starRingEnd ℂ) ρ) = 0: rw [riemannZeta_conj, hρ.1, map_zero] — riemannZeta_conj s : riemannZeta (conj s) = conj (riemannZeta s) — the pattern (conj s) = (starRingEnd ℂ) s ✓ same.\n · rw [Complex.conj_re]; exact hρ.2.1\n · rw [Complex.conj_re]; exact hρ.2.2\n```\nAnd the ordinate: (starRingEnd ℂ ρ).im = −ρ.im : Complex.conj_im ✓.\n\n§1 the count bridges:\n```lean\n/-- The local-count constant (Zeta23's RvM local count, [Tit86 Thm 9.2];\nmult-weighted, two-sided, ALL t — no perimeter). -/\ndef A0count : ℝ := Classical.choose Zeta23.RvM.zeta_local_zero_count\n\nlemma A0count_ge : (1 : ℝ) ≤ A0count := (Classical.choose_spec Zeta23.RvM.zeta_local_zero_count).1\n\nlemma Ncount_window_le (t : ℝ) :\n (Zeta23.Ncount t (t + 1) : ℝ) ≤ A0count * Real.log (|t| + 3) :=\n (Classical.choose_spec Zeta23.RvM.zeta_local_zero_count).2 t\n```\nWait — Ncount's namespace: `Zeta23.Ncount`? It's defined in Zeta23/Statement.lean line 49: `def Ncount (T₁ T₂ : ℝ) : ℕ := ∑ᶠ ρ ∈ zerosIn T₁ T₂, zeroMult ρ` — inside namespace Zeta23? The Statement.lean — check the namespace. The zeta_local_zero_count statement uses bare Ncount inside `namespace Zeta23.RvM`? — the theorem is Zeta23.RvM.zeta_local_zero_count and its statement says `(Ncount t (t + 1) : ℝ)` — Ncount resolves to Zeta23.Ncount presumably (open Zeta23 inside?). I'll use Zeta23.Ncount and adjust.\n\nWindow additivity lemma:\n```lean\nlemma Ncount_add_of_le {a b c : ℝ} (hab : a ≤ b) (hbc : b ≤ c) :\n Zeta23.Ncount a c = Zeta23.Ncount a b + Zeta23.Ncount b c := by\n rw [Zeta23.Ncount, Zeta23.Ncount, Zeta23.Ncount] -- unfold? Ncount is a def: rw [Ncount]?? — use `show` or simp only [Zeta23.Ncount]?? hmm — the def is Zeta23.Ncount: `unfold Zeta23.Ncount`? or `simp only [Zeta23.Ncount]`? The zerosIn union split:\n have hunion : zerosIn a c = zerosIn a b ∪ zerosIn b c := by\n ext ρ\n simp [zerosIn] -- membership: IsNontrivialZero ∧ a < im ∧ im ≤ c ↔ ...\n constructor\n · rintro ⟨hρ, ha, hc⟩\n rcases le_or_lt ρ.im b with h | h\n · exact Or.inl ⟨hρ, ha, h⟩\n · exact Or.inr ⟨hρ, h, hc⟩\n · rintro (⟨hρ, ha, hb⟩ | ⟨hρ, hb, hc⟩)\n · exact ⟨hρ, ha, hb.trans hbc⟩?? wait zerosIn a b: b-bound is ρ.im ≤ b: zerosIn a c needs ≤ c: hb : ρ.im ≤ b ≤ c ✓ ⟨hρ, ha, le_trans hb hbc⟩\n · exact ⟨hρ, lt_of_le_of_lt hab?? hb.1 : b < ρ.im with a ≤ b: a < ρ.im ✓ lt_of_le_of_lt hab hb.1 — wait hab : a ≤ b, hb.1 : b < ρ.im ⟹ a < ρ.im: lt_of_le_of_lt hab hb.1 ✓, hc⟩\n rw [hunion]\n exact finsum_union (disjoint: zerosIn a b ∩ zerosIn b c = ∅ — disjoint_iff: ρ in both: im ≤ b ∧ b < im — contra) (zerosIn_finite a b) (zerosIn_finite b c)\n```\nCheck `finsum_union` signature: `finsum_union (hs : s.Finite) (ht : t.Finite) (h : Disjoint s t)? : ∑ᶠ x ∈ (s ∪ t), f x = ...` — argument order varies; check. And zerosIn_finite is in Zeta23 namespace (used in LiContour: `zerosIn_finite (a-1) (a+1)` unqualified with open Zeta23 ✓).\n\nThen:\n```lean\nlemma Ncount_le_of_interval {a b : ℝ} (hab : a ≤ b) :\n (Zeta23.Ncount a b : ℝ) ≤ A0count * (b - a + 2) * Real.log (max |a| |b| + 3) := by\n -- split into unit windows (a, a+1], ..., (a+N−1, a+N], (a+N, b]\n -- N := ⌊b − a⌋₊ windows + last partial; count N+1 ≤ b−a+2? if b−a < 1: N = 0: single partial window (a, b]: Ncount a b ≤ Ncount a (a+1) (subset) ≤ A₀ log(|a|+3)... hmm — b could be < a+1: Ncount a b ≤ Ncount a (a+1) ✓ subset (zerosIn a b ⊆ zerosIn a (a+1) since b ≤ a+1) via finsum-le: `finsum_le_finsum`?? or toFinset card... The cleanest: prove by strong induction on ⌊b−a⌋₊? OR simpler: directly bound by unit windows with the Finset cover:\n```\nHmm — let me think about the cleanest form. Actually simpler: I'll bound Ncount a b by covering with ≤ ⌈b−a⌉₊+1 unit windows. Induction-free approach: \nzerosIn a b ⊆ zerosIn a (a + (N+1)) where N := ⌊b−a⌋₊... this still needs additivity to split. Let me just do the induction on N with the additivity lemma:\n\n```lean\nlemma Ncount_le_of_interval_aux (N : ℕ) (a : ℝ) :\n (Zeta23.Ncount a (a + N) : ℝ) ≤ A0count * (N + 1) * Real.log (|a| + N + 3) := by\n induction N with\n | zero => \n simp -- Ncount a a = 0 (zerosIn a a = ∅: a < im ≤ a impossible)\n -- need: zerosIn a a = ∅: `zerosIn a a`: T₁ < im ≤ T₁ impossible: finsum over ∅ = 0: \n | succ N ih =>\n rw [show a + (N+1 : ℕ) = (a + N) + 1 by push_cast; ring]\n -- hmm: a + ↑(N+1) = (a + ↑N) + 1: push_cast ring ✓\n rw [Ncount_add_of_le (by linarith) (by linarith)] -- Ncount a (a+N+1) = Ncount a (a+N) + Ncount (a+N) (a+N+1)\n push_cast\n rw [Nat.cast_add, ...]\n -- ≤ A₀(N+1)log(|a|+N+3) + A₀ log(|a+N|+3) ≤ A₀(N+2)log(|a|+N+1+3)\n have h1 := ih\n have h2 := Ncount_window_le (a + N)\n -- log(|a+N|+3) ≤ log(|a|+N+3): |a+N| ≤ |a|+N ✓\n ...\n```\nThe base: Ncount a a: zerosIn a a = ∅ ⟹ finsum = 0: zerosIn a a: {ρ | nontriv ∧ a < im ∧ im ≤ a} = ∅: Set.eq_empty: ... then finsum_mem_empty... `finsum_empty`? For ∑ᶠ ρ ∈ ∅: finsum_mem_empty : ∑ᶠ x ∈ (∅ : Set α), f x = 0 ✓. So Ncount a a = 0: unfold zerosIn: ext/simp. Then 0 ≤ anything ✓.\n\nThen the general interval: Ncount a b with N := ⌈b − a⌉₊: zerosIn a b ⊆ zerosIn a (a + N) (since b ≤ a + ⌈b−a⌉₊ ✓ Nat.le_ceil) ⟹ Ncount a b ≤ Ncount a (a+N) (subset monotonicity: finsum_le_finsum of nonneg...: `finsum_le_finsum (h : ∀ x ∈ t, f x ≤ g x)?? no — subset version: for f ≥ 0: ∑ᶠ x ∈ s, f ≤ ∑ᶠ x ∈ t, f for s ⊆ t: `finsum_le_finsum_of_subset`? hmm — via toFinset: ∑ᶠ = ∑ toFinset; toFinset-subset: `Set.Finite.toFinset_subset_toFinset`... + Finset.sum_le_sum_of_subset_of_nonneg ✓ (zeroMult nonneg cast). ~20 lines bridge.\n\nThen: Ncount a b ≤ Ncount a (a+N) ≤ A₀(N+1)·log(|a|+N+3) with N = ⌈b−a⌉₊ ≤ b−a+1 (for b−a ≥ 0: ⌈x⌉₊ ≤ x+1 ✓ Nat.ceil_le... `Nat.ceil_le : ⌈x⌉₊ ≤ ...`? Nat.ceil_lt_add_one gives < x+1 ⟹ ≤ b−a+1 when b−a ≥ 0? Nat.ceil_lt_add_one (h : 0 ≤ x) : ⌈x⌉₊ < x + 1 — as naturals: ⌈x⌉₊ ≤ ⌊...⌋: (⌈x⌉₊ : ℝ) < x+1 ⟹ (⌈x⌉₊:ℝ) ≤ b−a+1... < is fine) and |a|+N+3 ≤ max(|a|,|b|)+... |a| + (b−a+1) + 3 ≤ ... ≤ 2·max(|a|,|b|) + 4 — meh constants. Let me simplify the final form: Ncount a b ≤ A₀·(b−a+2)·log(2·max|a||b| + 4)?? Ugh the log argument. Cleaner: since a ≤ b and I mostly use [a, b] with a ≥ 2 (heights) or symmetric ±: use |a| ≤ |b|... Hmm — actually in my applications the intervals are [L, 2L] etc. with a ≥ 1: then |a| + N + 3 ≤ b + (b−a+1) + 3 ≤ 2b + 4: log ≤ log(2b+4). Let me just state the aux with its natural form and the final interval lemma as:\n\n`Ncount_le_of_interval {a b} (h2 : 2 ≤ a) (hab : a ≤ b) : (Ncount a b : ℝ) ≤ A0count * (b - a + 2) * Real.log (2 * b + 4)`\n\n(the h2 condition lets me drop |·|: a ≥ 2 ⟹ positive heights; the lower-side windows come via the conj symmetry or... wait — my shells use |γ| ∈ [2^j, 2^{j+1}] — both signs: zeros with γ ∈ [a,b] and γ ∈ [−b,−a] — the negative side: Ncount (−b) (−a) ≤ A₀(b−a+2)·log(|−b|+3) via the direct application ✓ (Ncount covers all t ✓) — with |−b| = b ✓. So state two-sided: Ncount a b ≤ A₀(b−a+2)·log(|b|+3) for 0 ≤ a ≤ b? For a ≥ 0: t ∈ [a, b]: |t| ≤ |b| = b ✓. So:\n\n`Ncount_le_of_interval {a b} (ha : 0 ≤ a) (hab : a ≤ b) : (Ncount a b : ℝ) ≤ A0count * (b - a + 2) * Real.log (b + 3)` — hmm but the aux's log argument: |a| + N + 3 with a ≥ 0: = a + N + 3 ≤ a + (b−a+1) + 3 = b + 4: log(b+4) vs log(b+3): fine adjust: use b + 4: whatever — pick log(2*b)+4... Let me not over-polish constants: state with log (b + 4).\n\nHmm wait — also need the aux base-case form: Ncount a (a + 0) = Ncount a a = 0 ≤ A₀·1·log(...) ✓.\n\nActually — hold on, let me reconsider: is the unit-step induction giving N+1 windows for length N — off-by-one: (a, a+N] splits into N unit windows (a+j, a+j+1] for j = 0..N−1 — N windows, not N+1! Ncount a (a+N) = Σ_{j<N} Ncount (a+j)(a+j+1) ≤ N·A₀·log(|a|+N−1+3)-ish. With the induction: Ncount a (a+N+1) = Ncount a (a+N) + Ncount (a+N)(a+N+1): ih gives ≤ N·A₀·log(|a|+N+3) (strengthened form!) — let me set the aux form: Ncount a (a+N) ≤ A₀·N·log(|a|+N+3)?? base N = 0: Ncount a a = 0 ≤ 0 ✓ (A₀·0·log = 0 ✓). Step: Ncount a (a+N+1) ≤ A₀N·log(|a|+N+3) + A₀·log(|a+N|+3) ≤ A₀(N+1)·log(|a|+N+1+3): |a+N| ≤ |a|+N ✓ log-mono ✓ and |a|+N+3 ≤ |a|+N+1+3 ✓: linarith ✓. So aux: Ncount a (a+N) ≤ A₀·N·log(|a|+N+3) ✓ N windows ✓.\n\nThen interval: Ncount a b ≤ Ncount a (a+⌈b−a⌉₊) ≤ A₀·⌈b−a⌉₊·log(|a|+⌈b−a⌉₊+3) ≤ A₀·(b−a+1)·log(2b+4)-ish (⌈x⌉₊ ≤ x+1 for x ≥ 0 ✓ (⌈x⌉₊ < x+1 ⟹ ⌈x⌉₊ ≤ ⌈... as reals (⌈b−a⌉₊:ℝ) < (b−a)+1 ⟹ ≤ b−a+1 exactly? < x+1 for naturals means ≤ ⌊x⌋+1... as real: (⌈x⌉₊:ℝ) < x+1 ⟹ (⌈x⌉₊:ℝ) ≤ x+1 (le_of_lt) ✓ good enough).\n\nFine. §2 the Dirichlet bound:\n\n```lean\n/-- The Dirichlet bound: ‖ζ′/ζ s‖ ≤ C₂ for re s ≥ 2, with\nC₂ := ∑' n, ‖LSeries.term (fun n => (Λ n : ℂ)) 2 n‖ (the absolutely\nsummable majorant; −ζ′/ζ = LSeries Λ for re > 1). -/\ndef dirichletC2 : ℝ := ∑' n : ℕ, ‖LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : ℂ)) 2 n‖\n```\nHmm — the Λ form: in Zeta23 they wrote `(fun n ↦ ↑(Λ n))` with Λ := ArithmeticFunction.vonMangoldt (open ArithmeticFunction?). The LSeriesSummable: `ArithmeticFunction.LSeriesSummable_vonMangoldt (hs : 1 < s.re)` ✓ (used in ZetaBounds). The equation: `ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div (hs : 1 < s.re) : L ↗Λ s = -deriv (riemannZeta) s / riemannZeta s`? — from the grep: `LSeries_vonMangoldt_eq_deriv_riemannZeta_div {s} (hs : 1 < s.re)` at Mathlib/NumberTheory/LSeries/Dirichlet.lean:436 — namespace ArithmeticFunction presumably: `LSeries_vonMangoldt_eq_deriv_riemannZeta_div : L ↗Λ s = -deriv (L 1) s / L 1 s`?? no wait line 429: `LSeries_vonMangoldt_eq (hs : 1 < s.re) : L ↗Λ s = - deriv (L 1) s / L 1 s` and 436 `LSeries_vonMangoldt_eq_deriv_riemannZeta_div`: probably `L ↗Λ s = - deriv riemannZeta s / riemannZeta s` ✓. The `L ↗Λ` notation: `ArithmeticFunction.LSeries`? the ↗Λ is the arithmetic-function-to-LSeries coercion: `LSeries (fun n => (Λ n : ℂ)) s`? In ZetaBounds they unfolded `LSeries` after rw — so L ↗Λ s = LSeries (fun n => ↑(Λ n)) s — there must be a rfl/simp bridge (`ArithmeticFunction.LSeries_eq`? or the ↗ notation IS `fun n => (f n : ℂ)`...). The notation `L f` for arithmetic function f is LSeries (fun n => (f n : ℂ)); `↗Λ` is the coercion of vonMangoldt to ℕ → ℂ... I'll handle with the ZetaBounds pattern verbatim: rw [← ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div hs]; unfold LSeries...\n\nThe lemma:\n```lean\nlemma norm_logDeriv_zeta_le_dirichlet {s : ℂ} (hs : 2 ≤ s.re) :\n ‖logDeriv riemannZeta s‖ ≤ dirichletC2 := by\n have hs1 : 1 < s.re := by linarith\n have hsum : Summable (fun n => ‖LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : ℂ)) s n‖) := by\n rw [summable_norm_iff]?? — from ZetaBounds: `rw [summable_norm_iff]; exact ArithmeticFunction.LSeriesSummable_vonMangoldt hs1` — wait that was for ‖term‖: summable_norm_iff : Summable (fun i => ‖f i‖) ↔ Summable f? no: `summable_norm_iff : Summable (fun x => ‖f x‖) ↔ Summable f`?? that's false in general (needs... for LSeries terms it was used: hmm `summable_norm_iff` exists? In ZetaBounds: `have summable_abs_value : Summable (fun i ↦ ‖LSeries.term ... s₁ i‖) := by rw [summable_norm_iff]; exact ArithmeticFunction.LSeriesSummable_vonMangoldt s₁_re_geq_one` — hmm summable_norm_iff might be LSeries-term-specific... whatever — copy the pattern.\n -- main: ‖LSeries Λ s‖ ≤ ∑' ‖term s‖ ≤ ∑' ‖term 2‖\n have h1 : -logDeriv riemannZeta s = LSeries (fun n => (ArithmeticFunction.vonMangoldt n : ℂ)) s := by\n rw [ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div hs1]\n rw [logDeriv_apply] -- logDeriv f s = deriv f s / f s: goal: -(-deriv ζ s/ζ s)?? LSeries_vonMangoldt_eq_deriv_riemannZeta_div : L ↗Λ s = -deriv riemannZeta s / riemannZeta s: so LSeries Λ s = -(deriv ζ/ζ) = -logDeriv ζ: \n ...\n```\nCareful with the ↗Λ vs (fun n => ↑(Λ n)) bridge: the ZetaBounds code: `rw [← (ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div s₁_re_geq_one)]; unfold LSeries` — so L ↗Λ s rewrites to LSeries form then unfold LSeries gives the tsum. The `↗Λ` : ArithmeticFunction.vonMangoldt's coercion into (ℕ → ℂ)?? the notation `L ↗Λ`... In the ZetaBounds usage the rewrite target was `LSeries (fun n => (Λ n:ℂ)) s₁`-form after unfold. Hmm — actually the cleanest: I'll prove my lemma using their exact tactic sequence. Let me look at what `L ↗Λ` unfolds to and just mirror. Actually from VerticalLine.lean:91: `-logDeriv riemannZeta ((c:ℂ) + t*I) = LSeries (fun n => (Λ n : ℂ)) ((c:ℂ)+t*I)` — proved somewhere — let me check how.","signature":""},{"type":"text","text":"Let me check how WeilEF/VerticalLine.lean proves the −logDeriv = LSeries identity (to mirror it exactly)."},{"type":"tool_use","id":"Bash_257","name":"Bash","input":{"command":"cd D:/Python/Quantum/zeta-23-lean && sed -n '85,100p' Zeta23/WeilEF/VerticalLine.lean && grep -n \"LSeries_vonMangoldt_eq\\|vonMangoldt_eq_logDeriv\\|logDeriv_riemannZeta_eq\" Zeta23/WeilEF/VerticalLine.lean | head -5 && sed -n '425,445p' .lake/packages/mathlib/Mathlib/NumberTheory/LSeries/Dirichlet.lean","description":"The −logDeriv = LSeries identity pattern"},"extra_content":null}]