Current task: —

← Session 30 — ii′-5e squeeze capstone + 5f perimeter repair

#1682 assistant 2026-08-24 06:06:19.638 UTC · 540→25750 tok open ⤢
thinking (61134 chars)
All names verified: - `AnalyticAt.differentiableAt : AnalyticAt 𝕜 f x → DifferentiableAt 𝕜 f x` ✓ - `Real.pow_rpow_inv_natCast (hx : 0 ≤ x) (hn : n ≠ 0) : (x ^ n) ^ (n⁻¹ : ℝ) = x` ✓ — this is the (c⁴)^{1/4} = c direction I need. Todo #2 done. Now write the file. Design recap for **LiSqueeze.lean**: ```lean import Mathlib import NguyenRH1.LiCircleBound -- brings LiFEntire, LiGapCircles, LiDisc, LiReflect, LiDigammaLeft open Zeta23 Complex Filter Topology noncomputable section namespace NguyenRH1 ``` **Lemma 1: `C0hat_add_two_le_five_log`** — for R with 9 ≤ log R (or 16002 ≤ R): C0hat (R+2) ≤ 5·log R. Proof: unfold C0hat. Pieces: - h1: Real.log (R+2+2) = log(R+4) ≤ 2·log R: since R+4 ≤ R² for R ≥ 3 (R² - R - 4 ≥ 0: at R=3, 9-7=2>0, monotone): R+4 ≤ R·R needs R ≥ ... nlinarith. Then log(R+4) ≤ log(R²) = 2·log R (Real.log_pow: log(R^2) = 2·log R — Real.log_pow : log (x^n) = n * log x). Need 0 < R+4 and R+4 ≤ R^2. Real.log_le_log (h : 0 < x) (h' : x ≤ y)? Signature: Real.log_le_log (hx : 0 < x) (h : x ≤ y)? Let me recall: `Real.log_le_log_iff`... There's `Real.log_le_log (hx : 0 < x) (hxy : x ≤ y) : log x ≤ log y`? Hmm — in Fexpr_circle_le they used `Real.log_le_log (by ... : (0:ℝ) < 2 + R/2) (by linarith : 2+R/2 ≤ R)`. So signature `Real.log_le_log (hx : 0 < x) (h : x ≤ y)`. ✓ (Used in LiCircleBound line 3894.) - h2: log(log(R+4)) ≤ 2·log R. Chain: log(R+4) ≤ 2·log R (h1); log monotone: log(log(R+4)) ≤ log(2·log R) — need 0 < log(R+4): log(R+4) ≥ 9 > 0 ✓ (log(R+4) ≥ log R ≥ 9). log(2·log R) = log 2 + log(log R) (Real.log_mul, 2≠0, log R ≠ 0) ≤ 1 + log R — wait log 2 ≤ 1 (log 2 < log e = 1? Real.log_two_lt_d9 or log_le_one... `Real.log_two_lt_d9 : log 2 < 0.6931471808`. Simpler: log 2 ≤ 1 via Real.log_le_one? hmm — log x ≤ x - 1: log 2 ≤ 1 ✓ via `Real.log_le_sub_one_of_pos`. And log(log R) ≤ log R (log x ≤ x: from log x ≤ x - 1 ≤ x: Real.log_le_sub_one_of_pos h gives log x ≤ x-1, linarith gives ≤ x; or maybe there's a direct lemma). So log(2 log R) ≤ 1 + log R ≤ 2·log R since log R ≥ 9 ≥ 1 ⟹ 1 + log R ≤ 2 log R. Hmm — actually I can simplify: 0.886·log(log(R+4)) ≤ 0.886·(1 + log R). And 0.433·log(R+4) ≤ 0.866·log R. And 2.9 ≤ 2.9/9·log R ≤ 0.33·log R (from 9 ≤ log R ⟹ 2.9 ≤ 2.9·(log R)/9). Total: 0.866·L + 0.886·(1+L) + 2.9 ≤ 0.866L + 0.886L + 0.886 + 0.33L — and 0.886 ≤ 0.1·L (L≥9). Total ≤ (0.866+0.886+0.33+0.1)·L = 2.182·L ≤ 5·L. ✓ Big margin. **Lemma 2: `gentire_eq_Fexpr_on_gapCircle`** — actually just do it inline in step 3. For ‖s‖ = R: ¬badPoint s: - ¬IsNontrivialZero s: not_isNontrivialZero_on_gapCircle hk hRlo hgap hs. - s ≠ 0: if s = 0 then ‖s‖ = 0 ≠ R ≥ 16002. - s ≠ 1: if s = 1 then ‖s‖ = 1 ≠ R. - ¬∃ n ≥ 1, s = −2n: if s = −2·(n:ℂ), then R = ‖s‖ = ‖−2n‖ = 2n (n≥1). R/2 = n. hgapInt (n:ℤ): 1/4 ≤ |R/2 − n| = 0. Contradiction. Details: ‖(-2*(n:ℂ))‖ = ‖(-2:ℂ)‖·‖(n:ℂ)‖ = 2·n. ((-2 : ℂ)) norm: ‖(-2:ℂ)‖ = 2. Via: rw [norm_mul]; show ‖(-2:ℂ)‖ = 2: (-2 : ℂ) = ((-2:ℝ):ℂ) by push_cast;ring; Complex.norm_real; norm_num. ‖(n:ℂ)‖ = n via Complex.norm_natCast? `Complex.norm_natCast : ‖(n : ℂ)‖ = n`. Hmm exact name maybe `Complex.norm_natCast`. There's Complex.norm_natCast in Mathlib? I recall `Complex.norm_natCast (n : ℕ) : ‖(n : ℂ)‖ = n`. Used elsewhere in the project? Let me grep later. Also R/2 − (n:ℤ) cast: (n:ℤ) from ℕ cast — hgapInt takes m : ℤ; use m := n. |R/2 − ↑n| where ↑n = ((n:ℤ):ℝ) = (n:ℝ). push_cast should bridge. **Lemma 3: `gentire_circle_le`** — k ≥ 4000, R gap circle (the 4 hyps), ‖s‖ = R ⟹ ‖Gentire s‖ ≤ RB R. Proof: rw [gentire_eq_Fexpr hgood]; exact Fexpr_circle_le hk hRlo _hRhi hgap hgapInt hs. Wait — Fexpr_circle_le's second arg is named `_hRhi` (unused). Fine, still pass it. **Lemma 4: `gentire_const`** (the squeeze) — under hZC : ZeroCountProp: ∀ z₀, Gentire z₀ = Gentire 0. Proof structure: ``` intro z₀ -- constants set C₀' := 2 * lowZeroConst + dirichletC2 + ‖Gentire 0‖ with hC0' set C₁ := 2000000 * A0count with hC1 -- 400000·A0·5 have hC0'nn : 0 ≤ C₀' := by positivity-ish (lowZeroConst_nonneg, dirichletC2_nonneg, norm_nonneg) have hC1nn : 0 ≤ C₁ := mul_nonneg (norm_num) A0count_pos.le -- key: ∀ ε > 0, dist (Gentire z₀) (Gentire 0) ≤ ε have key : ∀ ε : ℝ, 0 < ε → dist (Gentire z₀) (Gentire 0) ≤ ε := by intro ε hε -- choose c := 1 + (128*C₁ + 2*C₀')*‖z₀‖/ε -- choose M := max (c^4) (‖z₀‖ + 1) -- choose k := max 4000 ⌈M/4⌉₊ -- get R from exists_gapCircle_radius hZC (k) (1 ≤ k) -- ... ``` Hmm wait, one subtlety: I need R ≥ M to get R ≥ c⁴ and R ≥ ‖z₀‖+1. From exists_gapCircle_radius: R ≥ 4k+5/2 ≥ 4k ≥ M ✓ (k ≥ ⌈M/4⌉ ⟹ 4k ≥ 4·⌈M/4⌉ ≥ M: Nat.le_ceil (M/4) : M/4 ≤ ⌈M/4⌉₊ then ×4). And k ≥ 4000 ✓. Actually also need 1 ≤ k for exists_gapCircle_radius — k ≥ 4000 covers it. Steps inside: - obtain ⟨R, hRlo, hRhi, hgapInt, hgap⟩ := exists_gapCircle_radius hZC hk1 — check the argument order in the actual theorem: (hZC : ZeroCountProp) {k : ℕ} (hk : 1 ≤ k) : ∃ R, 4k+5/2 ≤ R ∧ R ≤ 4k+3 ∧ (∀ m:ℤ, 1/4 ≤ |R/2 − m|) ∧ ∀ ρ, IsNontrivialZero ρ → (clearance) ∨ (1 ≤ |ρ.im − R|). Note hgapInt comes third, hgap fourth. Fexpr_circle_le's signature: hgap (zero ordinates) then hgapInt (integers). Different orders — careful at the call site. - hk4000 : 4000 ≤ k (for Fexpr_circle_le). - hR16002 : 16002 ≤ R: from 4k+5/2 ≤ R and k ≥ 4000 ⟹ 4k ≥ 16000. ✓ - hlogR : 9 ≤ log R := nine_le_log_of_16002_le hR16002 (exists in LiCircleBound — used in Fexpr_circle_le). - Sphere bound: ∀ z ∈ Metric.sphere 0 R, ‖Gentire z‖ ≤ RB R where RB R := 2*lowZeroConst + dirichletC2 + 400000*A0count*C0hat (R+2)*(log R)^2: intro z hz; hz : dist z 0 = R (Metric.mem_sphere). ‖z‖ = R: dist_eq_norm, norm (z − 0) = ‖z‖ (sub_zero). Then gentire_circle_le with hs : ‖z‖ = R. - Ball bound: ∀ z ∈ closedBall 0 R, ‖Gentire z‖ ≤ RB R := AnalyticOn.norm_le_of_norm_le_on_sphere (r := R) (R := R) le_rfl analyticOn_closedBall sphere_bound. Where analyticOn_closedBall : AnalyticOn ℂ Gentire (closedBall 0 R) := AnalyticOnNhd.analyticOn (fun s _ => gentire_analyticAt_and_eq.1 s). Hmm — AnalyticOnNhd ℂ f s := ∀ x ∈ s, AnalyticAt ... yes: `AnalyticOnNhd f u = ∀ x ∈ u, AnalyticAt f x`. So (fun s _ => gentire_analyticAt_and_eq.1 s) : AnalyticOnNhd ℂ Gentire (closedBall 0 R) then .analyticOn. But wait — the sphere lemma signature asks `AnalyticOn ℂ f (Metric.closedBall 0 R)`. ✓. - MapsTo: MapsTo Gentire (ball 0 R) (closedBall (Gentire 0) R₂) where R₂ := RB R + ‖Gentire 0‖: intro z hz; hz : dist z 0 < R (Metric.mem_ball). z ∈ closedBall 0 R: dist z 0 ≤ R (le of lt; Metric.mem_closedBall). ‖Gentire z‖ ≤ RB R (ball bound). mem_closedBall target: dist (Gentire z) (Gentire 0) ≤ R₂. dist = ‖Gentire z − Gentire 0‖ (dist_eq_norm) ≤ ‖Gentire z‖ + ‖Gentire 0‖ (norm_sub_le) ≤ RB R + ‖Gentire 0‖. ✓ - hd : DifferentiableOn ℂ Gentire (ball 0 R) := fun z hz => (gentire_analyticAt_and_eq.1 z).differentiableAt.differentiableWithinAt. - hz0 : z₀ ∈ ball 0 R: dist z₀ 0 < R: ‖z₀‖ < R since ‖z₀‖ < ‖z₀‖+1 ≤ M ≤ 4k ≤ 4k+5/2 ≤ R. dist_eq_norm, sub_zero. - Schwarz: dist (Gentire z₀) (Gentire 0) ≤ R₂/R·dist z₀ 0 = R₂/R·‖z₀‖. - Real grind: R₂/R·‖z₀‖ ≤ ε: RB R ≤ 2·lowZeroConst + dirichletC2 + 400000·A0count·(5·log R)·(log R)² = 2·lowZeroConst + dirichletC2 + 2000000·A0count·(log R)³ (needs log R ≥ 0 for mul monotonicity; (log R)² = (log R)³/log R... careful: 400000·A0·Ĉ·L² ≤ 400000·A0·(5L)·L² = 2000000·A0·L³: rewrite (log R)^3 = (log R)^2 * (log R) (pow_succ or pow_three); mul_le_mul: 400000·A0 ≥ 0, Ĉ ≤ 5L, L² ≥ 0. mul_le_mul_of_nonneg_left (C0hat (R+2) ≤ 5 log R) (400000·A0count ≥ 0) then × L² (≥0): mul_le_mul_of_nonneg_right. R₂ ≤ C₀' + C₁·L³ where L := log R. L ≤ 4·Q where Q := R^{1/4}: Real.log_le_rpow_div (hx : 0 ≤ x)... wait signature: log_le_rpow_div {x ε} (hx : 0 ≤ x) (hε : 0 < ε) : log x ≤ x^ε / ε. With ε := 1/4: log R ≤ R^{1/4}/(1/4) = 4·R^{1/4}. The div: x^ε/ε with ε = 1/4: R^{1/4}/(1/4) = 4·R^{1/4} — field_simp or rw div_... `div_eq_mul_inv`, inv (1/4) = 4: 1/(1/4) = 4 by norm_num. So L ≤ 4·Q. L³ ≤ 64·Q³: both sides nonneg (L ≥ 9 ≥ 0, Q ≥ 0): pow_le_pow_left (ha : 0 ≤ a) (hab : a ≤ b) (n) : a^n ≤ b^n. Then (4Q)³ = 64·Q³ by ring (need (4*Q)^3 = 64*Q^3: ring after pow_succ... `mul_pow` then norm_num: (4*Q)^3 = 4^3 * Q^3 = 64*Q^3 ✓ via mul_pow + norm_num). Numerator: R₂ ≤ C₀' + 64·C₁·Q³. Denominator: R = Q⁴: Q = R^{(1/4:ℝ)}; R = (R^{1/4})^4: from pow_rpow_inv_natCast hRnn (4≠0): (R^4)^{1/4} = R — wrong direction. I need (R^{1/4})^4 = R: that's `rpow_inv_natCast_pow (hx : 0 ≤ x) (hn : n ≠ 0) : (x ^ (n⁻¹:ℝ))^n = x` ✓ — exactly. With n := 4: (R^{(4:ℝ)⁻¹})^4 = R. And (1/4 : ℝ) vs (4:ℝ)⁻¹: 1/4 = 4⁻¹ by `one_div` — Q := R^(1/4); show (1/4:ℝ) = (4:ℝ)⁻¹ via one_div. So R = Q^4 with Q := R^(1/4). Want: (C₀' + 64·C₁·Q³)·‖z₀‖ ≤ ε·Q⁴. Have Q ≥ c = 1 + (128·C₁ + 2·C₀')·‖z₀‖/ε: Q ≥ c: R ≥ M ≥ c⁴ ⟹ Q = R^{1/4} ≥ (c⁴)^{1/4} = c: Real.rpow_le_rpow (0 ≤ c⁴) (c⁴ ≤ R) (1/4 ≥ 0): rpow_le_rpow (hx : 0 ≤ x) (hxy : x ≤ y) (hz : 0 ≤ z) : x^z ≤ y^z. And (c⁴)^{1/4} = c: pow_rpow_inv_natCast (0 ≤ c) (4 ≠ 0). Need c ≥ 0: c = 1 + nonneg·nonneg/nonneg ≥ 1 > 0 ✓. Then: (i) 64·C₁·‖z₀‖ ≤ (ε/2)·Q: from Q ≥ c ≥ (128·C₁)·‖z₀‖/ε ⟹ ε·Q ≥ 128·C₁·‖z₀‖ ⟹ (ε/2)·Q ≥ 64·C₁·‖z₀‖. Careful with division: c ≥ (128·C₁ + 2·C₀')·‖z₀‖/ε ≥ 128·C₁·‖z₀‖/ε (drop nonneg term: 2·C₀'·‖z₀‖ ≥ 0; div monotonicity: a/ε ≤ (a+b)/ε for ε>0, b≥0). So Q·ε ≥ 128·C₁·‖z₀‖ (mul by ε: (x/ε)·ε = x, div_mul_cancel₀). nlinarith might handle the pieces or do linear_combination. Since C₁, C₀', ‖z₀‖, ε, Q are atoms, linarith works once the products are... hmm linarith doesn't do nonlinear: Q·ε ≥ 128·C₁·‖z₀‖ is nonlinear (product of variables ε·Q). Strategy: derive h1 : 128·C₁·‖z₀‖ ≤ ε·Q by: calc 128·C₁·‖z₀‖ = (128·C₁·‖z₀‖/ε)·ε := (div_mul_cancel₀ _ hε.ne').symm; _ ≤ c·ε := mul_le_mul_of_nonneg_right (le chain) hε.le; _ ≤ Q·ε := mul_le_mul_of_nonneg_right hQc hε.le. Then h2 : 64·C₁·‖z₀‖ ≤ ε/2·Q: ε/2·Q = ε·Q/2: nlinarith? ε/2·Q = (ε·Q)/2 ring-equal; linarith with the atom ε·Q... linarith treats ε·Q as atom; goal 64·C₁·‖z₀‖ ≤ ε/2·Q — the RHS is a different atom than ε·Q (ε/2·Q vs ε·Q are scalar multiples — linarith can handle scalar multiples of the same monomial? linarith works over ordered fields and treats nonlinear monomials as atoms, but it CAN scale: it knows ε/2·Q = (1/2)(ε·Q) only if the expressions are parsed as the same atom scaled. `ε/2*Q` normalizes to `(1/2)*ε*Q` in ring normal form — linarith does ring_nf on hypotheses and goals (linarith preprocesses with ring_nf? linarith does use ring normalization on comparisons). I believe linarith handles scalar multiples fine after ring_nf preprocessing. OK. (ii) 2·C₀'·‖z₀‖ ≤ (ε/2)·Q⁴: from Q ≥ c ≥ 2·C₀'·‖z₀‖/ε and Q ≥ 1: 2·C₀'·‖z₀‖ ≤ ε·Q (same div trick) ≤ ε·Q⁴ (Q ≥ 1 ⟹ Q ≤ Q⁴... need Q⁴ ≥ Q: since Q ≥ 1: Q⁴ = Q·Q³ ≥ Q·1 = Q — needs Q³ ≥ 1: one_le_pow... `one_le_pow_of_le` hmm: 1 ≤ Q ⟹ 1 ≤ Q^n for Q ≥ ... `one_le_pow₀ (h : 1 ≤ a) : 1 ≤ a ^ n`. Then Q^4 = Q^3 * Q or Q * Q^3: pow_succ: Q^4 = Q^3 * Q ≥ 1 * Q = Q (mul_le_mul_of_nonneg... 1 ≤ Q^3, times Q ≥ 0: mul_le_mul_of_nonneg_right? (1 ≤ Q^3) mul right by Q: 1*Q ≤ Q^3*Q ✓). So 2·C₀'·‖z₀‖ ≤ ε·Q ≤ ε·Q⁴ = (ε/2)·Q⁴ + ... just need ≤ (ε/2)·Q⁴: 2·C₀'·‖z₀‖ ≤ ε·Q ≤ ... hmm I need ε·Q ≤ (ε/2)·Q⁴ ⟸ Q ≤ Q⁴/2 ⟸ 2·Q ≤ Q⁴. With Q ≥ 1: Q⁴ ≥ 2Q? Not for Q=1 (1 < 2). Oops. Fix: make c ≥ 2: c := 2 + (128·C₁ + 2·C₀')·‖z₀‖/ε ⟹ Q ≥ 2 ⟹ Q⁴ = Q·Q³ ≥ Q·8 ≥ 2·Q·... Q³ ≥ 8 ⟹ Q⁴ ≥ 8Q ≥ ... want ε·Q ≤ (ε/2)·Q⁴ ⟸ 2 ≤ Q³ ⟸ 2 ≤ 8 ✓. So with c ≥ 2: 2·C₀'‖z₀‖ ≤ ε·Q, and ε·Q ≤ (ε/2)·Q⁴ ⟸ 2·Q ≤ Q⁴ ⟸ 2 ≤ Q³ (divide by Q>0) ⟸ Q ≥ 2 ⟹ Q³ ≥ 8 ✓. Handling divisions in Lean without dividing: state directly: have hQ2 : 2 ≤ Q; h2a : 2·C₀'·‖z₀‖ ≤ ε·Q (div trick as before); h2b : ε·Q ≤ (ε/2)·Q⁴: (ε/2)·Q⁴ − ε·Q = ε·Q·(Q³/2 − 1) ≥ 0: nlinarith [hQ2, ...]? Q³ ≥ 8: from Q ≥ 2: pow_le_pow_left (0≤2) hQ2 3 : 2³ ≤ Q³ = 8 ≤ Q³. Then (ε/2)·Q⁴ = (ε/2)·Q·Q³ ≥ (ε/2)·Q·8 = 4·ε·Q ≥ ε·Q: nlinarith [hε, hQpos, hQ3ge8] with atoms ε·Q... nlinarith multiplies pairs of hypotheses; the product (ε/2)·Q·Q³ — nlinarith sees monomials up to degree... The product (ε/2)*Q^4 vs ε*Q: factor as ((ε/2)*Q)*(Q^3) hmm nlinarith would need to multiply (ε·Q atom?) — it doesn't have ε·Q as hypothesis atom; hypotheses are ε>0, Q≥2, Q³≥8. Products: ε·Q³ ≥ ... nlinarith can multiply two hypotheses: (Q ≥ 2)·(Q³ ≥ 8)?? no. Let me just hand-roll: h2b : ε*Q ≤ ε/2*Q^4 := calc ε*Q = (ε/2)*(2*Q) := by ring; _ ≤ (ε/2)*(Q*Q^3) := mul_le_mul_of_nonneg_left (by nlinarith [hQ2, hQ3, hQnn]) (by positivity... ε/2 ≥ 0); where 2*Q ≤ Q*Q^3 ⟸ 2 ≤ Q³ (Q > 0): mul_le_mul_of_nonneg_right hQ3' (le of Q > 0)... hmm 2*Q ≤ Q*Q^3 ⟸ 2 ≤ Q^3: mul_le_mul_of_nonneg_right (h : 2 ≤ Q^3) (0 ≤ Q): 2*Q ≤ Q^3*Q; Q^3*Q = Q*Q^3 ring. OK then = ε/2 * Q^4 by ring (Q*Q^3 = Q^4: ring? Q*Q^3 = Q^4 is ring-normalizable ✓ (pow is ring-opaque? `ring` handles pow with literal exponents ✓)). Then h2 : 2·C₀'·‖z₀‖ ≤ (ε/2)·Q⁴ by trans. Sum: (C₀' + 64·C₁·Q³)·‖z₀‖ — hmm wait. Let me restructure: dist ≤ (R₂/R)·‖z₀‖; want ≤ ε. R₂ ≤ C₀' + 64·C₁·Q³ (shown). So dist·1 ≤ (C₀' + 64·C₁·Q³)/Q⁴·‖z₀‖ hmm R = Q⁴ substitution. Goal: (C₀' + 64·C₁·Q³)/Q⁴·‖z₀‖ ≤ ε ⟺ (C₀' + 64·C₁·Q³)·‖z₀‖ ≤ ε·Q⁴ (div_le_iff, Q⁴ > 0). Expand LHS: C₀'·‖z₀‖ + 64·C₁·Q³·‖z₀‖. From (i): 64·C₁·‖z₀‖ ≤ (ε/2)·Q ⟹ 64·C₁·‖z₀‖·Q³ ≤ (ε/2)·Q·Q³ = (ε/2)·Q⁴ (mul by Q³ ≥ 0 — but careful with assoc: 64·C₁·Q³·‖z₀‖ vs (64·C₁·‖z₀‖)·Q³ — assoc juggling; use ring-normal forms and per-step haves + linarith, per the banked gotcha). From (ii): C₀'·‖z₀‖ ≤ (ε/2)·Q⁴ — wait I had 2·C₀'·‖z₀‖ ≤ (ε/2)·Q⁴ which is stronger. Sum: LHS ≤ (ε/2)·Q⁴ + (ε/2)·Q⁴ = ε·Q⁴ ✓. So: hA : 64*C₁*‖z₀‖ ≤ (ε/2)*Q (derived from h1 by linarith with ε/2*Q = (ε*Q)/2 — need ring-equivalence; use have hhalf : (ε/2)*Q = (ε*Q)/2 := by ring; linarith). hA' : (64*C₁*‖z₀‖)*Q^3 ≤ (ε/2)*Q*Q^3 := mul_le_mul_of_nonneg_right hA (pow_nonneg hQnn 3). Then ring-normalize: (64*C₁*‖z₀‖)*Q^3 = 64*C₁*Q^3*‖z₀‖ and (ε/2)*Q*Q^3 = (ε/2)*Q^4 — via calc + ring steps. hB : C₀'*‖z₀‖ ≤ (ε/2)*Q^4 (from h2a : 2*C₀'*‖z₀‖ ≤ ε*Q... wait redo: h2a was 2·C₀'·‖z₀‖ ≤ ε·Q. Then C₀'·‖z₀‖ ≤ (ε/2)·Q ≤ (ε/2)·Q⁴? (ε/2)·Q ≤ (ε/2)·Q⁴ ⟸ Q ≤ Q⁴ ⟸ 1 ≤ Q³ ✓ (Q ≥ 2). Hmm or just: C₀'·‖z₀‖ ≤ 2·C₀'·‖z₀‖ (C₀'‖z₀‖ ≥ 0) ≤ ε·Q ≤ ... I'll assemble with linarith over the derived atoms: Final: have hsum : C₀'*‖z₀‖ + 64*C₁*Q^3*‖z₀‖ ≤ ε*Q^4 := by linarith [hA'normalized, hB, ...]. linarith treats (ε/2)*Q^4 as (1/2)·(ε·Q⁴) — same atom scaled ✓. Then div: (C₀' + 64·C₁·Q³)·‖z₀‖/Q⁴ ≤ ε: rw [div_le_iff₀ hQ4pos]: (C₀'+64·C₁·Q³)·‖z₀‖ ≤ ε·Q⁴ — matches hsum after LHS expansion: (C₀'+64·C₁·Q³)·‖z₀‖ = C₀'·‖z₀‖ + 64·C₁·Q³·‖z₀‖ (add_mul + assoc — ring-normalize via a calc or linear_combination hsum after `ring_nf`? Use: have hLHS : (C₀' + 64*C₁*Q^3)*‖z₀‖ = C₀'*‖z₀‖ + 64*C₁*Q^3*‖z₀‖ := by ring. Then rw [hLHS]; exact hsum. - Conclusion chain: dist (Gentire z₀) (Gentire 0) ≤ R₂/R·‖z₀‖ (Schwarz) and R₂/R·‖z₀‖ ≤ (C₀'+64·C₁·Q³)·‖z₀‖/Q⁴: since R₂ ≤ C₀'+64C₁Q³ and R = Q⁴: R₂/R·‖z₀‖ ≤ (C₀'+64C₁Q³)/Q⁴·‖z₀‖: div monotonicity + R = Q⁴ (rw). Then ≤ ε. So dist ≤ ε ✓. - Then dist = 0: le_of_forall_pos_le_add? The standard: `le_of_forall_pos_le_add : (∀ ε, 0 < ε → a ≤ b + ε) → a ≤ b`. We have ∀ ε>0, dist ≤ ε = 0 + ε. So dist ≤ 0. Then dist ≤ 0 ∧ 0 ≤ dist ⟹ dist = 0 (le_antisymm (dist_nonneg)). Then `dist_eq_zero.mp : dist x y = 0 → x = y`. So Gentire z₀ = Gentire 0. Hmm wait — `le_of_forall_pos_le_add` signature: `(h : ∀ ε, 0 < ε → a ≤ b + ε) : a ≤ b`. Our key gives dist ≤ ε; need dist ≤ 0 + ε: by linarith [key ε hε]. OK. **Lemma 5: `partialFraction_identity`** (capstone): ``` theorem partialFraction_identity (hZC : ZeroCountProp) : ∃ B : ℂ, ∀ s : ℂ, riemannZeta s ≠ 0 → s ≠ 0 → s ≠ 1 → (∀ n : ℕ, 1 ≤ n → s ≠ -2 * (n : ℂ)) → logDeriv riemannZeta s = B + seriesFun s - 1/s - 1/(s-1) + (Real.log Real.pi : ℂ)/2 - Complex.digamma (s/2)/2 := by refine ⟨Gentire 0, fun s hζ hs0 hs1 hsn ↦ ?_⟩ -- ¬ badPoint s have hgood : ¬ badPoint s := by rintro (h | h | h | ⟨n, hn, h⟩) · exact hζ h.1 · exact hs0 h · exact hs1 h · exact hsn n hn h have hG : Gentire s = Gentire 0 := gentire_const hZC s rw [gentire_eq_Fexpr hgood] at hG -- Gentire s = Fexpr s, so Fexpr s = Gentire 0 -- hG : Fexpr s = Gentire 0 unfold Fexpr at hG linear_combination hG ``` Wait: hG : Gentire s = Fexpr s from gentire_eq_Fexpr; combined with Gentire s = Gentire 0: Fexpr s = Gentire 0. Then unfold Fexpr at hG: logDeriv ζ s − seriesFun s + 1/s + 1/(s−1) − (log π)/2 + ψ(s/2)/2 = Gentire 0. Goal: logDeriv ζ s = Gentire 0 + seriesFun s − 1/s − 1/(s−1) + (log π)/2 − ψ(s/2)/2. linear_combination hG ✓ (pure linear identity in atoms over ℂ — division by constants s, s−1, 2 are fine for linear_combination? linear_combination works over commutative rings with the atoms being subterms: 1/s is an atom; the identity is linear in the atoms logDeriv ζ s, seriesFun s, 1/s, 1/(s−1), ((log π:ℂ)/2), (digamma(s/2)/2), Gentire 0 — yes, all coefficients are constants ✓. But careful: is `Real.log Real.pi` coerced consistently: in Fexpr def it's `(Real.log Real.pi : ℂ) / 2`. In my goal I write the same. ✓. Careful about `unfold Fexpr at hG` — Fexpr is a def; unfold might not fire if... `rw [Fexpr] at hG` was used in LiCircleBound (line 3846: `rw [Fexpr]`). For hG I'll use `rw [Fexpr] at hG` hmm — Fexpr is a def so `rw [Fexpr]`... they used `rw [Fexpr]` at line 3846 in a term-mode proof (`rw [Fexpr]` inside `by`?). Actually they had `have hc1 : ... := by rw [Fexpr]; exact norm_add_le _ _`. So `rw [Fexpr]` works — presumably there's an equational lemma Fexpr s = ... auto-generated (defs get equation lemmas; rw with a def name uses its eqn lemmas — works for non-recursive defs in Lean4 Mathlib style: `rw [Fexpr]` unfolds via Fexpr.eq_def or the auto equation lemma). I'll use `rw [Fexpr] at hG` — hmm, `show` may be safer: since everything is defeq, `linear_combination hG` might close the goal directly without unfolding (linear_combination checks the difference is a ring combination — hG's type is Fexpr s = Gentire 0; linear_combination treats `Fexpr s` as an atom but the goal mentions logDeriv... not Fexpr — so no, must unfold first). Use `unfold Fexpr at hG` — unfold is reliable for plain defs. Or `simp only [Fexpr] at hG`. I'll try unfold. One more check: `gentire_eq_Fexpr` signature: from line 1109 usage `rw [gentire_eq_Fexpr hygood]` where hygood : ¬ badPoint y. So `gentire_eq_Fexpr (h : ¬ badPoint s) : Gentire s = Fexpr s` ✓. Also `gentire_const` needs a name not clashing. And I should double check `not_isNontrivialZero_on_gapCircle`'s signature: used at line 3815-3816 as `not_isNontrivialZero_on_gapCircle hk hRlo hgap hs` where hk : 4000 ≤ k, hRlo, hgap (zeros), hs : ‖s‖ = R. ✓ Note it does NOT need hgapInt. Now, `badPoint` is: IsNontrivialZero s ∨ s = 0 ∨ s = 1 ∨ ∃ n, 1 ≤ n ∧ s = -2*(n:ℂ). For the on-circle goodness I need to discharge all four. Let me write the good-point lemma: ```lean lemma not_badPoint_on_gapCircle {k : ℕ} (hk : 4000 ≤ k) {R : ℝ} (hRlo : 4 * (k:ℝ) + 5/2 ≤ R) (hgap : ...) (hgapInt : ∀ m : ℤ, 1/4 ≤ |R/2 - (m:ℝ)|) {s : ℂ} (hs : ‖s‖ = R) : ¬ badPoint s := by rintro (h | h | h | ⟨n, hn, h⟩) · exact not_isNontrivialZero_on_gapCircle hk hRlo hgap hs h · -- s = 0 have : (0:ℝ) = R := by rw [← hs, h]; norm_num -- ‖(0:ℂ)‖ = 0 -- R ≥ 16002 ⟹ contradiction ... · -- s = 1 have : (1:ℝ) = R := by rw [← hs, h]; simp? ‖(1:ℂ)‖ = 1: norm_one ... · -- s = -2n ... ``` For s = 0: hs : ‖s‖ = R; rw [h] at hs : ‖(0:ℂ)‖ = R; norm_num at hs or rw norm_zero at hs: R = 0... but R ≥ 4k+5/2 ≥ 16002.5 > 0. hRpos : 0 < R. linarith. For s = 1: rw [h] at hs : ‖(1:ℂ)‖ = R; norm_one at hs : 1 = R... wait ‖(1:ℂ)‖ = (1:ℝ): norm_one. hs : (1:ℝ) = R. R ≥ 16002 contradiction linarith. For s = −2n: R = ‖s‖ = ‖−2·(n:ℂ)‖. Compute: ‖−2·(n:ℂ)‖ = 2·n. Then R/2 = n. hgapInt (n:ℤ) : 1/4 ≤ |R/2 − ((n:ℤ):ℝ)|. ((n:ℤ):ℝ) = (n:ℝ) by push_cast/Int.cast_natCast. R/2 − n = 0. |0| = 0 < 1/4. Contradiction. Details: have hR2 : R = 2 * n: from hs: R = ‖s‖ = ... : rw [← hs, h]; then ‖(-2:ℂ)*(n:ℂ)‖ = ‖(-2:ℂ)‖*‖(n:ℂ)‖ (norm_mul) = 2*n: ‖(-2:ℂ)‖ = 2: by rw [show (-2:ℂ) = ((-2:ℝ):ℂ) by push_cast;ring, Complex.norm_real]; norm_num. ‖(n:ℂ)‖ = (n:ℝ): Complex.norm_natCast? Let me check name: `Complex.norm_natCast` — hmm, grep. In Lean Mathlib it's `Complex.norm_natCast (n : ℕ) : ‖(n : ℂ)‖ = ↑n`. I've seen `Complex.norm_natCast`. I'll verify by grep in the project or Mathlib. Then hgapInt ((n : ℤ)): 1/4 ≤ |R/2 − ((n:ℤ):ℝ)|. Have ((n:ℤ):ℝ) = (n:ℝ) := by push_cast;ring or Int.cast_natCast n: `Int.cast_natCast : ((n:ℤ):ℝ) = n`? Int.cast_natCast : (↑(↑n : ℤ) : R) = ↑n. yes `Int.cast_natCast (n : ℕ) : ((n : ℤ) : α) = n`. rw that. R/2 − n = 0: from R = 2n: linarith... the expression |R/2 − (n:ℝ)| with hR2 : R = 2*(n:ℝ): rw [hR2]; 2*n/2 − n = 0: ring_nf then abs_zero. Have : |2*(n:ℝ)/2 − (n:ℝ)| = 0: by rw [...]; the cleanest: have h0 : 2*(n:ℝ)/2 − (n:ℝ) = 0 := by ring; rw [hR2, h0, abs_zero] at hcon; linarith. Note: hgapInt m is `∀ m : ℤ, 1 / 4 ≤ |R / 2 - (m : ℝ)|`. So hgapInt (n : ℤ) : 1/4 ≤ |R/2 − ((n:ℤ):ℝ)|. OK. Now, one design question: file placement. New file LiSqueeze.lean, import NguyenRH1.LiCircleBound (which transitively imports LiFEntire etc). Namespace NguyenRH1. Then add `import NguyenRH1.LiSqueeze` to the root file NguyenRH1.lean. Let me check the root file. Also, the AnalyticOn.norm_le_of_norm_le_on_sphere is in Zeta23's StrongPNTPrefix — is it in scope via existing imports? LiDisc.lean imports StrongPNTPrefix presumably (BC used there). LiCircleBound imports LiDisc so transitively available, and LiSqueeze imports LiCircleBound. It's a plain lemma in root namespace (AnalyticOn.norm_le_of_norm_le_on_sphere — namespaced under AnalyticOn, dot-accessible as AnalyticOn.norm_le_of_norm_le_on_sphere). ✓ The Schwarz lemma: Complex.dist_le_div_mul_dist_of_mapsTo_ball — with `open Complex` it's dist_le_div_mul_dist_of_mapsTo_ball; safer to write Complex.dist_le_div_mul_dist_of_mapsTo_ball. Now — one more check on `exists_gapCircle_radius`: it returns R with hRlo : 4*(k:ℝ)+5/2 ≤ R, hRhi : R ≤ 4*(k:ℝ)+3, hgapInt : ∀ m:ℤ, 1/4 ≤ |R/2 − m|, hgap : ∀ ρ, IsNontrivialZero ρ → 1/(16*C0hat(4k+9/2)) ≤ |ρ.im − R| ∨ 1 ≤ |ρ.im − R|. ✓ matches Fexpr_circle_le's needs (hgap then hgapInt order differs — Fexpr_circle_le takes hgap first, hgapInt second). The choice of k: given M : ℝ (M ≥ 16000), k := max 4000 ⌈M/4⌉₊. Then 4k ≥ M: ⌈M/4⌉₊ ≥ M/4 (Nat.le_ceil) ⟹ 4·⌈M/4⌉₊ ≥ M (for M ≥ 0). k ≥ 4000 ✓, and 1 ≤ k ✓. Then R ≥ 4k + 5/2 ≥ M + 5/2 > M ≥ max(...) hmm — need R ≥ c⁴ and R ≥ ‖z₀‖+1: M := max (c^4) (‖z₀‖ + 1) (and M ≥ 16000? no — k := max 4000 ⌈M/4⌉ gives 4k ≥ M automatically even if M < 16000; and k ≥ 4000 gives R ≥ 16002 anyway). So M := max (c^4) (‖z₀‖ + 1); k := max 4000 ⌈M/4⌉₊; 4k ≥ M ✓ (from the ceil branch: 4·⌈M/4⌉₊ ≥ M; and 4·max ≥ 4·⌈M/4⌉₊). Then R ≥ 4k+5/2 ≥ M + 5/2. Then: - hz0ball : ‖z₀‖ < R: ‖z₀‖ < ‖z₀‖+1 ≤ M ≤ ... < R. ✓ - hRc4 : c^4 ≤ R: c^4 ≤ M ≤ R ✓. - hQge : c ≤ Q where Q := R^(1/4:ℝ): c = (c^4)^(1/4) [pow_rpow_inv_natCast (c≥0) (4≠0), with exponent (4:ℝ)⁻¹ = 1/4] ≤ R^(1/4) [Real.rpow_le_rpow (0 ≤ c^4) hRc4 (1/4 ≥ 0)]. Exponent juggling: define Q := R ^ ((1:ℝ)/4)? or R ^ (4⁻¹ : ℝ)? pow_rpow_inv_natCast gives (c^4)^((4:ℝ)⁻¹) = c. If Q := R^(1/4), I need (1/4:ℝ) = (4:ℝ)⁻¹: `one_div 4`. So: rw [show (1/4:ℝ) = (4:ℝ)⁻¹ from one_div 4] — or just define Q := R ^ (4:ℝ)⁻¹ and note 1/4 never appears. But Real.log_le_rpow_div needs ε : ℝ, log R ≤ R^ε/ε — with ε := (4:ℝ)⁻¹: log R ≤ R^(4⁻¹)/(4⁻¹) = R^(4⁻¹)·4. The /ε = ·4 juggling: div by 4⁻¹ = mul by 4: `div_eq_mul_inv`, inv_inv. Fine — set ε := (4:ℝ)⁻¹, hε : 0 < (4:ℝ)⁻¹ := by positivity. So Q := R ^ (4:ℝ)⁻¹ (rpow). Facts: - hQnn : 0 ≤ Q := Real.rpow_nonneg hRnn _. - hQpos : 0 < Q := Real.rpow_pos_of_pos hRpos _. - hL : Real.log R ≤ 4 * Q: from log_le_rpow_div hRnn (show (0:ℝ) < (4:ℝ)⁻¹ by positivity): log R ≤ R^(4⁻¹)/(4⁻¹); R^(4⁻¹)/(4⁻¹) = 4·Q: field_simp? div by inv: R^a/(4⁻¹) = R^a * 4: `div_inv_eq_mul`... a/(4⁻¹) = a*4: rw [div_eq_mul_inv, inv_inv] : a * (4⁻¹)⁻¹ = a*4 ✓. So log R ≤ Q*4 = 4*Q (mul_comm juggling via calc or linarith with hQ4 : R^(4:ℝ)⁻¹/(4:ℝ)⁻¹ = 4*Q := by rw [div_eq_mul_inv, inv_inv]; ring). - hL3 : (Real.log R)^3 ≤ 64 * Q^3: have h1 : (log R)^3 ≤ (4*Q)^3 := pow_le_pow_left (by linarith [hlogR] : 0 ≤ log R) hL 3; (4*Q)^3 = 64*Q^3: by ring? (4*Q)^3 = 64*Q^3 — ring handles ✓ (pow with literal 3). pow_le_pow_left signature: (ha : 0 ≤ a) (hab : a ≤ b) (n : ℕ) : a^n ≤ b^n ✓ (used in project? standard). - hR4 : R = Q^4: from rpow_inv_natCast_pow hRnn (4≠0): (R^(4:ℝ)⁻¹)^4 = R, i.e., Q^4 = R — use .symm. Then the final grind as sketched. Let me also double check `Real.log_le_rpow_div` name (found at Pow/Real.lean:883: `lemma log_le_rpow_div {x ε : ℝ} (hx : 0 ≤ x) (hε : 0 < ε) : log x ≤ x ^ ε / ε`) — in Real namespace ✓. pow_le_pow_left — check name in current Mathlib: might be `pow_le_pow_left (ha : 0 ≤ a) (hab : a ≤ b) (n : ℕ)`. In recent Mathlib there's pow_le_pow_left₀ or pow_le_pow_left with swapped args... I recall `pow_le_pow_left (ha : 0 ≤ a) (hab : a ≤ b) : a ^ n ≤ b ^ n`. Grep at build time; fallback: nlinarith can't do it directly (L ≤ 4Q ⟹ L³ ≤ 64Q³ is nonlinear; nlinarith with hints: needs the product... nlinarith [sq_nonneg (L−4Q)...] might manage but messy; better find pow_le_pow_left). Also `one_le_pow₀`: name check — `one_le_pow₀ (ha : 1 ≤ a) : 1 ≤ a ^ n`? There's `one_le_pow_of_le'`... I'll grep. Actually I only need 8 ≤ Q^3 from 2 ≤ Q: pow_le_pow_left (0≤2) hQ2 3 gives 2^3 ≤ Q^3, 2^3 = 8 norm_num. ✓ same lemma. Also `Nat.le_ceil : x ≤ ⌈x⌉₊` for x : ℝ? `Nat.le_ceil (x : ℝ) : x ≤ ⌈x⌉₊` — requires? It's `Nat.le_ceil : ∀ (a : ℝ), a ≤ ↑⌈a⌉₊` ✓. Let me also confirm `Complex.norm_natCast` name and `norm_one`, `norm_zero`, `norm_mul`, `abs_zero` — all standard. `Metric.mem_sphere : z ∈ sphere x r ↔ dist z x = r` ✓; `Metric.mem_ball : dist z x < r`; `Metric.mem_closedBall : dist z x ≤ r` ✓. `dist_eq_norm : dist x y = ‖x − y‖` (for seminormed groups) ✓. `sub_zero` ✓. Alright. Also the RB definition: I'll phrase the sphere bound directly with the Fexpr_circle_le RHS expression rather than introducing a def (or a local let). Let me structure the file: §1. `C0hat_add_two_le` (the Ĉ₀(R+2) ≤ 5 log R growth bound). §2. `not_badPoint_on_gapCircle`. §3. `gentire_circle_le`. §4. `gentire_eq_zero_imp`... no — `gentire_const (hZC) : ∀ z₀, Gentire z₀ = Gentire 0`. §5. `partialFraction_identity (hZC : ZeroCountProp) : ∃ B, ...`. For §1, check what log lemmas exist: Real.log_pow (x:ℝ)(n:ℕ): log (x^n) = n*log x ✓ standard. Real.log_mul (hx : x ≠ 0)(hy : y ≠ 0): log (x*y) = log x + log y ✓. Real.log_le_sub_one_of_pos (hx : 0 < x) : log x ≤ x − 1 ✓ (I think that's the name — `Real.log_le_sub_one_of_pos`). Used in LiDigammaLeft probably. Let me grep quickly at build time if it fails; alternative: Real.add_pow_le_pow_mul_pow_of_sq_le_sq... no. There's also the possibility they already have a helper for log x ≤ x. Actually, let me check what's available: grep "log_le_sub_one_of_pos\|log_le_self" in Mathlib Log/Basic. Now write §1 proof in detail: ``` lemma C0hat_add_two_le {R : ℝ} (hR : 16002 ≤ R) : C0hat (R + 2) ≤ 5 * Real.log R := by have hRpos : (0:ℝ) < R := by linarith have hlogR : (9:ℝ) ≤ Real.log R := nine_le_log_of_16002_le hR -- log (R+4) ≤ 2 log R have h1 : Real.log (R + 2 + 2) ≤ 2 * Real.log R := by have hle : R + 4 ≤ R^2 := by nlinarith [hR] have h2 : Real.log (R + 2 + 2) ≤ Real.log (R^2) := by apply Real.log_le_log (by linarith : (0:ℝ) < R + 2 + 2) -- R+2+2 = R+4 ≤ R^2 (show R + 2 + 2 ≤ R^2 by linarith [hle]) -- ring_nf normalizes? ``` Hmm — R+2+2 vs R+4 syntactic difference: linarith handles ✓ (atoms R fine, linear). But the `apply Real.log_le_log` second goal is `R+2+2 ≤ R^2` — linarith [hle] where hle : R+4 ≤ R^2 — linear in atom R^2 ✓. ``` rw [Real.log_pow] at h2 -- log (R^2) = 2 * log R... log_pow : log (x^n) = n*log x with n:ℕ cast -- h2 : log (R+2+2) ≤ ↑(2:ℕ) * log R; push_cast at h2 rwa [Nat.cast_two] at h2 -- or push_cast at h2 ⊢? ``` Real.log_pow: `Real.log_pow (x : ℝ) (n : ℕ) : Real.log (x ^ n) = ↑n * Real.log x`. So rw [Real.log_pow] at h2 gives h2 : log(R+2+2) ≤ ↑2 * log R; norm_num at h2 or push_cast at h2 to make ↑2 = 2. Use `push_cast at h2; exact h2`. ``` -- log log (R+4) ≤ 2 log R have h2 : Real.log (Real.log (R + 2 + 2)) ≤ 2 * Real.log R := by have hpos1 : (0:ℝ) < Real.log (R + 2 + 2) := by have : Real.log R ≤ Real.log (R + 2 + 2) := Real.log_le_log hRpos (by linarith) linarith [hlogR] have h3 : Real.log (Real.log (R + 2 + 2)) ≤ Real.log (2 * Real.log R) := Real.log_le_log hpos1 h1 have h4 : Real.log (2 * Real.log R) = Real.log 2 + Real.log (Real.log R) := by rw [Real.log_mul (by norm_num) (by linarith [hlogR] : Real.log R ≠ 0)] have h5 : Real.log 2 ≤ 1 := by have h := Real.log_le_sub_one_of_pos (by norm_num : (0:ℝ) < 2) linarith have h6 : Real.log (Real.log R) ≤ Real.log R := by have h := Real.log_le_sub_one_of_pos (by linarith [hlogR] : (0:ℝ) < Real.log R) linarith linarith [h3, h4, h5, h6, hlogR] -- assemble: C0hat (R+2) = 0.433*log(R+4) + 0.886*log(log(R+4)) + 2.9 rw [C0hat] -- 2.9 ≤ (2.9/9)*log R ≤ ... just: 2.9 ≤ log R? no: 2.9 ≤ 2.9/9 * 9 ≤ ... use 2.9 ≤ (1/3)*log R hmm 2.9/9 ≈ 0.322; total 0.433*2 + 0.886*2 + 0.322 = 0.866+1.772+0.322 = 2.96 ≤ 5 ✓ nlinarith [h1, h2, hlogR] ``` nlinarith: goal 0.433*log(R+4) + 0.886*log(log(R+4)) + 2.9 ≤ 5*log R with h1: log(R+4) ≤ 2L, h2: loglog ≤ 2L, hlogR: 9 ≤ L. This is linear in atoms log(R+4), log(log(R+4)), log R — linarith should do it: 0.433*2L + 0.886*2L + 2.9 ≤ (0.866+1.772)*L + 2.9 = 2.638L + 2.9; need 2.9 ≤ 2.362*L ⟸ 2.9 ≤ 2.362*9 = 21.258 ✓. linarith handles decimal literals as rationals ✓. But careful: nlinarith/linarith need the hypotheses as linear atoms — ✓. Use linarith [h1, h2, hlogR]. Wait — after `rw [C0hat]`, goal shows `0.433 * Real.log (R + 2 + 2) + ...`? C0hat def: `0.433 * Real.log (t + 2) + 0.886 * Real.log (Real.log (t + 2)) + 2.9` with t := R+2, so log (R+2+2). My h1/h2 stated with R+2+2 ✓ (I wrote log (R+2+2)). ✓. unfold via `rw [C0hat]`? C0hat is a def — `rw [C0hat]` used in project? They used `rw [Fexpr]` — same mechanism ✓. Or `unfold C0hat`. I'll use `rw [C0hat]` hmm — actually `show` also works since defeq: `show 0.433 * Real.log (R + 2 + 2) + _ ≤ _`. I'll use unfold/rw. Also `nine_le_log_of_16002_le` — verify it exists (used in Fexpr_circle_le line 3826) ✓. §4 detail — the MapsTo R₂ radius: R₂ := RB + ‖Gentire 0‖ where RB := 2*lowZeroConst + dirichletC2 + 400000*A0count*C0hat (R+2)*(log R)^2. Schwarz gives dist ≤ R₂/R * dist z₀ 0. Subtlety: Schwarz's h_maps needs MapsTo into closedBall (Gentire 0) R₂ — I need R₂ defined as a plain ℝ expression. Fine. Also note: Schwarz's conclusion dist (f z) (f c) ≤ R₂/R₁ * dist z c — with c := (0:ℂ), f := Gentire: dist (Gentire z₀) (Gentire 0) ≤ R₂/R * dist z₀ 0. dist z₀ 0 = ‖z₀ − 0‖ = ‖z₀‖ ✓. Now the ball bound (max-modulus): AnalyticOn.norm_le_of_norm_le_on_sphere (hyp_r : r ≤ R) (analytic : AnalyticOn ℂ f (closedBall 0 R)) (cond : ∀ z ∈ sphere 0 r, ‖f z‖ ≤ C) (wInS : w ∈ closedBall 0 r) : ‖f w‖ ≤ C. With r = R ✓ le_refl. The `analytic` arg: AnalyticOn ℂ Gentire (closedBall 0 R): ``` have hGnhd : AnalyticOnNhd ℂ Gentire (Metric.closedBall 0 R) := fun s _ => gentire_analyticAt_and_eq.1 s have hGan : AnalyticOn ℂ Gentire (Metric.closedBall 0 R) := hGnhd.analyticOn ``` AnalyticOnNhd.analyticOn : AnalyticOnNhd f s → AnalyticOn f s ✓ (used in StrongPNTPrefix line 386). `gentire_analyticAt_and_eq.1 : ∀ s, AnalyticAt ℂ Gentire s` ✓. Now the full §4: ``` lemma gentire_const (hZC : ZeroCountProp) (z₀ : ℂ) : Gentire z₀ = Gentire 0 := by classical -- constants have hC0'nn : (0:ℝ) ≤ 2 * lowZeroConst + dirichletC2 + ‖Gentire 0‖ := by have h1 := lowZeroConst_nonneg have h2 := dirichletC2_nonneg have h3 := norm_nonneg (Gentire 0) linarith have hA0nn : (0:ℝ) ≤ A0count := A0count_pos.le -- main: ∀ ε > 0, dist ≤ ε have key : ∀ ε : ℝ, 0 < ε → dist (Gentire z₀) (Gentire 0) ≤ ε := by intro ε hε set C₀' := 2 * lowZeroConst + dirichletC2 + ‖Gentire 0‖ with hC0' set C₁ := 2000000 * A0count with hC1 have hC1nn : (0:ℝ) ≤ C₁ := by positivity -- 2000000 * A0count, needs A0count ≥ 0: positivity doesn't know A0count. use mul_nonneg ... ``` positivity won't know A0count ≥ 0 — use `mul_nonneg (by norm_num) hA0nn`. But C₁ is `set` — positivity on `C₁` fails; rw hC1 first or use `by rw [hC1]; exact mul_nonneg ...`. Hmm `set ... with h` gives hC1 : C₁ = 2000000 * A0count. rw [hC1]. OK. ``` set c := 2 + (128 * C₁ + 2 * C₀') * ‖z₀‖ / ε with hc have hcnn : (0:ℝ) ≤ 128 * C₁ + 2 * C₀' := by rw [hC1, hC0'] -- hmm messy; instead: ``` Since C₀' and C₁ are set-variables, nonneg proofs: have hC₀'nn : 0 ≤ C₀' := hC0' ▸ hC0'nn... With set, hC0' : C₀' = expr; rw [hC0'] replaces C₀' by expr. Fine: ``` have hC₀'nn : (0:ℝ) ≤ C₀' := by rw [hC0']; linarith [lowZeroConst_nonneg, dirichletC2_nonneg, norm_nonneg (Gentire 0)] have hC₁nn : (0:ℝ) ≤ C₁ := by rw [hC1]; exact mul_nonneg (by norm_num) hA0nn have hcz : (1:ℝ) ≤ c := by rw [hc] -- hmm set already replaced? with `set c := ... with hc`, occurrences replaced; hc : c = ... ``` Wait — `set x := e with h` introduces x and h : x = e, and replaces e by x in goal. New goals I create via `have` don't auto-rewrite. So `have hcz : 1 ≤ c := by rw [hc]; ...`: after rw [hc], goal 1 ≤ 2 + (128*C₁ + 2*C₀')*‖z₀‖/ε. Proof: (128*C₁ + 2*C₀')*‖z₀‖/ε ≥ 0: div_nonneg (mul_nonneg (add_nonneg (mul_nonneg (by norm_num) hC₁nn) (mul_nonneg (by norm_num) hC₀'nn)) (norm_nonneg _)) hε.le. linarith. ``` -- choose k and R set M := max (c ^ 4) (‖z₀‖ + 1) with hM obtain ⟨k, hk4000, hkM⟩ : ∃ k : ℕ, 4000 ≤ k ∧ M ≤ 4 * (k:ℝ) := by refine ⟨max 4000 ⌈M / 4⌉₊, le_max_left _ _, ?_⟩ have h1 : M / 4 ≤ (⌈M / 4⌉₊ : ℝ) := Nat.le_ceil _ have h2 : (⌈M / 4⌉₊ : ℝ) ≤ (max 4000 ⌈M / 4⌉₊ : ℕ) := by exact_mod_cast le_max_right _ _ have h3 : M ≤ 4 * (⌈M / 4⌉₊ : ℝ) := by linarith [h1] calc M ≤ 4 * (⌈M / 4⌉₊ : ℝ) := h3 _ ≤ 4 * ((max 4000 ⌈M / 4⌉₊ : ℕ) : ℝ) := by apply mul_le_mul_of_nonneg_left _ (by norm_num : (0:ℝ) ≤ 4) exact_mod_cast le_max_right _ _ ``` Hmm — cast juggling: (4 * (k:ℝ)) where k = max 4000 ⌈M/4⌉₊; ((max a b : ℕ) : ℝ) = max (a:ℝ) (b:ℝ)? Nat.cast_max ✓ exists. Simpler: ``` have hceil : M ≤ 4 * (⌈M / 4⌉₊ : ℝ) := by have h1 := Nat.le_ceil (M / 4) linarith have hcast : (4 : ℝ) * (⌈M / 4⌉₊ : ℝ) ≤ 4 * ((max 4000 ⌈M / 4⌉₊ : ℕ) : ℝ) := by have : (⌈M / 4⌉₊ : ℝ) ≤ ((max 4000 ⌈M / 4⌉₊ : ℕ) : ℝ) := by exact_mod_cast le_max_right _ _ linarith linarith [hceil, hcast] ``` linarith fine (atoms: casts). ``` obtain ⟨R, hRlo, hRhi, hgapInt, hgap⟩ := exists_gapCircle_radius hZC (k := k) (by omega : 1 ≤ k) ``` Wait signature: exists_gapCircle_radius (hZC : ZeroCountProp) {k : ℕ} (hk : 1 ≤ k). k implicit — pass (k := k)? If implicit it unifies from hk? hk : 1 ≤ k forces it ✓ just `exists_gapCircle_radius hZC (by omega)` might leave k as metavariable resolved by hk — hk's type mentions k... ambiguous; safer to give explicitly. Check how LiCircleBound calls it... Fexpr_circle_le takes the gap properties as hypotheses, doesn't call exists_gapCircle_radius. Let me check if anything calls it — probably not yet (5e-v-d is the first consumer). I'll write `exists_gapCircle_radius hZC (k := k) (by omega)` — if k is implicit, (k := k) works; if explicit positional, adjust. ``` have hR16002 : (16002:ℝ) ≤ R := by have hkR : (16000:ℝ) ≤ 4 * (k:ℝ) := by have h1 : (4000:ℝ) ≤ (k:ℝ) := by exact_mod_cast hk4000 linarith linarith [hRlo] have hRpos : (0:ℝ) < R := by linarith [hR16002] have hlogR : (9:ℝ) ≤ Real.log R := nine_le_log_of_16002_le hR16002 have hMR : M ≤ R := by linarith [hkM, hRlo] -- the circle bound on the sphere have hsphere : ∀ z ∈ Metric.sphere (0:ℂ) R, ‖Gentire z‖ ≤ 2 * lowZeroConst + dirichletC2 + 400000 * A0count * C0hat (R + 2) * (Real.log R)^2 := by intro z hz have hznorm : ‖z‖ = R := by have h := Metric.mem_sphere.mp hz rw [dist_eq_norm, sub_zero] at h -- h : ‖z‖ = R? dist z 0 = ‖z - 0‖ = ‖z‖ exact h have hgood : ¬ badPoint z := not_badPoint_on_gapCircle hk4000 hRlo hgap hgapInt hznorm rw [gentire_eq_Fexpr hgood] exact Fexpr_circle_le hk4000 hRlo hRhi hgap hgapInt hznorm ``` Check `dist_eq_norm : dist x y = ‖x − y‖` — for ℂ yes (SeminormedGroup). `sub_zero : x − 0 = x` ✓. But rw [sub_zero] at h where h : ‖z − 0‖ = R: sub_zero is about z − (0:ℂ) ✓. ``` -- ball bound via max-modulus have hGan : AnalyticOn ℂ Gentire (Metric.closedBall 0 R) := (fun s _ => gentire_analyticAt_and_eq.1 s : AnalyticOnNhd ℂ Gentire _).analyticOn ``` Hmm — the ascription `(fun s _ => ... : AnalyticOnNhd ℂ Gentire _)` — AnalyticOnNhd ℂ f s : Prop := ∀ x ∈ s, AnalyticAt ℂ f x. The lambda fun s _ => gentire_analyticAt_and_eq.1 s : ∀ s, s ∈ closedBall 0 R → AnalyticAt ℂ Gentire s ✓ defeq. Then `.analyticOn`. Cleaner: ``` have hGan : AnalyticOn ℂ Gentire (Metric.closedBall 0 R) := AnalyticOnNhd.analyticOn (fun s _ => gentire_analyticAt_and_eq.1 s) ``` The expected type guides the lambda ✓. ``` have hball : ∀ z ∈ Metric.closedBall (0:ℂ) R, ‖Gentire z‖ ≤ 2 * lowZeroConst + dirichletC2 + 400000 * A0count * C0hat (R + 2) * (Real.log R)^2 := fun z hz => AnalyticOn.norm_le_of_norm_le_on_sphere le_rfl hGan hsphere hz ``` Wait — the lemma is stated with implicit {C r R} and our C is the big expression; unification from hsphere ✓. ``` -- MapsTo set RB := 2 * lowZeroConst + dirichletC2 + 400000 * A0count * C0hat (R + 2) * (Real.log R)^2 with hRB have hRBnn : (0:ℝ) ≤ RB := by rw [hRB] have hĈ : (0:ℝ) ≤ C0hat (R + 2) := by have h1 : (2:ℝ) ≤ C0hat (R + 2) := two_le_C0hat (by linarith [hRpos] : (1:ℝ) ≤ R + 2) linarith have hlogRnn : (0:ℝ) ≤ Real.log R := by linarith [hlogR] positivity-ish: add_nonneg (add_nonneg (mul_nonneg (by norm_num) lowZeroConst_nonneg) dirichletC2_nonneg) (mul_nonneg (mul_nonneg (mul_nonneg (by norm_num) hA0nn) hĈ) (pow_nonneg hlogRnn 2)) have hmaps : MapsTo Gentire (Metric.ball 0 R) (Metric.closedBall (Gentire 0) (RB + ‖Gentire 0‖)) := by intro z hz have hzball : z ∈ Metric.closedBall (0:ℂ) R := by rw [Metric.mem_ball] at hz; rw [Metric.mem_closedBall]; exact hz.le have h1 := hball z hzball rw [Metric.mem_closedBall, dist_eq_norm] calc ‖Gentire z - Gentire 0‖ ≤ ‖Gentire z‖ + ‖Gentire 0‖ := norm_sub_le _ _ _ ≤ RB + ‖Gentire 0‖ := by linarith [h1] ``` Hmm — linarith [h1] with h1 : ‖Gentire z‖ ≤ RB: goal ‖Gentire z‖ + ‖Gentire 0‖ ≤ RB + ‖Gentire 0‖ — linear ✓ but wait the gotcha: add_le_add_left/right swapped — linarith avoids it ✓. ``` -- Schwarz have hdiff : DifferentiableOn ℂ Gentire (Metric.ball 0 R) := fun z _ => (gentire_analyticAt_and_eq.1 z).differentiableAt.differentiableWithinAt have hz0mem : z₀ ∈ Metric.ball (0:ℂ) R := by rw [Metric.mem_ball, dist_eq_norm, sub_zero] have h1 : ‖z₀‖ + 1 ≤ M := le_max_right _ _ -- wait M := max (c^4) (‖z₀‖+1): le_max_right gives ‖z₀‖+1 ≤ M ✓ have h2 : ‖z₀‖ < M := by linarith [norm_nonneg z₀] linarith [hMR] have hschwarz := Complex.dist_le_div_mul_dist_of_mapsTo_ball hdiff hmaps hz0mem -- hschwarz : dist (Gentire z₀) (Gentire 0) ≤ (RB + ‖Gentire 0‖)/R * dist z₀ 0 rw [dist_eq_norm, sub_zero] at hschwarz ``` Hmm — `Complex.dist_le_div_mul_dist_of_mapsTo_ball` signature: (hd : DifferentiableOn ℂ f (ball c R₁)) (h_maps : MapsTo f (ball c R₁) (closedBall (f c) R₂)) (hz : z ∈ ball c R₁) : dist (f z) (f c) ≤ R₂ / R₁ * dist z c. Note it's stated for general E F normed spaces with f : E → F and ℂ differentiability — here E = ℂ. The ball is `ball c R₁` — from Schwarz.lean line 190, `ball c R₁` with open Metric? Schwarz.lean opens... the lemma uses `ball`/`closedBall` — in that file there's `open Metric`? The statement shows `MapsTo f (ball c R₁) (closedBall (f c) R₂)` — these are Metric.ball/closedBall ✓. Also note the implicit args: {f}, {c}, {z}, {R₁}, {R₂} — unified from args ✓. ``` -- hschwarz : dist (Gentire z₀) (Gentire 0) ≤ (RB + ‖Gentire 0‖) / R * ‖z₀‖ -- the growth bound: RB ≤ C₀' + 64*C₁*Q^3, R = Q^4, Q ≥ c set Q := R ^ ((4:ℝ)⁻¹) with hQ have hQnn : (0:ℝ) ≤ Q := Real.rpow_nonneg hRpos.le _ have hQpos : (0:ℝ) < Q := Real.rpow_pos_of_pos hRpos _ have hQc : c ≤ Q := by have h1 : c = (c ^ 4) ^ ((4:ℝ)⁻¹) := (Real.pow_rpow_inv_natCast hcnn'? (four ≠ 0)).symm ``` pow_rpow_inv_natCast (hx : 0 ≤ x) (hn : n ≠ 0) : (x ^ n) ^ (n⁻¹ : ℝ) = x. So ((c^4) ^ ((4:ℝ)⁻¹)) = c ✓. hc ≥ 1 ⟹ 0 ≤ c ✓ (hcnn2 : 0 ≤ c := by linarith [hcz]). ``` have h2 : (c ^ 4) ^ ((4:ℝ)⁻¹) ≤ R ^ ((4:ℝ)⁻¹) := Real.rpow_le_rpow (pow_nonneg (by linarith [hcz]) 4) (by have : c ^ 4 ≤ M := le_max_left _ _ linarith [hMR]) (by positivity : (0:ℝ) ≤ (4:ℝ)⁻¹) rw [h1] -- hmm goal c ≤ Q; rw h1 makes goal ((c^4)^((4:ℝ)⁻¹)) ≤ Q; Q is set-var := R^(4⁻¹) exact h2 -- h2 : (c^4)^(4⁻¹) ≤ R^(4⁻¹); Q is let/set: after set, R^(4⁻¹) displayed as Q; defeq ✓ exact h2 should work since set uses let? `set` introduces a local def; exact h2 with h2 mentioning R^(4⁻¹) — the goal shows Q but is defeq ✓. ``` Hmm — `set Q := R ^ ((4:ℝ)⁻¹) with hQ` replaces occurrences in the goal only; my new haves mention R^(4⁻¹) directly; goals will show Q after set? New have-goals I state myself — I control their statements, so I'll state them with R^((4:ℝ)⁻¹) or Q consistently. With `set`, hQ : Q = R ^ ((4:ℝ)⁻¹). When I prove h2 : (c^4)^((4:ℝ)⁻¹) ≤ R^((4:ℝ)⁻¹) and need c ≤ Q: rw [hQ] at goal? Goal c ≤ Q; rw [hQ] gives c ≤ R^(4⁻¹) ✓ then rw [h1] gives ((c^4)^(4⁻¹)) ≤ R^(4⁻¹) = h2 ✓. OK — but rw [hQ] rewrites Q → R^(4⁻¹) in goal (hQ : Q = ...; rw [hQ] replaces Q with RHS ✓). Actually simpler: avoid `set` for Q; just use R^((4:ℝ)⁻¹) throughout, with a `have hQdef`-free approach. Expression is a bit long but fine. Actually let me use `set` and be careful. Or `let`? `set` is fine. Continue: ``` have hL : Real.log R ≤ 4 * Q := by have h := Real.log_le_rpow_div hRpos.le (show (0:ℝ) < (4:ℝ)⁻¹ by positivity) -- h : log R ≤ R^((4:ℝ)⁻¹) / (4:ℝ)⁻¹ have h2 : R ^ ((4:ℝ)⁻¹) / (4:ℝ)⁻¹ = 4 * Q := by rw [hQ, div_eq_mul_inv, inv_inv] -- Q * 4 → 4 * Q by ring ring rw [h2] at h -- hmm h's RHS rewritten exact h ``` Careful: `rw [h2] at h` — h2 : R^(4⁻¹)/(4⁻¹) = 4*Q; rw [h2] at h : h : log R ≤ 4*Q ✓. But hQ : Q = R^(4⁻¹); inside h2 I rw [hQ] turning goal R^(4⁻¹)/(4⁻¹) = 4*Q into Q/(4⁻¹) = 4*Q... wait rw [hQ] rewrites Q→R^(4⁻¹) everywhere: goal becomes R^(4⁻¹)/(4⁻¹) = 4*(R^(4⁻¹)). Then div_eq_mul_inv: R^(4⁻¹) * (4⁻¹)⁻¹ = ...; inv_inv: (4⁻¹)⁻¹ = 4: R^(4⁻¹)*4 = 4*R^(4⁻¹): ring ✓. ``` have hL3 : (Real.log R)^3 ≤ 64 * Q^3 := by have h1 : (Real.log R)^3 ≤ (4 * Q)^3 := pow_le_pow_left (by linarith [hlogR]) hL 3 have h2 : (4 * Q)^3 = 64 * Q^3 := by ring rw [h2] at h1; exact h1 -- RB ≤ C₀' + C₁*(log R)^3 ≤ C₀' + 64*C₁*Q^3 have hĈ5 : C0hat (R + 2) ≤ 5 * Real.log R := C0hat_add_two_le hR16002 have hRBle : RB ≤ C₀' + 64 * C₁ * Q^3 := by have hlogRnn : (0:ℝ) ≤ Real.log R := by linarith [hlogR] have hstep1 : 400000 * A0count * C0hat (R + 2) * (Real.log R)^2 ≤ 400000 * A0count * (5 * Real.log R) * (Real.log R)^2 := by apply mul_le_mul_of_nonneg_right _ (pow_nonneg hlogRnn 2) apply mul_le_mul_of_nonneg_left hĈ5 exact mul_nonneg (by norm_num) hA0nn have hstep2 : 400000 * A0count * (5 * Real.log R) * (Real.log R)^2 = C₁ * (Real.log R)^3 := by rw [hC1]; ring -- 400000*A0*5*L*L^2 = 2000000*A0*L^3: ring handles L^2*L = L^3? ring with pow ✓ have hstep3 : C₁ * (Real.log R)^3 ≤ C₁ * (64 * Q^3) := mul_le_mul_of_nonneg_left hL3 hC₁nn -- assemble: RB = 2*lowZeroConst + dirichletC2 + [big] ≤ (C₀' - ‖Gentire 0‖) + C₁*64*Q^3 ≤ C₀' + 64*C₁*Q^3 rw [hRB, hC0'] -- goal: 2*lowZeroConst + dirichletC2 + big ≤ (2*lowZeroConst + dirichletC2 + ‖Gentire 0‖) + 64*C₁*Q^3 have hbig : 400000 * A0count * C0hat (R + 2) * (Real.log R)^2 ≤ 64 * C₁ * Q^3 := by have : C₁ * (Real.log R)^3 ≤ 64 * C₁ * Q^3 := by have h := mul_le_mul_of_nonneg_left hL3 hC₁nn -- C₁*L^3 ≤ C₁*(64*Q^3) -- C₁*(64*Q^3) = 64*C₁*Q^3 by ring — need a bridge have have h2 : C₁ * (64 * Q^3) = 64 * C₁ * Q^3 := by ring rwa [h2] at h linarith [hstep1, hstep2, this] -- hmm hstep2 is an equation: linarith handles ✓ have hG0nn : (0:ℝ) ≤ ‖Gentire 0‖ := norm_nonneg _ linarith [hbig, hG0nn] ``` Careful with `linarith [hstep1, hstep2, this]`: goal `400000 * A0count * C0hat (R + 2) * (Real.log R)^2 ≤ 64 * C₁ * Q^3`; hstep1 : LHS ≤ 400000*A0*(5*L)*L^2; hstep2 : 400000*A0*(5*L)*L^2 = C₁*L^3; this : C₁*L^3 ≤ 64*C₁*Q^3. linarith chains ✓ (all linear atoms). ``` -- the final real inequality: (RB + ‖Gentire 0‖)/R * ‖z₀‖ ≤ ε have hR4 : R = Q^4 := by have h := Real.rpow_inv_natCast_pow hRpos.le (show (4:ℕ) ≠ 0 by norm_num) -- h : (R^((4:ℝ)⁻¹))^4 = R; R^(4⁻¹) = Q by hQ.symm rw [← hQ] at h -- h : Q^4 = R exact h.symm ``` rpow_inv_natCast_pow (hx : 0 ≤ x) (hn : n ≠ 0) : (x ^ (n⁻¹ : ℝ)) ^ n = x. Here n : ℕ implicit? From the source: `theorem rpow_inv_natCast_pow (hx : 0 ≤ x) (hn : n ≠ 0) : (x ^ (n⁻¹ : ℝ)) ^ n = x` — n implicit presumably {n : ℕ}. Call: Real.rpow_inv_natCast_pow hRpos.le (show (4:ℕ) ≠ 0 by norm_num) : (R ^ ((4:ℕ)⁻¹ : ℝ)) ^ 4 = R. The exponent is (↑(4:ℕ))⁻¹ : ℝ = ((4:ℝ))⁻¹ — Nat.cast 4 = 4: the term R ^ (↑4)⁻¹ vs my Q := R ^ ((4:ℝ)⁻¹) — (↑(4:ℕ) : ℝ) is defeq to (4:ℝ) but syntactically different after set... rw [← hQ] at h needs syntactic match of R^((4:ℝ)⁻¹) inside h's (↑(4:ℕ))⁻¹ form — might fail! Fix: push_cast at h first: push_cast turns ((4:ℕ):ℝ)⁻¹ into (4:ℝ)⁻¹ ✓. So: `push_cast at h` then rw [← hQ] at h. ``` have hmain : (RB + ‖Gentire 0‖) / R * ‖z₀‖ ≤ ε := by rw [hR4] -- goal: (RB + ‖Gentire 0‖)/Q^4 * ‖z₀‖ ≤ ε have hQ4pos : (0:ℝ) < Q^4 := pow_pos hQpos 4 rw [div_mul_eq_mul_div, le_div_iff₀ hQ4pos] -- ((RB+‖Gentire 0‖) * ‖z₀‖) ≤ ε * Q^4 ``` Hmm: (X/Q⁴)*‖z₀‖ = X*‖z₀‖/Q⁴ (div_mul_eq_mul_div ✓). le_div_iff₀ (hc : 0 < c) : a ≤ b / c ↔ a * c ≤ b ✓. Goal: (RB+‖G0‖)*‖z₀‖*Q^4 ≤ ε... wait direction: a ≤ b/c ↔ a*c ≤ b: ((RB+‖G0‖)*‖z₀‖) * Q^4 ≤ ε ✓. ``` -- pieces have hc1 : (128 * C₁) * ‖z₀‖ ≤ ε * Q := by have h1 : (128 * C₁ + 2 * C₀') * ‖z₀‖ / ε ≤ c := by rw [hc] -- c = 2 + .../ε; linarith with the div nonneg? goal (128C₁+2C₀')‖z₀‖/ε ≤ 2 + (128C₁+2C₀')‖z₀‖/ε: linarith have h2 : (128 * C₁) * ‖z₀‖ ≤ (128 * C₁ + 2 * C₀') * ‖z₀‖ := by apply mul_le_mul_of_nonneg_right _ (norm_nonneg _) -- 128*C₁ ≤ 128*C₁ + 2*C₀' linarith [hC₀'nn, hC₁nn] -- hmm linarith: goal 128*C₁ ≤ 128*C₁ + 2*C₀' with 0 ≤ C₀' ✓ have h3 : (128 * C₁) * ‖z₀‖ / ε ≤ c := by have h4 : (128 * C₁) * ‖z₀‖ / ε ≤ (128 * C₁ + 2 * C₀') * ‖z₀‖ / ε := div_le_div_of_nonneg_right h2 hε.le -- check name: div_le_div_of_nonneg_right? session-032 gotcha: "div_le_div_of_nonneg_right exists / div_le_div_right does NOT" ✓ exact h4.trans h1 -- multiply through by ε calc (128 * C₁) * ‖z₀‖ = (128 * C₁) * ‖z₀‖ / ε * ε := by rw [div_mul_cancel₀ _ hε.ne'] _ ≤ c * ε := mul_le_mul_of_nonneg_right h3 hε.le _ ≤ Q * ε := mul_le_mul_of_nonneg_right hQc hε.le _ = ε * Q := by ring have hA : 64 * C₁ * Q^3 * ‖z₀‖ ≤ (ε/2) * Q^4 := by have h1 : (64 * C₁ * ‖z₀‖) * Q^3 ≤ ((ε/2) * Q) * Q^3 := by apply mul_le_mul_of_nonneg_right _ (pow_nonneg hQnn 3) -- 64*C₁*‖z₀‖ ≤ (ε/2)*Q have hhalf : (ε/2) * Q = (ε * Q)/2 := by ring rw [hhalf] -- goal 64*C₁*‖z₀‖ ≤ ε*Q/2 -- from hc1: 128*C₁*‖z₀‖ ≤ ε*Q have h128 : 128 * C₁ * ‖z₀‖ ≤ ε * Q := hc1 -- 64*C₁*‖z₀‖ = (128*C₁*‖z₀‖)/2 have h64 : (64:ℝ) * C₁ * ‖z₀‖ = (128 * C₁ * ‖z₀‖)/2 := by ring rw [h64]; linarith [h128] -- reassociate: (64*C₁*‖z₀‖)*Q^3 = 64*C₁*Q^3*‖z₀‖ and ((ε/2)*Q)*Q^3 = (ε/2)*Q^4 have hL : (64 * C₁ * ‖z₀‖) * Q^3 = 64 * C₁ * Q^3 * ‖z₀‖ := by ring have hR' : ((ε/2) * Q) * Q^3 = (ε/2) * Q^4 := by ring rwa [hL, hR'] at h1 have hB : C₀' * ‖z₀‖ ≤ (ε/2) * Q^4 := by have h1 : (2 * C₀') * ‖z₀‖ ≤ ε * Q := by have h2 : (2 * C₀') * ‖z₀‖ ≤ (128 * C₁ + 2 * C₀') * ‖z₀‖ := by apply mul_le_mul_of_nonneg_right _ (norm_nonneg _) linarith [hC₁nn] have h3 : (128 * C₁ + 2 * C₀') * ‖z₀‖ / ε ≤ c := by rw [hc]; linarith have h4 : (2 * C₀') * ‖z₀‖ / ε ≤ c := (div_le_div_of_nonneg_right h2 hε.le).trans h3 calc (2 * C₀') * ‖z₀‖ = (2 * C₀') * ‖z₀‖ / ε * ε := by rw [div_mul_cancel₀ _ hε.ne'] _ ≤ c * ε := mul_le_mul_of_nonneg_right h4 hε.le _ ≤ Q * ε := mul_le_mul_of_nonneg_right hQc hε.le _ = ε * Q := by ring have hQ2 : (2:ℝ) ≤ Q := by linarith [hQc, hcz] -- c ≥ 2? c = 2 + nonneg ≥ 2 ✓ (hcz was 1 ≤ c; need 2 ≤ c) have hQ3 : (8:ℝ) ≤ Q^3 := by have h := pow_le_pow_left (by norm_num : (0:ℝ) ≤ 2) hQ2 3 -- 2^3 ≤ Q^3 norm_num at h -- 2^3 = 8 exact h have h2 : ε * Q ≤ (ε/2) * Q^4 := by -- (ε/2)*Q^4 = (ε/2)*Q*Q^3 ≥ (ε/2)*Q*8 = 4*ε*Q ≥ ε*Q have h3 : (ε/2) * Q^4 = ((ε/2) * Q) * Q^3 := by ring rw [h3] have h4 : (ε/2) * Q * 1 ≤ ((ε/2) * Q) * Q^3 := by apply mul_le_mul_of_nonneg_left _ (by positivity : (0:ℝ) ≤ ε/2 * Q) linarith [hQ3] -- 1 ≤ Q^3 hmm: linarith with hQ3 : 8 ≤ Q^3 ⟹ 1 ≤ Q^3 ✓ have h5 : ε * Q = (ε/2) * Q * 2 := by ring rw [h5] -- 2 ≤ Q^3 mul-left have h6 : (ε/2) * Q * 2 ≤ (ε/2) * Q * Q^3 := mul_le_mul_of_nonneg_left (by linarith [hQ3] : (2:ℝ) ≤ Q^3) (by positivity : (0:ℝ) ≤ ε/2*Q) exact h6 -- C₀'*‖z₀‖ ≤ (2*C₀')*‖z₀‖/2 ≤ ε*Q/2 ≤ (ε/2)*Q^4/2?? hmm redo ``` Hmm — h1 : 2·C₀'·‖z₀‖ ≤ ε·Q and h2 : ε·Q ≤ (ε/2)·Q⁴. Then 2·C₀'·‖z₀‖ ≤ (ε/2)·Q⁴, so C₀'·‖z₀‖ ≤ (ε/2)·Q⁴ follows (C₀'‖z₀‖ ≤ 2·C₀'‖z₀‖). linarith-friendly: need the atoms aligned: (2*C₀')*‖z₀‖ vs 2*(C₀'*‖z₀‖) — ring-equal, linarith normalizes ✓. So: ``` have h7 : C₀' * ‖z₀‖ ≤ 2 * C₀' * ‖z₀‖ := by have h : (0:ℝ) ≤ C₀' * ‖z₀‖ := mul_nonneg hC₀'nn (norm_nonneg _) linarith [h] -- C₀'*‖z₀‖ ≤ 2*C₀'*‖z₀‖ = C₀'*‖z₀‖ + C₀'*‖z₀‖ ✓ linarith normalizes (2*C₀')*‖z₀‖ to 2*(C₀'*‖z₀‖) linarith [h7, h1, h2] ``` linarith: C₀'‖z₀‖ ≤ 2 C₀'‖z₀‖ ≤ εQ ≤ (ε/2)Q⁴ ✓ — wait h1 : (2*C₀')*‖z₀‖ ≤ ε*Q: linarith normalizes (2*C₀')*‖z₀‖ → 2*(C₀'*‖z₀‖) ✓ same atom. ``` -- assemble have hsum : (RB + ‖Gentire 0‖) * ‖z₀‖ ≤ ε * Q^4 := by have h1 : (RB + ‖Gentire 0‖) * ‖z₀‖ ≤ (C₀' + 64 * C₁ * Q^3 + ‖Gentire 0‖) * ‖z₀‖ := by apply mul_le_mul_of_nonneg_right _ (norm_nonneg _) linarith [hRBle, norm_nonneg (Gentire 0)] -- RB + ‖G0‖ ≤ C₀' + 64C₁Q³ + ‖G0‖ have h2 : (C₀' + 64 * C₁ * Q^3 + ‖Gentire 0‖) * ‖z₀‖ = C₀' * ‖z₀‖ + 64 * C₁ * Q^3 * ‖z₀‖ + ‖Gentire 0‖ * ‖z₀‖ := by ring -- hmm wait C₀' already contains ‖Gentire 0‖: C₀' + ‖Gentire 0‖ ≤ 2*C₀'... simplify: C₀'*‖z₀‖ + ‖G0‖*‖z₀‖ ≤ C₀'*‖z₀‖ + C₀'*‖z₀‖ since ‖G0‖ ≤ C₀' (as 2*lowZeroConst + dirichletC2 ≥ 0) have h3 : ‖Gentire 0‖ * ‖z₀‖ ≤ C₀' * ‖z₀‖ := by apply mul_le_mul_of_nonneg_right _ (norm_nonneg _) rw [hC0'] -- ‖G0‖ ≤ 2*lowZeroConst + dirichletC2 + ‖G0‖: linarith linarith [lowZeroConst_nonneg, dirichletC2_nonneg] linarith [h1, h2, h3, hA, hB] -- convert calc (RB + ‖Gentire 0‖) / Q^4 * ‖z₀‖ = (RB + ‖Gentire 0‖) * ‖z₀‖ / Q^4 := by ring _ ≤ ε := by rw [div_le_iff₀ hQ4pos]; linarith [hsum] -- wait direction ``` div_le_iff₀ (hc : 0 < c) : a / c ≤ b ↔ a ≤ b * c. Goal: (RB+‖G0‖)*‖z₀‖/Q⁴ ≤ ε. rw [div_le_iff₀ hQ4pos]: goal (RB+‖G0‖)*‖z₀‖ ≤ ε*Q⁴ = hsum ✓ exact hsum. Hmm wait — I did `rw [hR4]` earlier then `rw [div_mul_eq_mul_div, le_div_iff₀ hQ4pos]` in hmain — let me restructure hmain cleanly: ``` have hmain : (RB + ‖Gentire 0‖) / R * ‖z₀‖ ≤ ε := by have hQ4pos : (0:ℝ) < Q^4 := pow_pos hQpos 4 have h1 : (RB + ‖Gentire 0‖) / R * ‖z₀‖ = (RB + ‖Gentire 0‖) * ‖z₀‖ / Q^4 := by rw [hR4]; ring rw [h1, div_le_iff₀ hQ4pos] exact hsum ``` where hsum as above. But hsum/hA/hB are built inside... I should inline them all inside hmain's proof or as separate haves in the key block. Structure: build hsum first, then hmain. And div_le_iff₀ check: per session-033 gotcha "div_lt_iff₀ is a/c<b here" — that's for <. For ≤: `div_le_iff₀ (hc : 0 < c) : a / c ≤ b ↔ a ≤ b * c` ✓ standard. Then finish key: ``` calc dist (Gentire z₀) (Gentire 0) ≤ (RB + ‖Gentire 0‖) / R * ‖z₀‖ := hschwarz _ ≤ ε := hmain ``` Wait — hschwarz after rw [dist_eq_norm, sub_zero] at hschwarz : dist (Gentire z₀) (Gentire 0) ≤ (RB + ‖Gentire 0‖)/R * ‖z₀‖. But hold on: hschwarz's RHS has dist z₀ 0: rw [dist_eq_norm] at hschwarz rewrites BOTH dists (dist (Gentire z₀) (Gentire 0) too!) → ‖Gentire z₀ − Gentire 0‖ ≤ ... * ‖z₀ − 0‖; then sub_zero rewrites z₀ − 0 AND Gentire z₀ − Gentire 0... sub_zero rw [sub_zero] at hschwarz rewrites all `? − 0` — both. Then the final equality uses dist_eq_zero: ‖Gentire z₀ − Gentire 0‖ = 0 ↔ Gentire z₀ − Gentire 0 = 0 (norm_eq_zero) ↔ Gentire z₀ = Gentire 0 (sub_eq_zero). OK workable but let me instead NOT rw at hschwarz; bridge in the calc: ``` have hdz0 : dist z₀ 0 = ‖z₀‖ := by rw [dist_eq_norm, sub_zero] calc dist (Gentire z₀) (Gentire 0) ≤ (RB + ‖Gentire 0‖)/R * dist z₀ 0 := hschwarz _ = (RB + ‖Gentire 0‖)/R * ‖z₀‖ := by rw [hdz0] _ ≤ ε := hmain ``` Cleaner ✓. Then after key: ``` -- dist ≤ 0 ⟹ = 0 ⟹ eq have h0 : dist (Gentire z₀) (Gentire 0) ≤ 0 := by apply le_of_forall_pos_le_add -- hmm signature: (∀ ε, 0 < ε → a ≤ b + ε) → a ≤ b intro ε hε have := key ε hε linarith ``` Check le_of_forall_pos_le_add exists: `le_of_forall_pos_le_add : (∀ ε : α, 0 < ε → a ≤ b + ε) → a ≤ b` — I believe it exists in Mathlib (Algebra/Order/...). Alternatively: le_antisymm: dist ≤ 0 from... or use `le_of_forall_lt'`... I'll check via grep. Fallback: by_contra + Archimedean-free: if 0 < dist then key (dist/2) gives dist ≤ dist/2 contradiction. That's robust: ``` by_contra hne have hpos : 0 < dist (Gentire z₀) (Gentire 0) := by exact lt_of_not_ge (by ...)? ``` hmm — cleaner: ``` rcases le_or_lt (dist (Gentire z₀) (Gentire 0)) 0 with h | h · exact dist_eq_zero.mp (le_antisymm h dist_nonneg) -- gives Gentire z₀ = Gentire 0 ✓ · have h2 := key (dist (Gentire z₀) (Gentire 0) / 2) (by linarith) linarith ``` ✓ robust, no lemma-name risk. Wait — goal of gentire_const is `Gentire z₀ = Gentire 0`; dist_eq_zero.mp : dist x y = 0 → x = y ✓. Then the capstone: ``` theorem partialFraction_identity (hZC : ZeroCountProp) : ∃ B : ℂ, ∀ s : ℂ, riemannZeta s ≠ 0 → s ≠ 0 → s ≠ 1 → (∀ n : ℕ, 1 ≤ n → s ≠ -2 * (n : ℂ)) → logDeriv riemannZeta s = B + seriesFun s - 1 / s - 1 / (s - 1) + (Real.log Real.pi : ℂ) / 2 - Complex.digamma (s / 2) / 2 := by refine ⟨Gentire 0, fun s hζ hs0 hs1 hsn => ?_⟩ have hgood : ¬ badPoint s := by rintro (h | h | h | ⟨n, hn, h⟩) · exact hζ h.1 · exact hs0 h · exact hs1 h · exact hsn n hn h have hG : Fexpr s = Gentire 0 := by rw [← gentire_eq_Fexpr hgood] exact gentire_const hZC s rw [Fexpr] at hG -- unfold linear_combination hG ``` Check: hG : logDeriv riemannZeta s - seriesFun s + 1/s + 1/(s-1) - (↑(Real.log π))/2 + Complex.digamma (s/2)/2 = Gentire 0. Goal: logDeriv riemannZeta s = Gentire 0 + seriesFun s - 1/s - 1/(s-1) + (↑(Real.log π))/2 - Complex.digamma (s/2)/2. linear_combination hG: LHS−RHS = (logDeriv ζ s) − (Gentire 0 + seriesFun s − 1/s − 1/(s−1) + logπ/2 − ψ/2); hG's LHS−RHS = (logDeriv − seriesFun + 1/s + 1/(s−1) − logπ/2 + ψ/2) − Gentire 0. Sum = 0? LHS−RHS − hG(LHS−RHS) = logDeriv − G0 − seriesFun + 1/s + 1/(s−1) − logπ/2 + ψ/2 − logDeriv + seriesFun − 1/s − 1/(s−1) + logπ/2 − ψ/2 + G0 = 0 ✓. So linear_combination hG works (coefficient 1). But wait: `rw [Fexpr] at hG` — does rw with a def name work here? In LiCircleBound they used `rw [Fexpr]` (line 3846). ✓ same mechanism. One concern: hsn : ∀ n : ℕ, 1 ≤ n → s ≠ -2 * (n : ℂ). badPoint's fourth disjunct: ∃ n : ℕ, 1 ≤ n ∧ s = -2 * (n : ℂ). rintro pattern ⟨n, hn, h⟩ gives h : s = -2 * (n : ℂ); hsn n hn : s ≠ -2*(n:ℂ) — exact match? badPoint def: `∃ n : ℕ, 1 ≤ n ∧ s = -2 * (n : ℂ)` ✓. hsn's form: ∀ n : ℕ, 1 ≤ n → s ≠ -2 * (n : ℂ) ✓ same. exact hsn n hn h ✓. And h.1 for IsNontrivialZero: IsNontrivialZero s := riemannZeta s = 0 ∧ ...; h.1 : riemannZeta s = 0; hζ : riemannZeta s ≠ 0 ✓. Now §2 `not_badPoint_on_gapCircle` — the on-circle goodness: ``` lemma not_badPoint_on_gapCircle {k : ℕ} (hk : 4000 ≤ k) {R : ℝ} (hRlo : 4 * (k:ℝ) + 5/2 ≤ R) (hgap : ∀ ρ : ℂ, IsNontrivialZero ρ → 1 / (16 * C0hat (4 * (k:ℝ) + 9/2)) ≤ |ρ.im - R| ∨ 1 ≤ |ρ.im - R|) (hgapInt : ∀ m : ℤ, 1/4 ≤ |R/2 - (m:ℝ)|) {s : ℂ} (hs : ‖s‖ = R) : ¬ badPoint s := by have hR16002 : (16002:ℝ) ≤ R := by have h1 : (4000:ℝ) ≤ (k:ℝ) := by exact_mod_cast hk linarith [hRlo] have hRpos : (0:ℝ) < R := by linarith [hR16002] rintro (h | h | h | ⟨n, hn, h⟩) · exact not_isNontrivialZero_on_gapCircle hk hRlo hgap hs h · -- s = 0 rw [h] at hs rw [norm_zero] at hs -- hs : 0 = R linarith [hRpos] · -- s = 1 rw [h] at hs rw [norm_one] at hs -- hs : 1 = R linarith [hR16002] · -- s = -2n have hR2 : R = 2 * (n:ℝ) := by rw [← hs, h] -- goal: ‖(-2:ℂ)*(n:ℂ)‖ = 2*(n:ℝ) rw [norm_mul] have h1 : ‖(-2:ℂ)‖ = 2 := by rw [show (-2:ℂ) = ((-2:ℝ):ℂ) by push_cast; ring, Complex.norm_real] norm_num have h2 : ‖(n:ℂ)‖ = (n:ℝ) := Complex.norm_natCast n -- check name rw [h1, h2] have hcon := hgapInt (n:ℤ) rw [Int.cast_natCast] at hcon -- ((n:ℤ):ℝ) = (n:ℝ) have h0 : R/2 - (n:ℝ) = 0 := by rw [hR2]; ring rw [h0, abs_zero] at hcon linarith [hcon] -- 1/4 ≤ 0 false ``` Wait: rw [← hs, h]: goal R = 2*(n:ℝ); rw [← hs] turns R into ‖s‖: ‖s‖ = 2*(n:ℝ); rw [h] turns s into -2*(n:ℂ): ‖-2*(n:ℂ)‖ = 2*(n:ℝ) ✓. Check `Complex.norm_natCast` name — grep needed. In Mathlib: `Complex.norm_natCast (n : ℕ) : ‖(n : ℂ)‖ = n` — I'm fairly sure it exists (norm_natCast general? `norm_natCast` in a NormedField... For ℂ specifically there should be Complex.norm_natCast). Fallback: `by simp` or Complex.norm_ofNat... I'll grep. Also `Int.cast_natCast : ((↑n : ℤ) : α) = ↑n` ✓ standard name. Wait, hgapInt (n:ℤ) : 1/4 ≤ |R/2 - ((n:ℤ):ℝ)| — the coercion ((n:ℤ):ℝ) is Int.cast; rw [Int.cast_natCast] at hcon changes it to (n:ℝ) ✓. Also `not_isNontrivialZero_on_gapCircle` — verify its exact signature: used at line 3815: `not_isNontrivialZero_on_gapCircle hk hRlo hgap hs : ¬ IsNontrivialZero s`. ✓ matches my usage. §1 C0hat_add_two_le — check `Real.log_le_sub_one_of_pos` name and `Real.log_le_log` signature. LiCircleBound used `Real.log_le_log (by ... : (0:ℝ) < 2 + R/2) (by linarith : ...)` — wait line 3894: `apply Real.log_le_log (by linarith [hRpos] : (0 : ℝ) < 2 + R / 2)` then `linarith [hR]` — so Real.log_le_log takes hx : 0 < x first, then remaining goal x ≤ y ✓. `Real.log_le_sub_one_of_pos`: grep to verify. Now — imports for LiSqueeze.lean: `import NguyenRH1.LiCircleBound` suffices (transitively gets LiFEntire, LiGapCircles, Mathlib, Zeta23.RvM.LocalCount). But `exists_gapCircle_radius` is in LiGapCircles ✓ transitively imported. `Metric`, `MapsTo`, `Complex.dist_le_div_mul_dist_of_mapsTo_ball` need Mathlib ✓ (LiCircleBound imports full Mathlib). `open Zeta23 Complex Filter Topology` mirror LiCircleBound. Note: `AnalyticOn.norm_le_of_norm_le_on_sphere` — from Zeta23 StrongPNTPrefix; is it transitively imported? LiCircleBound imports LiDisc which imports...? LiDisc used LogOfAnalyticFunction + BorelCaratheodoryDeriv from StrongPNTPrefix presumably. Let me verify LiDisc imports StrongPNTPrefix. If not, add `import Zeta23.FromPNTPlus.StrongPNTPrefix`. Let me check LiDisc's imports and the `open` in LiCircleBound (line ~27: open Zeta23 Complex Filter Topology). Also need `Real.rpow_le_rpow`, `Real.rpow_nonneg`, `Real.rpow_pos_of_pos`, `Real.rpow_inv_natCast_pow`, `Real.pow_rpow_inv_natCast`, `Real.log_le_rpow_div`, `pow_le_pow_left`, `pow_pos`, `pow_nonneg`, `Nat.le_ceil`, `le_max_left/right`, `div_le_div_of_nonneg_right`, `div_mul_cancel₀`, `div_le_iff₀`, `mul_le_mul_of_nonneg_left/right`, `dist_eq_zero`, `dist_nonneg`, `norm_sub_le`, `Metric.mem_ball/mem_closedBall/mem_sphere` — all standard Mathlib; verify the few risky ones: pow_le_pow_left (current name in this Mathlib version), le_of_forall_pos_le_add (not needed — using the by-cases approach), Complex.norm_natCast, Real.log_le_sub_one_of_pos. Let me grep these in Mathlib now. Then write the file.
All signatures verified. Checking the last few lemma names before writing.
tool: Bash
input
{
  "command": "M=D:/Python/Quantum/zeta-23-lean/.lake/packages/mathlib/Mathlib; grep -rn \"theorem pow_le_pow_left \\|theorem pow_le_pow_left{\" $M/Algebra/Order/*.lean $M/Algebra/Order/**/*.lean 2>/dev/null | head -3; grep -rn \"log_le_sub_one_of_pos\" $M/Analysis/SpecialFunctions/Log/Basic.lean | head -2; grep -rn \"theorem norm_natCast\\|lemma norm_natCast\" $M/Analysis/Complex/Basic.lean $M/Analysis/Normed/*.lean 2>/dev/null | head -3; grep -rn \"import Zeta23\" D:/Python/Quantum/research/lean/NguyenRH1/NguyenRH1/LiDisc.lean | head -3",
  "description": "Verify pow_le_pow_left, log_le_sub_one, norm_natCast, LiDisc imports"
}
raw content_json (database row)
[{"type":"thinking","thinking":"All names verified:\n- `AnalyticAt.differentiableAt : AnalyticAt 𝕜 f x → DifferentiableAt 𝕜 f x` ✓\n- `Real.pow_rpow_inv_natCast (hx : 0 ≤ x) (hn : n ≠ 0) : (x ^ n) ^ (n⁻¹ : ℝ) = x` ✓ — this is the (c⁴)^{1/4} = c direction I need.\n\nTodo #2 done. Now write the file. Design recap for **LiSqueeze.lean**:\n\n```lean\nimport Mathlib\nimport NguyenRH1.LiCircleBound   -- brings LiFEntire, LiGapCircles, LiDisc, LiReflect, LiDigammaLeft\nopen Zeta23 Complex Filter Topology\nnoncomputable section\nnamespace NguyenRH1\n```\n\n**Lemma 1: `C0hat_add_two_le_five_log`** — for R with 9 ≤ log R (or 16002 ≤ R): C0hat (R+2) ≤ 5·log R.\n\nProof: unfold C0hat. Pieces:\n- h1: Real.log (R+2+2) = log(R+4) ≤ 2·log R: since R+4 ≤ R² for R ≥ 3 (R² - R - 4 ≥ 0: at R=3, 9-7=2>0, monotone): R+4 ≤ R·R needs R ≥ ... nlinarith. Then log(R+4) ≤ log(R²) = 2·log R (Real.log_pow: log(R^2) = 2·log R — Real.log_pow : log (x^n) = n * log x). Need 0 < R+4 and R+4 ≤ R^2. Real.log_le_log (h : 0 < x) (h' : x ≤ y)? Signature: Real.log_le_log (hx : 0 < x) (h : x ≤ y)? Let me recall: `Real.log_le_log_iff`... There's `Real.log_le_log (hx : 0 < x) (hxy : x ≤ y) : log x ≤ log y`? Hmm — in Fexpr_circle_le they used `Real.log_le_log (by ... : (0:ℝ) < 2 + R/2) (by linarith : 2+R/2 ≤ R)`. So signature `Real.log_le_log (hx : 0 < x) (h : x ≤ y)`. ✓ (Used in LiCircleBound line 3894.)\n- h2: log(log(R+4)) ≤ 2·log R. Chain: log(R+4) ≤ 2·log R (h1); log monotone: log(log(R+4)) ≤ log(2·log R) — need 0 < log(R+4): log(R+4) ≥ 9 > 0 ✓ (log(R+4) ≥ log R ≥ 9). log(2·log R) = log 2 + log(log R) (Real.log_mul, 2≠0, log R ≠ 0) ≤ 1 + log R — wait log 2 ≤ 1 (log 2 < log e = 1? Real.log_two_lt_d9 or log_le_one... `Real.log_two_lt_d9 : log 2 < 0.6931471808`. Simpler: log 2 ≤ 1 via Real.log_le_one? hmm — log x ≤ x - 1: log 2 ≤ 1 ✓ via `Real.log_le_sub_one_of_pos`. And log(log R) ≤ log R (log x ≤ x: from log x ≤ x - 1 ≤ x: Real.log_le_sub_one_of_pos h gives log x ≤ x-1, linarith gives ≤ x; or maybe there's a direct lemma). So log(2 log R) ≤ 1 + log R ≤ 2·log R since log R ≥ 9 ≥ 1 ⟹ 1 + log R ≤ 2 log R. \n\n  Hmm — actually I can simplify: 0.886·log(log(R+4)) ≤ 0.886·(1 + log R). And 0.433·log(R+4) ≤ 0.866·log R. And 2.9 ≤ 2.9/9·log R ≤ 0.33·log R (from 9 ≤ log R ⟹ 2.9 ≤ 2.9·(log R)/9). Total: 0.866·L + 0.886·(1+L) + 2.9 ≤ 0.866L + 0.886L + 0.886 + 0.33L — and 0.886 ≤ 0.1·L (L≥9). Total ≤ (0.866+0.886+0.33+0.1)·L = 2.182·L ≤ 5·L. ✓ Big margin.\n\n**Lemma 2: `gentire_eq_Fexpr_on_gapCircle`** — actually just do it inline in step 3. For ‖s‖ = R: ¬badPoint s:\n- ¬IsNontrivialZero s: not_isNontrivialZero_on_gapCircle hk hRlo hgap hs.\n- s ≠ 0: if s = 0 then ‖s‖ = 0 ≠ R ≥ 16002.\n- s ≠ 1: if s = 1 then ‖s‖ = 1 ≠ R.\n- ¬∃ n ≥ 1, s = −2n: if s = −2·(n:ℂ), then R = ‖s‖ = ‖−2n‖ = 2n (n≥1). R/2 = n. hgapInt (n:ℤ): 1/4 ≤ |R/2 − n| = 0. Contradiction.\n  Details: ‖(-2*(n:ℂ))‖ = ‖(-2:ℂ)‖·‖(n:ℂ)‖ = 2·n. ((-2 : ℂ)) norm: ‖(-2:ℂ)‖ = 2. Via: rw [norm_mul]; show ‖(-2:ℂ)‖ = 2: (-2 : ℂ) = ((-2:ℝ):ℂ) by push_cast;ring; Complex.norm_real; norm_num. ‖(n:ℂ)‖ = n via Complex.norm_natCast? `Complex.norm_natCast : ‖(n : ℂ)‖ = n`. Hmm exact name maybe `Complex.norm_natCast`. There's Complex.norm_natCast in Mathlib? I recall `Complex.norm_natCast (n : ℕ) : ‖(n : ℂ)‖ = n`. Used elsewhere in the project? Let me grep later. Also R/2 − (n:ℤ) cast: (n:ℤ) from ℕ cast — hgapInt takes m : ℤ; use m := n. |R/2 − ↑n| where ↑n = ((n:ℤ):ℝ) = (n:ℝ). push_cast should bridge.\n\n**Lemma 3: `gentire_circle_le`** — k ≥ 4000, R gap circle (the 4 hyps), ‖s‖ = R ⟹ ‖Gentire s‖ ≤ RB R. Proof: rw [gentire_eq_Fexpr hgood]; exact Fexpr_circle_le hk hRlo _hRhi hgap hgapInt hs.\n\nWait — Fexpr_circle_le's second arg is named `_hRhi` (unused). Fine, still pass it.\n\n**Lemma 4: `gentire_const`** (the squeeze) — under hZC : ZeroCountProp: ∀ z₀, Gentire z₀ = Gentire 0.\n\nProof structure:\n```\nintro z₀\n-- constants\nset C₀' := 2 * lowZeroConst + dirichletC2 + ‖Gentire 0‖ with hC0'\nset C₁ := 2000000 * A0count with hC1   -- 400000·A0·5\nhave hC0'nn : 0 ≤ C₀' := by positivity-ish (lowZeroConst_nonneg, dirichletC2_nonneg, norm_nonneg)\nhave hC1nn : 0 ≤ C₁ := mul_nonneg (norm_num) A0count_pos.le\n-- key: ∀ ε > 0, dist (Gentire z₀) (Gentire 0) ≤ ε\nhave key : ∀ ε : ℝ, 0 < ε → dist (Gentire z₀) (Gentire 0) ≤ ε := by\n  intro ε hε\n  -- choose c := 1 + (128*C₁ + 2*C₀')*‖z₀‖/ε\n  -- choose M := max (c^4) (‖z₀‖ + 1)\n  -- choose k := max 4000 ⌈M/4⌉₊\n  -- get R from exists_gapCircle_radius hZC (k) (1 ≤ k)\n  -- ...\n```\nHmm wait, one subtlety: I need R ≥ M to get R ≥ c⁴ and R ≥ ‖z₀‖+1. From exists_gapCircle_radius: R ≥ 4k+5/2 ≥ 4k ≥ M ✓ (k ≥ ⌈M/4⌉ ⟹ 4k ≥ 4·⌈M/4⌉ ≥ M: Nat.le_ceil (M/4) : M/4 ≤ ⌈M/4⌉₊ then ×4). And k ≥ 4000 ✓.\n\nActually also need 1 ≤ k for exists_gapCircle_radius — k ≥ 4000 covers it.\n\nSteps inside:\n- obtain ⟨R, hRlo, hRhi, hgapInt, hgap⟩ := exists_gapCircle_radius hZC hk1 — check the argument order in the actual theorem: (hZC : ZeroCountProp) {k : ℕ} (hk : 1 ≤ k) : ∃ R, 4k+5/2 ≤ R ∧ R ≤ 4k+3 ∧ (∀ m:ℤ, 1/4 ≤ |R/2 − m|) ∧ ∀ ρ, IsNontrivialZero ρ → (clearance) ∨ (1 ≤ |ρ.im − R|). Note hgapInt comes third, hgap fourth. Fexpr_circle_le's signature: hgap (zero ordinates) then hgapInt (integers). Different orders — careful at the call site.\n- hk4000 : 4000 ≤ k (for Fexpr_circle_le).\n- hR16002 : 16002 ≤ R: from 4k+5/2 ≤ R and k ≥ 4000 ⟹ 4k ≥ 16000. ✓\n- hlogR : 9 ≤ log R := nine_le_log_of_16002_le hR16002 (exists in LiCircleBound — used in Fexpr_circle_le).\n- Sphere bound: ∀ z ∈ Metric.sphere 0 R, ‖Gentire z‖ ≤ RB R where RB R := 2*lowZeroConst + dirichletC2 + 400000*A0count*C0hat (R+2)*(log R)^2:\n  intro z hz; hz : dist z 0 = R (Metric.mem_sphere). ‖z‖ = R: dist_eq_norm, norm (z − 0) = ‖z‖ (sub_zero). Then gentire_circle_le with hs : ‖z‖ = R.\n- Ball bound: ∀ z ∈ closedBall 0 R, ‖Gentire z‖ ≤ RB R := AnalyticOn.norm_le_of_norm_le_on_sphere (r := R) (R := R) le_rfl analyticOn_closedBall sphere_bound. Where analyticOn_closedBall : AnalyticOn ℂ Gentire (closedBall 0 R) := AnalyticOnNhd.analyticOn (fun s _ => gentire_analyticAt_and_eq.1 s). Hmm — AnalyticOnNhd ℂ f s := ∀ x ∈ s, AnalyticAt ... yes: `AnalyticOnNhd f u = ∀ x ∈ u, AnalyticAt f x`. So (fun s _ => gentire_analyticAt_and_eq.1 s) : AnalyticOnNhd ℂ Gentire (closedBall 0 R) then .analyticOn. But wait — the sphere lemma signature asks `AnalyticOn ℂ f (Metric.closedBall 0 R)`. ✓.\n- MapsTo: MapsTo Gentire (ball 0 R) (closedBall (Gentire 0) R₂) where R₂ := RB R + ‖Gentire 0‖:\n  intro z hz; hz : dist z 0 < R (Metric.mem_ball). z ∈ closedBall 0 R: dist z 0 ≤ R (le of lt; Metric.mem_closedBall). ‖Gentire z‖ ≤ RB R (ball bound). mem_closedBall target: dist (Gentire z) (Gentire 0) ≤ R₂. dist = ‖Gentire z − Gentire 0‖ (dist_eq_norm) ≤ ‖Gentire z‖ + ‖Gentire 0‖ (norm_sub_le) ≤ RB R + ‖Gentire 0‖. ✓\n- hd : DifferentiableOn ℂ Gentire (ball 0 R) := fun z hz => (gentire_analyticAt_and_eq.1 z).differentiableAt.differentiableWithinAt.\n- hz0 : z₀ ∈ ball 0 R: dist z₀ 0 < R: ‖z₀‖ < R since ‖z₀‖ < ‖z₀‖+1 ≤ M ≤ 4k ≤ 4k+5/2 ≤ R. dist_eq_norm, sub_zero.\n- Schwarz: dist (Gentire z₀) (Gentire 0) ≤ R₂/R·dist z₀ 0 = R₂/R·‖z₀‖.\n- Real grind: R₂/R·‖z₀‖ ≤ ε:\n  RB R ≤ 2·lowZeroConst + dirichletC2 + 400000·A0count·(5·log R)·(log R)² = 2·lowZeroConst + dirichletC2 + 2000000·A0count·(log R)³ (needs log R ≥ 0 for mul monotonicity; (log R)² = (log R)³/log R... careful: 400000·A0·Ĉ·L² ≤ 400000·A0·(5L)·L² = 2000000·A0·L³: rewrite (log R)^3 = (log R)^2 * (log R) (pow_succ or pow_three); mul_le_mul: 400000·A0 ≥ 0, Ĉ ≤ 5L, L² ≥ 0. mul_le_mul_of_nonneg_left (C0hat (R+2) ≤ 5 log R) (400000·A0count ≥ 0) then × L² (≥0): mul_le_mul_of_nonneg_right.\n  R₂ ≤ C₀' + C₁·L³ where L := log R.\n  L ≤ 4·Q where Q := R^{1/4}: Real.log_le_rpow_div (hx : 0 ≤ x)... wait signature: log_le_rpow_div {x ε} (hx : 0 ≤ x) (hε : 0 < ε) : log x ≤ x^ε / ε. With ε := 1/4: log R ≤ R^{1/4}/(1/4) = 4·R^{1/4}. The div: x^ε/ε with ε = 1/4: R^{1/4}/(1/4) = 4·R^{1/4} — field_simp or rw div_... `div_eq_mul_inv`, inv (1/4) = 4: 1/(1/4) = 4 by norm_num. So L ≤ 4·Q.\n  L³ ≤ 64·Q³: both sides nonneg (L ≥ 9 ≥ 0, Q ≥ 0): pow_le_pow_left (ha : 0 ≤ a) (hab : a ≤ b) (n) : a^n ≤ b^n. Then (4Q)³ = 64·Q³ by ring (need (4*Q)^3 = 64*Q^3: ring after pow_succ... `mul_pow` then norm_num: (4*Q)^3 = 4^3 * Q^3 = 64*Q^3 ✓ via mul_pow + norm_num).\n  Numerator: R₂ ≤ C₀' + 64·C₁·Q³. Denominator: R = Q⁴: Q = R^{(1/4:ℝ)}; R = (R^{1/4})^4: from pow_rpow_inv_natCast hRnn (4≠0): (R^4)^{1/4} = R — wrong direction. I need (R^{1/4})^4 = R: that's `rpow_inv_natCast_pow (hx : 0 ≤ x) (hn : n ≠ 0) : (x ^ (n⁻¹:ℝ))^n = x` ✓ — exactly. With n := 4: (R^{(4:ℝ)⁻¹})^4 = R. And (1/4 : ℝ) vs (4:ℝ)⁻¹: 1/4 = 4⁻¹ by `one_div` — Q := R^(1/4); show (1/4:ℝ) = (4:ℝ)⁻¹ via one_div. So R = Q^4 with Q := R^(1/4).\n  Want: (C₀' + 64·C₁·Q³)·‖z₀‖ ≤ ε·Q⁴. Have Q ≥ c = 1 + (128·C₁ + 2·C₀')·‖z₀‖/ε:\n  Q ≥ c: R ≥ M ≥ c⁴ ⟹ Q = R^{1/4} ≥ (c⁴)^{1/4} = c: Real.rpow_le_rpow (0 ≤ c⁴) (c⁴ ≤ R) (1/4 ≥ 0): rpow_le_rpow (hx : 0 ≤ x) (hxy : x ≤ y) (hz : 0 ≤ z) : x^z ≤ y^z. And (c⁴)^{1/4} = c: pow_rpow_inv_natCast (0 ≤ c) (4 ≠ 0). Need c ≥ 0: c = 1 + nonneg·nonneg/nonneg ≥ 1 > 0 ✓.\n  Then: (i) 64·C₁·‖z₀‖ ≤ (ε/2)·Q: from Q ≥ c ≥ (128·C₁)·‖z₀‖/ε ⟹ ε·Q ≥ 128·C₁·‖z₀‖ ⟹ (ε/2)·Q ≥ 64·C₁·‖z₀‖. Careful with division: c ≥ (128·C₁ + 2·C₀')·‖z₀‖/ε ≥ 128·C₁·‖z₀‖/ε (drop nonneg term: 2·C₀'·‖z₀‖ ≥ 0; div monotonicity: a/ε ≤ (a+b)/ε for ε>0, b≥0). So Q·ε ≥ 128·C₁·‖z₀‖ (mul by ε: (x/ε)·ε = x, div_mul_cancel₀). nlinarith might handle the pieces or do linear_combination. Since C₁, C₀', ‖z₀‖, ε, Q are atoms, linarith works once the products are... hmm linarith doesn't do nonlinear: Q·ε ≥ 128·C₁·‖z₀‖ is nonlinear (product of variables ε·Q). Strategy: derive h1 : 128·C₁·‖z₀‖ ≤ ε·Q by: calc 128·C₁·‖z₀‖ = (128·C₁·‖z₀‖/ε)·ε := (div_mul_cancel₀ _ hε.ne').symm; _ ≤ c·ε := mul_le_mul_of_nonneg_right (le chain) hε.le; _ ≤ Q·ε := mul_le_mul_of_nonneg_right hQc hε.le. Then h2 : 64·C₁·‖z₀‖ ≤ ε/2·Q: ε/2·Q = ε·Q/2: nlinarith? ε/2·Q = (ε·Q)/2 ring-equal; linarith with the atom ε·Q... linarith treats ε·Q as atom; goal 64·C₁·‖z₀‖ ≤ ε/2·Q — the RHS is a different atom than ε·Q (ε/2·Q vs ε·Q are scalar multiples — linarith can handle scalar multiples of the same monomial? linarith works over ordered fields and treats nonlinear monomials as atoms, but it CAN scale: it knows ε/2·Q = (1/2)(ε·Q) only if the expressions are parsed as the same atom scaled. `ε/2*Q` normalizes to `(1/2)*ε*Q` in ring normal form — linarith does ring_nf on hypotheses and goals (linarith preprocesses with ring_nf? linarith does use ring normalization on comparisons). I believe linarith handles scalar multiples fine after ring_nf preprocessing. OK.\n  (ii) 2·C₀'·‖z₀‖ ≤ (ε/2)·Q⁴: from Q ≥ c ≥ 2·C₀'·‖z₀‖/ε and Q ≥ 1: 2·C₀'·‖z₀‖ ≤ ε·Q (same div trick) ≤ ε·Q⁴ (Q ≥ 1 ⟹ Q ≤ Q⁴... need Q⁴ ≥ Q: since Q ≥ 1: Q⁴ = Q·Q³ ≥ Q·1 = Q — needs Q³ ≥ 1: one_le_pow... `one_le_pow_of_le` hmm: 1 ≤ Q ⟹ 1 ≤ Q^n for Q ≥ ... `one_le_pow₀ (h : 1 ≤ a) : 1 ≤ a ^ n`. Then Q^4 = Q^3 * Q or Q * Q^3: pow_succ: Q^4 = Q^3 * Q ≥ 1 * Q = Q (mul_le_mul_of_nonneg... 1 ≤ Q^3, times Q ≥ 0: mul_le_mul_of_nonneg_right? (1 ≤ Q^3) mul right by Q: 1*Q ≤ Q^3*Q ✓). So 2·C₀'·‖z₀‖ ≤ ε·Q ≤ ε·Q⁴ = (ε/2)·Q⁴ + ... just need ≤ (ε/2)·Q⁴: 2·C₀'·‖z₀‖ ≤ ε·Q ≤ ... hmm I need ε·Q ≤ (ε/2)·Q⁴ ⟸ Q ≤ Q⁴/2 ⟸ 2·Q ≤ Q⁴. With Q ≥ 1: Q⁴ ≥ 2Q? Not for Q=1 (1 < 2). Oops. Fix: make c ≥ 2: c := 2 + (128·C₁ + 2·C₀')·‖z₀‖/ε ⟹ Q ≥ 2 ⟹ Q⁴ = Q·Q³ ≥ Q·8 ≥ 2·Q·... Q³ ≥ 8 ⟹ Q⁴ ≥ 8Q ≥ ... want ε·Q ≤ (ε/2)·Q⁴ ⟸ 2 ≤ Q³ ⟸ 2 ≤ 8 ✓. So with c ≥ 2: 2·C₀'‖z₀‖ ≤ ε·Q, and ε·Q ≤ (ε/2)·Q⁴ ⟸ 2·Q ≤ Q⁴ ⟸ 2 ≤ Q³ (divide by Q>0) ⟸ Q ≥ 2 ⟹ Q³ ≥ 8 ✓. Handling divisions in Lean without dividing: state directly: have hQ2 : 2 ≤ Q; h2a : 2·C₀'·‖z₀‖ ≤ ε·Q (div trick as before); h2b : ε·Q ≤ (ε/2)·Q⁴: (ε/2)·Q⁴ − ε·Q = ε·Q·(Q³/2 − 1) ≥ 0: nlinarith [hQ2, ...]? Q³ ≥ 8: from Q ≥ 2: pow_le_pow_left (0≤2) hQ2 3 : 2³ ≤ Q³ = 8 ≤ Q³. Then (ε/2)·Q⁴ = (ε/2)·Q·Q³ ≥ (ε/2)·Q·8 = 4·ε·Q ≥ ε·Q: nlinarith [hε, hQpos, hQ3ge8] with atoms ε·Q... nlinarith multiplies pairs of hypotheses; the product (ε/2)·Q·Q³ — nlinarith sees monomials up to degree... The product (ε/2)*Q^4 vs ε*Q: factor as ((ε/2)*Q)*(Q^3) hmm nlinarith would need to multiply (ε·Q atom?) — it doesn't have ε·Q as hypothesis atom; hypotheses are ε>0, Q≥2, Q³≥8. Products: ε·Q³ ≥ ... nlinarith can multiply two hypotheses: (Q ≥ 2)·(Q³ ≥ 8)?? no. Let me just hand-roll: h2b : ε*Q ≤ ε/2*Q^4 := calc ε*Q = (ε/2)*(2*Q) := by ring; _ ≤ (ε/2)*(Q*Q^3) := mul_le_mul_of_nonneg_left (by nlinarith [hQ2, hQ3, hQnn]) (by positivity... ε/2 ≥ 0);  where 2*Q ≤ Q*Q^3 ⟸ 2 ≤ Q³ (Q > 0): mul_le_mul_of_nonneg_right hQ3' (le of Q > 0)... hmm 2*Q ≤ Q*Q^3 ⟸ 2 ≤ Q^3: mul_le_mul_of_nonneg_right (h : 2 ≤ Q^3) (0 ≤ Q): 2*Q ≤ Q^3*Q; Q^3*Q = Q*Q^3 ring. OK then = ε/2 * Q^4 by ring (Q*Q^3 = Q^4: ring? Q*Q^3 = Q^4 is ring-normalizable ✓ (pow is ring-opaque? `ring` handles pow with literal exponents ✓)).\n  Then h2 : 2·C₀'·‖z₀‖ ≤ (ε/2)·Q⁴ by trans.\n  Sum: (C₀' + 64·C₁·Q³)·‖z₀‖ — hmm wait. Let me restructure: dist ≤ (R₂/R)·‖z₀‖; want ≤ ε. R₂ ≤ C₀' + 64·C₁·Q³ (shown). So dist·1 ≤ (C₀' + 64·C₁·Q³)/Q⁴·‖z₀‖ hmm R = Q⁴ substitution. Goal: (C₀' + 64·C₁·Q³)/Q⁴·‖z₀‖ ≤ ε ⟺ (C₀' + 64·C₁·Q³)·‖z₀‖ ≤ ε·Q⁴ (div_le_iff, Q⁴ > 0). Expand LHS: C₀'·‖z₀‖ + 64·C₁·Q³·‖z₀‖. From (i): 64·C₁·‖z₀‖ ≤ (ε/2)·Q ⟹ 64·C₁·‖z₀‖·Q³ ≤ (ε/2)·Q·Q³ = (ε/2)·Q⁴ (mul by Q³ ≥ 0 — but careful with assoc: 64·C₁·Q³·‖z₀‖ vs (64·C₁·‖z₀‖)·Q³ — assoc juggling; use ring-normal forms and per-step haves + linarith, per the banked gotcha). From (ii): C₀'·‖z₀‖ ≤ (ε/2)·Q⁴ — wait I had 2·C₀'·‖z₀‖ ≤ (ε/2)·Q⁴ which is stronger. Sum: LHS ≤ (ε/2)·Q⁴ + (ε/2)·Q⁴ = ε·Q⁴ ✓.\n  So: hA : 64*C₁*‖z₀‖ ≤ (ε/2)*Q (derived from h1 by linarith with ε/2*Q = (ε*Q)/2 — need ring-equivalence; use have hhalf : (ε/2)*Q = (ε*Q)/2 := by ring; linarith).\n  hA' : (64*C₁*‖z₀‖)*Q^3 ≤ (ε/2)*Q*Q^3 := mul_le_mul_of_nonneg_right hA (pow_nonneg hQnn 3). Then ring-normalize: (64*C₁*‖z₀‖)*Q^3 = 64*C₁*Q^3*‖z₀‖ and (ε/2)*Q*Q^3 = (ε/2)*Q^4 — via calc + ring steps.\n  hB : C₀'*‖z₀‖ ≤ (ε/2)*Q^4 (from h2a : 2*C₀'*‖z₀‖ ≤ ε*Q... wait redo: h2a was 2·C₀'·‖z₀‖ ≤ ε·Q. Then C₀'·‖z₀‖ ≤ (ε/2)·Q ≤ (ε/2)·Q⁴? (ε/2)·Q ≤ (ε/2)·Q⁴ ⟸ Q ≤ Q⁴ ⟸ 1 ≤ Q³ ✓ (Q ≥ 2). Hmm or just: C₀'·‖z₀‖ ≤ 2·C₀'·‖z₀‖ (C₀'‖z₀‖ ≥ 0) ≤ ε·Q ≤ ... I'll assemble with linarith over the derived atoms:\n  Final: have hsum : C₀'*‖z₀‖ + 64*C₁*Q^3*‖z₀‖ ≤ ε*Q^4 := by linarith [hA'normalized, hB, ...]. linarith treats (ε/2)*Q^4 as (1/2)·(ε·Q⁴) — same atom scaled ✓.\n  Then div: (C₀' + 64·C₁·Q³)·‖z₀‖/Q⁴ ≤ ε: rw [div_le_iff₀ hQ4pos]: (C₀'+64·C₁·Q³)·‖z₀‖ ≤ ε·Q⁴ — matches hsum after LHS expansion: (C₀'+64·C₁·Q³)·‖z₀‖ = C₀'·‖z₀‖ + 64·C₁·Q³·‖z₀‖ (add_mul + assoc — ring-normalize via a calc or linear_combination hsum after `ring_nf`? Use: have hLHS : (C₀' + 64*C₁*Q^3)*‖z₀‖ = C₀'*‖z₀‖ + 64*C₁*Q^3*‖z₀‖ := by ring. Then rw [hLHS]; exact hsum.\n\n- Conclusion chain: dist (Gentire z₀) (Gentire 0) ≤ R₂/R·‖z₀‖ (Schwarz) and R₂/R·‖z₀‖ ≤ (C₀'+64·C₁·Q³)·‖z₀‖/Q⁴: since R₂ ≤ C₀'+64C₁Q³ and R = Q⁴: R₂/R·‖z₀‖ ≤ (C₀'+64C₁Q³)/Q⁴·‖z₀‖: div monotonicity + R = Q⁴ (rw). Then ≤ ε. So dist ≤ ε ✓.\n- Then dist = 0: le_of_forall_pos_le_add? The standard: `le_of_forall_pos_le_add : (∀ ε, 0 < ε → a ≤ b + ε) → a ≤ b`. We have ∀ ε>0, dist ≤ ε = 0 + ε. So dist ≤ 0. Then dist ≤ 0 ∧ 0 ≤ dist ⟹ dist = 0 (le_antisymm (dist_nonneg)). Then `dist_eq_zero.mp : dist x y = 0 → x = y`. So Gentire z₀ = Gentire 0.\n\nHmm wait — `le_of_forall_pos_le_add` signature: `(h : ∀ ε, 0 < ε → a ≤ b + ε) : a ≤ b`. Our key gives dist ≤ ε; need dist ≤ 0 + ε: by linarith [key ε hε]. OK.\n\n**Lemma 5: `partialFraction_identity`** (capstone):\n```\ntheorem partialFraction_identity (hZC : ZeroCountProp) :\n    ∃ B : ℂ, ∀ s : ℂ, riemannZeta s ≠ 0 → s ≠ 0 → s ≠ 1 →\n      (∀ n : ℕ, 1 ≤ n → s ≠ -2 * (n : ℂ)) →\n      logDeriv riemannZeta s = B + seriesFun s - 1/s - 1/(s-1)\n        + (Real.log Real.pi : ℂ)/2 - Complex.digamma (s/2)/2 := by\n  refine ⟨Gentire 0, fun s hζ hs0 hs1 hsn ↦ ?_⟩\n  -- ¬ badPoint s\n  have hgood : ¬ badPoint s := by\n    rintro (h | h | h | ⟨n, hn, h⟩)\n    · exact hζ h.1\n    · exact hs0 h\n    · exact hs1 h\n    · exact hsn n hn h\n  have hG : Gentire s = Gentire 0 := gentire_const hZC s\n  rw [gentire_eq_Fexpr hgood] at hG  -- Gentire s = Fexpr s, so Fexpr s = Gentire 0\n  -- hG : Fexpr s = Gentire 0\n  unfold Fexpr at hG\n  linear_combination hG\n```\nWait: hG : Gentire s = Fexpr s from gentire_eq_Fexpr; combined with Gentire s = Gentire 0: Fexpr s = Gentire 0. Then unfold Fexpr at hG: logDeriv ζ s − seriesFun s + 1/s + 1/(s−1) − (log π)/2 + ψ(s/2)/2 = Gentire 0. Goal: logDeriv ζ s = Gentire 0 + seriesFun s − 1/s − 1/(s−1) + (log π)/2 − ψ(s/2)/2. linear_combination hG ✓ (pure linear identity in atoms over ℂ — division by constants s, s−1, 2 are fine for linear_combination? linear_combination works over commutative rings with the atoms being subterms: 1/s is an atom; the identity is linear in the atoms logDeriv ζ s, seriesFun s, 1/s, 1/(s−1), ((log π:ℂ)/2), (digamma(s/2)/2), Gentire 0 — yes, all coefficients are constants ✓. But careful: is `Real.log Real.pi` coerced consistently: in Fexpr def it's `(Real.log Real.pi : ℂ) / 2`. In my goal I write the same. ✓.\n\nCareful about `unfold Fexpr at hG` — Fexpr is a def; unfold might not fire if... `rw [Fexpr] at hG` was used in LiCircleBound (line 3846: `rw [Fexpr]`). For hG I'll use `rw [Fexpr] at hG` hmm — Fexpr is a def so `rw [Fexpr]`... they used `rw [Fexpr]` at line 3846 in a term-mode proof (`rw [Fexpr]` inside `by`?). Actually they had `have hc1 : ... := by rw [Fexpr]; exact norm_add_le _ _`. So `rw [Fexpr]` works — presumably there's an equational lemma Fexpr s = ... auto-generated (defs get equation lemmas; rw with a def name uses its eqn lemmas — works for non-recursive defs in Lean4 Mathlib style: `rw [Fexpr]` unfolds via Fexpr.eq_def or the auto equation lemma). I'll use `rw [Fexpr] at hG` — hmm, `show` may be safer: since everything is defeq, `linear_combination hG` might close the goal directly without unfolding (linear_combination checks the difference is a ring combination — hG's type is Fexpr s = Gentire 0; linear_combination treats `Fexpr s` as an atom but the goal mentions logDeriv... not Fexpr — so no, must unfold first). Use `unfold Fexpr at hG` — unfold is reliable for plain defs. Or `simp only [Fexpr] at hG`. I'll try unfold.\n\nOne more check: `gentire_eq_Fexpr` signature: from line 1109 usage `rw [gentire_eq_Fexpr hygood]` where hygood : ¬ badPoint y. So `gentire_eq_Fexpr (h : ¬ badPoint s) : Gentire s = Fexpr s` ✓.\n\nAlso `gentire_const` needs a name not clashing. And I should double check `not_isNontrivialZero_on_gapCircle`'s signature: used at line 3815-3816 as `not_isNontrivialZero_on_gapCircle hk hRlo hgap hs` where hk : 4000 ≤ k, hRlo, hgap (zeros), hs : ‖s‖ = R. ✓ Note it does NOT need hgapInt.\n\nNow, `badPoint` is: IsNontrivialZero s ∨ s = 0 ∨ s = 1 ∨ ∃ n, 1 ≤ n ∧ s = -2*(n:ℂ). For the on-circle goodness I need to discharge all four. Let me write the good-point lemma:\n\n```lean\nlemma not_badPoint_on_gapCircle {k : ℕ} (hk : 4000 ≤ k) {R : ℝ}\n    (hRlo : 4 * (k:ℝ) + 5/2 ≤ R) (hgap : ...) (hgapInt : ∀ m : ℤ, 1/4 ≤ |R/2 - (m:ℝ)|)\n    {s : ℂ} (hs : ‖s‖ = R) : ¬ badPoint s := by\n  rintro (h | h | h | ⟨n, hn, h⟩)\n  · exact not_isNontrivialZero_on_gapCircle hk hRlo hgap hs h\n  · -- s = 0\n    have : (0:ℝ) = R := by rw [← hs, h]; norm_num  -- ‖(0:ℂ)‖ = 0\n    -- R ≥ 16002 ⟹ contradiction\n    ...\n  · -- s = 1\n    have : (1:ℝ) = R := by rw [← hs, h]; simp?  ‖(1:ℂ)‖ = 1: norm_one\n    ...\n  · -- s = -2n\n    ...\n```\nFor s = 0: hs : ‖s‖ = R; rw [h] at hs : ‖(0:ℂ)‖ = R; norm_num at hs or rw norm_zero at hs: R = 0... but R ≥ 4k+5/2 ≥ 16002.5 > 0. hRpos : 0 < R. linarith.\nFor s = 1: rw [h] at hs : ‖(1:ℂ)‖ = R; norm_one at hs : 1 = R... wait ‖(1:ℂ)‖ = (1:ℝ): norm_one. hs : (1:ℝ) = R. R ≥ 16002 contradiction linarith.\nFor s = −2n: R = ‖s‖ = ‖−2·(n:ℂ)‖. Compute: ‖−2·(n:ℂ)‖ = 2·n. Then R/2 = n. hgapInt (n:ℤ) : 1/4 ≤ |R/2 − ((n:ℤ):ℝ)|. ((n:ℤ):ℝ) = (n:ℝ) by push_cast/Int.cast_natCast. R/2 − n = 0. |0| = 0 < 1/4. Contradiction.\n  Details: have hR2 : R = 2 * n: from hs: R = ‖s‖ = ... : rw [← hs, h]; then ‖(-2:ℂ)*(n:ℂ)‖ = ‖(-2:ℂ)‖*‖(n:ℂ)‖ (norm_mul) = 2*n: ‖(-2:ℂ)‖ = 2: by rw [show (-2:ℂ) = ((-2:ℝ):ℂ) by push_cast;ring, Complex.norm_real]; norm_num. ‖(n:ℂ)‖ = (n:ℝ): Complex.norm_natCast? Let me check name: `Complex.norm_natCast` — hmm, grep. In Lean Mathlib it's `Complex.norm_natCast (n : ℕ) : ‖(n : ℂ)‖ = ↑n`. I've seen `Complex.norm_natCast`. I'll verify by grep in the project or Mathlib.\n  Then hgapInt ((n : ℤ)): 1/4 ≤ |R/2 − ((n:ℤ):ℝ)|. Have ((n:ℤ):ℝ) = (n:ℝ) := by push_cast;ring or Int.cast_natCast n: `Int.cast_natCast : ((n:ℤ):ℝ) = n`? Int.cast_natCast : (↑(↑n : ℤ) : R) = ↑n. yes `Int.cast_natCast (n : ℕ) : ((n : ℤ) : α) = n`. rw that. R/2 − n = 0: from R = 2n: linarith... the expression |R/2 − (n:ℝ)| with hR2 : R = 2*(n:ℝ): rw [hR2]; 2*n/2 − n = 0: ring_nf then abs_zero. Have : |2*(n:ℝ)/2 − (n:ℝ)| = 0: by rw [...]; the cleanest: have h0 : 2*(n:ℝ)/2 − (n:ℝ) = 0 := by ring; rw [hR2, h0, abs_zero] at hcon; linarith. \n\nNote: hgapInt m is `∀ m : ℤ, 1 / 4 ≤ |R / 2 - (m : ℝ)|`. So hgapInt (n : ℤ) : 1/4 ≤ |R/2 − ((n:ℤ):ℝ)|.\n\nOK. Now, one design question: file placement. New file LiSqueeze.lean, import NguyenRH1.LiCircleBound (which transitively imports LiFEntire etc). Namespace NguyenRH1. Then add `import NguyenRH1.LiSqueeze` to the root file NguyenRH1.lean. Let me check the root file.\n\nAlso, the AnalyticOn.norm_le_of_norm_le_on_sphere is in Zeta23's StrongPNTPrefix — is it in scope via existing imports? LiDisc.lean imports StrongPNTPrefix presumably (BC used there). LiCircleBound imports LiDisc so transitively available, and LiSqueeze imports LiCircleBound. It's a plain lemma in root namespace (AnalyticOn.norm_le_of_norm_le_on_sphere — namespaced under AnalyticOn, dot-accessible as AnalyticOn.norm_le_of_norm_le_on_sphere). ✓\n\nThe Schwarz lemma: Complex.dist_le_div_mul_dist_of_mapsTo_ball — with `open Complex` it's dist_le_div_mul_dist_of_mapsTo_ball; safer to write Complex.dist_le_div_mul_dist_of_mapsTo_ball.\n\nNow — one more check on `exists_gapCircle_radius`: it returns R with hRlo : 4*(k:ℝ)+5/2 ≤ R, hRhi : R ≤ 4*(k:ℝ)+3, hgapInt : ∀ m:ℤ, 1/4 ≤ |R/2 − m|, hgap : ∀ ρ, IsNontrivialZero ρ → 1/(16*C0hat(4k+9/2)) ≤ |ρ.im − R| ∨ 1 ≤ |ρ.im − R|. ✓ matches Fexpr_circle_le's needs (hgap then hgapInt order differs — Fexpr_circle_le takes hgap first, hgapInt second).\n\nThe choice of k: given M : ℝ (M ≥ 16000), k := max 4000 ⌈M/4⌉₊. Then 4k ≥ M: ⌈M/4⌉₊ ≥ M/4 (Nat.le_ceil) ⟹ 4·⌈M/4⌉₊ ≥ M (for M ≥ 0). k ≥ 4000 ✓, and 1 ≤ k ✓.\n\nThen R ≥ 4k + 5/2 ≥ M + 5/2 > M ≥ max(...) hmm — need R ≥ c⁴ and R ≥ ‖z₀‖+1: M := max (c^4) (‖z₀‖ + 1) (and M ≥ 16000? no — k := max 4000 ⌈M/4⌉ gives 4k ≥ M automatically even if M < 16000; and k ≥ 4000 gives R ≥ 16002 anyway). So M := max (c^4) (‖z₀‖ + 1); k := max 4000 ⌈M/4⌉₊; 4k ≥ M ✓ (from the ceil branch: 4·⌈M/4⌉₊ ≥ M; and 4·max ≥ 4·⌈M/4⌉₊). Then R ≥ 4k+5/2 ≥ M + 5/2.\n\nThen:\n- hz0ball : ‖z₀‖ < R: ‖z₀‖ < ‖z₀‖+1 ≤ M ≤ ... < R. ✓\n- hRc4 : c^4 ≤ R: c^4 ≤ M ≤ R ✓.\n- hQge : c ≤ Q where Q := R^(1/4:ℝ): c = (c^4)^(1/4) [pow_rpow_inv_natCast (c≥0) (4≠0), with exponent (4:ℝ)⁻¹ = 1/4] ≤ R^(1/4) [Real.rpow_le_rpow (0 ≤ c^4) hRc4 (1/4 ≥ 0)].\n\nExponent juggling: define Q := R ^ ((1:ℝ)/4)? or R ^ (4⁻¹ : ℝ)? pow_rpow_inv_natCast gives (c^4)^((4:ℝ)⁻¹) = c. If Q := R^(1/4), I need (1/4:ℝ) = (4:ℝ)⁻¹: `one_div 4`. So: rw [show (1/4:ℝ) = (4:ℝ)⁻¹ from one_div 4] — or just define Q := R ^ (4:ℝ)⁻¹ and note 1/4 never appears. But Real.log_le_rpow_div needs ε : ℝ, log R ≤ R^ε/ε — with ε := (4:ℝ)⁻¹: log R ≤ R^(4⁻¹)/(4⁻¹) = R^(4⁻¹)·4. The /ε = ·4 juggling: div by 4⁻¹ = mul by 4: `div_eq_mul_inv`, inv_inv. Fine — set ε := (4:ℝ)⁻¹, hε : 0 < (4:ℝ)⁻¹ := by positivity.\n\nSo Q := R ^ (4:ℝ)⁻¹ (rpow). Facts:\n- hQnn : 0 ≤ Q := Real.rpow_nonneg hRnn _.\n- hQpos : 0 < Q := Real.rpow_pos_of_pos hRpos _.\n- hL : Real.log R ≤ 4 * Q: from log_le_rpow_div hRnn (show (0:ℝ) < (4:ℝ)⁻¹ by positivity): log R ≤ R^(4⁻¹)/(4⁻¹); R^(4⁻¹)/(4⁻¹) = 4·Q: field_simp? div by inv: R^a/(4⁻¹) = R^a * 4: `div_inv_eq_mul`... a/(4⁻¹) = a*4: rw [div_eq_mul_inv, inv_inv] : a * (4⁻¹)⁻¹ = a*4 ✓. So log R ≤ Q*4 = 4*Q (mul_comm juggling via calc or linarith with hQ4 : R^(4:ℝ)⁻¹/(4:ℝ)⁻¹ = 4*Q := by rw [div_eq_mul_inv, inv_inv]; ring).\n- hL3 : (Real.log R)^3 ≤ 64 * Q^3: have h1 : (log R)^3 ≤ (4*Q)^3 := pow_le_pow_left (by linarith [hlogR] : 0 ≤ log R) hL 3; (4*Q)^3 = 64*Q^3: by ring? (4*Q)^3 = 64*Q^3 — ring handles ✓ (pow with literal 3).\n  pow_le_pow_left signature: (ha : 0 ≤ a) (hab : a ≤ b) (n : ℕ) : a^n ≤ b^n ✓ (used in project? standard).\n- hR4 : R = Q^4: from rpow_inv_natCast_pow hRnn (4≠0): (R^(4:ℝ)⁻¹)^4 = R, i.e., Q^4 = R — use .symm.\n\nThen the final grind as sketched. Let me also double check `Real.log_le_rpow_div` name (found at Pow/Real.lean:883: `lemma log_le_rpow_div {x ε : ℝ} (hx : 0 ≤ x) (hε : 0 < ε) : log x ≤ x ^ ε / ε`) — in Real namespace ✓.\n\npow_le_pow_left — check name in current Mathlib: might be `pow_le_pow_left (ha : 0 ≤ a) (hab : a ≤ b) (n : ℕ)`. In recent Mathlib there's pow_le_pow_left₀ or pow_le_pow_left with swapped args... I recall `pow_le_pow_left (ha : 0 ≤ a) (hab : a ≤ b) : a ^ n ≤ b ^ n`. Grep at build time; fallback: nlinarith can't do it directly (L ≤ 4Q ⟹ L³ ≤ 64Q³ is nonlinear; nlinarith with hints: needs the product... nlinarith [sq_nonneg (L−4Q)...] might manage but messy; better find pow_le_pow_left).\n\nAlso `one_le_pow₀`: name check — `one_le_pow₀ (ha : 1 ≤ a) : 1 ≤ a ^ n`? There's `one_le_pow_of_le'`... I'll grep. Actually I only need 8 ≤ Q^3 from 2 ≤ Q: pow_le_pow_left (0≤2) hQ2 3 gives 2^3 ≤ Q^3, 2^3 = 8 norm_num. ✓ same lemma.\n\nAlso `Nat.le_ceil : x ≤ ⌈x⌉₊` for x : ℝ? `Nat.le_ceil (x : ℝ) : x ≤ ⌈x⌉₊` — requires? It's `Nat.le_ceil : ∀ (a : ℝ), a ≤ ↑⌈a⌉₊` ✓.\n\nLet me also confirm `Complex.norm_natCast` name and `norm_one`, `norm_zero`, `norm_mul`, `abs_zero` — all standard.\n\n`Metric.mem_sphere : z ∈ sphere x r ↔ dist z x = r` ✓; `Metric.mem_ball : dist z x < r`; `Metric.mem_closedBall : dist z x ≤ r` ✓.\n\n`dist_eq_norm : dist x y = ‖x − y‖` (for seminormed groups) ✓. `sub_zero` ✓.\n\nAlright. Also the RB definition: I'll phrase the sphere bound directly with the Fexpr_circle_le RHS expression rather than introducing a def (or a local let). Let me structure the file:\n\n§1. `C0hat_add_two_le` (the Ĉ₀(R+2) ≤ 5 log R growth bound).\n§2. `not_badPoint_on_gapCircle`.\n§3. `gentire_circle_le`.\n§4. `gentire_eq_zero_imp`... no — `gentire_const (hZC) : ∀ z₀, Gentire z₀ = Gentire 0`.\n§5. `partialFraction_identity (hZC : ZeroCountProp) : ∃ B, ...`.\n\nFor §1, check what log lemmas exist: Real.log_pow (x:ℝ)(n:ℕ): log (x^n) = n*log x ✓ standard. Real.log_mul (hx : x ≠ 0)(hy : y ≠ 0): log (x*y) = log x + log y ✓. Real.log_le_sub_one_of_pos (hx : 0 < x) : log x ≤ x − 1 ✓ (I think that's the name — `Real.log_le_sub_one_of_pos`). Used in LiDigammaLeft probably. Let me grep quickly at build time if it fails; alternative: Real.add_pow_le_pow_mul_pow_of_sq_le_sq... no. There's also the possibility they already have a helper for log x ≤ x.\n\nActually, let me check what's available: grep \"log_le_sub_one_of_pos\\|log_le_self\" in Mathlib Log/Basic.\n\nNow write §1 proof in detail:\n\n```\nlemma C0hat_add_two_le {R : ℝ} (hR : 16002 ≤ R) : C0hat (R + 2) ≤ 5 * Real.log R := by\n  have hRpos : (0:ℝ) < R := by linarith\n  have hlogR : (9:ℝ) ≤ Real.log R := nine_le_log_of_16002_le hR\n  -- log (R+4) ≤ 2 log R\n  have h1 : Real.log (R + 2 + 2) ≤ 2 * Real.log R := by\n    have hle : R + 4 ≤ R^2 := by nlinarith [hR]\n    have h2 : Real.log (R + 2 + 2) ≤ Real.log (R^2) := by\n      apply Real.log_le_log (by linarith : (0:ℝ) < R + 2 + 2)\n      -- R+2+2 = R+4 ≤ R^2\n      (show R + 2 + 2 ≤ R^2 by linarith [hle])  -- ring_nf normalizes?\n```\nHmm — R+2+2 vs R+4 syntactic difference: linarith handles ✓ (atoms R fine, linear). But the `apply Real.log_le_log` second goal is `R+2+2 ≤ R^2` — linarith [hle] where hle : R+4 ≤ R^2 — linear in atom R^2 ✓.\n```\n    rw [Real.log_pow] at h2  -- log (R^2) = 2 * log R... log_pow : log (x^n) = n*log x with n:ℕ cast\n    -- h2 : log (R+2+2) ≤ ↑(2:ℕ) * log R; push_cast at h2\n    rwa [Nat.cast_two] at h2  -- or push_cast at h2 ⊢?\n```\nReal.log_pow: `Real.log_pow (x : ℝ) (n : ℕ) : Real.log (x ^ n) = ↑n * Real.log x`. So rw [Real.log_pow] at h2 gives h2 : log(R+2+2) ≤ ↑2 * log R; norm_num at h2 or push_cast at h2 to make ↑2 = 2. Use `push_cast at h2; exact h2`.\n```\n  -- log log (R+4) ≤ 2 log R\n  have h2 : Real.log (Real.log (R + 2 + 2)) ≤ 2 * Real.log R := by\n    have hpos1 : (0:ℝ) < Real.log (R + 2 + 2) := by\n      have : Real.log R ≤ Real.log (R + 2 + 2) := Real.log_le_log hRpos (by linarith)\n      linarith [hlogR]\n    have h3 : Real.log (Real.log (R + 2 + 2)) ≤ Real.log (2 * Real.log R) :=\n      Real.log_le_log hpos1 h1\n    have h4 : Real.log (2 * Real.log R) = Real.log 2 + Real.log (Real.log R) := by\n      rw [Real.log_mul (by norm_num) (by linarith [hlogR] : Real.log R ≠ 0)]\n    have h5 : Real.log 2 ≤ 1 := by\n      have h := Real.log_le_sub_one_of_pos (by norm_num : (0:ℝ) < 2)\n      linarith\n    have h6 : Real.log (Real.log R) ≤ Real.log R := by\n      have h := Real.log_le_sub_one_of_pos (by linarith [hlogR] : (0:ℝ) < Real.log R)\n      linarith\n    linarith [h3, h4, h5, h6, hlogR]\n  -- assemble: C0hat (R+2) = 0.433*log(R+4) + 0.886*log(log(R+4)) + 2.9\n  rw [C0hat]\n  -- 2.9 ≤ (2.9/9)*log R ≤ ... just: 2.9 ≤ log R? no: 2.9 ≤ 2.9/9 * 9 ≤ ... use 2.9 ≤ (1/3)*log R hmm 2.9/9 ≈ 0.322; total 0.433*2 + 0.886*2 + 0.322 = 0.866+1.772+0.322 = 2.96 ≤ 5 ✓\n  nlinarith [h1, h2, hlogR]\n```\nnlinarith: goal 0.433*log(R+4) + 0.886*log(log(R+4)) + 2.9 ≤ 5*log R with h1: log(R+4) ≤ 2L, h2: loglog ≤ 2L, hlogR: 9 ≤ L. This is linear in atoms log(R+4), log(log(R+4)), log R — linarith should do it: 0.433*2L + 0.886*2L + 2.9 ≤ (0.866+1.772)*L + 2.9 = 2.638L + 2.9; need 2.9 ≤ 2.362*L ⟸ 2.9 ≤ 2.362*9 = 21.258 ✓. linarith handles decimal literals as rationals ✓. But careful: nlinarith/linarith need the hypotheses as linear atoms — ✓. Use linarith [h1, h2, hlogR].\n\nWait — after `rw [C0hat]`, goal shows `0.433 * Real.log (R + 2 + 2) + ...`? C0hat def: `0.433 * Real.log (t + 2) + 0.886 * Real.log (Real.log (t + 2)) + 2.9` with t := R+2, so log (R+2+2). My h1/h2 stated with R+2+2 ✓ (I wrote log (R+2+2)). ✓. unfold via `rw [C0hat]`? C0hat is a def — `rw [C0hat]` used in project? They used `rw [Fexpr]` — same mechanism ✓. Or `unfold C0hat`. I'll use `rw [C0hat]` hmm — actually `show` also works since defeq: `show 0.433 * Real.log (R + 2 + 2) + _ ≤ _`. I'll use unfold/rw.\n\nAlso `nine_le_log_of_16002_le` — verify it exists (used in Fexpr_circle_le line 3826) ✓.\n\n§4 detail — the MapsTo R₂ radius: R₂ := RB + ‖Gentire 0‖ where RB := 2*lowZeroConst + dirichletC2 + 400000*A0count*C0hat (R+2)*(log R)^2. Schwarz gives dist ≤ R₂/R * dist z₀ 0. \n\nSubtlety: Schwarz's h_maps needs MapsTo into closedBall (Gentire 0) R₂ — I need R₂ defined as a plain ℝ expression. Fine.\n\nAlso note: Schwarz's conclusion dist (f z) (f c) ≤ R₂/R₁ * dist z c — with c := (0:ℂ), f := Gentire: dist (Gentire z₀) (Gentire 0) ≤ R₂/R * dist z₀ 0. dist z₀ 0 = ‖z₀ − 0‖ = ‖z₀‖ ✓.\n\nNow the ball bound (max-modulus): AnalyticOn.norm_le_of_norm_le_on_sphere (hyp_r : r ≤ R) (analytic : AnalyticOn ℂ f (closedBall 0 R)) (cond : ∀ z ∈ sphere 0 r, ‖f z‖ ≤ C) (wInS : w ∈ closedBall 0 r) : ‖f w‖ ≤ C. With r = R ✓ le_refl. The `analytic` arg: AnalyticOn ℂ Gentire (closedBall 0 R): \n\n```\nhave hGnhd : AnalyticOnNhd ℂ Gentire (Metric.closedBall 0 R) :=\n  fun s _ => gentire_analyticAt_and_eq.1 s\nhave hGan : AnalyticOn ℂ Gentire (Metric.closedBall 0 R) := hGnhd.analyticOn\n```\nAnalyticOnNhd.analyticOn : AnalyticOnNhd f s → AnalyticOn f s ✓ (used in StrongPNTPrefix line 386).\n\n`gentire_analyticAt_and_eq.1 : ∀ s, AnalyticAt ℂ Gentire s` ✓.\n\nNow the full §4:\n\n```\nlemma gentire_const (hZC : ZeroCountProp) (z₀ : ℂ) : Gentire z₀ = Gentire 0 := by\n  classical\n  -- constants\n  have hC0'nn : (0:ℝ) ≤ 2 * lowZeroConst + dirichletC2 + ‖Gentire 0‖ := by\n    have h1 := lowZeroConst_nonneg\n    have h2 := dirichletC2_nonneg\n    have h3 := norm_nonneg (Gentire 0)\n    linarith\n  have hA0nn : (0:ℝ) ≤ A0count := A0count_pos.le\n  -- main: ∀ ε > 0, dist ≤ ε\n  have key : ∀ ε : ℝ, 0 < ε → dist (Gentire z₀) (Gentire 0) ≤ ε := by\n    intro ε hε\n    set C₀' := 2 * lowZeroConst + dirichletC2 + ‖Gentire 0‖ with hC0'\n    set C₁ := 2000000 * A0count with hC1\n    have hC1nn : (0:ℝ) ≤ C₁ := by positivity  -- 2000000 * A0count, needs A0count ≥ 0: positivity doesn't know A0count. use mul_nonneg\n    ...\n```\npositivity won't know A0count ≥ 0 — use `mul_nonneg (by norm_num) hA0nn`. But C₁ is `set` — positivity on `C₁` fails; rw hC1 first or use `by rw [hC1]; exact mul_nonneg ...`. Hmm `set ... with h` gives hC1 : C₁ = 2000000 * A0count. rw [hC1]. OK.\n\n```\n    set c := 2 + (128 * C₁ + 2 * C₀') * ‖z₀‖ / ε with hc\n    have hcnn : (0:ℝ) ≤ 128 * C₁ + 2 * C₀' := by\n      rw [hC1, hC0']  -- hmm messy; instead:\n```\nSince C₀' and C₁ are set-variables, nonneg proofs: have hC₀'nn : 0 ≤ C₀' := hC0' ▸ hC0'nn... With set, hC0' : C₀' = expr; rw [hC0'] replaces C₀' by expr. Fine: \n```\n    have hC₀'nn : (0:ℝ) ≤ C₀' := by rw [hC0']; linarith [lowZeroConst_nonneg, dirichletC2_nonneg, norm_nonneg (Gentire 0)]\n    have hC₁nn : (0:ℝ) ≤ C₁ := by rw [hC1]; exact mul_nonneg (by norm_num) hA0nn\n    have hcz : (1:ℝ) ≤ c := by\n      rw [hc]  -- hmm set already replaced? with `set c := ... with hc`, occurrences replaced; hc : c = ...\n```\nWait — `set x := e with h` introduces x and h : x = e, and replaces e by x in goal. New goals I create via `have` don't auto-rewrite. So `have hcz : 1 ≤ c := by rw [hc]; ...`: after rw [hc], goal 1 ≤ 2 + (128*C₁ + 2*C₀')*‖z₀‖/ε. Proof: (128*C₁ + 2*C₀')*‖z₀‖/ε ≥ 0: div_nonneg (mul_nonneg (add_nonneg (mul_nonneg (by norm_num) hC₁nn) (mul_nonneg (by norm_num) hC₀'nn)) (norm_nonneg _)) hε.le. linarith.\n\n```\n    -- choose k and R\n    set M := max (c ^ 4) (‖z₀‖ + 1) with hM\n    obtain ⟨k, hk4000, hkM⟩ : ∃ k : ℕ, 4000 ≤ k ∧ M ≤ 4 * (k:ℝ) := by\n      refine ⟨max 4000 ⌈M / 4⌉₊, le_max_left _ _, ?_⟩\n      have h1 : M / 4 ≤ (⌈M / 4⌉₊ : ℝ) := Nat.le_ceil _\n      have h2 : (⌈M / 4⌉₊ : ℝ) ≤ (max 4000 ⌈M / 4⌉₊ : ℕ) := by exact_mod_cast le_max_right _ _\n      have h3 : M ≤ 4 * (⌈M / 4⌉₊ : ℝ) := by linarith [h1]\n      calc M ≤ 4 * (⌈M / 4⌉₊ : ℝ) := h3\n        _ ≤ 4 * ((max 4000 ⌈M / 4⌉₊ : ℕ) : ℝ) := by\n            apply mul_le_mul_of_nonneg_left _ (by norm_num : (0:ℝ) ≤ 4)\n            exact_mod_cast le_max_right _ _\n```\nHmm — cast juggling: (4 * (k:ℝ)) where k = max 4000 ⌈M/4⌉₊; ((max a b : ℕ) : ℝ) = max (a:ℝ) (b:ℝ)? Nat.cast_max ✓ exists. Simpler: \n```\n      have hceil : M ≤ 4 * (⌈M / 4⌉₊ : ℝ) := by\n        have h1 := Nat.le_ceil (M / 4)\n        linarith\n      have hcast : (4 : ℝ) * (⌈M / 4⌉₊ : ℝ) ≤ 4 * ((max 4000 ⌈M / 4⌉₊ : ℕ) : ℝ) := by\n        have : (⌈M / 4⌉₊ : ℝ) ≤ ((max 4000 ⌈M / 4⌉₊ : ℕ) : ℝ) := by exact_mod_cast le_max_right _ _\n        linarith\n      linarith [hceil, hcast]\n```\nlinarith fine (atoms: casts).\n\n```\n    obtain ⟨R, hRlo, hRhi, hgapInt, hgap⟩ := exists_gapCircle_radius hZC (k := k) (by omega : 1 ≤ k)\n```\nWait signature: exists_gapCircle_radius (hZC : ZeroCountProp) {k : ℕ} (hk : 1 ≤ k). k implicit — pass (k := k)? If implicit it unifies from hk? hk : 1 ≤ k forces it ✓ just `exists_gapCircle_radius hZC (by omega)` might leave k as metavariable resolved by hk — hk's type mentions k... ambiguous; safer to give explicitly. Check how LiCircleBound calls it... Fexpr_circle_le takes the gap properties as hypotheses, doesn't call exists_gapCircle_radius. Let me check if anything calls it — probably not yet (5e-v-d is the first consumer). I'll write `exists_gapCircle_radius hZC (k := k) (by omega)` — if k is implicit, (k := k) works; if explicit positional, adjust.\n\n```\n    have hR16002 : (16002:ℝ) ≤ R := by\n      have hkR : (16000:ℝ) ≤ 4 * (k:ℝ) := by\n        have h1 : (4000:ℝ) ≤ (k:ℝ) := by exact_mod_cast hk4000\n        linarith\n      linarith [hRlo]\n    have hRpos : (0:ℝ) < R := by linarith [hR16002]\n    have hlogR : (9:ℝ) ≤ Real.log R := nine_le_log_of_16002_le hR16002\n    have hMR : M ≤ R := by linarith [hkM, hRlo]\n    -- the circle bound on the sphere\n    have hsphere : ∀ z ∈ Metric.sphere (0:ℂ) R, ‖Gentire z‖ ≤\n        2 * lowZeroConst + dirichletC2 + 400000 * A0count * C0hat (R + 2) * (Real.log R)^2 := by\n      intro z hz\n      have hznorm : ‖z‖ = R := by\n        have h := Metric.mem_sphere.mp hz\n        rw [dist_eq_norm, sub_zero] at h  -- h : ‖z‖ = R? dist z 0 = ‖z - 0‖ = ‖z‖\n        exact h\n      have hgood : ¬ badPoint z := not_badPoint_on_gapCircle hk4000 hRlo hgap hgapInt hznorm\n      rw [gentire_eq_Fexpr hgood]\n      exact Fexpr_circle_le hk4000 hRlo hRhi hgap hgapInt hznorm\n```\nCheck `dist_eq_norm : dist x y = ‖x − y‖` — for ℂ yes (SeminormedGroup). `sub_zero : x − 0 = x` ✓. But rw [sub_zero] at h where h : ‖z − 0‖ = R: sub_zero is about z − (0:ℂ) ✓.\n\n```\n    -- ball bound via max-modulus\n    have hGan : AnalyticOn ℂ Gentire (Metric.closedBall 0 R) :=\n      (fun s _ => gentire_analyticAt_and_eq.1 s : AnalyticOnNhd ℂ Gentire _).analyticOn\n```\nHmm — the ascription `(fun s _ => ... : AnalyticOnNhd ℂ Gentire _)` — AnalyticOnNhd ℂ f s : Prop := ∀ x ∈ s, AnalyticAt ℂ f x. The lambda fun s _ => gentire_analyticAt_and_eq.1 s : ∀ s, s ∈ closedBall 0 R → AnalyticAt ℂ Gentire s ✓ defeq. Then `.analyticOn`. Cleaner:\n```\n    have hGan : AnalyticOn ℂ Gentire (Metric.closedBall 0 R) :=\n      AnalyticOnNhd.analyticOn (fun s _ => gentire_analyticAt_and_eq.1 s)\n```\nThe expected type guides the lambda ✓.\n\n```\n    have hball : ∀ z ∈ Metric.closedBall (0:ℂ) R, ‖Gentire z‖ ≤\n        2 * lowZeroConst + dirichletC2 + 400000 * A0count * C0hat (R + 2) * (Real.log R)^2 :=\n      fun z hz => AnalyticOn.norm_le_of_norm_le_on_sphere le_rfl hGan hsphere hz\n```\nWait — the lemma is stated with implicit {C r R} and our C is the big expression; unification from hsphere ✓.\n\n```\n    -- MapsTo\n    set RB := 2 * lowZeroConst + dirichletC2 + 400000 * A0count * C0hat (R + 2) * (Real.log R)^2 with hRB\n    have hRBnn : (0:ℝ) ≤ RB := by\n      rw [hRB]\n      have hĈ : (0:ℝ) ≤ C0hat (R + 2) := by\n        have h1 : (2:ℝ) ≤ C0hat (R + 2) := two_le_C0hat (by linarith [hRpos] : (1:ℝ) ≤ R + 2)\n        linarith\n      have hlogRnn : (0:ℝ) ≤ Real.log R := by linarith [hlogR]\n      positivity-ish: add_nonneg (add_nonneg (mul_nonneg (by norm_num) lowZeroConst_nonneg) dirichletC2_nonneg) (mul_nonneg (mul_nonneg (mul_nonneg (by norm_num) hA0nn) hĈ) (pow_nonneg hlogRnn 2))\n    have hmaps : MapsTo Gentire (Metric.ball 0 R) (Metric.closedBall (Gentire 0) (RB + ‖Gentire 0‖)) := by\n      intro z hz\n      have hzball : z ∈ Metric.closedBall (0:ℂ) R := by\n        rw [Metric.mem_ball] at hz; rw [Metric.mem_closedBall]; exact hz.le\n      have h1 := hball z hzball\n      rw [Metric.mem_closedBall, dist_eq_norm]\n      calc ‖Gentire z - Gentire 0‖ ≤ ‖Gentire z‖ + ‖Gentire 0‖ := norm_sub_le _ _\n        _ ≤ RB + ‖Gentire 0‖ := by linarith [h1]\n```\nHmm — linarith [h1] with h1 : ‖Gentire z‖ ≤ RB: goal ‖Gentire z‖ + ‖Gentire 0‖ ≤ RB + ‖Gentire 0‖ — linear ✓ but wait the gotcha: add_le_add_left/right swapped — linarith avoids it ✓.\n\n```\n    -- Schwarz\n    have hdiff : DifferentiableOn ℂ Gentire (Metric.ball 0 R) :=\n      fun z _ => (gentire_analyticAt_and_eq.1 z).differentiableAt.differentiableWithinAt\n    have hz0mem : z₀ ∈ Metric.ball (0:ℂ) R := by\n      rw [Metric.mem_ball, dist_eq_norm, sub_zero]\n      have h1 : ‖z₀‖ + 1 ≤ M := le_max_right _ _  -- wait M := max (c^4) (‖z₀‖+1): le_max_right gives ‖z₀‖+1 ≤ M ✓\n      have h2 : ‖z₀‖ < M := by linarith [norm_nonneg z₀]\n      linarith [hMR]\n    have hschwarz := Complex.dist_le_div_mul_dist_of_mapsTo_ball hdiff hmaps hz0mem\n    -- hschwarz : dist (Gentire z₀) (Gentire 0) ≤ (RB + ‖Gentire 0‖)/R * dist z₀ 0\n    rw [dist_eq_norm, sub_zero] at hschwarz\n```\nHmm — `Complex.dist_le_div_mul_dist_of_mapsTo_ball` signature: (hd : DifferentiableOn ℂ f (ball c R₁)) (h_maps : MapsTo f (ball c R₁) (closedBall (f c) R₂)) (hz : z ∈ ball c R₁) : dist (f z) (f c) ≤ R₂ / R₁ * dist z c. Note it's stated for general E F normed spaces with f : E → F and ℂ differentiability — here E = ℂ. The ball is `ball c R₁` — from Schwarz.lean line 190, `ball c R₁` with open Metric? Schwarz.lean opens... the lemma uses `ball`/`closedBall` — in that file there's `open Metric`? The statement shows `MapsTo f (ball c R₁) (closedBall (f c) R₂)` — these are Metric.ball/closedBall ✓.\n\nAlso note the implicit args: {f}, {c}, {z}, {R₁}, {R₂} — unified from args ✓.\n\n```\n    -- hschwarz : dist (Gentire z₀) (Gentire 0) ≤ (RB + ‖Gentire 0‖) / R * ‖z₀‖\n    -- the growth bound: RB ≤ C₀' + 64*C₁*Q^3, R = Q^4, Q ≥ c\n    set Q := R ^ ((4:ℝ)⁻¹) with hQ\n    have hQnn : (0:ℝ) ≤ Q := Real.rpow_nonneg hRpos.le _\n    have hQpos : (0:ℝ) < Q := Real.rpow_pos_of_pos hRpos _\n    have hQc : c ≤ Q := by\n      have h1 : c = (c ^ 4) ^ ((4:ℝ)⁻¹) := (Real.pow_rpow_inv_natCast hcnn'? (four ≠ 0)).symm\n```\npow_rpow_inv_natCast (hx : 0 ≤ x) (hn : n ≠ 0) : (x ^ n) ^ (n⁻¹ : ℝ) = x. So ((c^4) ^ ((4:ℝ)⁻¹)) = c ✓. hc ≥ 1 ⟹ 0 ≤ c ✓ (hcnn2 : 0 ≤ c := by linarith [hcz]).\n```\n      have h2 : (c ^ 4) ^ ((4:ℝ)⁻¹) ≤ R ^ ((4:ℝ)⁻¹) :=\n        Real.rpow_le_rpow (pow_nonneg (by linarith [hcz]) 4) (by\n          have : c ^ 4 ≤ M := le_max_left _ _\n          linarith [hMR]) (by positivity : (0:ℝ) ≤ (4:ℝ)⁻¹)\n      rw [h1]  -- hmm goal c ≤ Q; rw h1 makes goal ((c^4)^((4:ℝ)⁻¹)) ≤ Q; Q is set-var := R^(4⁻¹)\n      exact h2  -- h2 : (c^4)^(4⁻¹) ≤ R^(4⁻¹); Q is let/set: after set, R^(4⁻¹) displayed as Q; defeq ✓ exact h2 should work since set uses let? `set` introduces a local def; exact h2 with h2 mentioning R^(4⁻¹) — the goal shows Q but is defeq ✓.\n```\nHmm — `set Q := R ^ ((4:ℝ)⁻¹) with hQ` replaces occurrences in the goal only; my new haves mention R^(4⁻¹) directly; goals will show Q after set? New have-goals I state myself — I control their statements, so I'll state them with R^((4:ℝ)⁻¹) or Q consistently. With `set`, hQ : Q = R ^ ((4:ℝ)⁻¹). When I prove h2 : (c^4)^((4:ℝ)⁻¹) ≤ R^((4:ℝ)⁻¹) and need c ≤ Q: rw [hQ] at goal? Goal c ≤ Q; rw [hQ] gives c ≤ R^(4⁻¹) ✓ then rw [h1] gives ((c^4)^(4⁻¹)) ≤ R^(4⁻¹) = h2 ✓. OK — but rw [hQ] rewrites Q → R^(4⁻¹) in goal (hQ : Q = ...; rw [hQ] replaces Q with RHS ✓).\n\nActually simpler: avoid `set` for Q; just use R^((4:ℝ)⁻¹) throughout, with a `have hQdef`-free approach. Expression is a bit long but fine. Actually let me use `set` and be careful. Or `let`? `set` is fine.\n\nContinue:\n```\n    have hL : Real.log R ≤ 4 * Q := by\n      have h := Real.log_le_rpow_div hRpos.le (show (0:ℝ) < (4:ℝ)⁻¹ by positivity)\n      -- h : log R ≤ R^((4:ℝ)⁻¹) / (4:ℝ)⁻¹\n      have h2 : R ^ ((4:ℝ)⁻¹) / (4:ℝ)⁻¹ = 4 * Q := by\n        rw [hQ, div_eq_mul_inv, inv_inv]  -- Q * 4 → 4 * Q by ring\n        ring\n      rw [h2] at h  -- hmm h's RHS rewritten\n      exact h\n```\nCareful: `rw [h2] at h` — h2 : R^(4⁻¹)/(4⁻¹) = 4*Q; rw [h2] at h : h : log R ≤ 4*Q ✓. But hQ : Q = R^(4⁻¹); inside h2 I rw [hQ] turning goal R^(4⁻¹)/(4⁻¹) = 4*Q into Q/(4⁻¹) = 4*Q... wait rw [hQ] rewrites Q→R^(4⁻¹) everywhere: goal becomes R^(4⁻¹)/(4⁻¹) = 4*(R^(4⁻¹)). Then div_eq_mul_inv: R^(4⁻¹) * (4⁻¹)⁻¹ = ...; inv_inv: (4⁻¹)⁻¹ = 4: R^(4⁻¹)*4 = 4*R^(4⁻¹): ring ✓.\n\n```\n    have hL3 : (Real.log R)^3 ≤ 64 * Q^3 := by\n      have h1 : (Real.log R)^3 ≤ (4 * Q)^3 := pow_le_pow_left (by linarith [hlogR]) hL 3\n      have h2 : (4 * Q)^3 = 64 * Q^3 := by ring\n      rw [h2] at h1; exact h1\n    -- RB ≤ C₀' + C₁*(log R)^3 ≤ C₀' + 64*C₁*Q^3\n    have hĈ5 : C0hat (R + 2) ≤ 5 * Real.log R := C0hat_add_two_le hR16002\n    have hRBle : RB ≤ C₀' + 64 * C₁ * Q^3 := by\n      have hlogRnn : (0:ℝ) ≤ Real.log R := by linarith [hlogR]\n      have hstep1 : 400000 * A0count * C0hat (R + 2) * (Real.log R)^2\n          ≤ 400000 * A0count * (5 * Real.log R) * (Real.log R)^2 := by\n        apply mul_le_mul_of_nonneg_right _ (pow_nonneg hlogRnn 2)\n        apply mul_le_mul_of_nonneg_left hĈ5\n        exact mul_nonneg (by norm_num) hA0nn\n      have hstep2 : 400000 * A0count * (5 * Real.log R) * (Real.log R)^2 = C₁ * (Real.log R)^3 := by\n        rw [hC1]; ring  -- 400000*A0*5*L*L^2 = 2000000*A0*L^3: ring handles L^2*L = L^3? ring with pow ✓\n      have hstep3 : C₁ * (Real.log R)^3 ≤ C₁ * (64 * Q^3) :=\n        mul_le_mul_of_nonneg_left hL3 hC₁nn\n      -- assemble: RB = 2*lowZeroConst + dirichletC2 + [big] ≤ (C₀' - ‖Gentire 0‖) + C₁*64*Q^3 ≤ C₀' + 64*C₁*Q^3\n      rw [hRB, hC0']\n      -- goal: 2*lowZeroConst + dirichletC2 + big ≤ (2*lowZeroConst + dirichletC2 + ‖Gentire 0‖) + 64*C₁*Q^3\n      have hbig : 400000 * A0count * C0hat (R + 2) * (Real.log R)^2 ≤ 64 * C₁ * Q^3 := by\n        have : C₁ * (Real.log R)^3 ≤ 64 * C₁ * Q^3 := by\n          have h := mul_le_mul_of_nonneg_left hL3 hC₁nn  -- C₁*L^3 ≤ C₁*(64*Q^3)\n          -- C₁*(64*Q^3) = 64*C₁*Q^3 by ring — need a bridge have\n          have h2 : C₁ * (64 * Q^3) = 64 * C₁ * Q^3 := by ring\n          rwa [h2] at h\n        linarith [hstep1, hstep2, this]  -- hmm hstep2 is an equation: linarith handles ✓\n      have hG0nn : (0:ℝ) ≤ ‖Gentire 0‖ := norm_nonneg _\n      linarith [hbig, hG0nn]\n```\nCareful with `linarith [hstep1, hstep2, this]`: goal `400000 * A0count * C0hat (R + 2) * (Real.log R)^2 ≤ 64 * C₁ * Q^3`; hstep1 : LHS ≤ 400000*A0*(5*L)*L^2; hstep2 : 400000*A0*(5*L)*L^2 = C₁*L^3; this : C₁*L^3 ≤ 64*C₁*Q^3. linarith chains ✓ (all linear atoms).\n\n```\n    -- the final real inequality: (RB + ‖Gentire 0‖)/R * ‖z₀‖ ≤ ε\n    have hR4 : R = Q^4 := by\n      have h := Real.rpow_inv_natCast_pow hRpos.le (show (4:ℕ) ≠ 0 by norm_num)\n      -- h : (R^((4:ℝ)⁻¹))^4 = R; R^(4⁻¹) = Q by hQ.symm\n      rw [← hQ] at h  -- h : Q^4 = R\n      exact h.symm\n```\nrpow_inv_natCast_pow (hx : 0 ≤ x) (hn : n ≠ 0) : (x ^ (n⁻¹ : ℝ)) ^ n = x. Here n : ℕ implicit? From the source: `theorem rpow_inv_natCast_pow (hx : 0 ≤ x) (hn : n ≠ 0) : (x ^ (n⁻¹ : ℝ)) ^ n = x` — n implicit presumably {n : ℕ}. Call: Real.rpow_inv_natCast_pow hRpos.le (show (4:ℕ) ≠ 0 by norm_num) : (R ^ ((4:ℕ)⁻¹ : ℝ)) ^ 4 = R. The exponent is (↑(4:ℕ))⁻¹ : ℝ = ((4:ℝ))⁻¹ — Nat.cast 4 = 4: the term R ^ (↑4)⁻¹ vs my Q := R ^ ((4:ℝ)⁻¹) — (↑(4:ℕ) : ℝ) is defeq to (4:ℝ) but syntactically different after set... rw [← hQ] at h needs syntactic match of R^((4:ℝ)⁻¹) inside h's (↑(4:ℕ))⁻¹ form — might fail! Fix: push_cast at h first: push_cast turns ((4:ℕ):ℝ)⁻¹ into (4:ℝ)⁻¹ ✓. So: `push_cast at h` then rw [← hQ] at h. \n\n```\n    have hmain : (RB + ‖Gentire 0‖) / R * ‖z₀‖ ≤ ε := by\n      rw [hR4]\n      -- goal: (RB + ‖Gentire 0‖)/Q^4 * ‖z₀‖ ≤ ε\n      have hQ4pos : (0:ℝ) < Q^4 := pow_pos hQpos 4\n      rw [div_mul_eq_mul_div, le_div_iff₀ hQ4pos]  -- ((RB+‖Gentire 0‖) * ‖z₀‖) ≤ ε * Q^4\n```\nHmm: (X/Q⁴)*‖z₀‖ = X*‖z₀‖/Q⁴ (div_mul_eq_mul_div ✓). le_div_iff₀ (hc : 0 < c) : a ≤ b / c ↔ a * c ≤ b ✓. Goal: (RB+‖G0‖)*‖z₀‖*Q^4 ≤ ε... wait direction: a ≤ b/c ↔ a*c ≤ b: ((RB+‖G0‖)*‖z₀‖) * Q^4 ≤ ε ✓.\n```\n      -- pieces\n      have hc1 : (128 * C₁) * ‖z₀‖ ≤ ε * Q := by\n        have h1 : (128 * C₁ + 2 * C₀') * ‖z₀‖ / ε ≤ c := by\n          rw [hc]  -- c = 2 + .../ε; linarith with the div nonneg? goal (128C₁+2C₀')‖z₀‖/ε ≤ 2 + (128C₁+2C₀')‖z₀‖/ε: linarith\n        have h2 : (128 * C₁) * ‖z₀‖ ≤ (128 * C₁ + 2 * C₀') * ‖z₀‖ := by\n          apply mul_le_mul_of_nonneg_right _ (norm_nonneg _)\n          -- 128*C₁ ≤ 128*C₁ + 2*C₀'\n          linarith [hC₀'nn, hC₁nn]  -- hmm linarith: goal 128*C₁ ≤ 128*C₁ + 2*C₀' with 0 ≤ C₀' ✓\n        have h3 : (128 * C₁) * ‖z₀‖ / ε ≤ c := by\n          have h4 : (128 * C₁) * ‖z₀‖ / ε ≤ (128 * C₁ + 2 * C₀') * ‖z₀‖ / ε :=\n            div_le_div_of_nonneg_right h2 hε.le  -- check name: div_le_div_of_nonneg_right? session-032 gotcha: \"div_le_div_of_nonneg_right exists / div_le_div_right does NOT\" ✓\n          exact h4.trans h1\n        -- multiply through by ε\n        calc (128 * C₁) * ‖z₀‖ = (128 * C₁) * ‖z₀‖ / ε * ε := by rw [div_mul_cancel₀ _ hε.ne']\n          _ ≤ c * ε := mul_le_mul_of_nonneg_right h3 hε.le\n          _ ≤ Q * ε := mul_le_mul_of_nonneg_right hQc hε.le\n          _ = ε * Q := by ring\n      have hA : 64 * C₁ * Q^3 * ‖z₀‖ ≤ (ε/2) * Q^4 := by\n        have h1 : (64 * C₁ * ‖z₀‖) * Q^3 ≤ ((ε/2) * Q) * Q^3 := by\n          apply mul_le_mul_of_nonneg_right _ (pow_nonneg hQnn 3)\n          -- 64*C₁*‖z₀‖ ≤ (ε/2)*Q\n          have hhalf : (ε/2) * Q = (ε * Q)/2 := by ring\n          rw [hhalf]  -- goal 64*C₁*‖z₀‖ ≤ ε*Q/2\n          -- from hc1: 128*C₁*‖z₀‖ ≤ ε*Q\n          have h128 : 128 * C₁ * ‖z₀‖ ≤ ε * Q := hc1\n          -- 64*C₁*‖z₀‖ = (128*C₁*‖z₀‖)/2\n          have h64 : (64:ℝ) * C₁ * ‖z₀‖ = (128 * C₁ * ‖z₀‖)/2 := by ring\n          rw [h64]; linarith [h128]\n        -- reassociate: (64*C₁*‖z₀‖)*Q^3 = 64*C₁*Q^3*‖z₀‖ and ((ε/2)*Q)*Q^3 = (ε/2)*Q^4\n        have hL : (64 * C₁ * ‖z₀‖) * Q^3 = 64 * C₁ * Q^3 * ‖z₀‖ := by ring\n        have hR' : ((ε/2) * Q) * Q^3 = (ε/2) * Q^4 := by ring\n        rwa [hL, hR'] at h1\n      have hB : C₀' * ‖z₀‖ ≤ (ε/2) * Q^4 := by\n        have h1 : (2 * C₀') * ‖z₀‖ ≤ ε * Q := by\n          have h2 : (2 * C₀') * ‖z₀‖ ≤ (128 * C₁ + 2 * C₀') * ‖z₀‖ := by\n            apply mul_le_mul_of_nonneg_right _ (norm_nonneg _)\n            linarith [hC₁nn]\n          have h3 : (128 * C₁ + 2 * C₀') * ‖z₀‖ / ε ≤ c := by rw [hc]; linarith\n          have h4 : (2 * C₀') * ‖z₀‖ / ε ≤ c := (div_le_div_of_nonneg_right h2 hε.le).trans h3\n          calc (2 * C₀') * ‖z₀‖ = (2 * C₀') * ‖z₀‖ / ε * ε := by rw [div_mul_cancel₀ _ hε.ne']\n            _ ≤ c * ε := mul_le_mul_of_nonneg_right h4 hε.le\n            _ ≤ Q * ε := mul_le_mul_of_nonneg_right hQc hε.le\n            _ = ε * Q := by ring\n        have hQ2 : (2:ℝ) ≤ Q := by linarith [hQc, hcz]  -- c ≥ 2? c = 2 + nonneg ≥ 2 ✓ (hcz was 1 ≤ c; need 2 ≤ c)\n        have hQ3 : (8:ℝ) ≤ Q^3 := by\n          have h := pow_le_pow_left (by norm_num : (0:ℝ) ≤ 2) hQ2 3  -- 2^3 ≤ Q^3\n          norm_num at h  -- 2^3 = 8\n          exact h\n        have h2 : ε * Q ≤ (ε/2) * Q^4 := by\n          -- (ε/2)*Q^4 = (ε/2)*Q*Q^3 ≥ (ε/2)*Q*8 = 4*ε*Q ≥ ε*Q\n          have h3 : (ε/2) * Q^4 = ((ε/2) * Q) * Q^3 := by ring\n          rw [h3]\n          have h4 : (ε/2) * Q * 1 ≤ ((ε/2) * Q) * Q^3 := by\n            apply mul_le_mul_of_nonneg_left _ (by positivity : (0:ℝ) ≤ ε/2 * Q)\n            linarith [hQ3]  -- 1 ≤ Q^3 hmm: linarith with hQ3 : 8 ≤ Q^3 ⟹ 1 ≤ Q^3 ✓\n          have h5 : ε * Q = (ε/2) * Q * 2 := by ring\n          rw [h5]\n          -- 2 ≤ Q^3 mul-left\n          have h6 : (ε/2) * Q * 2 ≤ (ε/2) * Q * Q^3 :=\n            mul_le_mul_of_nonneg_left (by linarith [hQ3] : (2:ℝ) ≤ Q^3) (by positivity : (0:ℝ) ≤ ε/2*Q)\n          exact h6\n        -- C₀'*‖z₀‖ ≤ (2*C₀')*‖z₀‖/2 ≤ ε*Q/2 ≤ (ε/2)*Q^4/2?? hmm redo\n```\nHmm — h1 : 2·C₀'·‖z₀‖ ≤ ε·Q and h2 : ε·Q ≤ (ε/2)·Q⁴. Then 2·C₀'·‖z₀‖ ≤ (ε/2)·Q⁴, so C₀'·‖z₀‖ ≤ (ε/2)·Q⁴ follows (C₀'‖z₀‖ ≤ 2·C₀'‖z₀‖). linarith-friendly: need the atoms aligned: (2*C₀')*‖z₀‖ vs 2*(C₀'*‖z₀‖) — ring-equal, linarith normalizes ✓. So:\n```\n        have h7 : C₀' * ‖z₀‖ ≤ 2 * C₀' * ‖z₀‖ := by\n          have h : (0:ℝ) ≤ C₀' * ‖z₀‖ := mul_nonneg hC₀'nn (norm_nonneg _)\n          linarith [h]  -- C₀'*‖z₀‖ ≤ 2*C₀'*‖z₀‖ = C₀'*‖z₀‖ + C₀'*‖z₀‖ ✓ linarith normalizes (2*C₀')*‖z₀‖ to 2*(C₀'*‖z₀‖)\n        linarith [h7, h1, h2]\n```\nlinarith: C₀'‖z₀‖ ≤ 2 C₀'‖z₀‖ ≤ εQ ≤ (ε/2)Q⁴ ✓ — wait h1 : (2*C₀')*‖z₀‖ ≤ ε*Q: linarith normalizes (2*C₀')*‖z₀‖ → 2*(C₀'*‖z₀‖) ✓ same atom.\n\n```\n      -- assemble\n      have hsum : (RB + ‖Gentire 0‖) * ‖z₀‖ ≤ ε * Q^4 := by\n        have h1 : (RB + ‖Gentire 0‖) * ‖z₀‖ ≤ (C₀' + 64 * C₁ * Q^3 + ‖Gentire 0‖) * ‖z₀‖ := by\n          apply mul_le_mul_of_nonneg_right _ (norm_nonneg _)\n          linarith [hRBle, norm_nonneg (Gentire 0)]  -- RB + ‖G0‖ ≤ C₀' + 64C₁Q³ + ‖G0‖\n        have h2 : (C₀' + 64 * C₁ * Q^3 + ‖Gentire 0‖) * ‖z₀‖\n            = C₀' * ‖z₀‖ + 64 * C₁ * Q^3 * ‖z₀‖ + ‖Gentire 0‖ * ‖z₀‖ := by ring\n        -- hmm wait C₀' already contains ‖Gentire 0‖: C₀' + ‖Gentire 0‖ ≤ 2*C₀'... simplify: C₀'*‖z₀‖ + ‖G0‖*‖z₀‖ ≤ C₀'*‖z₀‖ + C₀'*‖z₀‖ since ‖G0‖ ≤ C₀' (as 2*lowZeroConst + dirichletC2 ≥ 0)\n        have h3 : ‖Gentire 0‖ * ‖z₀‖ ≤ C₀' * ‖z₀‖ := by\n          apply mul_le_mul_of_nonneg_right _ (norm_nonneg _)\n          rw [hC0']  -- ‖G0‖ ≤ 2*lowZeroConst + dirichletC2 + ‖G0‖: linarith\n          linarith [lowZeroConst_nonneg, dirichletC2_nonneg]\n        linarith [h1, h2, h3, hA, hB]\n      -- convert\n      calc (RB + ‖Gentire 0‖) / Q^4 * ‖z₀‖ = (RB + ‖Gentire 0‖) * ‖z₀‖ / Q^4 := by ring\n        _ ≤ ε := by rw [div_le_iff₀ hQ4pos]; linarith [hsum]  -- wait direction\n```\ndiv_le_iff₀ (hc : 0 < c) : a / c ≤ b ↔ a ≤ b * c. Goal: (RB+‖G0‖)*‖z₀‖/Q⁴ ≤ ε. rw [div_le_iff₀ hQ4pos]: goal (RB+‖G0‖)*‖z₀‖ ≤ ε*Q⁴ = hsum ✓ exact hsum.\n\nHmm wait — I did `rw [hR4]` earlier then `rw [div_mul_eq_mul_div, le_div_iff₀ hQ4pos]` in hmain — let me restructure hmain cleanly:\n```\n    have hmain : (RB + ‖Gentire 0‖) / R * ‖z₀‖ ≤ ε := by\n      have hQ4pos : (0:ℝ) < Q^4 := pow_pos hQpos 4\n      have h1 : (RB + ‖Gentire 0‖) / R * ‖z₀‖ = (RB + ‖Gentire 0‖) * ‖z₀‖ / Q^4 := by\n        rw [hR4]; ring\n      rw [h1, div_le_iff₀ hQ4pos]\n      exact hsum\n```\nwhere hsum as above. But hsum/hA/hB are built inside... I should inline them all inside hmain's proof or as separate haves in the key block. Structure: build hsum first, then hmain. And div_le_iff₀ check: per session-033 gotcha \"div_lt_iff₀ is a/c<b here\" — that's for <. For ≤: `div_le_iff₀ (hc : 0 < c) : a / c ≤ b ↔ a ≤ b * c` ✓ standard.\n\nThen finish key:\n```\n    calc dist (Gentire z₀) (Gentire 0) ≤ (RB + ‖Gentire 0‖) / R * ‖z₀‖ := hschwarz\n      _ ≤ ε := hmain\n```\nWait — hschwarz after rw [dist_eq_norm, sub_zero] at hschwarz : dist (Gentire z₀) (Gentire 0) ≤ (RB + ‖Gentire 0‖)/R * ‖z₀‖. But hold on: hschwarz's RHS has dist z₀ 0: rw [dist_eq_norm] at hschwarz rewrites BOTH dists (dist (Gentire z₀) (Gentire 0) too!) → ‖Gentire z₀ − Gentire 0‖ ≤ ... * ‖z₀ − 0‖; then sub_zero rewrites z₀ − 0 AND Gentire z₀ − Gentire 0... sub_zero rw [sub_zero] at hschwarz rewrites all `? − 0` — both. Then the final equality uses dist_eq_zero: ‖Gentire z₀ − Gentire 0‖ = 0 ↔ Gentire z₀ − Gentire 0 = 0 (norm_eq_zero) ↔ Gentire z₀ = Gentire 0 (sub_eq_zero). OK workable but let me instead NOT rw at hschwarz; bridge in the calc:\n```\n    have hdz0 : dist z₀ 0 = ‖z₀‖ := by rw [dist_eq_norm, sub_zero]\n    calc dist (Gentire z₀) (Gentire 0) ≤ (RB + ‖Gentire 0‖)/R * dist z₀ 0 := hschwarz\n      _ = (RB + ‖Gentire 0‖)/R * ‖z₀‖ := by rw [hdz0]\n      _ ≤ ε := hmain\n```\nCleaner ✓.\n\n  Then after key:\n```\n  -- dist ≤ 0 ⟹ = 0 ⟹ eq\n  have h0 : dist (Gentire z₀) (Gentire 0) ≤ 0 := by\n    apply le_of_forall_pos_le_add  -- hmm signature: (∀ ε, 0 < ε → a ≤ b + ε) → a ≤ b\n    intro ε hε\n    have := key ε hε\n    linarith\n```\nCheck le_of_forall_pos_le_add exists: `le_of_forall_pos_le_add : (∀ ε : α, 0 < ε → a ≤ b + ε) → a ≤ b` — I believe it exists in Mathlib (Algebra/Order/...). Alternatively: le_antisymm: dist ≤ 0 from... or use `le_of_forall_lt'`... I'll check via grep. Fallback: by_contra + Archimedean-free: if 0 < dist then key (dist/2) gives dist ≤ dist/2 contradiction. That's robust:\n```\n  by_contra hne\n  have hpos : 0 < dist (Gentire z₀) (Gentire 0) := by\n    exact lt_of_not_ge (by ...)? \n```\nhmm — cleaner:\n```\n  rcases le_or_lt (dist (Gentire z₀) (Gentire 0)) 0 with h | h\n  · exact dist_eq_zero.mp (le_antisymm h dist_nonneg)  -- gives Gentire z₀ = Gentire 0 ✓\n  · have h2 := key (dist (Gentire z₀) (Gentire 0) / 2) (by linarith)\n    linarith\n```\n✓ robust, no lemma-name risk.\n\nWait — goal of gentire_const is `Gentire z₀ = Gentire 0`; dist_eq_zero.mp : dist x y = 0 → x = y ✓.\n\nThen the capstone:\n```\ntheorem partialFraction_identity (hZC : ZeroCountProp) :\n    ∃ B : ℂ, ∀ s : ℂ, riemannZeta s ≠ 0 → s ≠ 0 → s ≠ 1 →\n      (∀ n : ℕ, 1 ≤ n → s ≠ -2 * (n : ℂ)) →\n      logDeriv riemannZeta s\n        = B + seriesFun s - 1 / s - 1 / (s - 1) + (Real.log Real.pi : ℂ) / 2\n          - Complex.digamma (s / 2) / 2 := by\n  refine ⟨Gentire 0, fun s hζ hs0 hs1 hsn => ?_⟩\n  have hgood : ¬ badPoint s := by\n    rintro (h | h | h | ⟨n, hn, h⟩)\n    · exact hζ h.1\n    · exact hs0 h\n    · exact hs1 h\n    · exact hsn n hn h\n  have hG : Fexpr s = Gentire 0 := by\n    rw [← gentire_eq_Fexpr hgood]\n    exact gentire_const hZC s\n  rw [Fexpr] at hG  -- unfold\n  linear_combination hG\n```\nCheck: hG : logDeriv riemannZeta s - seriesFun s + 1/s + 1/(s-1) - (↑(Real.log π))/2 + Complex.digamma (s/2)/2 = Gentire 0. Goal: logDeriv riemannZeta s = Gentire 0 + seriesFun s - 1/s - 1/(s-1) + (↑(Real.log π))/2 - Complex.digamma (s/2)/2. linear_combination hG: LHS−RHS = (logDeriv ζ s) − (Gentire 0 + seriesFun s − 1/s − 1/(s−1) + logπ/2 − ψ/2); hG's LHS−RHS = (logDeriv − seriesFun + 1/s + 1/(s−1) − logπ/2 + ψ/2) − Gentire 0. Sum = 0? LHS−RHS − hG(LHS−RHS) = logDeriv − G0 − seriesFun + 1/s + 1/(s−1) − logπ/2 + ψ/2 − logDeriv + seriesFun − 1/s − 1/(s−1) + logπ/2 − ψ/2 + G0 = 0 ✓. So linear_combination hG works (coefficient 1).\n\nBut wait: `rw [Fexpr] at hG` — does rw with a def name work here? In LiCircleBound they used `rw [Fexpr]` (line 3846). ✓ same mechanism.\n\nOne concern: hsn : ∀ n : ℕ, 1 ≤ n → s ≠ -2 * (n : ℂ). badPoint's fourth disjunct: ∃ n : ℕ, 1 ≤ n ∧ s = -2 * (n : ℂ). rintro pattern ⟨n, hn, h⟩ gives h : s = -2 * (n : ℂ); hsn n hn : s ≠ -2*(n:ℂ) — exact match? badPoint def: `∃ n : ℕ, 1 ≤ n ∧ s = -2 * (n : ℂ)` ✓. hsn's form: ∀ n : ℕ, 1 ≤ n → s ≠ -2 * (n : ℂ) ✓ same. exact hsn n hn h ✓.\n\nAnd h.1 for IsNontrivialZero: IsNontrivialZero s := riemannZeta s = 0 ∧ ...; h.1 : riemannZeta s = 0; hζ : riemannZeta s ≠ 0 ✓.\n\nNow §2 `not_badPoint_on_gapCircle` — the on-circle goodness:\n```\nlemma not_badPoint_on_gapCircle {k : ℕ} (hk : 4000 ≤ k) {R : ℝ}\n    (hRlo : 4 * (k:ℝ) + 5/2 ≤ R)\n    (hgap : ∀ ρ : ℂ, IsNontrivialZero ρ →\n      1 / (16 * C0hat (4 * (k:ℝ) + 9/2)) ≤ |ρ.im - R| ∨ 1 ≤ |ρ.im - R|)\n    (hgapInt : ∀ m : ℤ, 1/4 ≤ |R/2 - (m:ℝ)|)\n    {s : ℂ} (hs : ‖s‖ = R) : ¬ badPoint s := by\n  have hR16002 : (16002:ℝ) ≤ R := by\n    have h1 : (4000:ℝ) ≤ (k:ℝ) := by exact_mod_cast hk\n    linarith [hRlo]\n  have hRpos : (0:ℝ) < R := by linarith [hR16002]\n  rintro (h | h | h | ⟨n, hn, h⟩)\n  · exact not_isNontrivialZero_on_gapCircle hk hRlo hgap hs h\n  · -- s = 0\n    rw [h] at hs\n    rw [norm_zero] at hs  -- hs : 0 = R\n    linarith [hRpos]\n  · -- s = 1\n    rw [h] at hs\n    rw [norm_one] at hs  -- hs : 1 = R\n    linarith [hR16002]\n  · -- s = -2n\n    have hR2 : R = 2 * (n:ℝ) := by\n      rw [← hs, h]  -- goal: ‖(-2:ℂ)*(n:ℂ)‖ = 2*(n:ℝ)\n      rw [norm_mul]\n      have h1 : ‖(-2:ℂ)‖ = 2 := by\n        rw [show (-2:ℂ) = ((-2:ℝ):ℂ) by push_cast; ring, Complex.norm_real]\n        norm_num\n      have h2 : ‖(n:ℂ)‖ = (n:ℝ) := Complex.norm_natCast n  -- check name\n      rw [h1, h2]\n    have hcon := hgapInt (n:ℤ)\n    rw [Int.cast_natCast] at hcon  -- ((n:ℤ):ℝ) = (n:ℝ)\n    have h0 : R/2 - (n:ℝ) = 0 := by rw [hR2]; ring\n    rw [h0, abs_zero] at hcon\n    linarith [hcon]  -- 1/4 ≤ 0 false\n```\nWait: rw [← hs, h]: goal R = 2*(n:ℝ); rw [← hs] turns R into ‖s‖: ‖s‖ = 2*(n:ℝ); rw [h] turns s into -2*(n:ℂ): ‖-2*(n:ℂ)‖ = 2*(n:ℝ) ✓.\n\nCheck `Complex.norm_natCast` name — grep needed. In Mathlib: `Complex.norm_natCast (n : ℕ) : ‖(n : ℂ)‖ = n` — I'm fairly sure it exists (norm_natCast general? `norm_natCast` in a NormedField... For ℂ specifically there should be Complex.norm_natCast). Fallback: `by simp` or Complex.norm_ofNat... I'll grep.\n\nAlso `Int.cast_natCast : ((↑n : ℤ) : α) = ↑n` ✓ standard name.\n\nWait, hgapInt (n:ℤ) : 1/4 ≤ |R/2 - ((n:ℤ):ℝ)| — the coercion ((n:ℤ):ℝ) is Int.cast; rw [Int.cast_natCast] at hcon changes it to (n:ℝ) ✓.\n\nAlso `not_isNontrivialZero_on_gapCircle` — verify its exact signature: used at line 3815: `not_isNontrivialZero_on_gapCircle hk hRlo hgap hs : ¬ IsNontrivialZero s`. ✓ matches my usage.\n\n§1 C0hat_add_two_le — check `Real.log_le_sub_one_of_pos` name and `Real.log_le_log` signature. LiCircleBound used `Real.log_le_log (by ... : (0:ℝ) < 2 + R/2) (by linarith : ...)` — wait line 3894: `apply Real.log_le_log (by linarith [hRpos] : (0 : ℝ) < 2 + R / 2)` then `linarith [hR]` — so Real.log_le_log takes hx : 0 < x first, then remaining goal x ≤ y ✓.\n\n`Real.log_le_sub_one_of_pos`: grep to verify.\n\nNow — imports for LiSqueeze.lean: `import NguyenRH1.LiCircleBound` suffices (transitively gets LiFEntire, LiGapCircles, Mathlib, Zeta23.RvM.LocalCount). But `exists_gapCircle_radius` is in LiGapCircles ✓ transitively imported. `Metric`, `MapsTo`, `Complex.dist_le_div_mul_dist_of_mapsTo_ball` need Mathlib ✓ (LiCircleBound imports full Mathlib). `open Zeta23 Complex Filter Topology` mirror LiCircleBound. Note: `AnalyticOn.norm_le_of_norm_le_on_sphere` — from Zeta23 StrongPNTPrefix; is it transitively imported? LiCircleBound imports LiDisc which imports...? LiDisc used LogOfAnalyticFunction + BorelCaratheodoryDeriv from StrongPNTPrefix presumably. Let me verify LiDisc imports StrongPNTPrefix. If not, add `import Zeta23.FromPNTPlus.StrongPNTPrefix`.\n\nLet me check LiDisc's imports and the `open` in LiCircleBound (line ~27: open Zeta23 Complex Filter Topology).\n\nAlso need `Real.rpow_le_rpow`, `Real.rpow_nonneg`, `Real.rpow_pos_of_pos`, `Real.rpow_inv_natCast_pow`, `Real.pow_rpow_inv_natCast`, `Real.log_le_rpow_div`, `pow_le_pow_left`, `pow_pos`, `pow_nonneg`, `Nat.le_ceil`, `le_max_left/right`, `div_le_div_of_nonneg_right`, `div_mul_cancel₀`, `div_le_iff₀`, `mul_le_mul_of_nonneg_left/right`, `dist_eq_zero`, `dist_nonneg`, `norm_sub_le`, `Metric.mem_ball/mem_closedBall/mem_sphere` — all standard Mathlib; verify the few risky ones: pow_le_pow_left (current name in this Mathlib version), le_of_forall_pos_le_add (not needed — using the by-cases approach), Complex.norm_natCast, Real.log_le_sub_one_of_pos.\n\nLet me grep these in Mathlib now. Then write the file.","signature":""},{"type":"text","text":"All signatures verified. Checking the last few lemma names before writing."},{"type":"tool_use","id":"Bash_23","name":"Bash","input":{"command":"M=D:/Python/Quantum/zeta-23-lean/.lake/packages/mathlib/Mathlib; grep -rn \"theorem pow_le_pow_left \\|theorem pow_le_pow_left{\" $M/Algebra/Order/*.lean $M/Algebra/Order/**/*.lean 2>/dev/null | head -3; grep -rn \"log_le_sub_one_of_pos\" $M/Analysis/SpecialFunctions/Log/Basic.lean | head -2; grep -rn \"theorem norm_natCast\\|lemma norm_natCast\" $M/Analysis/Complex/Basic.lean $M/Analysis/Normed/*.lean 2>/dev/null | head -3; grep -rn \"import Zeta23\" D:/Python/Quantum/research/lean/NguyenRH1/NguyenRH1/LiDisc.lean | head -3","description":"Verify pow_le_pow_left, log_le_sub_one, norm_natCast, LiDisc imports"},"extra_content":null}]