Current task: —

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

#1367 assistant 2026-08-23 05:16:55.348 UTC · 652→12791 tok open ⤢
thinking (31994 chars)
`abs_im_le_norm` is in RCLike namespace (RCLike.abs_im_le_norm) — but since Complex is an RCLike, `Complex.abs_im_le_norm`... In StirlingVert they wrote `Complex.abs_im_le_norm w` — wait the earlier grep of StirlingVert showed `Complex.abs_im_le_norm w` at line 483-ish ("hwn : |w.im| ≤ ‖w‖ := Complex.abs_im_le_norm w"). Hmm, RCLike.Basic line 694: `theorem abs_im_le_norm (z : K)` — inside `namespace RCLike`? If so, `Complex.abs_im_le_norm` wouldn't exist unless there's an alias. But StirlingVert USED Complex.abs_im_le_norm successfully (it compiles), so it exists (maybe via `namespace Complex` re-export or the RCLike file has namespace Complex section). Whatever — it works, I've seen it used. For norm_le_abs_re_add_abs_im — didn't appear. Let me search once more; if missing, prove via normSq: ‖z‖² = re² + im² ≤ (|re| + |im|)²... or use `Complex.norm_eq_sqrt...`. Actually there might be `Complex.norm_le_abs_re_add_abs_im` in Mathlib.Analysis.Complex.Basic? grep didn't find. Alternatives: `Complex.abs_re_le_norm`, and just use: ‖z‖ ≤ |z.re| + |z.im| — prove: ‖z‖ = √(re²+im²) ≤ |re| + |im| via Real.sqrt_le...: `Complex.norm_eq_sqrt_sq_add_sq`? hmm there's `Complex.norm_eq_abs (z) : ‖z‖ = Complex.abs z`, `Complex.abs_eq_sqrt_sq_add_sq`? `Complex.sq_abs`? Let me instead use: ‖z‖ ^ 2 = re² + im² (normSq) ≤ (|re|+|im|)² and then sqrt: Real.sqrt_le_sqrt then Real.sqrt_sq (abs_nonneg)... Fine — small helper: ``` theorem norm_le_abs_re_add_abs_im' (z : ℂ) : ‖z‖ ≤ |z.re| + |z.im| := by have h : ‖z‖ ^ 2 ≤ (|z.re| + |z.im|) ^ 2 := by rw [← Complex.normSq_eq_norm_sq, Complex.normSq_apply] -- re² + im² ≤ |re|² + 2|re||im| + |im|² nlinarith [sq_abs z.re, sq_abs z.im, abs_nonneg z.re, abs_nonneg z.im, mul_nonneg (abs_nonneg z.re) (abs_nonneg z.im)] -- then via pow_le_pow_left₀? no — from a² ≤ b², b ≥ 0: a ≤ b have hb : (0:ℝ) ≤ |z.re| + |z.im| := add_nonneg (abs_nonneg _) (abs_nonneg _) -- a ≤ b from a² ≤ b²: by_contra hlt; push_neg at hlt have := pow_le_pow_left₀ (norm_nonneg _) hlt.le 2 -- ‖z‖² ≤ (..)² already have; contradiction needs strict: ... ``` Simpler: `abs_le_of_sq_le_sq'`? or `Real.sqrt_le_iff`: ‖z‖ = √(‖z‖²)... There's a standard trick: `pow_le_pow_iff_left₀`? or `le_of_pow_le_pow_left₀ (n ≠ 0) (hb) : a^n ≤ b^n → a ≤ b`: `le_of_pow_le_pow_left₀ (hn : n ≠ 0) (hb : 0 ≤ b) (h : a ^ n ≤ b ^ n) : a ≤ b` ✓ I believe this exists. Use n = 2. OK. And `sum_neg_distrib` — didn't confirm; alternative: `Finset.sum_neg_distrib`? For groups: `Finset.sum_neg_distrib : ∑ i ∈ s, -f i = -∑ i ∈ s, f i`? Hmm — maybe it's `Finset.sum_neg_distrib` in Mathlib.Algebra.BigOperators.Ring? If not: map: ∑ (−f) = −∑ f via `Finset.sum_neg_distrib` or `(Finset.sum_hom s Neg.neg)`? or simp: `simp [← Finset.sum_neg_distrib]`... Safe fallback: `Finset.sum_congr` to turn each term into −(m/(s−ρ)) then `Finset.sum_neg_distrib`; if that doesn't exist, `neg_sum`: `Finset.neg_sum : -∑ i ∈ s, f i = ∑ i ∈ s, -f i`? I'll check in Lean directly; worst case: induction-free via `Finset.sum_sub_distrib` with 0 − f: ∑ (0 − f) = ∑ 0 − ∑ f = −∑ f: `Finset.sum_sub_distrib` ✓ exists (I'm confident). ∑_{i} (0 − f i) = ∑ 0 − ∑ f = 0 − ∑ f = −∑ f; and each 0 − f i = −f i by zero_sub. Robust. OK — now let me also double check `Finset.sum_image` form in this Mathlib: journal-024: "Finset.sum_image takes Set.InjOn in this Mathlib" ✓: `Finset.sum_image (h : Set.InjOn f s) : ∑ x ∈ s.image f, g x = ∑ x ∈ s, g (f x)`? roughly ✓ (used in sum_image_zeroMult_div). `sub_left_inj : a - b = a - c ↔ b = c` ✓ standard. Also for C: nearZeros membership gives zeroDiscFinset membership + im window; zeroDisc_isNontrivial gives IsNontrivialZero (0 < re < 1 + ζ = 0). ✓ Now — one design question for §6's E1 hypothesis: digamma shift needs ∀ m : ℕ, w + ↑j ≠ −↑m at each step. With 2 ≤ |w.im|: w + j = −m (real) ⟹ im(w + j) = im w = 0, contradiction with |im w| ≥ 2 ✓. Let me also decide §6's exact final form. The design says: "the left-plane uniform digamma bound |ψ(w) − log w| ≤ C away from poles". My version: theorem norm_digamma_sub_log_le_of_two_le_im {w : ℂ} (hw : 2 ≤ |w.im|) : ‖digamma w − Complex.log w‖ ≤ 3 Hmm — wait. Is 3 achievable? Recap: ‖ψ(v) − log v‖ ≤ 1 (v = w+n, |im v| ≥ 2: 3/(im v)² ≤ 3/4, ‖1/(2v)‖ ≤ 1/(2·2) = 1/4: total ≤ 1 ✓); ‖Σ f − (log v − log w)‖ ≤ 1/2 + π/4·...: boundary (f 0 − f n)/2 ≤ (1/2)(1/2+1/2) = 1/2 ✓; B1 integral ≤ (1/2)·∫₀ⁿ ((x+a)²+c²)⁻¹ dx ≤ (1/2)·(π/c) ≤ (1/2)(π/2) = π/4 ≤ 1 (π ≤ 4 ✓). So ‖Σ f − (log v − log w)‖ ≤ 1/2 + 1 = 3/2. Total: ‖ψ w − log w‖ = ‖[ψ v − log v] − [Σ f − (log v − log w)]‖ ≤ 1 + 3/2 = 5/2 ≤ 3 ✓. Constant 3 with room to spare. Hmm wait — π/4 ≤ 1 needs π ≤ 4 ✓ (Real.pi_lt_315 : π < 3.15 ✓). But 1/2 + π/4: with π < 3.15: 0.5 + 0.7875 = 1.2875; plus 1 = 2.2875 ≤ 3 ✓ comfortable. Use 3. Actually, hmm, wait: in E4 I need ∫₀ⁿ ((x+a)²+c²)⁻¹ dx ≤ π/c where c = |im w|. Let me redo with arctan FTC: ∫₀ⁿ dx/((x+a)²+c²) = (1/c)[arctan((n+a)/c) − arctan(a/c)]. HasDerivAt (fun x => (1/c)·arctan((x+a)/c)) (1/((x+a)²+c²)) x: Real.hasDerivAt_arctan (y) : HasDerivAt arctan (1/(1+y²)) y. chain: (x+a)/c has deriv 1/c; then arctan: 1/(1+((x+a)/c)²) · (1/c); then ·(1/c): total (1/c)·(1/(1+((x+a)/c)²))·(1/c) = 1/(c²(1+(x+a)²/c²)) = 1/(c²+(x+a)²) ✓. In Lean: HasDerivAt (fun x => (x+a)/c) (1/c) x [(hasDerivAt_id x).add_const a |>.div_const c]; .arctan: `Real.HasDerivAt.arctan (hf : HasDerivAt f f' x) : HasDerivAt (fun x => arctan (f x)) (1/(1+(f x)^2) * f') x` ✓ exists (Real.HasDerivAt.arctan); .const_mul (1/c): (1/c) * (1/(1+((x+a)/c)^2) * (1/c)). Need this = 1/((x+a)^2+c^2): field_simp [c ≠ 0]: (1/c)·(1/(1+u²))·(1/c) = 1/(c²(1+u²)) and c²(1+u²) = c² + c²u² = c² + (x+a)² (c≠0) ✓ ring. Then FTC: ∫₀ⁿ 1/((x+a)²+c²) dx = (1/c)(arctan((n+a)/c) − arctan(a/c)) [intervalIntegral.integral_eq_sub_of_hasDerivAt; integrability: continuous]. Bound: (1/c)|arctan diff| ≤ (1/c)(π/2 + π/2) = π/c: |arctan x| < π/2: `Real.abs_arctan_lt_pi_div_two`? — earlier grep found `arctan_lt_pi_div_two` (Trigonometric/Arctan.lean:150). The neg side: `Real.neg_pi_div_two_lt_arctan (x) : -(π/2) < arctan x` — likely exists; else from arctan_neg: arctan x = −arctan (−x) > −(π/2). So |arctan u − arctan v| ≤ |arctan u| + |arctan v| < π/2 + π/2 = π; for ≤: ≤ π fine (use .le of each < ... to get ≤ π). Then (1/c)·π = π/c ≤ π/2 (c ≥ 2: 1/c ≤ 1/2 ⟹ π/c ≤ π/2 ✓). The integrand equality: 1/((x+a)²+c²) vs my normSq expression: ‖w + ↑x‖⁻²: ‖w + ↑x‖² = (w.re + x)² + w.im² via Complex.normSq: normSq (w + ↑x) = (w.re + x)² + (w.im)² [normSq_apply, add_re w ↑x: (w + ↑x).re = w.re + x (ofReal_re), im = w.im + 0]. And ‖z‖⁻² = (normSq z)⁻¹: normSq z = ‖z‖² (Complex.normSq_eq_norm_sq — used in LiDisc ✓) so ‖z‖⁻² = (‖z‖²)⁻¹ = (normSq z)⁻¹ = ((w.re+x)² + w.im²)⁻¹. With c² = w.im² (c = |w.im|, sq_abs). So the pointwise: ‖(w+↑x)⁻¹‖² = ‖w+↑x‖⁻² = ((x + w.re)² + |w.im|²)⁻¹·... ‖u⁻¹‖ = ‖u‖⁻¹ so ‖(w+x)⁻¹‖² = (‖w+x‖⁻¹)² = ‖w+x‖⁻² ✓. The B1-integral bound: ‖∫₀ⁿ deriv f x · B1 x dx‖ ≤ ∫₀ⁿ ‖deriv f x * B1 x‖ dx [intervalIntegral.norm_integral_le_integral_norm (zero_le n)] ≤ ∫₀ⁿ (1/2)·((x+a)²+c²)⁻¹ dx [pointwise: ‖deriv f x‖·|B1 x| ≤ ‖w+x‖⁻²·(1/2); abs_B1_le_half (0 ≤ x)] = (1/2)·∫₀ⁿ ((x+a)²+c²)⁻¹ dx [integral_mul_const... wait the integrand is REAL: ‖deriv f x * B1 x‖ where deriv f x : ℂ and B1 x : ℝ... the EM lemma's term is deriv f t * B1 t : ℂ (𝕜 = ℂ, B1 coerced? B1 t : ℝ; deriv f t * (B1 t : ℂ)? The EM lemma signature: ∫ t in a..b, deriv f t * B1 t — with f : ℝ → 𝕜 and B1 : ℝ → ℝ, the product deriv f t * B1 t needs smul or coe: RCLike 𝕜 has algebra ℝ ↪ 𝕜 so B1 t coerces ✓ (the file wrote it directly with RCLike coercion). So the integrand is deriv f t * ↑(B1 t) : ℂ, norm = ‖deriv f t‖ · |B1 t| ✓ (norm_mul, Complex.norm_real...). Pointwise deriv value: deriv (fun x : ℝ => (w + ↑x)⁻¹) x = −(w+↑x)⁻²: HasDerivAt: ((hasDerivAt_id' ...)... (w + ↑x)⁻¹ = e' (↑x) with e' z = (w + z)⁻¹: HasDerivAt e' (−(w+z)⁻²) z: hasDerivAt_inv? `HasDerivAt.inv (hf : HasDerivAt f f' x) (hx : f x ≠ 0) : HasDerivAt (fun x => (f x)⁻¹) (-(f x)⁻² * f') x`? hmm — I recall `HasDerivAt.inv (hf : HasDerivAt f f' x) (hx : f x ≠ 0) : HasDerivAt f⁻¹ (-(f x ^ 2)⁻¹ * f') x`? or `hasDerivAt_inv (hx : x ≠ 0) : HasDerivAt (·⁻¹) (-(x⁻²)) x`? For id: HasDerivAt (fun x => (w + ↑x)... I'll compose: e' = Inv.inv ∘ (w + ·): (hasDerivAt_inv-ish).comp... Let me check name: `HasDerivAt.inv` exists (f⁻¹ form). Then via comp_ofReal for the ofReal. Then .deriv gives deriv value; then ‖·‖ = ‖−(w+x)⁻²‖ = ‖w+x‖⁻² ✓. Actually for the EM application I need: hf_diff : ∀ t ∈ Icc 0 n, DifferentiableAt ℝ f t (f := fun x => (w+↑x)⁻¹) and h_cont : ContinuousOn (deriv f) [[0, n]]. Both from the HasDerivAt formula (differentiableAt from hasDerivAt; deriv f = fun x => −(w+↑x)⁻² on the interval via HasDerivAt.deriv at each point — ContinuousOn of the deriv FUNCTION: since deriv f x = −(w+↑x)⁻² pointwise EVERYWHERE (all x, not just interval), ContinuousOn from the formula's continuity: Continuous (fun x : ℝ => −(w+↑x)⁻¹...): continuous_inv₀ (fun x hx => w+↑x ≠ 0 (im ≠ 0)) ∘ (continuous_const.add continuous_ofReal...). `Complex.continuous_ofReal` ✓. Then ContinuousNeg, inv₀: `Continuous.inv₀ (hf : Continuous f) (h : ∀ x, f x ≠ 0) : Continuous f⁻¹`? hmm `Continuous.inv₀` exists ✓. Then deriv f = that function: funext over deriv eq: (hder x).deriv : deriv f x = −(w+↑x)⁻² for ALL x; then deriv f = fun x => −(w+↑x)⁻² by funext; rw; exact continuous-ness.continuousOn ✓. E1 detail — the sum in EM is Σ_{k ∈ Ioc ⌊0⌋₊ ⌊↑n⌋₊} f k = Ioc 0 n (Nat.floor_zero? ⌊(0:ℝ)⌋₊ = 0: Nat.floor_zero; ⌊(↑n:ℝ)⌋₊ = n: Nat.floor_natCast ✓). Alright — I've surveyed enough. There will be build-time fixes but the plan is solid. Let me also quickly look at the exact head of LiContour.lean to match style/imports for the new file, then start writing LiReflect.lean §1–§5 first (capstone), compile, then §6. One more check — the exact name `Complex.hasDerivAt_log` and slit plane lemma: from Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean:37: `lemma hasDerivAt_log {z : ℂ} (hz : z ∈ slitPlane) : HasDerivAt log z⁻¹ z` — in namespace Complex ✓. slitPlane membership: `Complex.mem_slitPlane_iff : z ∈ slitPlane ↔ 0 < z.re ∨ z.im ≠ 0`? — the grep showed usage `mem_slitPlane_iff` in Arg.lean — likely `Complex.mem_slitPlane_iff`. I'll use `.mpr (Or.inr him)`. Now — check what LiContour.lean imports to make sure digamma_apply_add_one etc. are available via `import Mathlib` (yes, Mathlib full import covers everything; LiDisc imports Mathlib + Zeta23.FromPNTPlus.StrongPNTPrefix + LiRBound + LiContour). For LiReflect.lean imports: Mathlib + NguyenRH1.LiDisc (which brings LiContour, LiRBound, Zeta23 StrongPNTPrefix) + Zeta23.RvM.GammaSide (logDeriv_Gammaℝ) + Zeta23.GammaFacts.StirlingVert (digamma_stirling) + Zeta23.ZetaReflect (analyticOrderAt_zeta_one_sub) + Zeta23.RvM.CountByIntegral (completedRiemannZeta_eq_Gammaℝ_mul / eq_zero_iff — probably already via LiContour? LiContour used RvM.completedRiemannZeta_eq_Gammaℝ_mul? zeroDisc_isNontrivial in LiDisc used it — so it's available via LiDisc's imports. And analyticOrderAt_zeta_one_sub is Zeta23.ZetaReflect — is it transitively imported? LiContour's zeroMult_neg_two... probably imports CountByIntegral. To be safe, import explicitly: Zeta23.ZetaReflect, Zeta23.RvM.GammaSide, Zeta23.GammaFacts.StirlingVert, Zeta23.RvM.CountByIntegral, Zeta23.FromPNTPlus.EulerMaclaurin (for B1 + sum_eq_integral_add_integral_deriv — though probably transitively via StrongPNTPrefix; explicit is safe). Also need `IsNontrivialZero` — from Zeta23.Statement (transitively imported everywhere). Now write the file. I'll write §1–§5 in one go, compile, iterate; then §6. Let me be careful about a few Lean idioms learned from journals: - bare π auto-binds: use Real.pi explicitly. - ascribe (↑x : ℂ) when needed. - field_simp may close goals (check before ring). - Finset.sum_image takes Set.InjOn. - logDeriv_apply for unfolding. Let me draft the code. ```lean /- NguyenRH1/LiReflect.lean — tier ii′ sub-stage ii′-5d (D-067 §3 left half + §6): the FE-reflection of the loose Davenport-disc R-bound (ii′-5c) to σ ∈ [−5/2, 1/2], |t| ≥ 10, plus the left-plane uniform digamma bound ‖ψ(w) − log w‖ ≤ 3 for |im w| ≥ 2 (recurrence + Euler–Maclaurin series-vs-log comparison; the 5e input). Route (D-067 §3): * Λ = ΓR·ζ and Λ(1−s) = Λ(s) give the pointwise log-derivative FE logDeriv ζ s = −logDeriv ζ (1−s) − [logDeriv ΓR s + logDeriv ΓR (1−s)]; * the near-zero sums at t and −t CANCEL EXACTLY under ρ ↦ 1−ρ (Zeta23 `analyticOrderAt_zeta_one_sub` for the multiplicities); * the ΓR-bracket is −log π + ½ψ((1−s)/2) + ½ψ((s+4)/2) − 2(s+1)/(s(s+2)) (the s-side shifted by +4 via the ΓR recurrence so both digammas sit in re > 0), each piece O(log|t|) by Zeta23 `StirlingVert.digamma_stirling`. Archive references: D-067 §3/§6, journal-024. -/ import Mathlib import Zeta23.RvM.GammaSide import Zeta23.RvM.CountByIntegral import Zeta23.GammaFacts.StirlingVert import Zeta23.ZetaReflect import Zeta23.FromPNTPlus.EulerMaclaurin import NguyenRH1.LiDisc open Zeta23 Complex Filter Topology MeasureTheory open scoped Nat noncomputable section namespace NguyenRH1 ``` §0 small helpers: ```lean /-! ## 0. Small complex helpers -/ theorem norm_le_abs_re_add_abs_im' (z : ℂ) : ‖z‖ ≤ |z.re| + |z.im| := by have hb : (0:ℝ) ≤ |z.re| + |z.im| := add_nonneg (abs_nonneg _) (abs_nonneg _) refine le_of_pow_le_pow_left₀ (two_ne_zero) hb ?_ -- check name: le_of_pow_le_pow_left₀ (hn : n ≠ 0) (hb : 0 ≤ b) (h : a ^ n ≤ b ^ n) rw [← Complex.normSq_eq_norm_sq, Complex.normSq_apply] nlinarith [sq_abs z.re, sq_abs z.im, mul_nonneg (abs_nonneg z.re) (abs_nonneg z.im)] ``` Hmm — le_of_pow_le_pow_left₀ signature: `le_of_pow_le_pow_left₀ (hn : n ≠ 0) (hb : 0 ≤ b) : a ^ n ≤ b ^ n → a ≤ b`? I think it's `le_of_pow_le_pow_left₀ (hn : n ≠ 0) (hb : 0 ≤ b) (h : a ^ n ≤ b ^ n) : a ≤ b` ✓. If not, fallback: by_contra + pow_le_pow_left₀ strict. Wait — normSq_apply : normSq z = z.re * z.re + z.im * z.im? and goal after rw: z.re * z.re + z.im * z.im ≤ (|z.re| + |z.im|)^2 — nlinarith with sq_abs (|a|² = a²... sq_abs : |a|^2 = a^2) and nonneg of the cross term ✓. - im helpers: ```lean theorem im_ne_zero_of_abs_im_ge {z : ℂ} (h : 2 ≤ |z.im|) : z.im ≠ 0 := by intro hz; rw [hz, abs_zero] at h; norm_num at h ``` Hmm — or just (abs_nonneg).trans_lt... |z.im| ≥ 2 > 0 ⟹ z.im ≠ 0: fun hz => by rw [hz] at h; simp at h. I'll inline as needed. Let me now write §1 (ΓR shift). Actually — I realize I should double check `Complex.Gammaℝ_def` exact form: from logDeriv_Gammaℝ's proof: `Complex.Gammaℝ_def : Gammaℝ s = (Real.pi : ℂ) ^ (-s / 2) * Complex.Gamma (s / 2)` — they wrote `Complex.Gammaℝ = fun s => (Real.pi : ℂ) ^ (-s / 2) * Complex.Gamma (s / 2)` via funext Gammaℝ_def, so Gammaℝ_def : Gammaℝ s = (Real.pi:ℂ)^(−s/2) * Gamma (s/2) ✓ (namespace Complex; with open Complex: Gammaℝ_def). And `Complex.Gamma_add_one (s : ℂ) (hs : s ≠ 0) : Gamma (s + 1) = s * Gamma s` — from digamma_apply_add_one's proof usage `Gamma_add_one s hs0` inside namespace Complex ✓. Now write the full §1–§5. Let me think about the trickiest proof steps once more: **gammaR_shift**: ``` theorem gammaR_shift {s : ℂ} (hs : s.im ≠ 0) : Complex.Gammaℝ s = (Real.pi : ℂ) ^ 2 * Complex.Gammaℝ (s + 4) / ((s / 2) * (s / 2 + 1)) := by have hs0 : s ≠ 0 := fun h => hs (by rw [h]; simp) -- im 0 = 0: Complex.zero_im? simp: (0 : ℂ).im = 0 ✓ have hs2 : s / 2 ≠ 0 := fun h => hs0 (by ... ) -- s/2 = 0 ⟹ s = 0: div_eq_zero_iff... s/2 = 0 → s = 0: mul? s = 2*(s/2) = 0: by field_simp? simplest: fun h => hs0 (by have := congrArg (· * 2) h; ... ) — or: div_ne_zero hs0 two_ne_zero: `div_ne_zero (ha : a ≠ 0) (hb : b ≠ 0) : a / b ≠ 0` ✓. have hs21 : s / 2 + 1 ≠ 0 := fun h => hs (by have := congrArg Complex.im h; simp [add_im, div_im, ofReal_im...] at this; ...) ``` Hmm im(s/2 + 1) = s.im / 2: (s/2 + 1).im = (s/2).im + (1:ℂ).im = (s/2).im = s.im/2: simp [add_im, div_re...]: the simp set: add_im, one_im, div_re... for (s/2).im: s/2 = s * (1/2): hmm. Cleaner: s/2 = (s.re/2) + (s.im/2)I... The robust pattern from LiDisc: `have him : (s/2 + 1).im = s.im / 2 := by simp [div_re, div_im, add_im, ofReal_re, ofReal_im]...` hmm — actually (s / 2) with 2 : ℂ: div_im : (a / b).im = (a.re * b.im + a.im * b.re) / (b.re^2 + b.im^2)? There's `Complex.div_im : (x / y).im = (x.im * y.re - x.re * y.im) / (y.re^2 + y.im^2)`? whatever — simp [Complex.div_im, Complex.div_re, ofReal_re, ofReal_im] should evaluate (s/2).im = s.im / 2. LiDisc line 1008 pattern: `simp [discCenter, sub_re, add_re, mul_re, ofReal_re, ofReal_im, I_re, I_im]`. For division by a real cast: there are simp lemmas `Complex.ofReal_div_re`? Let me avoid the guesswork: write s / 2 = s * (2 : ℂ)⁻¹ and use mul_im: (s * (2:ℂ)⁻¹).im = s.re * (2⁻¹).im + s.im * (2⁻¹).re = s.im * (1/2) — simp [mul_im, inv_re, inv_im, ofReal_re, ofReal_im]: (2:ℂ)⁻¹.re = 1/2: inv_re: (z⁻¹).re = z.re / (normSq z): (2)⁻¹.re = 2/(4) = 1/2 — simp should do with norm_num. OK — in practice: `by simp [Complex.div_re, Complex.div_im]` often handles x/2; or just compute via `Complex.ext_iff` approach... I'll write `have him2 : (s / 2).im = s.im / 2 := by simp [Complex.div_im, Complex.div_re]; ring`? risky. Alternative bulletproof: field_simp-free: (s/2 + 1) ≠ 0: suppose = 0: then s/2 = −1: s = −2: then s.im = (−2).im = 0 contra. s = −2 from s/2 = −1: by_contra... simplest: ``` have hs21 : s / 2 + 1 ≠ 0 := by intro h have h1 : s / 2 = -1 := eq_neg_of_add_eq_zero_left h -- `eq_neg_of_add_eq_zero_left : a + b = 0 → a = -b` ✓ have h2 : s = -2 := by have := congrArg (· * (2:ℂ)) h1 -- (s/2)*2 = s rw [div_mul_cancel₀ s (two_ne_zero : (2:ℂ) ≠ 0)] at this -- div_mul_cancel₀ (a) (hb : b ≠ 0) : a / b * b = a ✓ -- this : s = -1 * 2 rw [this]; ring -- hmm: goal s = -2 from this : s = -1 * 2: exact this.trans (by ring)? no: this says s = −1*2 = −2: `norm_num at this`? or rw [this]; norm_num exact hs (by rw [h2]; simp) -- (-2 : ℂ).im = 0: simp: neg_im, ofReal_im — ((-2):ℂ).im = 0 ✓ simp should handle: `simp` knows ((-2):ℂ) = -(2:ℂ)? norm_num1... I'll use: rw [h2] at ⊢; exact hs (by simp : (-2:ℂ).im = 0 ▸ ...) — meh. Directly: hs : s.im ≠ 0; rw [h2] at hs; simp at hs ✓ (simp at hs derives False from ((−2):ℂ).im ≠ 0 — simp computes (−2:ℂ).im = 0, contradiction ✓). ``` OK these little ≠ 0 proofs: im(s/2+1) = s.im/2 approach vs algebraic approach — algebraic is more verbose but robust. I'll go algebraic: - hs0 : s ≠ 0 — from im ≠ 0: `fun h => hs (h ▸ Complex.zero_im)`? h : s = 0: s.im = 0: by rw [h]; exact Complex.zero_im... `Complex.zero_im : (0:ℂ).im = 0`? simp lemma. `fun h => hs (by rw [h]; simp)` ✓. - hs2 : s/2 ≠ 0 := div_ne_zero hs0 (by norm_num) ✓. - hs21 : s/2 + 1 ≠ 0: via h1 : s/2 = −1 from add_eq_zero... `eq_neg_of_add_eq_zero_left (h : a + b = 0) : a = −b` ✓; then s = −2 as above; then im contradiction. Robust ✓. Then the main identity: ``` have hGamma : Complex.Gamma (s / 2 + 2) = (s / 2 + 1) * (s / 2) * Complex.Gamma (s / 2) := by rw [Complex.Gamma_add_one (s / 2 + 1) hs21, Complex.Gamma_add_one (s / 2) hs2]; ring ``` ✓ (Gamma_add_one (s/2+1) hs21 : Gamma (s/2+1+1) = (s/2+1)*Gamma(s/2+1); note s/2+2 = s/2+1+1 by ring — need a `show Complex.Gamma (s/2+1+1) = ...` bridge: rw under binder: convert? Use: `have h1 := Complex.Gamma_add_one (s/2 + 1) hs21` : Gamma (s/2+1+1) = ...; rw [show s/2 + 2 = s/2 + 1 + 1 by ring]; rw [h1, Complex.Gamma_add_one (s/2) hs2]; ring ✓. ``` have hpi : ((Real.pi : ℂ) ^ (-(s + 4) / 2)) = (Real.pi : ℂ) ^ (-s / 2) * ((Real.pi ^ 2 : ℝ)⁻¹ : ℂ) := by rw [Complex.cpow_def_of_ne_zero (by exact_mod_cast Real.pi_ne_zero : (Real.pi:ℂ) ≠ 0) _, Complex.cpow_def_of_ne_zero ... _] ``` hmm — cpow_def_of_ne_zero (hx : x ≠ 0) (y : ℂ) : x ^ y = exp (log x * y). So: (π:ℂ)^(−(s+4)/2) = exp (log π * (−(s+4)/2)); log (π:ℂ) = ↑(Real.log π) [Complex.ofReal_log Real.pi_nonneg — ofReal_log (hx : 0 ≤ x) : (↑(Real.log x) : ℂ)... wait the statement from grep: `theorem ofReal_log {x : ℝ} (hx : 0 ≤ x) : (x.log : ℂ) = log x` — i.e., ↑(Real.log x) = Complex.log ↑x ✓ use .symm]. Then exp (↑logπ * (−(s+4)/2)) = exp (↑logπ * (−s/2) + ↑(−2 * logπ)) [by ring_nf / push_cast: ↑(−2*logπ) vs ↑logπ * (−2): push_cast; ring ✓] = exp(↑logπ*(−s/2)) * exp(↑(−2*logπ)) [exp_add] = (π:ℂ)^(−s/2) * ↑(Real.exp (−2 * Real.log π)) [← cpow_def_of_ne_zero, ← Complex.ofReal_exp] and Real.exp (−2 * log π) = (π²)⁻¹: Real.exp (−2 * Real.log π) = (Real.pi ^ 2)⁻¹: have : (−2) * Real.log π = Real.log ((Real.pi ^ 2)⁻¹) := by rw [Real.log_inv, Real.log_pow]; ring ✓ (Real.log_pow : log (x^n) = n * log x ✓, Real.log_inv : log x⁻¹ = − log x ✓). rw [this, Real.exp_log (inv_pos.mpr (pow_pos Real.pi_pos 2))] ✓. So: ``` have hexp2 : Real.exp (-2 * Real.log Real.pi) = (Real.pi ^ 2)⁻¹ := by have h1 : (-2 : ℝ) * Real.log Real.pi = Real.log ((Real.pi ^ 2)⁻¹) := by rw [Real.log_inv, Real.log_pow]; push_cast; ring rw [h1, Real.exp_log (by positivity)] ``` Real.log_pow : Real.log (x ^ n) = ↑n * Real.log x ✓. Then −2 * log π = −(2 * log π) and log (π²)⁻¹ = −(2 * log π) ✓ ring after the rewrites. Then: ``` have hmain : Complex.Gammaℝ (s + 4) = ((Real.pi ^ 2 : ℝ)⁻¹ : ℂ) * ((s / 2) * (s / 2 + 1)) * Complex.Gammaℝ s := by rw [Complex.Gammaℝ_def, Complex.Gammaℝ_def] -- ΓR(s+4) = π^{−(s+4)/2} Γ((s+4)/2); ΓR s = π^{−s/2} Γ(s/2) rw [show (s + 4) / 2 = s / 2 + 2 by ring, hGamma, hpi] -- goal: π^{−s/2} * ↑(π²)⁻¹ * ((s/2+1)*(s/2)*Γ(s/2)) = ↑(π²)⁻¹ * ((s/2)(s/2+1)) * (π^{−s/2} * Γ(s/2)) ring ``` Hmm wait — Gammaℝ_def applied to (s+4) gives exponent −(s+4)/2 and Gamma ((s+4)/2) ✓. And −(s+4)/2 vs my hpi's −(s+4)/2 ✓ match. After rewrites: LHS = [π^{−s/2} * ↑(π²)⁻¹] * [(s/2+1)*(s/2)*Γ(s/2)]; RHS = ↑(π²)⁻¹ * (s/2*(s/2+1)) * [π^{−s/2} * Γ(s/2)] — ring ✓ (commutative). Then conclude: ``` -- divide: Gammaℝ s = (π:ℂ)^2 * Gammaℝ (s+4) / P where P = (s/2)(s/2+1) have hP : (s / 2) * (s / 2 + 1) ≠ 0 := mul_ne_zero hs2 hs21 have hC : ((Real.pi ^ 2 : ℝ)⁻¹ : ℂ) ≠ 0 := by exact_mod_cast inv_ne_zero (pow_ne_zero 2 Real.pi_ne_zero) -- hmm: ((π²)⁻¹ : ℝ) ≠ 0 → cast ≠ 0: ofReal_ne_zero.mpr ✓ field_simp [hmain] -- goal: ΓR s = π² * ΓR(s+4) / P; from hmain: ΓR(s+4) = C * P * ΓR s, C⁻¹ = π² ``` Risky. More controlled: ``` rw [eq_div_iff hP] -- goal: Gammaℝ s * P = (π:ℂ)^2 * Gammaℝ (s+4) rw [hmain] -- ΓR s * P = π² * (C * P * ΓR s) -- π² * C = 1: (↑(π²)⁻¹)... (π:ℂ)^2 * ((π²:ℝ)⁻¹ : ℂ) = 1 have hpi2 : (Real.pi : ℂ) ^ 2 * ((Real.pi ^ 2 : ℝ)⁻¹ : ℂ) = 1 := by push_cast rw [mul_inv_cancel₀ (pow_ne_zero 2 Real.pi_ne_zero)] -- then: π² * (C * P * ΓR s) = (π² * C) * (ΓR s * P) = ΓR s * P calc Complex.Gammaℝ s * ((s/2)*(s/2+1)) = (Real.pi:ℂ)^2 * (((Real.pi^2:ℝ)⁻¹:ℂ) * ((s/2)*(s/2+1)) * Complex.Gammaℝ s) := by rw [hpi2]... ``` hmm direction: I want ΓR s * P = π² * ΓR (s+4). rw [hmain] changes ΓR (s+4) to C*P*ΓR s: goal ΓR s * P = π² * (C * P * ΓR s). Then: π² * (C * P * ΓR s) = (π² * C) * (ΓR s * P) [ring] = 1 * (ΓR s * P) [hpi2] = ΓR s * P [one_mul] ✓: ``` rw [hmain] calc Complex.Gammaℝ s * ((s/2)*(s/2+1)) = ((Real.pi:ℂ)^2 * ((Real.pi^2:ℝ)⁻¹:ℂ)) * (Complex.Gammaℝ s * ((s/2)*(s/2+1))) := by rw [hpi2, one_mul] _ = (Real.pi:ℂ)^2 * (((Real.pi^2:ℝ)⁻¹:ℂ) * ((s/2)*(s/2+1)) * Complex.Gammaℝ s) := by ring ``` ✓ (note calc with mixed — fine). Actually eq_div_iff signature: `eq_div_iff (hc : c ≠ 0) : a = b / c ↔ a * c = b` ✓. **logDeriv_congr**: ``` theorem logDeriv_congr {f g : ℂ → ℂ} {s : ℂ} (h : f =ᶠ[𝓝 s] g) : logDeriv f s = logDeriv g s := by simp only [logDeriv_apply, h.deriv_eq, h.eq_of_nhds] ``` ✓ (logDeriv_apply : logDeriv f x = deriv f x / f x — from Mathlib LogDeriv.lean: `logDeriv_apply` simp only in their proofs ✓). **logDeriv_Gammaℝ_shift**: ``` theorem logDeriv_Gammaℝ_shift {s : ℂ} (hs : s.im ≠ 0) : logDeriv Complex.Gammaℝ s = logDeriv Complex.Gammaℝ (s + 4) - 2 * (s + 1) / (s * (s + 2)) := by have hU : IsOpen {z : ℂ | z.im ≠ 0} := isOpen_ne_fun Complex.continuous_im continuous_const -- the EventuallyEq have hEv : Complex.Gammaℝ =ᶠ[𝓝 s] fun z => (Real.pi : ℂ) ^ 2 * Complex.Gammaℝ (z + 4) / ((z / 2) * (z / 2 + 1)) := by filter_upwards [hU.mem_nhds hs] with z hz using gammaR_shift hz rw [logDeriv_congr hEv] -- nonzero facts at s have hs0 : s ≠ 0 := ... have hs2 : s / 2 ≠ 0 := ... have hs21 : s / 2 + 1 ≠ 0 := ... have hG4 : Complex.Gammaℝ (s + 4) ≠ 0 := by -- im(s+4) = s.im ≠ 0 ⟹ not of the form −2n intro h rw [Complex.Gammaℝ_eq_zero_iff] at h obtain ⟨n, hn⟩ := h apply hs -- im(s+4) = im(−2n) = 0 ⟹ im s = 0 have him : (s + 4).im = ((-2 : ℝ) * (n : ℝ) : ℂ).im := by rw [hn] -- hn : s + 4 = −2 * ↑n simp [add_im, ofReal_im, mul_im...] at him -- (s+4).im = s.im; RHS im = 0 exact him ... ``` Hmm — hn : s + 4 = −2 * ↑n where the RHS: the Gammaℝ_eq_zero_iff : Gammaℝ s = 0 ↔ ∃ n : ℕ, s = -2 * n? the exact form from zeroDisc_isNontrivial: after rw they got `hre' : ρ.re = -2 * (n:ℝ)` by `rw [hn]; simp [neg_re, mul_re]` — so hn : ρ = -2 * (n : ℂ)? with −2 * ↑n : ℂ ✓. So ((−2:ℂ) * ↑n).im = 0: simp [neg_mul, mul_im, ofReal_re, ofReal_im, natCast_re, natCast_im] — should close: (−2 * ↑n).im = (−2).re * (↑n).im + ... simp with mul_im, neg_re, ofReal_im, natCast_im (Nat.cast im = 0) ✓ norm_num-ish. Let me write: `have : (s + 4).im = 0 := by rw [hn]; simp` then `(s+4).im = s.im`: simp [add_im] → s.im + (4:ℂ).im = s.im: `Complex.add_im : (x+y).im = x.im + y.im`, (4:ℂ).im = 0 via ofReal? 4 = ((4:ℝ):ℂ)? simp should know (4:ℂ).im = 0 via `Complex.ofReal_im` after norm_num cast lemmas... risk. Alternative bulletproof: from h : s + 4 = −2*↑n get s = −2*↑n − 4 (by linarith? no — complex: eq_sub_of_add_eq... just: s = (s+4) − 4 = −2↑n − 4); then s.im = (−2↑n − 4).im = 0: rw [this] at hs; simp at hs: (−2*↑n − 4 : ℂ).im: sub_im, mul_im, neg_re... simp [Complex.sub_im, Complex.mul_im] with ofReal_im, natCast_im, neg_im: all real components have im 0 ⟹ total 0 ⟹ hs : (0:ℝ) ≠ 0? no — hs becomes (…).im ≠ 0 = 0 ≠ 0 after simp computes im = 0 ⟹ contradiction: simp at hs should close False. I'll write `rw [show s = -2 * (n:ℂ) - 4 from by rw [← hn]; ring] at hs; simp at hs` and hope simp computes the im of that expression to 0. simp set for im computations: Complex.sub_im, Complex.neg_im, Complex.mul_im, Complex.ofReal_im, Complex.natCast_im, Complex.neg_re... The default simp set includes Complex.?. Actually many Complex re/im lemmas are @[simp]: sub_im, add_im, mul_im, mul_re, neg_im, neg_re, ofReal_im, ofReal_re, natCast_im, natCast_re, intCast_im, intCast_re, I_im, I_re are all simp. So `simp at hs` with hs : (−2 * ↑n − 4 : ℂ).im ≠ 0 should simplify (−2*↑n−4).im to 0 via the simp set and close by contradiction ✓ confident. Then: ``` -- logDeriv via div/mul rules have hdG4 : DifferentiableAt ℂ Complex.Gammaℝ (s + 4) := differentiableAt_Gammaℝ_of_im_ne_zero' (by ... im(s+4) = s.im ≠ 0 ...) ``` Wait — I decided to write my own differentiableAt_Gammaℝ_of_im_ne_zero in namespace NguyenRH1 (to avoid the heavy XiPrime.Hardy.Basic import). Its proof needs `half_ne_neg_nat`-style: ∀ m : ℕ, s/2 ≠ −↑m: if s/2 = −↑m then im(s/2) = 0; im(s/2) = s.im/2 ≠ 0. Via: intro m h; apply hs; ... (s/2).im = 0 from h: rw [h] — need (s/2).im = s.im/2 FIRST. So I do need the div-im computation. Let me just prove the small lemma: ``` theorem im_div_two (s : ℂ) : (s / 2).im = s.im / 2 := by rw [Complex.div_im] -- (x/y).im = ? exact formula simp -- with ofReal_re, ofReal_im, normSq... ``` Complex.div_im : (x / y).im = (x.im * y.re − x.re * y.im) / (y.re ^ 2 + y.im ^ 2)? I believe `Complex.div_im (x y : ℂ) : (x / y).im = (x.im * y.re - x.re * y.im) / (y.re^2 + y.im^2)`? or via normSq: / normSq y. For y = 2: (s.im * 2 − s.re * 0)/(4 + 0) = s.im * 2/4 = s.im/2: `simp [Complex.div_im]; ring`? After rw [Complex.div_im]: goal (s.im * (2:ℂ).re − s.re * (2:ℂ).im)/((2:ℂ).re^2 + (2:ℂ).im^2) = s.im/2: simp [ofReal_re, ofReal_im] → (s.im * 2 − 0)/(4) = s.im/2: ring... wait (2:ℂ).re: 2 : ℂ is OfNat.ofReal? simp lemmas `Complex.ofNat_re`? There are simp lemmas for numeral re/im (OfNat.ofReal? in Lean4 Mathlib numerals in ℂ are `OfNat.ofNat` and there are simp lemmas `Complex.ofNat_re`, `Complex.ofNat_im`? hmm — there ARE: `Complex.ofNat_re : (OfNat.ofNat n : ℂ).re = ...`? I recall `Complex.ofNat_re`/`Complex.ofNat_im` exist as simp. If not, `show (s / ((2:ℝ):ℂ)).im = ...` conversion: (2:ℂ) = ((2:ℝ):ℂ) by norm_num (OfNat.ofReal? `Complex.ofReal_ofNat`? `Complex.ofReal_ofNat : ((OfNat.ofNat n : ℝ) : ℂ) = OfNat.ofNat n`? exists as simp). Then ((r:ℝ):ℂ) division: `Complex.ofReal_div_re`? : ((x / ↑r).re = x.re / r)? there's `Complex.ofReal_div_re : (x / ↑r).re = x.re / r` and `Complex.ofReal_div_im : (x / ↑r).im = x.im / r` — I THINK these exist (they're in Data/Complex/Basic or Exponential?). Hmm. Safest: use the mul form: s/2 = s * (2:ℂ)⁻¹: im_div_two: (s/2).im: rw [div_eq_mul_inv, Complex.mul_im]: = s.re * (2:ℂ)⁻¹.im + s.im * (2:ℂ)⁻¹.re. (2:ℂ)⁻¹ = ((1/2 : ℝ):ℂ): `show (2:ℂ)⁻¹ = ((1/2:ℝ):ℂ) by rw [Complex.ofReal_inv]... ` hmm: Complex.ofReal_inv : (↑r)⁻¹ = ↑(r⁻¹) ✓ exists. So (2:ℂ)⁻¹ = ↑(1/2): (2:ℂ) = ↑(2:ℝ) (norm_num / push_cast), inv: ↑(2⁻¹) = ↑(1/2) ✓. Then mul_im with ofReal: s.re * 0 + s.im * (1/2) = s.im/2 ✓ ring. Let me write it as: ``` theorem im_div_two (s : ℂ) : (s / 2).im = s.im / 2 := by have h2 : (2 : ℂ) = ((2 : ℝ) : ℂ) := by norm_num rw [h2, Complex.div_eq... ``` hmm — actually simplest: `(s/2).im`: note s/2 = s * ↑((1:ℝ)/2): `div_eq_mul_inv`; (2:ℂ)⁻¹: rw [← Complex.ofReal_ofNat? ...]. You know what, let me check if `Complex.ofNat_im`/`ofNat_re` exist, and `Complex.div_im` formula — quick grep. Also `Complex.ofReal_div_im`. Actually, easier idea: avoid im-division entirely using ext-free algebraic arguments: - s/2 ≠ 0: div_ne_zero ✓ no im needed. - s/2 + 1 ≠ 0: algebraic (shown above) ✓ no im needed. - s/2 ≠ −↑m: suppose s/2 = −↑m: then s = −2↑m: s.im = 0 contra: s = 2*(s/2) = 2*(−↑m) = −2↑m: rw [this] at hs; simp at hs ✓ algebraic ✓. - im(s + 4) = s.im: simp [add_im] + numeral im = 0: hmm same numeral issue: (4:ℂ).im = 0. If ofNat_im is simp: fine. Else: (4:ℂ) = ((4:ℝ):ℂ) by norm_num (push_cast handles). I'll assume simp handles (I saw `ofReal_im` used with numerals in LiDisc line 1008: `simp [discCenter, sub_re, add_re, mul_re, ofReal_re, ofReal_im, I_re, I_im]` computed (ρ − discCenter t).re = ρ.re − 2 where discCenter has `2 + t * I` with 2 : ℂ — that simp call worked with the numeral re — so numerals' re/im ARE simp-computable in this environment ✓ good, `simp [add_im]` will give (s+4).im = s.im + 0 = s.im). For (s/2).im I'll test `by simp [Complex.div_im]; ring` fallback the inv route. Actually — wait, even simpler: I can sidestep im(s/2) by choosing the shift identity in the form avoiding division-im needs... no — half_ne_neg_nat needs it. Alternative for half_ne_neg_nat: ∀ m, s/2 ≠ −↑m algebraically (shown above: s = −2↑m ⟹ s.im = 0 via simp on (−2*↑m : ℂ).im — mul_im, natCast_im ✓ no division-im needed!) ✓. So I only need im computations for: (s+4).im = s.im [simp [add_im] ✓], (1−s).im = −t [simp [sub_im, hsim] ✓ one_im], (s/2) nowhere. And in D: w₁ = (1−s)/2 im = −t/2, w₂ = (s+4)/2 im = t/2 — NEEDED for the digamma_stirling hypothesis |im w| ≥ 1/2 and the 3/(im)² bound. Hmm! So I DO need im((1−s)/2) = −t/2 etc. So the div-im computation is needed. Let me nail it: `(x / 2).im = x.im / 2`: ``` theorem im_div_two (x : ℂ) : (x / 2).im = x.im / 2 := by rw [div_eq_mul_inv, Complex.mul_im] have : ((2 : ℂ)⁻¹).im = 0 ∧ ((2 : ℂ)⁻¹).re = 1 / 2 := by rw [show (2:ℂ) = ((2:ℝ):ℂ) by norm_num, ← Complex.ofReal_inv] constructor · rw [Complex.ofReal_im] -- (↑(2⁻¹)).im = 0... wait after ← ofReal_inv: ↑(2:ℝ)⁻¹ = ↑((2:ℝ)⁻¹): (2:ℝ)⁻¹ as real = 1/2: norm_num ... ``` getting long. Try: ``` theorem im_div_two (x : ℂ) : (x / 2).im = x.im / 2 := by rw [Complex.div_im] simp only [ofNat_re, ofNat_im, mul_zero, sub_zero, ofReal_re? ...] ``` Let me just grep the exact simp lemma names for numeral re/im and div_im formula.
A few last name checks for numeral re/im simp lemmas and `div_im`.
tool: Bash
input
{
  "command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem div_im\\|theorem div_re \\|ofNat_im\\|ofNat_re\" Mathlib/Data/Complex/Basic.lean Mathlib/Analysis/Complex/Basic.lean Mathlib/Data/Complex/Exponential.lean 2>/dev/null | head -8 && grep -rn \"ofReal_div_im\\|ofReal_div_re\\|theorem ofReal_im\\|theorem ofReal_re\" Mathlib/Data/Complex/Basic.lean 2>/dev/null | head -6",
  "description": "Find div_im and numeral re/im simp lemmas"
}
raw content_json (database row)
[{"type":"thinking","thinking":"`abs_im_le_norm` is in RCLike namespace (RCLike.abs_im_le_norm) — but since Complex is an RCLike, `Complex.abs_im_le_norm`... In StirlingVert they wrote `Complex.abs_im_le_norm w` — wait the earlier grep of StirlingVert showed `Complex.abs_im_le_norm w` at line 483-ish (\"hwn : |w.im| ≤ ‖w‖ := Complex.abs_im_le_norm w\"). Hmm, RCLike.Basic line 694: `theorem abs_im_le_norm (z : K)` — inside `namespace RCLike`? If so, `Complex.abs_im_le_norm` wouldn't exist unless there's an alias. But StirlingVert USED Complex.abs_im_le_norm successfully (it compiles), so it exists (maybe via `namespace Complex` re-export or the RCLike file has namespace Complex section). Whatever — it works, I've seen it used.\n\nFor norm_le_abs_re_add_abs_im — didn't appear. Let me search once more; if missing, prove via normSq: ‖z‖² = re² + im² ≤ (|re| + |im|)²... or use `Complex.norm_eq_sqrt...`. Actually there might be `Complex.norm_le_abs_re_add_abs_im` in Mathlib.Analysis.Complex.Basic? grep didn't find. Alternatives: `Complex.abs_re_le_norm`, and just use: ‖z‖ ≤ |z.re| + |z.im| — prove: ‖z‖ = √(re²+im²) ≤ |re| + |im| via Real.sqrt_le...: `Complex.norm_eq_sqrt_sq_add_sq`? hmm there's `Complex.norm_eq_abs (z) : ‖z‖ = Complex.abs z`, `Complex.abs_eq_sqrt_sq_add_sq`? `Complex.sq_abs`? Let me instead use: ‖z‖ ^ 2 = re² + im² (normSq) ≤ (|re|+|im|)² and then sqrt: Real.sqrt_le_sqrt then Real.sqrt_sq (abs_nonneg)... Fine — small helper:\n```\ntheorem norm_le_abs_re_add_abs_im' (z : ℂ) : ‖z‖ ≤ |z.re| + |z.im| := by\n  have h : ‖z‖ ^ 2 ≤ (|z.re| + |z.im|) ^ 2 := by\n    rw [← Complex.normSq_eq_norm_sq, Complex.normSq_apply]\n    -- re² + im² ≤ |re|² + 2|re||im| + |im|²\n    nlinarith [sq_abs z.re, sq_abs z.im, abs_nonneg z.re, abs_nonneg z.im, mul_nonneg (abs_nonneg z.re) (abs_nonneg z.im)]\n  -- then via pow_le_pow_left₀? no — from a² ≤ b², b ≥ 0: a ≤ b\n  have hb : (0:ℝ) ≤ |z.re| + |z.im| := add_nonneg (abs_nonneg _) (abs_nonneg _)\n  -- a ≤ b from a² ≤ b²: \n  by_contra hlt; push_neg at hlt\n  have := pow_le_pow_left₀ (norm_nonneg _) hlt.le 2  -- ‖z‖² ≤ (..)² already have; contradiction needs strict: \n  ...\n```\nSimpler: `abs_le_of_sq_le_sq'`? or `Real.sqrt_le_iff`: ‖z‖ = √(‖z‖²)... There's a standard trick: `pow_le_pow_iff_left₀`? or `le_of_pow_le_pow_left₀ (n ≠ 0) (hb) : a^n ≤ b^n → a ≤ b`: `le_of_pow_le_pow_left₀ (hn : n ≠ 0) (hb : 0 ≤ b) (h : a ^ n ≤ b ^ n) : a ≤ b` ✓ I believe this exists. Use n = 2.\n\nOK. And `sum_neg_distrib` — didn't confirm; alternative: `Finset.sum_neg_distrib`? For groups: `Finset.sum_neg_distrib : ∑ i ∈ s, -f i = -∑ i ∈ s, f i`? Hmm — maybe it's `Finset.sum_neg_distrib` in Mathlib.Algebra.BigOperators.Ring? If not: map: ∑ (−f) = −∑ f via `Finset.sum_neg_distrib` or `(Finset.sum_hom s Neg.neg)`? or simp: `simp [← Finset.sum_neg_distrib]`... Safe fallback: `Finset.sum_congr` to turn each term into −(m/(s−ρ)) then `Finset.sum_neg_distrib`; if that doesn't exist, `neg_sum`: `Finset.neg_sum : -∑ i ∈ s, f i = ∑ i ∈ s, -f i`? I'll check in Lean directly; worst case: induction-free via `Finset.sum_sub_distrib` with 0 − f: ∑ (0 − f) = ∑ 0 − ∑ f = −∑ f: `Finset.sum_sub_distrib` ✓ exists (I'm confident). ∑_{i} (0 − f i) = ∑ 0 − ∑ f = 0 − ∑ f = −∑ f; and each 0 − f i = −f i by zero_sub. Robust.\n\nOK — now let me also double check `Finset.sum_image` form in this Mathlib: journal-024: \"Finset.sum_image takes Set.InjOn in this Mathlib\" ✓: `Finset.sum_image (h : Set.InjOn f s) : ∑ x ∈ s.image f, g x = ∑ x ∈ s, g (f x)`? roughly ✓ (used in sum_image_zeroMult_div).\n\n`sub_left_inj : a - b = a - c ↔ b = c` ✓ standard.\n\nAlso for C: nearZeros membership gives zeroDiscFinset membership + im window; zeroDisc_isNontrivial gives IsNontrivialZero (0 < re < 1 + ζ = 0). ✓\n\nNow — one design question for §6's E1 hypothesis: digamma shift needs ∀ m : ℕ, w + ↑j ≠ −↑m at each step. With 2 ≤ |w.im|: w + j = −m (real) ⟹ im(w + j) = im w = 0, contradiction with |im w| ≥ 2 ✓.\n\nLet me also decide §6's exact final form. The design says: \"the left-plane uniform digamma bound |ψ(w) − log w| ≤ C away from poles\". My version: \n\ntheorem norm_digamma_sub_log_le_of_two_le_im {w : ℂ} (hw : 2 ≤ |w.im|) : ‖digamma w − Complex.log w‖ ≤ 3\n\nHmm — wait. Is 3 achievable? Recap: ‖ψ(v) − log v‖ ≤ 1 (v = w+n, |im v| ≥ 2: 3/(im v)² ≤ 3/4, ‖1/(2v)‖ ≤ 1/(2·2) = 1/4: total ≤ 1 ✓); ‖Σ f − (log v − log w)‖ ≤ 1/2 + π/4·...: boundary (f 0 − f n)/2 ≤ (1/2)(1/2+1/2) = 1/2 ✓; B1 integral ≤ (1/2)·∫₀ⁿ ((x+a)²+c²)⁻¹ dx ≤ (1/2)·(π/c) ≤ (1/2)(π/2) = π/4 ≤ 1 (π ≤ 4 ✓). So ‖Σ f − (log v − log w)‖ ≤ 1/2 + 1 = 3/2. Total: ‖ψ w − log w‖ = ‖[ψ v − log v] − [Σ f − (log v − log w)]‖ ≤ 1 + 3/2 = 5/2 ≤ 3 ✓. Constant 3 with room to spare. Hmm wait — π/4 ≤ 1 needs π ≤ 4 ✓ (Real.pi_lt_315 : π < 3.15 ✓). But 1/2 + π/4: with π < 3.15: 0.5 + 0.7875 = 1.2875; plus 1 = 2.2875 ≤ 3 ✓ comfortable. Use 3.\n\nActually, hmm, wait: in E4 I need ∫₀ⁿ ((x+a)²+c²)⁻¹ dx ≤ π/c where c = |im w|. Let me redo with arctan FTC:\n∫₀ⁿ dx/((x+a)²+c²) = (1/c)[arctan((n+a)/c) − arctan(a/c)].\nHasDerivAt (fun x => (1/c)·arctan((x+a)/c)) (1/((x+a)²+c²)) x:\n  Real.hasDerivAt_arctan (y) : HasDerivAt arctan (1/(1+y²)) y.\n  chain: (x+a)/c has deriv 1/c; then arctan: 1/(1+((x+a)/c)²) · (1/c); then ·(1/c): total (1/c)·(1/(1+((x+a)/c)²))·(1/c) = 1/(c²(1+(x+a)²/c²)) = 1/(c²+(x+a)²) ✓.\n  In Lean: HasDerivAt (fun x => (x+a)/c) (1/c) x [(hasDerivAt_id x).add_const a |>.div_const c]; .arctan: `Real.HasDerivAt.arctan (hf : HasDerivAt f f' x) : HasDerivAt (fun x => arctan (f x)) (1/(1+(f x)^2) * f') x` ✓ exists (Real.HasDerivAt.arctan); .const_mul (1/c): (1/c) * (1/(1+((x+a)/c)^2) * (1/c)). Need this = 1/((x+a)^2+c^2): field_simp [c ≠ 0]: (1/c)·(1/(1+u²))·(1/c) = 1/(c²(1+u²)) and c²(1+u²) = c² + c²u² = c² + (x+a)² (c≠0) ✓ ring.\nThen FTC: ∫₀ⁿ 1/((x+a)²+c²) dx = (1/c)(arctan((n+a)/c) − arctan(a/c)) [intervalIntegral.integral_eq_sub_of_hasDerivAt; integrability: continuous].\nBound: (1/c)|arctan diff| ≤ (1/c)(π/2 + π/2) = π/c: |arctan x| < π/2: `Real.abs_arctan_lt_pi_div_two`? — earlier grep found `arctan_lt_pi_div_two` (Trigonometric/Arctan.lean:150). The neg side: `Real.neg_pi_div_two_lt_arctan (x) : -(π/2) < arctan x` — likely exists; else from arctan_neg: arctan x = −arctan (−x) > −(π/2). So |arctan u − arctan v| ≤ |arctan u| + |arctan v| < π/2 + π/2 = π; for ≤: ≤ π fine (use .le of each < ... to get ≤ π).\nThen (1/c)·π = π/c ≤ π/2 (c ≥ 2: 1/c ≤ 1/2 ⟹ π/c ≤ π/2 ✓).\n\nThe integrand equality: 1/((x+a)²+c²) vs my normSq expression: ‖w + ↑x‖⁻²: ‖w + ↑x‖² = (w.re + x)² + w.im² via Complex.normSq: normSq (w + ↑x) = (w.re + x)² + (w.im)² [normSq_apply, add_re w ↑x: (w + ↑x).re = w.re + x (ofReal_re), im = w.im + 0]. And ‖z‖⁻² = (normSq z)⁻¹: normSq z = ‖z‖² (Complex.normSq_eq_norm_sq — used in LiDisc ✓) so ‖z‖⁻² = (‖z‖²)⁻¹ = (normSq z)⁻¹ = ((w.re+x)² + w.im²)⁻¹. With c² = w.im² (c = |w.im|, sq_abs). So the pointwise: ‖(w+↑x)⁻¹‖² = ‖w+↑x‖⁻² = ((x + w.re)² + |w.im|²)⁻¹·... ‖u⁻¹‖ = ‖u‖⁻¹ so ‖(w+x)⁻¹‖² = (‖w+x‖⁻¹)² = ‖w+x‖⁻² ✓.\n\nThe B1-integral bound: ‖∫₀ⁿ deriv f x · B1 x dx‖ ≤ ∫₀ⁿ ‖deriv f x * B1 x‖ dx [intervalIntegral.norm_integral_le_integral_norm (zero_le n)] ≤ ∫₀ⁿ (1/2)·((x+a)²+c²)⁻¹ dx [pointwise: ‖deriv f x‖·|B1 x| ≤ ‖w+x‖⁻²·(1/2); abs_B1_le_half (0 ≤ x)] = (1/2)·∫₀ⁿ ((x+a)²+c²)⁻¹ dx [integral_mul_const... wait the integrand is REAL: ‖deriv f x * B1 x‖ where deriv f x : ℂ and B1 x : ℝ... the EM lemma's term is deriv f t * B1 t : ℂ (𝕜 = ℂ, B1 coerced? B1 t : ℝ; deriv f t * (B1 t : ℂ)? The EM lemma signature: ∫ t in a..b, deriv f t * B1 t — with f : ℝ → 𝕜 and B1 : ℝ → ℝ, the product deriv f t * B1 t needs smul or coe: RCLike 𝕜 has algebra ℝ ↪ 𝕜 so B1 t coerces ✓ (the file wrote it directly with RCLike coercion). So the integrand is deriv f t * ↑(B1 t) : ℂ, norm = ‖deriv f t‖ · |B1 t| ✓ (norm_mul, Complex.norm_real...).\n  Pointwise deriv value: deriv (fun x : ℝ => (w + ↑x)⁻¹) x = −(w+↑x)⁻²: HasDerivAt: ((hasDerivAt_id' ...)... (w + ↑x)⁻¹ = e' (↑x) with e' z = (w + z)⁻¹: HasDerivAt e' (−(w+z)⁻²) z: hasDerivAt_inv? `HasDerivAt.inv (hf : HasDerivAt f f' x) (hx : f x ≠ 0) : HasDerivAt (fun x => (f x)⁻¹) (-(f x)⁻² * f') x`? hmm — I recall `HasDerivAt.inv (hf : HasDerivAt f f' x) (hx : f x ≠ 0) : HasDerivAt f⁻¹ (-(f x ^ 2)⁻¹ * f') x`? or `hasDerivAt_inv (hx : x ≠ 0) : HasDerivAt (·⁻¹) (-(x⁻²)) x`? For id: HasDerivAt (fun x => (w + ↑x)... I'll compose: e' = Inv.inv ∘ (w + ·): (hasDerivAt_inv-ish).comp... Let me check name: `HasDerivAt.inv` exists (f⁻¹ form). Then via comp_ofReal for the ofReal. Then .deriv gives deriv value; then ‖·‖ = ‖−(w+x)⁻²‖ = ‖w+x‖⁻² ✓.\n  Actually for the EM application I need: hf_diff : ∀ t ∈ Icc 0 n, DifferentiableAt ℝ f t (f := fun x => (w+↑x)⁻¹) and h_cont : ContinuousOn (deriv f) [[0, n]]. Both from the HasDerivAt formula (differentiableAt from hasDerivAt; deriv f = fun x => −(w+↑x)⁻² on the interval via HasDerivAt.deriv at each point — ContinuousOn of the deriv FUNCTION: since deriv f x = −(w+↑x)⁻² pointwise EVERYWHERE (all x, not just interval), ContinuousOn from the formula's continuity: Continuous (fun x : ℝ => −(w+↑x)⁻¹...): continuous_inv₀ (fun x hx => w+↑x ≠ 0 (im ≠ 0)) ∘ (continuous_const.add continuous_ofReal...). `Complex.continuous_ofReal` ✓. Then ContinuousNeg, inv₀: `Continuous.inv₀ (hf : Continuous f) (h : ∀ x, f x ≠ 0) : Continuous f⁻¹`? hmm `Continuous.inv₀` exists ✓. Then deriv f = that function: funext over deriv eq: (hder x).deriv : deriv f x = −(w+↑x)⁻² for ALL x; then deriv f = fun x => −(w+↑x)⁻² by funext; rw; exact continuous-ness.continuousOn ✓.\n\nE1 detail — the sum in EM is Σ_{k ∈ Ioc ⌊0⌋₊ ⌊↑n⌋₊} f k = Ioc 0 n (Nat.floor_zero? ⌊(0:ℝ)⌋₊ = 0: Nat.floor_zero; ⌊(↑n:ℝ)⌋₊ = n: Nat.floor_natCast ✓).\n\nAlright — I've surveyed enough. There will be build-time fixes but the plan is solid. Let me also quickly look at the exact head of LiContour.lean to match style/imports for the new file, then start writing LiReflect.lean §1–§5 first (capstone), compile, then §6.\n\nOne more check — the exact name `Complex.hasDerivAt_log` and slit plane lemma: from Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean:37: `lemma hasDerivAt_log {z : ℂ} (hz : z ∈ slitPlane) : HasDerivAt log z⁻¹ z` — in namespace Complex ✓. slitPlane membership: `Complex.mem_slitPlane_iff : z ∈ slitPlane ↔ 0 < z.re ∨ z.im ≠ 0`? — the grep showed usage `mem_slitPlane_iff` in Arg.lean — likely `Complex.mem_slitPlane_iff`. I'll use `.mpr (Or.inr him)`.\n\nNow — check what LiContour.lean imports to make sure digamma_apply_add_one etc. are available via `import Mathlib` (yes, Mathlib full import covers everything; LiDisc imports Mathlib + Zeta23.FromPNTPlus.StrongPNTPrefix + LiRBound + LiContour).\n\nFor LiReflect.lean imports: Mathlib + NguyenRH1.LiDisc (which brings LiContour, LiRBound, Zeta23 StrongPNTPrefix) + Zeta23.RvM.GammaSide (logDeriv_Gammaℝ) + Zeta23.GammaFacts.StirlingVert (digamma_stirling) + Zeta23.ZetaReflect (analyticOrderAt_zeta_one_sub) + Zeta23.RvM.CountByIntegral (completedRiemannZeta_eq_Gammaℝ_mul / eq_zero_iff — probably already via LiContour? LiContour used RvM.completedRiemannZeta_eq_Gammaℝ_mul? zeroDisc_isNontrivial in LiDisc used it — so it's available via LiDisc's imports. And analyticOrderAt_zeta_one_sub is Zeta23.ZetaReflect — is it transitively imported? LiContour's zeroMult_neg_two... probably imports CountByIntegral. To be safe, import explicitly: Zeta23.ZetaReflect, Zeta23.RvM.GammaSide, Zeta23.GammaFacts.StirlingVert, Zeta23.RvM.CountByIntegral, Zeta23.FromPNTPlus.EulerMaclaurin (for B1 + sum_eq_integral_add_integral_deriv — though probably transitively via StrongPNTPrefix; explicit is safe).\n\nAlso need `IsNontrivialZero` — from Zeta23.Statement (transitively imported everywhere).\n\nNow write the file. I'll write §1–§5 in one go, compile, iterate; then §6.\n\nLet me be careful about a few Lean idioms learned from journals:\n- bare π auto-binds: use Real.pi explicitly.\n- ascribe (↑x : ℂ) when needed.\n- field_simp may close goals (check before ring).\n- Finset.sum_image takes Set.InjOn.\n- logDeriv_apply for unfolding.\n\nLet me draft the code.\n\n```lean\n/-\nNguyenRH1/LiReflect.lean — tier ii′ sub-stage ii′-5d (D-067 §3 left half + §6):\nthe FE-reflection of the loose Davenport-disc R-bound (ii′-5c) to\nσ ∈ [−5/2, 1/2], |t| ≥ 10, plus the left-plane uniform digamma bound\n‖ψ(w) − log w‖ ≤ 3 for |im w| ≥ 2 (recurrence + Euler–Maclaurin\nseries-vs-log comparison; the 5e input).\n\nRoute (D-067 §3):\n* Λ = ΓR·ζ and Λ(1−s) = Λ(s) give the pointwise log-derivative FE\n  logDeriv ζ s = −logDeriv ζ (1−s) − [logDeriv ΓR s + logDeriv ΓR (1−s)];\n* the near-zero sums at t and −t CANCEL EXACTLY under ρ ↦ 1−ρ\n  (Zeta23 `analyticOrderAt_zeta_one_sub` for the multiplicities);\n* the ΓR-bracket is −log π + ½ψ((1−s)/2) + ½ψ((s+4)/2) − 2(s+1)/(s(s+2))\n  (the s-side shifted by +4 via the ΓR recurrence so both digammas sit in\n  re > 0), each piece O(log|t|) by Zeta23 `StirlingVert.digamma_stirling`.\n\nArchive references: D-067 §3/§6, journal-024.\n-/\nimport Mathlib\nimport Zeta23.RvM.GammaSide\nimport Zeta23.RvM.CountByIntegral\nimport Zeta23.GammaFacts.StirlingVert\nimport Zeta23.ZetaReflect\nimport Zeta23.FromPNTPlus.EulerMaclaurin\nimport NguyenRH1.LiDisc\n\nopen Zeta23 Complex Filter Topology MeasureTheory\nopen scoped Nat\n\nnoncomputable section\n\nnamespace NguyenRH1\n```\n\n§0 small helpers:\n\n```lean\n/-! ## 0. Small complex helpers -/\n\ntheorem norm_le_abs_re_add_abs_im' (z : ℂ) : ‖z‖ ≤ |z.re| + |z.im| := by\n  have hb : (0:ℝ) ≤ |z.re| + |z.im| := add_nonneg (abs_nonneg _) (abs_nonneg _)\n  refine le_of_pow_le_pow_left₀ (two_ne_zero) hb ?_  -- check name: le_of_pow_le_pow_left₀ (hn : n ≠ 0) (hb : 0 ≤ b) (h : a ^ n ≤ b ^ n)\n  rw [← Complex.normSq_eq_norm_sq, Complex.normSq_apply]\n  nlinarith [sq_abs z.re, sq_abs z.im, mul_nonneg (abs_nonneg z.re) (abs_nonneg z.im)]\n```\nHmm — le_of_pow_le_pow_left₀ signature: `le_of_pow_le_pow_left₀ (hn : n ≠ 0) (hb : 0 ≤ b) : a ^ n ≤ b ^ n → a ≤ b`? I think it's `le_of_pow_le_pow_left₀ (hn : n ≠ 0) (hb : 0 ≤ b) (h : a ^ n ≤ b ^ n) : a ≤ b` ✓. If not, fallback: by_contra + pow_le_pow_left₀ strict.\n\nWait — normSq_apply : normSq z = z.re * z.re + z.im * z.im? and goal after rw: z.re * z.re + z.im * z.im ≤ (|z.re| + |z.im|)^2 — nlinarith with sq_abs (|a|² = a²... sq_abs : |a|^2 = a^2) and nonneg of the cross term ✓.\n\n- im helpers:\n```lean\ntheorem im_ne_zero_of_abs_im_ge {z : ℂ} (h : 2 ≤ |z.im|) : z.im ≠ 0 := by\n  intro hz; rw [hz, abs_zero] at h; norm_num at h\n```\nHmm — or just (abs_nonneg).trans_lt... |z.im| ≥ 2 > 0 ⟹ z.im ≠ 0: fun hz => by rw [hz] at h; simp at h. I'll inline as needed.\n\nLet me now write §1 (ΓR shift). Actually — I realize I should double check `Complex.Gammaℝ_def` exact form: from logDeriv_Gammaℝ's proof: `Complex.Gammaℝ_def : Gammaℝ s = (Real.pi : ℂ) ^ (-s / 2) * Complex.Gamma (s / 2)` — they wrote `Complex.Gammaℝ = fun s => (Real.pi : ℂ) ^ (-s / 2) * Complex.Gamma (s / 2)` via funext Gammaℝ_def, so Gammaℝ_def : Gammaℝ s = (Real.pi:ℂ)^(−s/2) * Gamma (s/2) ✓ (namespace Complex; with open Complex: Gammaℝ_def).\n\nAnd `Complex.Gamma_add_one (s : ℂ) (hs : s ≠ 0) : Gamma (s + 1) = s * Gamma s` — from digamma_apply_add_one's proof usage `Gamma_add_one s hs0` inside namespace Complex ✓.\n\nNow write the full §1–§5. Let me think about the trickiest proof steps once more:\n\n**gammaR_shift**: \n```\ntheorem gammaR_shift {s : ℂ} (hs : s.im ≠ 0) :\n    Complex.Gammaℝ s = (Real.pi : ℂ) ^ 2 * Complex.Gammaℝ (s + 4) / ((s / 2) * (s / 2 + 1)) := by\n  have hs0 : s ≠ 0 := fun h => hs (by rw [h]; simp)  -- im 0 = 0: Complex.zero_im? simp: (0 : ℂ).im = 0 ✓\n  have hs2 : s / 2 ≠ 0 := fun h => hs0 (by ... ) -- s/2 = 0 ⟹ s = 0: div_eq_zero_iff... s/2 = 0 → s = 0: mul? s = 2*(s/2) = 0: by field_simp? simplest: fun h => hs0 (by have := congrArg (· * 2) h; ... ) — or: div_ne_zero hs0 two_ne_zero: `div_ne_zero (ha : a ≠ 0) (hb : b ≠ 0) : a / b ≠ 0` ✓.\n  have hs21 : s / 2 + 1 ≠ 0 := fun h => hs (by have := congrArg Complex.im h; simp [add_im, div_im, ofReal_im...] at this; ...) \n```\nHmm im(s/2 + 1) = s.im / 2: (s/2 + 1).im = (s/2).im + (1:ℂ).im = (s/2).im = s.im/2: simp [add_im, div_re...]: the simp set: add_im, one_im, div_re... for (s/2).im: s/2 = s * (1/2): hmm. Cleaner: s/2 = (s.re/2) + (s.im/2)I... The robust pattern from LiDisc: `have him : (s/2 + 1).im = s.im / 2 := by simp [div_re, div_im, add_im, ofReal_re, ofReal_im]...` hmm — actually (s / 2) with 2 : ℂ: div_im : (a / b).im = (a.re * b.im + a.im * b.re) / (b.re^2 + b.im^2)? There's `Complex.div_im : (x / y).im = (x.im * y.re - x.re * y.im) / (y.re^2 + y.im^2)`? whatever — simp [Complex.div_im, Complex.div_re, ofReal_re, ofReal_im] should evaluate (s/2).im = s.im / 2. LiDisc line 1008 pattern: `simp [discCenter, sub_re, add_re, mul_re, ofReal_re, ofReal_im, I_re, I_im]`. For division by a real cast: there are simp lemmas `Complex.ofReal_div_re`? Let me avoid the guesswork: write s / 2 = s * (2 : ℂ)⁻¹ and use mul_im: (s * (2:ℂ)⁻¹).im = s.re * (2⁻¹).im + s.im * (2⁻¹).re = s.im * (1/2) — simp [mul_im, inv_re, inv_im, ofReal_re, ofReal_im]: (2:ℂ)⁻¹.re = 1/2: inv_re: (z⁻¹).re = z.re / (normSq z): (2)⁻¹.re = 2/(4) = 1/2 — simp should do with norm_num. OK — in practice: `by simp [Complex.div_re, Complex.div_im]` often handles x/2; or just compute via `Complex.ext_iff` approach... I'll write `have him2 : (s / 2).im = s.im / 2 := by simp [Complex.div_im, Complex.div_re]; ring`? risky. Alternative bulletproof: field_simp-free: \n(s/2 + 1) ≠ 0: suppose = 0: then s/2 = −1: s = −2: then s.im = (−2).im = 0 contra. s = −2 from s/2 = −1: by_contra... simplest: \n```\nhave hs21 : s / 2 + 1 ≠ 0 := by\n  intro h\n  have h1 : s / 2 = -1 := eq_neg_of_add_eq_zero_left h  -- `eq_neg_of_add_eq_zero_left : a + b = 0 → a = -b` ✓\n  have h2 : s = -2 := by\n    have := congrArg (· * (2:ℂ)) h1\n    -- (s/2)*2 = s\n    rw [div_mul_cancel₀ s (two_ne_zero : (2:ℂ) ≠ 0)] at this  -- div_mul_cancel₀ (a) (hb : b ≠ 0) : a / b * b = a ✓\n    -- this : s = -1 * 2\n    rw [this]; ring  -- hmm: goal s = -2 from this : s = -1 * 2: exact this.trans (by ring)? no: this says s = −1*2 = −2: `norm_num at this`? or rw [this]; norm_num\n  exact hs (by rw [h2]; simp)  -- (-2 : ℂ).im = 0: simp: neg_im, ofReal_im — ((-2):ℂ).im = 0 ✓ simp should handle: `simp` knows ((-2):ℂ) = -(2:ℂ)? norm_num1... I'll use: rw [h2] at ⊢; exact hs (by simp : (-2:ℂ).im = 0 ▸ ...) — meh. Directly: hs : s.im ≠ 0; rw [h2] at hs; simp at hs ✓ (simp at hs derives False from ((−2):ℂ).im ≠ 0 — simp computes (−2:ℂ).im = 0, contradiction ✓).\n```\nOK these little ≠ 0 proofs: im(s/2+1) = s.im/2 approach vs algebraic approach — algebraic is more verbose but robust. I'll go algebraic:\n- hs0 : s ≠ 0 — from im ≠ 0: `fun h => hs (h ▸ Complex.zero_im)`? h : s = 0: s.im = 0: by rw [h]; exact Complex.zero_im... `Complex.zero_im : (0:ℂ).im = 0`? simp lemma. `fun h => hs (by rw [h]; simp)` ✓.\n- hs2 : s/2 ≠ 0 := div_ne_zero hs0 (by norm_num) ✓.\n- hs21 : s/2 + 1 ≠ 0: via h1 : s/2 = −1 from add_eq_zero... `eq_neg_of_add_eq_zero_left (h : a + b = 0) : a = −b` ✓; then s = −2 as above; then im contradiction. Robust ✓.\n\nThen the main identity:\n```\n  have hGamma : Complex.Gamma (s / 2 + 2) = (s / 2 + 1) * (s / 2) * Complex.Gamma (s / 2) := by\n    rw [Complex.Gamma_add_one (s / 2 + 1) hs21, Complex.Gamma_add_one (s / 2) hs2]; ring\n```\n✓ (Gamma_add_one (s/2+1) hs21 : Gamma (s/2+1+1) = (s/2+1)*Gamma(s/2+1); note s/2+2 = s/2+1+1 by ring — need a `show Complex.Gamma (s/2+1+1) = ...` bridge: rw under binder: convert? Use: `have h1 := Complex.Gamma_add_one (s/2 + 1) hs21` : Gamma (s/2+1+1) = ...; rw [show s/2 + 2 = s/2 + 1 + 1 by ring]; rw [h1, Complex.Gamma_add_one (s/2) hs2]; ring ✓.\n\n```\n  have hpi : ((Real.pi : ℂ) ^ (-(s + 4) / 2)) = (Real.pi : ℂ) ^ (-s / 2) * ((Real.pi ^ 2 : ℝ)⁻¹ : ℂ) := by\n    rw [Complex.cpow_def_of_ne_zero (by exact_mod_cast Real.pi_ne_zero : (Real.pi:ℂ) ≠ 0) _, \n        Complex.cpow_def_of_ne_zero ... _]\n```\nhmm — cpow_def_of_ne_zero (hx : x ≠ 0) (y : ℂ) : x ^ y = exp (log x * y). So:\n(π:ℂ)^(−(s+4)/2) = exp (log π * (−(s+4)/2)); log (π:ℂ) = ↑(Real.log π) [Complex.ofReal_log Real.pi_nonneg — ofReal_log (hx : 0 ≤ x) : (↑(Real.log x) : ℂ)... wait the statement from grep: `theorem ofReal_log {x : ℝ} (hx : 0 ≤ x) : (x.log : ℂ) = log x` — i.e., ↑(Real.log x) = Complex.log ↑x ✓ use .symm].\nThen exp (↑logπ * (−(s+4)/2)) = exp (↑logπ * (−s/2) + ↑(−2 * logπ)) [by ring_nf / push_cast: ↑(−2*logπ) vs ↑logπ * (−2): push_cast; ring ✓] = exp(↑logπ*(−s/2)) * exp(↑(−2*logπ)) [exp_add] = (π:ℂ)^(−s/2) * ↑(Real.exp (−2 * Real.log π)) [← cpow_def_of_ne_zero, ← Complex.ofReal_exp] and Real.exp (−2 * log π) = (π²)⁻¹:\n  Real.exp (−2 * Real.log π) = (Real.pi ^ 2)⁻¹:\n    have : (−2) * Real.log π = Real.log ((Real.pi ^ 2)⁻¹) := by rw [Real.log_inv, Real.log_pow]; ring ✓ (Real.log_pow : log (x^n) = n * log x ✓, Real.log_inv : log x⁻¹ = − log x ✓).\n    rw [this, Real.exp_log (inv_pos.mpr (pow_pos Real.pi_pos 2))] ✓.\nSo:\n```\n  have hexp2 : Real.exp (-2 * Real.log Real.pi) = (Real.pi ^ 2)⁻¹ := by\n    have h1 : (-2 : ℝ) * Real.log Real.pi = Real.log ((Real.pi ^ 2)⁻¹) := by\n      rw [Real.log_inv, Real.log_pow]; push_cast; ring\n    rw [h1, Real.exp_log (by positivity)]\n```\nReal.log_pow : Real.log (x ^ n) = ↑n * Real.log x ✓. Then −2 * log π = −(2 * log π) and log (π²)⁻¹ = −(2 * log π) ✓ ring after the rewrites.\n\nThen:\n```\n  have hmain : Complex.Gammaℝ (s + 4) = ((Real.pi ^ 2 : ℝ)⁻¹ : ℂ) * ((s / 2) * (s / 2 + 1)) * Complex.Gammaℝ s := by\n    rw [Complex.Gammaℝ_def, Complex.Gammaℝ_def]  -- ΓR(s+4) = π^{−(s+4)/2} Γ((s+4)/2); ΓR s = π^{−s/2} Γ(s/2)\n    rw [show (s + 4) / 2 = s / 2 + 2 by ring, hGamma, hpi]\n    -- goal: π^{−s/2} * ↑(π²)⁻¹ * ((s/2+1)*(s/2)*Γ(s/2)) = ↑(π²)⁻¹ * ((s/2)(s/2+1)) * (π^{−s/2} * Γ(s/2))\n    ring\n```\nHmm wait — Gammaℝ_def applied to (s+4) gives exponent −(s+4)/2 and Gamma ((s+4)/2) ✓. And −(s+4)/2 vs my hpi's −(s+4)/2 ✓ match. After rewrites: LHS = [π^{−s/2} * ↑(π²)⁻¹] * [(s/2+1)*(s/2)*Γ(s/2)]; RHS = ↑(π²)⁻¹ * (s/2*(s/2+1)) * [π^{−s/2} * Γ(s/2)] — ring ✓ (commutative).\n\nThen conclude:\n```\n  -- divide: Gammaℝ s = (π:ℂ)^2 * Gammaℝ (s+4) / P where P = (s/2)(s/2+1)\n  have hP : (s / 2) * (s / 2 + 1) ≠ 0 := mul_ne_zero hs2 hs21\n  have hC : ((Real.pi ^ 2 : ℝ)⁻¹ : ℂ) ≠ 0 := by\n    exact_mod_cast inv_ne_zero (pow_ne_zero 2 Real.pi_ne_zero)  -- hmm: ((π²)⁻¹ : ℝ) ≠ 0 → cast ≠ 0: ofReal_ne_zero.mpr ✓\n  field_simp [hmain]  -- goal: ΓR s = π² * ΓR(s+4) / P; from hmain: ΓR(s+4) = C * P * ΓR s, C⁻¹ = π²\n```\nRisky. More controlled:\n```\n  rw [eq_div_iff hP]  -- goal: Gammaℝ s * P = (π:ℂ)^2 * Gammaℝ (s+4)\n  rw [hmain]  -- ΓR s * P = π² * (C * P * ΓR s)\n  -- π² * C = 1: (↑(π²)⁻¹)... (π:ℂ)^2 * ((π²:ℝ)⁻¹ : ℂ) = 1\n  have hpi2 : (Real.pi : ℂ) ^ 2 * ((Real.pi ^ 2 : ℝ)⁻¹ : ℂ) = 1 := by\n    push_cast\n    rw [mul_inv_cancel₀ (pow_ne_zero 2 Real.pi_ne_zero)]\n  -- then: π² * (C * P * ΓR s) = (π² * C) * (ΓR s * P) = ΓR s * P\n  calc Complex.Gammaℝ s * ((s/2)*(s/2+1)) \n      = (Real.pi:ℂ)^2 * (((Real.pi^2:ℝ)⁻¹:ℂ) * ((s/2)*(s/2+1)) * Complex.Gammaℝ s) := by\n        rw [hpi2]... \n```\nhmm direction: I want ΓR s * P = π² * ΓR (s+4). rw [hmain] changes ΓR (s+4) to C*P*ΓR s: goal ΓR s * P = π² * (C * P * ΓR s). Then: π² * (C * P * ΓR s) = (π² * C) * (ΓR s * P) [ring] = 1 * (ΓR s * P) [hpi2] = ΓR s * P [one_mul] ✓:\n```\n  rw [hmain]\n  calc Complex.Gammaℝ s * ((s/2)*(s/2+1))\n      = ((Real.pi:ℂ)^2 * ((Real.pi^2:ℝ)⁻¹:ℂ)) * (Complex.Gammaℝ s * ((s/2)*(s/2+1))) := by rw [hpi2, one_mul]\n    _ = (Real.pi:ℂ)^2 * (((Real.pi^2:ℝ)⁻¹:ℂ) * ((s/2)*(s/2+1)) * Complex.Gammaℝ s) := by ring\n```\n✓ (note calc with mixed — fine).\n\nActually eq_div_iff signature: `eq_div_iff (hc : c ≠ 0) : a = b / c ↔ a * c = b` ✓.\n\n**logDeriv_congr**:\n```\ntheorem logDeriv_congr {f g : ℂ → ℂ} {s : ℂ} (h : f =ᶠ[𝓝 s] g) :\n    logDeriv f s = logDeriv g s := by\n  simp only [logDeriv_apply, h.deriv_eq, h.eq_of_nhds]\n```\n✓ (logDeriv_apply : logDeriv f x = deriv f x / f x — from Mathlib LogDeriv.lean: `logDeriv_apply` simp only in their proofs ✓).\n\n**logDeriv_Gammaℝ_shift**:\n```\ntheorem logDeriv_Gammaℝ_shift {s : ℂ} (hs : s.im ≠ 0) :\n    logDeriv Complex.Gammaℝ s = logDeriv Complex.Gammaℝ (s + 4) - 2 * (s + 1) / (s * (s + 2)) := by\n  have hU : IsOpen {z : ℂ | z.im ≠ 0} := isOpen_ne_fun Complex.continuous_im continuous_const\n  -- the EventuallyEq\n  have hEv : Complex.Gammaℝ =ᶠ[𝓝 s] fun z => (Real.pi : ℂ) ^ 2 * Complex.Gammaℝ (z + 4) / ((z / 2) * (z / 2 + 1)) := by\n    filter_upwards [hU.mem_nhds hs] with z hz using gammaR_shift hz\n  rw [logDeriv_congr hEv]\n  -- nonzero facts at s\n  have hs0 : s ≠ 0 := ...\n  have hs2 : s / 2 ≠ 0 := ...\n  have hs21 : s / 2 + 1 ≠ 0 := ...\n  have hG4 : Complex.Gammaℝ (s + 4) ≠ 0 := by\n    -- im(s+4) = s.im ≠ 0 ⟹ not of the form −2n\n    intro h\n    rw [Complex.Gammaℝ_eq_zero_iff] at h\n    obtain ⟨n, hn⟩ := h\n    apply hs\n    -- im(s+4) = im(−2n) = 0 ⟹ im s = 0\n    have him : (s + 4).im = ((-2 : ℝ) * (n : ℝ) : ℂ).im := by rw [hn]  -- hn : s + 4 = −2 * ↑n\n    simp [add_im, ofReal_im, mul_im...] at him  -- (s+4).im = s.im; RHS im = 0\n    exact him\n  ...\n```\nHmm — hn : s + 4 = −2 * ↑n where the RHS: the Gammaℝ_eq_zero_iff : Gammaℝ s = 0 ↔ ∃ n : ℕ, s = -2 * n? the exact form from zeroDisc_isNontrivial: after rw they got `hre' : ρ.re = -2 * (n:ℝ)` by `rw [hn]; simp [neg_re, mul_re]` — so hn : ρ = -2 * (n : ℂ)? with −2 * ↑n : ℂ ✓. So ((−2:ℂ) * ↑n).im = 0: simp [neg_mul, mul_im, ofReal_re, ofReal_im, natCast_re, natCast_im] — should close: (−2 * ↑n).im = (−2).re * (↑n).im + ... simp with mul_im, neg_re, ofReal_im, natCast_im (Nat.cast im = 0) ✓ norm_num-ish. Let me write: `have : (s + 4).im = 0 := by rw [hn]; simp` then `(s+4).im = s.im`: simp [add_im] → s.im + (4:ℂ).im = s.im: `Complex.add_im : (x+y).im = x.im + y.im`, (4:ℂ).im = 0 via ofReal? 4 = ((4:ℝ):ℂ)? simp should know (4:ℂ).im = 0 via `Complex.ofReal_im` after norm_num cast lemmas... risk. Alternative bulletproof: from h : s + 4 = −2*↑n get s = −2*↑n − 4 (by linarith? no — complex: eq_sub_of_add_eq... just: s = (s+4) − 4 = −2↑n − 4); then s.im = (−2↑n − 4).im = 0: rw [this] at hs; simp at hs: (−2*↑n − 4 : ℂ).im: sub_im, mul_im, neg_re... simp [Complex.sub_im, Complex.mul_im] with ofReal_im, natCast_im, neg_im: all real components have im 0 ⟹ total 0 ⟹ hs : (0:ℝ) ≠ 0? no — hs becomes (…).im ≠ 0 = 0 ≠ 0 after simp computes im = 0 ⟹ contradiction: simp at hs should close False. I'll write `rw [show s = -2 * (n:ℂ) - 4 from by rw [← hn]; ring] at hs; simp at hs` and hope simp computes the im of that expression to 0. simp set for im computations: Complex.sub_im, Complex.neg_im, Complex.mul_im, Complex.ofReal_im, Complex.natCast_im, Complex.neg_re... The default simp set includes Complex.?. Actually many Complex re/im lemmas are @[simp]: sub_im, add_im, mul_im, mul_re, neg_im, neg_re, ofReal_im, ofReal_re, natCast_im, natCast_re, intCast_im, intCast_re, I_im, I_re are all simp. So `simp at hs` with hs : (−2 * ↑n − 4 : ℂ).im ≠ 0 should simplify (−2*↑n−4).im to 0 via the simp set and close by contradiction ✓ confident.\n\nThen:\n```\n  -- logDeriv via div/mul rules\n  have hdG4 : DifferentiableAt ℂ Complex.Gammaℝ (s + 4) := differentiableAt_Gammaℝ_of_im_ne_zero' (by ... im(s+4) = s.im ≠ 0 ...)\n```\nWait — I decided to write my own differentiableAt_Gammaℝ_of_im_ne_zero in namespace NguyenRH1 (to avoid the heavy XiPrime.Hardy.Basic import). Its proof needs `half_ne_neg_nat`-style: ∀ m : ℕ, s/2 ≠ −↑m: if s/2 = −↑m then im(s/2) = 0; im(s/2) = s.im/2 ≠ 0. Via: intro m h; apply hs; ... (s/2).im = 0 from h: rw [h] — need (s/2).im = s.im/2 FIRST. So I do need the div-im computation. Let me just prove the small lemma:\n```\ntheorem im_div_two (s : ℂ) : (s / 2).im = s.im / 2 := by\n  rw [Complex.div_im]  -- (x/y).im = ? exact formula\n  simp  -- with ofReal_re, ofReal_im, normSq...\n```\nComplex.div_im : (x / y).im = (x.im * y.re − x.re * y.im) / (y.re ^ 2 + y.im ^ 2)? I believe `Complex.div_im (x y : ℂ) : (x / y).im = (x.im * y.re - x.re * y.im) / (y.re^2 + y.im^2)`? or via normSq: / normSq y. For y = 2: (s.im * 2 − s.re * 0)/(4 + 0) = s.im * 2/4 = s.im/2: `simp [Complex.div_im]; ring`? After rw [Complex.div_im]: goal (s.im * (2:ℂ).re − s.re * (2:ℂ).im)/((2:ℂ).re^2 + (2:ℂ).im^2) = s.im/2: simp [ofReal_re, ofReal_im] → (s.im * 2 − 0)/(4) = s.im/2: ring... wait (2:ℂ).re: 2 : ℂ is OfNat.ofReal? simp lemmas `Complex.ofNat_re`? There are simp lemmas for numeral re/im (OfNat.ofReal? in Lean4 Mathlib numerals in ℂ are `OfNat.ofNat` and there are simp lemmas `Complex.ofNat_re`, `Complex.ofNat_im`? hmm — there ARE: `Complex.ofNat_re : (OfNat.ofNat n : ℂ).re = ...`? I recall `Complex.ofNat_re`/`Complex.ofNat_im` exist as simp. If not, `show (s / ((2:ℝ):ℂ)).im = ...` conversion: (2:ℂ) = ((2:ℝ):ℂ) by norm_num (OfNat.ofReal? `Complex.ofReal_ofNat`? `Complex.ofReal_ofNat : ((OfNat.ofNat n : ℝ) : ℂ) = OfNat.ofNat n`? exists as simp). Then ((r:ℝ):ℂ) division: `Complex.ofReal_div_re`? : ((x / ↑r).re = x.re / r)? there's `Complex.ofReal_div_re : (x / ↑r).re = x.re / r` and `Complex.ofReal_div_im : (x / ↑r).im = x.im / r` — I THINK these exist (they're in Data/Complex/Basic or Exponential?). Hmm. Safest: use the mul form: s/2 = s * (2:ℂ)⁻¹:\nim_div_two: (s/2).im: rw [div_eq_mul_inv, Complex.mul_im]: = s.re * (2:ℂ)⁻¹.im + s.im * (2:ℂ)⁻¹.re. (2:ℂ)⁻¹ = ((1/2 : ℝ):ℂ): `show (2:ℂ)⁻¹ = ((1/2:ℝ):ℂ) by rw [Complex.ofReal_inv]... ` hmm: Complex.ofReal_inv : (↑r)⁻¹ = ↑(r⁻¹) ✓ exists. So (2:ℂ)⁻¹ = ↑(1/2): (2:ℂ) = ↑(2:ℝ) (norm_num / push_cast), inv: ↑(2⁻¹) = ↑(1/2) ✓. Then mul_im with ofReal: s.re * 0 + s.im * (1/2) = s.im/2 ✓ ring.\nLet me write it as:\n```\ntheorem im_div_two (s : ℂ) : (s / 2).im = s.im / 2 := by\n  have h2 : (2 : ℂ) = ((2 : ℝ) : ℂ) := by norm_num\n  rw [h2, Complex.div_eq... \n```\nhmm — actually simplest: `(s/2).im`: note s/2 = s * ↑((1:ℝ)/2): `div_eq_mul_inv`; (2:ℂ)⁻¹: rw [← Complex.ofReal_ofNat? ...]. \n\nYou know what, let me check if `Complex.ofNat_im`/`ofNat_re` exist, and `Complex.div_im` formula — quick grep. Also `Complex.ofReal_div_im`. Actually, easier idea: avoid im-division entirely using ext-free algebraic arguments:\n- s/2 ≠ 0: div_ne_zero ✓ no im needed.\n- s/2 + 1 ≠ 0: algebraic (shown above) ✓ no im needed.\n- s/2 ≠ −↑m: suppose s/2 = −↑m: then s = −2↑m: s.im = 0 contra: s = 2*(s/2) = 2*(−↑m) = −2↑m: rw [this] at hs; simp at hs ✓ algebraic ✓.\n- im(s + 4) = s.im: simp [add_im] + numeral im = 0: hmm same numeral issue: (4:ℂ).im = 0. If ofNat_im is simp: fine. Else: (4:ℂ) = ((4:ℝ):ℂ) by norm_num (push_cast handles). I'll assume simp handles (I saw `ofReal_im` used with numerals in LiDisc line 1008: `simp [discCenter, sub_re, add_re, mul_re, ofReal_re, ofReal_im, I_re, I_im]` computed (ρ − discCenter t).re = ρ.re − 2 where discCenter has `2 + t * I` with 2 : ℂ — that simp call worked with the numeral re — so numerals' re/im ARE simp-computable in this environment ✓ good, `simp [add_im]` will give (s+4).im = s.im + 0 = s.im).\n\nFor (s/2).im I'll test `by simp [Complex.div_im]; ring` fallback the inv route. Actually — wait, even simpler: I can sidestep im(s/2) by choosing the shift identity in the form avoiding division-im needs... no — half_ne_neg_nat needs it. Alternative for half_ne_neg_nat: ∀ m, s/2 ≠ −↑m algebraically (shown above: s = −2↑m ⟹ s.im = 0 via simp on (−2*↑m : ℂ).im — mul_im, natCast_im ✓ no division-im needed!) ✓.\n\nSo I only need im computations for: (s+4).im = s.im [simp [add_im] ✓], (1−s).im = −t [simp [sub_im, hsim] ✓ one_im], (s/2) nowhere. And in D: w₁ = (1−s)/2 im = −t/2, w₂ = (s+4)/2 im = t/2 — NEEDED for the digamma_stirling hypothesis |im w| ≥ 1/2 and the 3/(im)² bound. Hmm! So I DO need im((1−s)/2) = −t/2 etc. So the div-im computation is needed. Let me nail it:\n\n`(x / 2).im = x.im / 2`: \n```\ntheorem im_div_two (x : ℂ) : (x / 2).im = x.im / 2 := by\n  rw [div_eq_mul_inv, Complex.mul_im]\n  have : ((2 : ℂ)⁻¹).im = 0 ∧ ((2 : ℂ)⁻¹).re = 1 / 2 := by\n    rw [show (2:ℂ) = ((2:ℝ):ℂ) by norm_num, ← Complex.ofReal_inv]\n    constructor\n    · rw [Complex.ofReal_im]  -- (↑(2⁻¹)).im = 0... wait after ← ofReal_inv: ↑(2:ℝ)⁻¹ = ↑((2:ℝ)⁻¹): (2:ℝ)⁻¹ as real = 1/2: norm_num\n      ...\n```\ngetting long. Try: \n```\ntheorem im_div_two (x : ℂ) : (x / 2).im = x.im / 2 := by\n  rw [Complex.div_im]\n  simp only [ofNat_re, ofNat_im, mul_zero, sub_zero, ofReal_re? ...]\n```\nLet me just grep the exact simp lemma names for numeral re/im and div_im formula.","signature":""},{"type":"text","text":"A few last name checks for numeral re/im simp lemmas and `div_im`."},{"type":"tool_use","id":"Bash_36","name":"Bash","input":{"command":"cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem div_im\\|theorem div_re \\|ofNat_im\\|ofNat_re\" Mathlib/Data/Complex/Basic.lean Mathlib/Analysis/Complex/Basic.lean Mathlib/Data/Complex/Exponential.lean 2>/dev/null | head -8 && grep -rn \"ofReal_div_im\\|ofReal_div_re\\|theorem ofReal_im\\|theorem ofReal_re\" Mathlib/Data/Complex/Basic.lean 2>/dev/null | head -6","description":"Find div_im and numeral re/im simp lemmas"},"extra_content":null}]