← Session 30 — ii′-5e squeeze capstone + 5f perimeter repair
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}]