Session 21 — Tier ii′ planning + launch: close SfBoundProp in Lean (D-064)
08-21-2026 → 08-21-2026 · kimi-k3 · 112 messages · 1142.4k tokens · $39.5136
Summary
Focus: paper split + tier ii′ launch (research sessions 013–014).
What happened:
- Paper split executed: paperA.tex (self-contained finite-height Li artifact, 8 pp), paperB.tex (spectral-line note skeleton), draft.tex frozen; authorship set to sole author Dan T Nguyen, Research Ai; submission documents written; pre-submission audit D-063 all checks pass.
- User chose option (a): close SfBoundProp in Lean BEFORE submission — tier ii′ launched.
- ii′-0 design (D-064) with two discoveries: the liCoeff encoding defect (junk tsum ⟹ vacuous theorems) and the crux identity Sf(n) = Res₁(n) EXACT (assembly becomes tail-free).
Outcome: Paper A submission-ready and frozen; the ii′ sub-stage map (~9–16 sessions) opened.
review the current research and let me know when you are ready for me
thinking (427 chars)
I've read STATE.md, session-013 journal, and results/index.md. Let me quickly check git status to see if there's anything uncommitted, and verify the working tree is clean. Actually the git status snapshot shows only untracked build artifacts (.bbl, .blg, .fdb_latexmk, .fls, .pdf) and research/paper/submit/ — all consistent with session 013's end state.
I have a complete picture. Time to report ready to the user concisely.
Review complete. I'm up to speed and ready.
**Where the project stands (end of session 013, 2026-08-20):**
- **Phases 0–4 complete.** Phase 5: paper (5.3 ✔), honesty audit (5.4 ✔), live axiom audit (5.2 ✔), Lean tier (i) + tier (ii) steps 1–2 ✔.
- **Paper A is submission-ready**: 9 pp, compiles clean, sole-authored (Dan T Nguyen, Research Ai), AI Contribution Statement, fixed Voros reference, full pre-submission Lean audit ALL CHECKS PASS (D-063 — 139 declarations swept, only 3 standard axioms + 5 intended skeletons). Cover letter + referee list drafted (target: *Experimental Mathematics*).
- **Paper B**: 6 pp research-note skeleton with §0 standing items (R-003 FT bookkeeping trace → queued as D-064; L3/L4 skeleton; authorship resolved).
- **Working tree**: clean except untracked LaTeX build artifacts — consistent with the session-013 end state.
**Open items, in the order STATE.md recommends:**
1. Your read-through of `paperA.pdf` — nothing else blocks circulation.
2. Repo-publication prep (README + Lean build instructions + license) → then arXiv (endorsement needed, start early).
3. Paper B Task 1 (next research action): trace R-003's tempered-FT bookkeeping, make o(eᵃ) quantitative → D-064.
4. Optional polish: E-023b acb M₀ certificate; figures from numerics CSVs.
No blockers. What would you like to do?
Please check the research process and paper if the full D-037/D-056 contour was calculated and Lean proves |S_f(n)| \leq B(n) over the required range without assuming SfBoundProp as follow:
Platt–Trudgian RH verification to 3 × 10¹²
plus
rigorously certified finite Li-coefficient verification up to the splice point
plus
Lean-verified contour bound
plus
Lean-verified archimedean bound, convexity, and assembly
which would yield
λₙ > 0 for 1 ≤ n ≤ (3 × 10¹² − 1)² ≈ 9 × 10²⁴.
Please check if the reseach do this?
thinking (1926 chars)
The user is asking a precise audit question: does the current research actually achieve the R-004 theorem with the Lean proof discharging the contour bound |S_f(n)| ≤ B(n) over the required range WITHOUT assuming SfBoundProp as a hypothesis?
From what I know from the session logs:
- Session 012: `lambda_pos_finite_height_verified` PROVED modulo the single named analytic hypothesis SfBoundProp + the declared computational perimeter (RHUpTo, LiVerifiedUpTo).
- D-062 §4: PERIMETER DECISION — Trudgian N(T)/S(T) inside the trusted perimeter; tier ii′ (SfBoundProp contour layers L0–L3) POST-PUBLICATION per session-012-end-notes review.
So the short answer is almost certainly: NO — the current state assumes SfBoundProp as a hypothesis; the Lean-verified contour bound is NOT done (tier ii′ is post-publication). The D-037/D-056 contour was calculated analytically (with constants traced: D-056 reference-point R-bound proved, A=10.5, B₀=48; E-028 verified with 26× slack), but the Lean formalization of that contour bound is NOT done — it's exactly what SfBoundProp stands in for.
But I should verify this carefully by checking the actual files rather than just relying on memory/STATE.md. Let me check:
1. LiSkeleton.lean / LiBasePoints.lean — look at SfBoundProp and what hypotheses the theorem has.
2. D-037 (assembly) and D-056 (R-bound proof) — what was actually calculated.
3. D-062 §4 — the perimeter decision and what's inside/outside.
4. Paper A's statement — what it claims.
Let me read the relevant files. I need to be thorough and precise here — the user is asking for an audit.
Plan:
- Grep for SfBoundProp in the Lean package.
- Read D-062 (triage of SfBoundProp, perimeter decision).
- Read D-037 (assembly) to see the contour calculation.
- Read D-056 (R-bound reference-point proof).
- Check paperA.tex's formal verification appendix to see what's claimed.
Let me do this in parallel where possible.
Good question — this is exactly the right audit to run before circulation. Let me verify against the actual files rather than the summaries.
tool: Grep
input
{
"pattern": "SfBoundProp",
"path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1",
"output_mode": "content",
"-n": true
}
tool: Glob
input
{
"pattern": "research/derivations/D-0{37,56,62}*.md",
"path": "D:\\Python\\Quantum"
}
thinking (428 chars)
The answer is now quite clear. Let me also verify what the paper (paperA.tex) actually claims, to make sure the paper is honest about this. Let me check the Formal Verification appendix of paperA.tex and its theorem statement. Also double-check D-037/D-056 to confirm the contour WAS calculated analytically (pen-and-paper with traced constants), which the user is also asking ("if the full D-037/D-056 contour was calculated").
Now let me check what Paper A actually claims, and confirm the D-037/D-056 analytic status.
tool: Grep
input
{
"pattern": "SfBoundProp|contour|hypotheses|remaining|modulo",
"path": "D:\\Python\\Quantum\\research\\paper\\paperA.tex",
"output_mode": "content",
"-n": true,
"head_limit": 60
}
tool: Read
input
{
"file_path": "D:\\Python\\Quantum\\research\\derivations\\D-037-finite-height-theorem.md",
"limit": 80
}
thinking (4364 chars)
Now I have the complete picture. Let me summarize precisely for the user.
The user's proposed four-part stack:
1. Platt–Trudgian RH verification to 3×10¹² ✓ (this is the `RHUpTo` hypothesis — declared perimeter, NOT proved by us; it's a published computational certificate)
2. Rigorously certified finite Li verification up to splice point ✓ (`LiVerifiedUpTo 5×10⁵` — declared perimeter: our E-011/E-015 to 3000 + Misguich–Voros to 5×10⁵)
3. **Lean-verified contour bound** — ✗ NOT done. This is exactly `SfBoundProp`, which is ASSUMED as a named hypothesis, not proved.
4. Lean-verified archimedean bound, convexity, assembly ✓ (tier (i): sInfty_lower_bound, marginTilde_convex, chain_rule_sqrt_shift all PROVED; tier (ii) steps 1+2: assembly + base points PROVED)
So the answer to the user's question "Please check if the research do this?" is: NO — three of the four components are in place, but the third one (Lean-verified contour bound) is NOT. The current theorem `lambda_pos_finite_height_verified` has SfBoundProp as a hypothesis. D-062 §4 says tier ii′ (the contour layers L0–L3 inside SfBoundProp) is POST-PUBLICATION.
What IS done on the contour side:
- The full D-037/D-056 contour WAS calculated analytically (pen-and-paper with all constants traced): D-036 (contour constants), D-037 §4 (assembly of B(n)), D-056 (reference-point R-bound repair, A = 10.5, B₀ = 48, proved honestly with the C₀ log log term), E-028 (26× slack verification), E-029 (convexity). The analytic chain is complete and survived the adversarial review (D-054 found the holes; 4.5a–4.5d repaired them).
- But the Lean formalization of that contour argument is exactly what's isolated in SfBoundProp. D-062 §3 triages its eventual proof into layers L0–L7: L0 (rectangle contour identity — the main lift, Mathlib meromorphic-residue machinery is thin), L1–L3 (Mathlib-tractable modulo L4), L4 (Trudgian N(T)/S(T) — decided PERIMETER), L5 (bridge — perimeter via RHUpTo), L6 (M₀ — computational perimeter after E-023b), L7 (summability).
So the user's four-part decomposition is EXACTLY the structure the research has — but with component 3 still open (it's the declared hypothesis, honestly tagged in the paper). The paper itself says this explicitly: paperA.tex line 347ff "machine-proved from exactly three named hypotheses", line 351 SfBoundProp = "the traced contour bound", line 370-371 "The remaining formalization target inside this paper is (ii′) the contour estimate inside SfBoundProp".
One more check — the user's item 1 says "Platt–Trudgian RH verification" and item 2 "certified finite Li verification" — in the current Lean theorem these are also hypotheses (RHUpTo, LiVerifiedUpTo), i.e., trusted perimeter, not Lean-proved. The user's list presents them as ingredients to trust, which matches the perimeter decision. But note the user's framing says "plus rigorously certified finite Li-coefficient verification" — that's the perimeter too, not Lean-internal. So in the user's proposed stack, items 1 and 2 are external certificates (trusted), and 3, 4 are Lean-verified. Current state: 1 ✓ (as hypothesis), 2 ✓ (as hypothesis), 4 ✓ (proved), 3 ✗ (hypothesis, not proved).
Also worth noting: the range. SfBoundProp covers n ∈ [10⁵, N₁]; LiVerifiedUpTo covers n ≤ 5×10⁵ (overlap 5× at the splice 10⁵); the assembly covers everything. The final conclusion ∀ n, 1 ≤ n → n ≤ (3×10¹²−1)² → 0 < liCoeff n.re is exactly the user's stated yield.
So the answer: No — the research does NOT currently achieve that full stack. It achieves it modulo SfBoundProp. The contour bound |S_f(n)| ≤ B(n) over [10⁵, N₁] is the single remaining analytic hypothesis. It was triaged (D-062) and deferred to post-publication (tier ii′) per the mathematician's review guidance. Everything else in the user's stack is in place.
Also relevant: the paper is HONEST about this — it claims exactly "machine-verified modulo one named analytic hypothesis (the traced contour bound) + the declared computational perimeter." So no overclaim. If the user wants the full stack as they describe, the remaining work is tier ii′: formalizing L0–L3 (with L4/L6 as declared perimeter). D-062 estimates L0 (rectangle contour identity with residues) is the main lift — Mathlib's meromorphic residue machinery on rectangles is thin.
Let me write a concise, precise answer with file:line references.
Clear answer: **No — the research does not yet do this.** Three of your four components are in place, but the third — the Lean-verified contour bound — is exactly the one remaining open hypothesis. It is assumed, not proved, and the paper says so explicitly.
Component-by-component against your stack:
| Your component | Status |
|---|---|
| Platt–Trudgian RH to 3×10¹² | In Lean as named hypothesis `RHUpTo (3*10^12)` — trusted perimeter, not re-proved (matches your framing) |
| Certified Li verification to splice | In Lean as `LiVerifiedUpTo (5*10^5)` — trusted perimeter (E-011/E-015 to 3000 + Misguich–Voros to 5×10⁵) |
| **Lean-verified contour bound \|S_f(n)\| ≤ B(n)** | **NOT DONE.** This is precisely `SfBoundProp` (LiSkeleton.lean:2131-2133), assumed as a named hypothesis over n ∈ [10⁵, N₁] |
| Lean-verified archimedean bound, convexity, assembly | DONE — `sInfty_lower_bound`, `marginTilde_convex` (tier i), assembly + certified base points (tier ii steps 1–2), all sorry-free |
What exists now is `lambda_pos_finite_height_verified` (LiBasePoints.lean:631-637): λₙ > 0 for 1 ≤ n ≤ (3×10¹²−1)² proved from exactly three hypotheses — `RHUpTo`, `LiVerifiedUpTo`, **`hSf : SfBoundProp`**. PrintAxioms = 3 standard axioms, no sorryAx.
**On the contour itself:** the full D-037/D-056 contour *was* calculated analytically — all constants traced (A = 10.5, B₀ = 48 with the honest C₀ log log term, D-056; B(n) assembly D-037 §4; E-028 verified with 26× slack), and it survived the four-instance adversarial review plus repairs (D-054 → D-056–D-059). But that is pen-and-paper mathematics, not Lean. The Lean formalization of the contour argument is what `SfBoundProp` stands in for.
D-062 §3 triages what closing it takes: L0 (rectangle contour identity with residues — the main lift; Mathlib's meromorphic-residue machinery on rectangles is thin), L1–L3 (Mathlib-tractable), L4 (Trudgian N(T)/S(T) — decided perimeter), L6 (M₀ — perimeter after E-023b). This is "tier ii′", explicitly deferred to **post-publication** per the session-012 mathematician review, and Paper A declares it as the remaining formalization target (paperA.tex:370-371).
So: the theorem statement and the paper's claim are honest — "machine-verified modulo one named analytic hypothesis" — but the stack you describe, with the contour bound Lean-proved, is the tier ii′ project, not the current state. Do you want to take up tier ii′ now (starting with L0, the contour identity), or proceed with submission with `SfBoundProp` declared?
Let's regroup to work on tier ii', but first let plan it correctly. What is take to accomplish this task? Break this down into sub-stages so we can work on it one at a time. What is the possiblity of this can be done? Please think deep and analyze the problem we have here and find ways to close the Lean-verified contour bound issue we have in this paper. Let me know what you think and your plan on this matter.
thinking (55491 chars)
The user wants to plan tier ii′: closing the Lean-verified contour bound `SfBoundProp`. This is a significant planning task. Let me think deeply about this.
The goal: prove in Lean 4 (Mathlib):
```
SfBoundProp : ∀ n : ℕ, 100000 ≤ n → (n : ℝ) ≤ (3 * 10^12 - 1 : ℝ)^2 → |Sf n| ≤ Bn FAlt (n : ℝ)
```
where `Sf n := SInfty n + 1 - (liCoeff n).re` and `Bn FAlt n` is the explicit traced bound.
Per D-062 §3 triage, the proof decomposes into layers:
- **L0**: Rectangle contour identity for `k_n(w−1)(−ζ′/ζ)`: residues at zeros give the truncated zero sum; assembling Sf = S_∞ + 1 − λ_n from the contour output. **Mathlib-partial**: meromorphic residue machinery on rectangles is thin in current Mathlib; this is the main formalization lift.
- **L1**: Kernel bounds: |k_n| ≤ 2, ≤ e⁴+1, ≤ e^{√n/2}+1; stepping (6.12); trivial residue ≤ 1. **Mathlib-tractable**.
- **L2**: Reference-point R-bound (D-056 Thm R: |R(s)| ≤ 10.5 log(|t|+2) + 48): partial fractions for ζ′/ζ (Hadamard product of ξ), digamma Lemma D, unit-interval grouping. **Mathlib-tractable modulo L4**.
- **L3**: Zero-avoiding T ∈ [√n, √n+1] (pigeonhole gap center). **Mathlib-tractable modulo L4**.
- **L4**: Trudgian 2014 explicit N(T), S(T) bounds — decided PERIMETER.
- **L5**: Bridge: zeros with |γ| ≤ T ≤ T₀ on the line ⟹ each zero term ≤ 2 — uses RHUpTo, already perimeter.
- **L6**: M₀ ≤ 1.3352 on |t| ≤ 10 — grid-verified E-023; computational perimeter after E-023b.
- **L7**: liCoeff summability — folds into L0.
The user asks:
1. What does it take to accomplish this task?
2. Break it down into sub-stages to work on one at a time.
3. What is the possibility this can be done?
4. Think deep, analyze, find ways to close the Lean-verified contour bound issue.
Let me think deeply about the actual mathematical and formalization content.
### What is the actual mathematics that needs formalizing?
The contour argument (D-036, D-037 §4, Lagarias Thm 6.1 variant B):
1. **Setup**: For n ≥ 10⁵, consider the rectangle with vertices at σ₀ = −5/2, σ₁ = 2√n, Im = ±T, where T ∈ [√n, √n+1] is chosen zero-avoiding. Integrand: `k_n(w−1)(−ζ′/ζ(w))` where `k_n(s) = (1+1/s)^n − 1`.
2. **Residue theorem**: The integral over the rectangle equals 2πi × sum of residues at poles inside:
- At each nontrivial zero ρ with |γ| ≤ T: residue contributes `k_n(ρ−1)` × (order), giving the truncated zero sum `Σ'_{|γ|≤T} [1 − (ρ/(ρ−1))^n]·(−1)` (note `k_n(ρ−1) = (ρ/(ρ−1))^n − 1`).
- At s = 0 (pole of ζ′/ζ? No — ζ has no pole at 0... wait, let me think. ζ′/ζ has poles at zeros of ζ and at s = 1 (pole of ζ). Actually also trivial zeros are inside or on boundary... σ₀ = −5/2 so trivial zeros at −2, −4 are inside. Hmm, wait, trivial zeros at −2 and −4 are inside the rectangle (σ from −5/2 to 2√n). So their residues also contribute.
- At s = 1: pole of ζ, residue of ζ′/ζ is −1, contributing `k_n(0)·1 = (1+1/0)^n...` wait, `k_n(w−1)` at w = 1 is `k_n(0)` which is singular. Hmm, but k_n(s) = (1+1/s)^n − 1 has a pole at s = 0 of order n. And ζ′/ζ at s = 1 has residue −1 (since ζ has a pole, ζ′/ζ ~ −1/(s−1)). The product k_n(w−1)(−ζ′/ζ(w)) at w=1: k_n(w−1) ~ (w−1)^{−n}, −ζ′/ζ ~ 1/(w−1). So the product has a pole of order n+1 at w = 1. The residue there is a complicated expression — but this is exactly what produces the S_∞ archimedean terms...
Actually wait. In Lagarias's setup (BL Thm 2): λ_n = S_∞ − S_f + 1 where the contour integral identity directly gives S_f = S_∞ + 1 − λ_n. The way D-062 phrased it: "the D-036 contour computation (Lagarias Thm 6.1 variant B) produces the identity AND the bound in one stroke, so SfBoundProp as stated is exactly what the contour argument proves directly."
The identity: S_f(n) = Σ_{|γ|≤T}′ [1 − (ρ/(ρ−1))ⁿ]·(−1) + (1/2πi)(I_I+I_II+I_III+I_IV) + triv(−2) where I_I..I_IV are the four sides, and the residue at w=1 contributes the S_∞-related terms... hmm, actually let me not over-reconstruct; the point is the identity is established in D-036/D-037 and the residues at w=1 (high-order pole) yield polynomial-in-n terms involving log and constants that combine into the S_∞ + 1 − λ_n structure.
Actually, from D-037: `S_f(n) = Σ_{|γ|≤T}′ [1 − (ρ/(ρ−1))ⁿ]·(−1) + (1/2πi)(I_I+I_II+I_III+I_IV) + triv(−2)`. And `Sf n := SInfty n + 1 − (liCoeff n).re`. And λ_n = Σ′_ρ [1−(1−1/ρ)ⁿ] (full sum over all zeros). So the identity is: SInfty + 1 − λ_n = −Σ_{|γ|≤T}′[1−(ρ/(ρ−1))ⁿ] + contour terms + trivial-zero terms. Hmm, and the full zero sum λ_n = Σ′_ρ[1−(1−1/ρ)ⁿ] — note 1−1/ρ = (ρ−1)/ρ, so (1−1/ρ)ⁿ... and 1−(ρ/(ρ−1))ⁿ is a different expression. The relation: pairing ρ ↔ 1−ρ. This is standard Li-coefficient theory.
OK, the point for planning: the identity involves:
- The full zero sum (liCoeff, defined as a tsum over zeros — summability = L7)
- The truncated zero sum (finite, from residues)
- The tail of the zero sum beyond T — bounded by 2N(tail)... wait no. Actually the identity as stated in D-037 has the truncated sum on the RHS plus the contour integrals. The full λ_n appears on the LHS. So the identity must account for the tail Σ_{|γ|>T}. Hmm — how does that work?
Let me think again. In Lagarias Thm 6.1 variant B (D-036): the contour at finite T gives:
∫rectangle k_n(w−1)(−ζ′/ζ) = 2πi [Σ_{|γ|≤T} residues + residue at w=1 + trivial-zero residues]
And separately, λ_n is defined by the convergent sum over ALL zeros. The identity S_f = S_∞ + 1 − λ_n is BL Thm 2. Lagarias's variant B computes S_f(n) (which is a sum over zeros, the "finite part" of the BL decomposition) by truncating at T: the zero sum Σ_ρ [1−(ρ/(ρ−1))ⁿ]...
Hmm, actually in BL Thm 2, λ_n = S_∞ − S_f + 1 where S_f is itself a sum over zeros (the finite part). The contour method evaluates this zero sum by truncation + explicit remainder. The tail beyond T for the S_f sum: terms ~ n/|ρ|² (since 1−(ρ/(ρ−1))ⁿ ≈ ... for large ρ, (ρ/(ρ−1))ⁿ = (1+1/(ρ−1))ⁿ ≈ 1 + n/(ρ−1) + O(n²/ρ²), so 1 − that ≈ −n/(ρ−1) + O(n²/ρ²), and Σ_{|γ|>T} n/|ρ|² ~ n log T / T ≤ √n-ish small. Hmm wait, but actually D-037's identity as quoted includes "Σ_{|γ|≤T}′ [1 − (ρ/(ρ−1))ⁿ]·(−1)" — so the contour directly produces the truncated version of the S_f zero sum, and the tail of S_f's zero sum must be bounded separately (that's part of the B(n) accounting, presumably in the "zeros ≤ 2N(T)" term plus a tail term... actually D-037 says "|Σ| ≤ 2N(T) ≤ 2F(T) + 2S_bnd(T)" using RH-to-T₀ — that's the truncated sum bound, each term ≤ 2. The tail of the S_f sum: bounded by Σ_{|γ|>T} |1−(ρ/(ρ−1))ⁿ| ≤ Σ n·|ρ|⁻¹-ish...
Hmm, I'm not going to fully reconstruct D-036's exact accounting here. For the plan, what matters is the STRUCTURE of what must be formalized, at the level of the D-062 triage. But let me look at what I know:
From D-037 §4 (what I read):
- Rectangle σ₀ = −5/2, σ₁ = 2√n, Im = ±T, T ∈ [√n, √n+1] zero-avoiding
- Integrand k_n(w−1)(−ζ′/ζ(w)), k_n(s) = (1+1/s)ⁿ − 1
- Identity: S_f(n) = Σ_{|γ|≤T}′ [1 − (ρ/(ρ−1))ⁿ]·(−1) + (1/2πi)(I_I+I_II+I_III+I_IV) + triv(−2)
- Trudgian N(T) bounds, C₀ unit-interval counts
- R-bound: |ζ′/ζ(w) − Σ_{|γ−t|<1} 1/(w−ρ)| ≤ A log(|t|+2) + B₀
- Pieces: zeros ≤ 2N(T); left vertical via |k_n| ≤ 2 and |ζ′/ζ| bound; etc.
- B(n) = 2F(T) + 4T[(2/3)Ĉ₀(T) + 10.5 log(T+2) + 48] + 40·1.3352 + 2(e⁴+1)·[7Ĥ(T) + 3.3] + IIMaj(n) + 1
### What's in Mathlib?
This is the crux of feasibility. What does current Mathlib (v4.33.0-rc2 era, mid-2026... well, the project uses v4.33.0-rc2) have?
1. **riemannZeta**: Mathlib has `riemannZeta` with analytic continuation, functional equation, the pole at 1, trivial zeros. As of recent versions, Mathlib has:
- `riemannZeta` defined for all s via Hurwitz zeta
- Functional equation (completedRiemannZeta, the ξ function as `completedRiemannZeta`)
- `riemannZeta_residue_one` / the simple pole at s=1 with residue 1
- Trivial zeros: `riemannZeta_neg_two_mul_nat` (ζ(−2n) = 0)
- Log derivative ζ′/ζ: there's `logDeriv`, and for ζ there might be some API. zeta-23-lean repo itself has counting functions vs Mathlib riemannZeta — the R3 resource. The zeta-23-lean project (v1.0) formalized zero-counting functions. That's OUR inherited library — it has N(T)-related machinery? Let me recall: R3 "zeta-23-lean repo (tag v1.0): Lean 4 formalization, counting functions vs Mathlib riemannZeta". D-007 audited it. So zeta-23-lean has SOME zero-counting infrastructure on top of Mathlib. That's relevant — L3/L4 might partially exist there. Actually the zeta-23 challenge was about... hmm, "counting functions vs Mathlib riemannZeta". I should check what's actually in it during planning execution.
2. **Contour integration / residue theorem**: Mathlib has:
- `circleIntegral`, Cauchy integral formula for circles, `Complex.circleIntegral_sub_inv_smul_of_differentiable_on_off_countable`...
- Rectangle integrals: Mathlib has `Complex.integral_boundary_rect_of_hasFDerivAt_real_off_countable` (Cauchy's theorem for rectangles), and `Complex.windingNumber`... There's the "Cauchy integral formula for a rectangle" — I recall `Complex.integral_boundary_rect_eq_zero_of_differentiable_on_off_countable` and versions with the winding number. For RESIDUES at multiple poles on rectangles: Mathlib has been developing `MellinTransform` and residue machinery for PNT... Actually, the Prime Number Theorem formalization (PNT+ project by Kontorovich et al.) developed exactly this: rectangle contours, ζ′/ζ bounds, residue computations! PNT+ is a separate project, not in Mathlib core, but parts have been upstreamed. By 2026, how much is in Mathlib? Uncertain. The PNT+ project (Kontorovich, Bordg, Do, etc.) formalized PNT with explicit contours around ζ′/ζ. If PNT+ is available as a dependency, L0 gets dramatically easier — they have `RectangleIntegral`, residue computations for ζ′/ζ with poles at zeros and at 1.
Hmm, but adding PNT+ as a dependency is a big decision (version compatibility with v4.33.0-rc2). Alternatively, port the needed lemmas.
3. **Zeros of ζ**: Mathlib has `riemannZeta` zeros API? There's `Complex.riemannZeta` and... I believe Mathlib has the nontrivial zeros set? Not sure there's much. zeta-23-lean defines its own zero-counting.
4. **Hadamard factorization of ξ**: Does Mathlib have entire-function product theory? There's some: `Complex.Prod`... Mathlib has Weierstrass products? There's `MellinCalculus`... Actually Mathlib does have the Hadamard product for ξ? I recall work on `riemannXi`... not sure. The partial-fraction expansion ζ′/ζ(s) = B + log... − Σ ... (the R-bound reference-point formula) requires:
- ζ′/ζ(s) = log Γ(s/2)-related terms + Σ_ρ [1/(s−ρ) + 1/ρ] + const (Hadamard)
- The digamma bound (Lemma D in D-056, proved in D-039/D-056 with |r| ≤ 1.2/|w|² remainder)
- Reference-point trick (D-056 repair: bound R(s) by comparing at a reference point to avoid the O(|t| log t) hole)
Mathlib has `Complex.Gamma` log derivative = digamma? Mathlib has `Complex.digamma`? There's `Real.Gamma`... As of recent Mathlib, there IS `Complex.digamma` I believe (added for Gamma function API). And the product formula... uncertain.
5. **Convexity/margin machinery**: DONE (tier i/ii).
### Feasibility assessment
Let me think about each layer's real difficulty:
**L0 (contour identity)** — The hardest. Needs:
- Rectangle residue theorem for meromorphic functions with finitely many poles inside (partially in Mathlib; the rectangle version with winding number exists; multiple-pole version needs assembling)
- Identification of poles of k_n(w−1)(−ζ′/ζ(w)): at zeros ρ (simple, residue −k_n(ρ−1)·ord... for simple zeros), at w = 1 (pole of order n+1 — residue = a specific finite combination, computable via the Taylor expansion of the regular part), at trivial zeros −2, −4 (simple)
- The residue at w=1 computation: order n+1 pole — in Lean this is `(n)!⁻¹ · lim dⁿ/dwⁿ [(w−1)^{n+1} · integrand]` — messy but doable? Actually there's a trick: Lagarias variant B might handle s=1 differently (the k_n kernel is designed so that... hmm, k_n(w−1) = (1+1/(w−1))ⁿ − 1 = (w/(w−1))ⁿ − 1. At w = 1 this has a pole of order n. And −ζ′/ζ has a simple pole with residue +1 (since ζ has a pole, ζ′/ζ ~ −1/(s−1), so −ζ′/ζ ~ +1/(s−1)). So product pole order n+1. The residue yields the archimedean/S_∞-side terms. In D-037's accounting, the identity is S_f = truncated zero sum + contour sides + triv(−2) — the w=1 residue must equal −(S_∞-side) exactly? No wait — S_f(n) := S_∞(n) + 1 − λ_n. And BL Thm 2 gives λ_n = S_∞ − S_f + 1. The contour identity must reproduce this. The residue at w=1 of order n+1 gives exactly the terms that turn "Σ over ALL zeros" into "S_∞ + 1 − λ_n"...
Hmm, actually maybe the cleaner formalization route: prove the identity in the form
S_f(n) = Σ_{|γ|≤T} [residue terms] + (1/2πi)∮sides
where S_f is DEFINED as SInfty + 1 − liCoeff.re (as in the Lean code). The identity to prove is an equation between a tsum-defined quantity and contour data. The natural proof: (a) λ_n as zero sum (definition of liCoeff in Mathlib? Is there `liCoeff` in Mathlib?? The Lean code references `liCoeff n` — where is that defined? In NguyenRH1! Let me recall — `Sf (n : ℕ) : ℝ := SInfty n + 1 - (liCoeff n).re`. `liCoeff` must be defined somewhere in NguyenRH1 or Mathlib. Probably NguyenRH1 defines `liCoeff n := ∑' ρ, (1 - (1 - 1/ρ)^n)` over the zero set — and L7 (summability) is flagged. So liCoeff is our own definition over the nontrivial zeros (defined via some enumeration or as a tsum over the zero set as a subtype).
So the contour identity proof needs:
(i) The residue computation at each zero inside (simple poles — clean)
(ii) The residue at w = 1 (order n+1 pole — the hard residue; but its value is EXACTLY `S_∞(n) + 1 − [tail of zero sum]`... no. Let me think about what the w=1 residue actually equals.
From Lagarias Thm 6.1: he computes exactly this residue. k_n(w−1) = Σ_{j=1}^n C(n,j) (w−1)^{−j}. So the integrand is Σ_j C(n,j) (w−1)^{−j} · (−ζ′/ζ(w)). Near w = 1: −ζ′/ζ(w) = 1/(w−1) − γ + O(w−1) (the Laurent series with Stieltjes constants: ζ′/ζ(s) = −1/(s−1) + γ + ...). So (w−1)^{−j}(−ζ′/ζ) has residue = coefficient of (w−1)^{j−1} in −ζ′/ζ = the Stieltjes-ish coefficient: for j=1: 1; for j≥2: (−1)^j γ_{j−2}/(j−2)!? The residue at w=1 is then Σ_{j=1}^n C(n,j)·a_j where a_1 = 1 and a_j = coefficient. And Lagarias identifies this with the archimedean sum S_∞(n) = Σ_j (−1)^j C(n,j) a_j... with the a_j = (1−2^{−j})ζ(j) relation via the Laurent coefficients of −ζ′/ζ at 1 being expressed through η(j) = (1−2^{1−j})ζ(j)... There are standard identities here (D-037 §3 uses Lagarias (4.11): S_∞(n) = Σ_{j=1}^n (−1)^j C(n,j) a_j, a₁ = (log 4π + γ)/2, a_j = (1−2^{−j})ζ(j)).
So the w=1 residue equals S_∞(n) ± const, and the trivial-zero residues are computable constants. The identity assembly:
(1/2πi)∮ = [Σ_{|γ|≤T} −(1−(ρ/(ρ−1))ⁿ)... signs] + [S_∞(n) piece] + [trivial pieces]
and rearranging with λ_n = full zero sum gives S_f = S_∞ + 1 − λ_n = [truncated sum] + [sides] + [trivial] + [tail of zero sum with sign].
Wait — but then where does the TAIL of the zero sum enter B(n)? |λ_n − truncated|: the tail Σ_{|γ|>T} [1−(1−1/ρ)ⁿ]. Bound: |1−(1−1/ρ)ⁿ| = |1−((ρ−1)/ρ)ⁿ| ≤ n/|ρ| · (something) for large ρ — standard: |(1−w)ⁿ − 1| ≤ n|w|·e^{n|w|} or ≤ 2n|w| for |w| ≤ 1/n. With w = 1/ρ: ≤ 2n/|ρ|. Tail ≤ 2n Σ_{|γ|>T} 1/|ρ|² ~ 2n·(log T)/T ≈ 2√n log T. Hmm, that's significant — is there such a term in B(n)? B(n) = 2F(T) + 4T[...] + ... The 4T[...] terms ~ 4T·(2/3)C₀ ~ T·log T-ish = √n log n-ish. The tail ~ √n log T would be smaller. But I don't see an explicit tail term in B(n)... unless the "zeros" term 2F(T) is bounding |Σ_{|γ|≤T}′[1−(ρ/(ρ−1))ⁿ]| ≤ 2N(T) AND the identity as D-037 states it directly has S_f = truncated + sides + triv, with the tail absorbed because... hmm, D-037's identity is EXACT: "S_f(n) = Σ_{|γ|≤T}′ [1 − (ρ/(ρ−1))ⁿ]·(−1) + (1/2πi)(I_I+I_II+I_III+I_IV) + triv(−2)". So there's no tail — the identity is exact at finite T. That means S_f's zero-sum definition must be such that truncation is exact — i.e., the contour identity proves S_f (defined via S_∞ + 1 − λ_n) equals the truncated expression exactly. Fine — that's the L0 theorem. The tail is handled inside the identity proof: ∮ sides converge... no, at finite T the identity is exact by residues. The connection between the residue sum and liCoeff requires the FULL zero sum to appear, i.e., the residue computation gives Σ_{|γ|≤T}, and the definition S_f = S_∞ + 1 − λ_n involves the full sum. So the identity proof needs: full sum = truncated + tail, and the tail must be canceled/absorbed by something — presumably the residue at w=1 and the S_∞ identification don't involve the tail...
Hmm wait, I think I have the structure slightly off. Let me reconsider: probably the actual Lagarias variant-B identity is:
λ_n = Σ_{|γ|≤T}[1−(1−1/ρ)ⁿ] + tail, and separately the contour gives an exact expression for the truncated sum Σ_{|γ|≤T}[1−(1−1/ρ)ⁿ] = [sides + w=1 residue + trivial residues]. Then S_f = S_∞ + 1 − λ_n = S_∞ + 1 − [that exact expression] − tail. And the w=1 residue = S_∞ + 1 − (constants) so it cancels. Then |S_f| ≤ |sides| + |trivial| + |tail|, and the tail IS one of the bounded pieces. Given B(n) includes "2F(T)" as "the zeros term", maybe 2F(T) bounds the tail? No — tail ≤ 2nΣ_{|γ|>T}1/|ρ|² — with Σ_{|γ|>T}1/|ρ|² ≤ ∫_T^∞ dN(t)/t² ≤ ~log T/T: tail ≤ 2n·C·log T/T ≈ 2√n·C·log T. And 2F(T) ≈ (T/π)log T = (√n/π)·(½log n). Compare: 2√n C log T vs (√n/π)(log n)/2... these are the same order! So maybe the 2F(T) term actually bounds the TAIL (via Stieltjes-integral zero-counting), and the truncated sum... no wait, D-037 §4 says "zeros: with RH to height T₀ and n ≤ (T₀−1)², every zero with |γ| ≤ T ≤ T₀ is on the line ⟹ |ρ/(ρ−1)| = 1 ⟹ each term ≤ 2: |Σ| ≤ 2N(T) ≤ 2F(T) + 2S_bnd(T)". So 2F(T) bounds the TRUNCATED sum (each of N(T) terms ≤ 2). Hmm, so the identity in D-037 has the truncated sum on the RHS — meaning S_f itself equals truncated + sides + triv EXACTLY, with no tail. OK so the exact identity at finite T is what it is; the formalizer must prove exactly that identity. The subtle point: the identity connects liCoeff (full sum) to the truncated sum — the difference IS the tail, and the identity says tail = sides + w=1-residue-excess + triv... i.e., the identity IS nontrivial but exact. Whatever — the exact bookkeeping is in D-036; for the plan, L0 = "prove the exact identity (D-036 §0)".
**The w=1 high-order-pole residue**: order n+1 pole. In Lean, computing residues of order n+1... Mathlib has `Complex.residue`?? I don't think Mathlib has a general residue API. PNT+ computes residues via `RectangleIntegral` + explicit local manipulations. For a pole of order n+1 where n is a VARIABLE (n ≥ 10⁵!), you can't just "compute the residue" — you need the closed-form identification with S_∞(n) = Σ_j (−1)^j C(n,j) a_j and then the a_j values. This is genuinely intricate: it requires the Laurent coefficients of −ζ′/ζ at s=1 to all orders j ≤ n, identified with (1−2^{−j})ζ(j) up to signs — via the Laurent series of ζ at 1 (Stieltjes constants) — but expressed through the LOGARITHMIC derivative, so there's a recursion (Newton-identity-like) between Stieltjes constants and the log-derivative coefficients. Doable but real work: it's the kind of thing that takes a page of analysis and a formalization of "logDeriv Laurent coefficients of a function with a simple pole" lemma.
ALTERNATIVE ROUTE around the w=1 pole: **change the kernel or the contour to avoid the high-order pole.** Hmm, is there a way? The kernel k_n(w−1) has its pole AT w=1 necessarily (k_n(s) = (1+1/s)ⁿ−1 has pole at s=0). Any kernel with the right interpolation property (k_n(ρ−1) = (ρ/(ρ−1))ⁿ − 1 at zeros) will have the pole where 1+1/s blows up, i.e., s = 0 ⟺ w = 1. So the high-order pole at w=1 is intrinsic to this kernel family. BUT — the residue there is exactly computable in closed form (Lagarias does it), so it's a finite-but-n-dependent explicit quantity. The formalization doesn't need asymptotics; it needs the exact identity.
ANOTHER ALTERNATIVE: **prove SfBoundProp via a different, contour-free route?** Is there any? |S_f(n)| ≤ B(n) where S_f = S_∞ + 1 − λ_n. Directly bounding |S_f| without the contour: S_f is a zero-sum; the only known way to relate the zero sum to the archimedean data with explicit constants IS the contour argument (that IS BL Thm 2's quantitative version). Alternatively, could we prove the weaker statement needed — λ_n > 0 for n ∈ [10⁵, N₁] — some other way? E.g., direct zero-sum argument: λ_n = Σ[1−(1−1/ρ)ⁿ]; for zeros on the line, each term ≥ 0 individually! (Since |1−1/ρ| = 1 on the line... wait, ρ = 1/2+iγ: 1−1/ρ = (ρ−1)/ρ, |ρ−1| = |ρ| on the line ⟹ |1−1/ρ| = 1, but 1−(1−1/ρ)ⁿ is NOT obviously ≥ 0 — it's 1 − e^{inθ} which has real part 1−cos(nθ) ≥ 0! YES: on the line, each term's real part is 1−cos(nθ_ρ) ≥ 0 where θ_ρ = arg((ρ−1)/ρ).) So IF all zeros with... but λ_n is a sum over ALL zeros, and terms with |γ| large: Re[1−(1−1/ρ)ⁿ] — for ρ on the line this is ≥ 0 ALWAYS. So under FULL RH, λ_n ≥ 0 termwise — trivially. Under RH-only-to-T₀: zeros beyond T₀ could be off-line and contribute negative real parts. The off-line zeros beyond T₀: ρ = σ+iγ with σ possibly ≠ 1/2; |1−1/ρ| vs 1: if σ > 1/2, |1−1/ρ| = |ρ−1|/|ρ| > 1 (since |ρ−1|²−|ρ|² = 1−2σ > 0 ⟺ σ < 1/2... wait: |ρ−1|² = (σ−1)²+γ², |ρ|² = σ²+γ²; |ρ−1|² − |ρ|² = 1−2σ. So σ < 1/2 ⟹ |ρ−1| > |ρ| ⟹ |1−1/ρ| > 1.) Zeros come in symmetric quartets; for σ < 1/2 (equivalently 1−σ > 1/2), |1−1/ρ| > 1, so (1−1/ρ)ⁿ grows exponentially in n and 1−(1−1/ρ)ⁿ ~ −(1−1/ρ)ⁿ has huge NEGATIVE real part along the argument. So off-line zeros high up contribute catastrophically to λ_n for large n — this is WHY the finite-height result needs the contour bound: the margin argument must dominate these hypothetical contributions. Could one bound the off-line contribution directly? |contribution of zero ρ| ≤ 1 + |1−1/ρ|ⁿ ≤ 1 + (|ρ−1|/|ρ|)ⁿ. For zeros beyond T₀ with σ ≤ 1−ε... we have zero-free regions (classical: σ ≤ 1 − c/log|γ|, or explicit Vinogradov–Korobov, or explicit zero-free regions like Mossinghoff–Trudgian: σ ≤ 1 − 1/(R log(|t|+...)) with R ≈ 5.5-ish). With the FUNCTIONAL EQUATION, zeros are symmetric about 1/2, so σ ≤ 1 − δ implies a mirror at 1−σ ≥ δ... the bad zeros have σ < 1/2, factor |1−1/ρ| = |ρ−1|/|ρ| = sqrt(1 + (1−2σ)/|ρ|²) ≤ sqrt(1 + 1/|ρ|²) ≤ 1 + 1/(2|ρ|²). So |1−1/ρ|ⁿ ≤ exp(n/(2|ρ|²)) — for |ρ| > T₀ = 3×10¹² and n ≤ 9×10²⁴: n/(2|ρ|²) ≤ 9×10²⁴/(2·9×10²⁴) = 1/2. Hmm! So |1−1/ρ|ⁿ ≤ e^{n/(2γ²)} ≤ e^{1/2} — the GROWTH is at most e^{1/2} per zero?! That's because n ≤ (T₀−1)² ≈ γ². So each high zero contributes at most ~1 + e^{1/2}... no wait, that's the point — but there are INFINITELY many zeros beyond T₀, and Σ_ρ n/(2|ρ|²) over |γ| > T₀... Σ_{|γ|>T₀} 1/γ² ~ log T₀/T₀ — tiny. And Σ |1−(1−1/ρ)ⁿ| over the tail: using |1−(1−w)ⁿ|... for |1/ρ| small, 1−(1−1/ρ)ⁿ ≈ Σ_{j≥1} C(n,j)(−1)^{j+1}ρ^{−j} — hmm the sum over the tail of the FIRST-order term n/ρ: Σ_{|γ|>T₀} n/ρ doesn't converge absolutely (Σ 1/ρ conditionally converges). With pairing ρ, ρ̄: n·(1/ρ + 1/ρ̄) = 2n·Re(1/ρ) = 2nσ/|ρ|² — absolutely summable. So the tail (paired) ≤ Σ_{pairs, |γ|>T₀} [2nσ/|ρ|² + higher order ≤ C n²/|ρ|⁴-ish]... Σ_{|γ|>T₀} 1/γ² ≈ (1/2π)log T₀/T₀·... ≈ 29/(2π·3×10¹²) ~ 1.5×10⁻¹². Times n = 9×10²⁴: ~ 1.4×10¹³. Hmm, that's big — bigger than the margin (margin at N₁ is 2.46×10²⁶ — no wait, margin(N₁) = 2.458e26 per STATE.md... and S_∞ lower bound ~ ½n log n ~ ½·9×10²⁴·57 ~ 2.6×10²⁶). Tail bound 1.4×10¹³ ≪ 2.6×10²⁶. WAIT. So the tail of the zero sum beyond T₀ is bounded by ~n·(log T₀)/(2π T₀)·2 ≈ tiny compared to S_∞(n) at n = N₁?!
Hold on, is that right? Σ_{|γ|>T} 1/γ² ≈ ∫_T^∞ (1/2π)log(t/2π) dt/t² = (1/2π)[(log(T/2π)+1)/T]. At T = 3×10¹²: log(3×10¹²/2π) ≈ log(4.77×10¹¹) ≈ 26.9. So Σ ≈ 27.9/(2π·3×10¹²) ≈ 1.48×10⁻¹². Paired first-order tail term: 2n·Σ σ/|ρ|² ≤ 2n·Σ 1/γ² ≈ 2n×1.48×10⁻¹². At n = N₁ ≈ 9×10²⁴: ≈ 2.7×10¹³. And higher-order terms: Σ_j≥2 C(n,j)|ρ|^{−j} ≤ Σ_j (ne/ρ)^j/j! ≤ ... dominated by j=2: n²/γ⁴; Σ_{|γ|>T}1/γ⁴ ~ log T/T³; n²/T³ ~ 8.1×10⁴⁹/2.7×10³⁷ = 3×10¹²·log T — comparable-ish but smaller. OK so order ~10¹³-10¹⁴.
And the ON-LINE zeros up to T₀ contribute ≥ 0 each (1−cos ≥ 0). So:
λ_n = Σ_{|γ|≤T₀} [1−cos(nθ_ρ)] + (potential off-line zeros up to T₀: NONE by Platt–Trudgian!) + tail_{|γ|>T₀} ≥ −|tail| ≥ −3×10¹³-ish.
That's not > 0 — it's ≥ −3×10¹³. The on-line terms are ≥ 0 but most are tiny; their sum: Σ_{|γ|≤T₀}[1−cos(nθ_ρ)] — on AVERAGE ≈ N(T₀) ≈ huge (N(3×10¹²) ≈ (3×10¹²/2π)·log(...) ≈ 1.3×10¹³). But it could be small for particular n if the phases align badly... for SPECIFIC n, no easy lower bound. Hmm, so this direct approach gives λ_n ≥ −tail, useless by itself. The S_∞ − S_f decomposition is fundamentally needed because the archimedean side provides the positive main term. So no, there's no cheap contour-free route. The contour argument is essential. Fine.
Hmm wait, actually — hold on. Is that really true? λ_n = S_∞(n) − S_f(n) + 1 where S_∞(n) ~ ½n log n is the big positive term and S_f is the zero-side. And S_f as a zero sum: S_f(n) = Σ_ρ [1 − (ρ/(ρ−1))ⁿ]... and Re[1−(ρ/(ρ−1))ⁿ] for ρ ON the line: ρ/(ρ−1) has modulus 1, so = 1−cos ≥ 0. So −S_f's on-line part is ≤ 0, i.e., on-line zeros make S_f SMALLER (λ bigger). The bound |S_f| ≤ B(n) needs to control the on-line part too (≤ 2N(T) as D-037 does) — but on-line zeros actually HELP (their contribution to S_f has positive real part 1−cos... wait sign: S_f = Σ[1−(ρ/(ρ−1))ⁿ]; Re = 1−cos(nφ_ρ) ≥ 0; so S_f ≥ 0-ish from on-line zeros, and λ = S_∞ − S_f + 1 ≤ S_∞ + 1. The DANGER is S_f being very POSITIVE (reducing λ): on-line zeros give S_f up to 2N(T₀) ~ 2.6×10¹³ positive — vs S_∞ ~ 2.6×10²⁶. Fine, dominated.
So conceptually: at n ~ N₁, S_∞ ~ 2.6×10²⁶ vs all zero-side contributions ~ 10¹³–10¹⁴. MASSIVE slack. The contour bound B(n) with its traced constants is what formalizes "the zero side is small". Any sufficiently explicit bound works — the slack is ~10¹²-fold. This means the formalization has ENORMOUS room: crude bounds are fine. This matters for feasibility — we can afford the crudest possible estimates at every step.
### Alternative strategies to close SfBoundProp
**Strategy 1 (frontal, per D-062 triage):** Formalize L0 (contour identity) + L1 (kernel bounds) + L2 (R-bound) + L3 (zero-avoiding T), with L4/L5/L6 as perimeter. This is the plan D-062 sketches: "multi-session formalization (contour + residue machinery); the honest long pole."
**Strategy 2 (PNT+ dependency):** The PNT+ project (Kontorovich et al., "Prime Number Theorem and..." — the Lean PNT project at github.com/AlexKontorovich/PrimeNumberTheoremAnd) has already formalized:
- Rectangle integrals of ζ′/ζ with poles at zeros (they prove the explicit formula ψ(x) = x − Σ x^ρ/ρ − ...)
- Residue computations including at s=1 and at zeros
- ζ′/ζ bounds in the critical strip
- Zero-free region arguments
If PNT+ (or its Mathlib-upstreamed parts) is compatible with our toolchain (v4.33.0-rc2), L0's residue infrastructure could be largely imported. Their `Rectangle` API, `ResidueTheoremOnRectangleWithPoles`, `RectangleIntegral` etc. exist in PNT+. Big caveat: dependency pinning/version compat, and PNT+ targets ζ′/ζ with kernel x^s/s-type, not our k_n kernel — but the MACHINERY (rectangle residues with finitely many poles, residue at a zero of ζ, pole at 1) transfers.
**Strategy 3 (circumvent the high-order pole):** The w=1 residue of order n+1 is the ugliest exact-computation piece. Alternative: use a MODIFIED contour/kernel that makes the archimedean side cleaner. E.g., Lagarias's variant A vs B; or BL's original proof; or Akbary–... hmm. OR: avoid identifying the residue with S_∞ at all — instead, prove the inequality directly: we need |Sf n| ≤ Bn where Sf = SInfty + 1 − λ. The identity route computes Sf exactly. Alternative INEQUALITY route:
|Sf n| = |S_∞ + 1 − λ_n|. Bound λ_n ≥ (something) and ≤ ... no — we need BOTH sides of λ_n... |S_f| two-sided. λ_n = S_∞ + 1 − S_f; |S_f| ≤ B ⟺ S_∞ + 1 − B ≤ λ_n ≤ S_∞ + 1 + B. We only NEED the lower bound on λ_n for the theorem (λ_n > 0 via margin), but SfBoundProp as stated is two-sided. We could RESTATE the hypothesis the assembly actually consumes... but the assembly is already proved from SfBoundProp; changing it means re-proving the assembly glue (minor). A one-sided version: λ_n ≥ S_∞(n) − B(n) + 1 directly. Contour-wise, the lower bound on λ_n comes from an UPPER bound on S_f... no wait: λ_n = S_∞ − S_f + 1 ≥ S_∞ − |S_f| + 1. We need upper bound on S_f = S_∞ + 1 − λ_n, i.e., lower bound on λ_n... circular-ish. The identity S_f = S_∞ + 1 − λ_n is DEFINITIONAL in the Lean code (Sf := SInfty + 1 − liCoeff.re). So |Sf n| ≤ Bn is |S_∞ + 1 − λ_n| ≤ B. The contour identity proves S_∞ + 1 − λ_n = [truncated zero sum + sides + trivial]. One-sided wouldn't simplify the identity proof materially — the identity is the identity. But the EXACT identity needs the w=1 residue exactly. Hmm — actually does it? |S_f| ≤ B: S_f = [truncated] + [sides] + [trivial] EXACTLY (no w=1 residue remains after the BL bookkeeping... but deriving THAT needs the w=1 residue identified with the S_∞ side). The w=1 residue identification is unavoidable in the frontal route. It's exact finite algebra (Laurent coefficients via Stieltjes recursion), painful but mechanical.
**Strategy 4 (different identity entirely — the η-function route):** Lagarias's a_j = (1−2^{−j})ζ(j) suggests working with η(s) = (1−2^{1−s})ζ(s), whose log-derivative Laurent coefficients at 1 are cleaner? The residue at w=1 for the η-based kernel... The standard trick: −ζ′/ζ(s) = 1/(s−1) − γ − Σ ... Stieltjes. And the identification Σ_j C(n,j) η-related = S_∞. This is bookkeeping, same class.
**Strategy 5 (verify the inequality numerically-certified instead of proving the contour bound):** E-021 computed |S_f(n)| EXACTLY (via the exact S_∞ and λ_n) for n ≤ 10⁴ and found max 13.52 vs bound ~2280. Could we certify |S_f(n)| ≤ B(n) for ALL n ∈ [10⁵, N₁] computationally?? N₁ = 9×10²⁴ — NO, impossible by direct computation. The contour bound's whole point is uniformity in n. What about: for n ∈ [10⁵, N₁], use the ZERO-SUM directly: |S_f(n)| = |Σ_ρ 1−(ρ/(ρ−1))ⁿ| ≤ Σ |...| — infinite sum, needs truncation + tail bound — that IS the contour-free equivalent: truncated sum over |γ| ≤ T (computable for T up to... we have 10⁴ zeros, maybe 10⁶ zeros available? Platt's data? Not to 3×10¹²!). The truncated sum to T₀ = 3×10¹² has ~10¹³ terms — incomputable. So no.
**Strategy 6 (shrink what's needed):** Note SfBoundProp's range starts at 10⁵ (splice with finite verification at 5×10⁵, overlap). The margin at 10⁵ is ~10⁵-scale and B(10⁵) ~ 3.5×10⁵... wait margin = slower − Bn + 1 with margin(10⁵) ≥ 85 501 certified, Bn(10⁵) ≤ 347 000. So we need |S_f(n)| ≤ B(n) with B(10⁵) ≈ 3.4×10⁵ — while TRUE |S_f| values (E-021) are ~13 at n ~ 3000, growing slowly (max 13.52 at n=3298; E-021 says the |S_f| curve vs the traced bound has ~170× slack). At n = 10⁵, true |S_f| maybe ~50–100? vs B ~ 3.4×10⁵. Slack ~10³–10⁴×. At n = N₁: B ~? B(n) ~ 4T·(2/3)C₀(T)·... ~ c·T log²T-ish ~ c·√n·(log n)². At n = 9×10²⁴: √n = 3×10¹², (log n)² ~ 57² ~ 3.2×10³, so B ~ c·10¹⁶-ish; true |S_f| ~ 2N(T)+tail ~ 2.6×10¹³+... The point: slack everywhere. Crude bounds fine.
### Feasibility verdict
The dominant cost is L0 (the exact contour identity with the order-(n+1) pole residue identified with S_∞(n)) — this is a genuine formalization project: rectangle residue theorem for meromorphic functions with multiple poles INCLUDING a variable-order pole, Laurent coefficients of −ζ′/ζ at 1 to all orders (Stieltjes recursion), exact finite algebra. Plus L2's partial fractions (Hadamard) — does Mathlib have the Hadamard product for ξ? There's been work: Mathlib has `Complex.riemannXi`?? Hmm. Actually I recall Mathlib DOES have `riemannZeta` functional equation and the completed zeta, but the HADAMARD product (Weierstrass factorization of ξ with the zero sum Σ[1/(s−ρ)+1/ρ]) — I believe that's NOT in Mathlib core as of early 2026. The R-bound reference-point proof (D-056) needs the partial-fraction expansion of ζ′/ζ — that's Hadamard. Formalizing Hadamard factorization of ξ from scratch: order-1 entire function, convergence of Σ1/|ρ|², product formula... Mathlib has some entire-function machinery (Hadamard three-circles? Phragmén–Lindelöf? factorization?). There's `Complex.Hadamard`?? I don't think full Weierstrass/Hadamard factorization exists in Mathlib. This is another serious lift. ALTERNATIVE for L2: the R-bound can be proved WITHOUT full Hadamard via the classical route: ζ′/ζ(s) = Σ_{|γ−t|<1} 1/(s−ρ) + O(log t) is usually proved FROM the partial fraction expansion, but there are alternative routes: via the Dirichlet-series/log-derivative bounds + Jensen's formula + Borel–Carathéodory (the standard "Lemma α" route in Davenport Ch. 15 uses the partial fractions, but the O(log t) bound for ζ′/ζ − Σ can also be gotten via: log ζ bounds from Borel–Carathéodory on a disc, then Cauchy estimate for the derivative, subtracting the local zero contributions via Jensen/Blaschke). Mathlib has Jensen's formula? There's been formalization of Jensen formula in Mathlib (`Complex.Jensen`?)... I believe Mathlib HAS Jensen's formula (added ~2024 for complex analysis). Borel–Carathéodory: not sure. If not, these are standard and provable from Cauchy estimates — a few hundred lines.
D-056's actual proof uses the reference-point trick + Hadamard partial fractions + digamma Lemma D. To formalize D-056 as-is we'd need partial fractions for ζ′/ζ (Hadamard for ξ). To avoid Hadamard: prove the R-bound via the "local" route (Borel–Carathéodory + zero counting C₀). Either way it's work.
**Dependency check needed (sub-stage 0):** survey exactly what Mathlib v4.33.0-rc2 has: rectangle residue theorem (yes: `Complex.integral_boundary_rect...` plus winding-number based residue versions — actually I recall `Complex.rectangleIntegral` and residue-on-rectangle landed via PNT upstreaming efforts by 2024–2025), Jensen's formula (I believe yes), Hadamard factorization (likely no), digamma (yes — `Complex.digamma` exists I think), Stieltjes constants (no — we'd define the needed Laurent coefficients ourselves), riemannZeta Laurent at 1 (Mathlib has the simple pole: `riemannZeta` has `hasSum`...? there's the limit statement `tendsto_riemannZeta_sub...`? Something like residue 1 exists). zeta-23-lean: what's in it (zero counting functions — may provide N(T) infrastructure? D-007 audited: "counting functions vs Mathlib riemannZeta" — worth re-examining for L3/L4-adjacent API).
PNT+ as a dependency: check compatibility. If PNT+ pins a different Mathlib version, porting selected files is an option (license Apache 2.0, fine).
### Effort estimate (honest)
This is the largest single formalization push of the project — bigger than tier (i)+(ii) combined (~1700 lines). Realistic decomposition:
- Sub-stage A (scoping/inventory): Mathlib/PNT+/zeta-23 capability survey; fix the exact target lemma stack; write the proof skeleton with sorries top-down. Deliverable: D-064 (design doc) + LiContour.lean skeleton compiling with named sorries. (1 session)
- Sub-stage B (L1 kernel + elementary bounds): |k_n| estimates, trivial-zero residues, the easy contour-side estimates. Mathlib-tractable. (1 session)
- Sub-stage C (L3 zero-avoiding T): pigeonhole gap center from the C₀ count (perimeter N(T) bound as hypothesis — already decided). Finite combinatorics. (0.5–1 session)
- Sub-stage D (L2 R-bound): choose route (Hadamard vs Borel–Carathéodory local route); formalize. The biggest "analysis" chunk after L0. (2–3 sessions)
- Sub-stage E (L0 part 1: rectangle residue theorem for the needed class + residue at zeros (simple poles)); (1–2 sessions)
- Sub-stage F (L0 part 2: the w=1 pole of order n+1 — Laurent/Stieltjes identification with S_∞(n); exact finite algebra); (2–3 sessions, the crux)
- Sub-stage G (L0 part 3: assemble the identity S_f = truncated + sides + trivial; limit/limit-free bookkeeping; L7 summability of liCoeff). (1–2 sessions)
- Sub-stage H (final assembly: bound each piece by the B(n) terms with the traced constants; plug into lambda_pos_finite_height_verified replacing the hypothesis; axiom audit; paper Appendix B update). (1 session)
Total: ~9–14 sessions of focused Lean work. Feasibility: I'd say HIGH that it's achievable (it's all "plain complex analysis, no input obstacles" per D-062, with Mathlib gaps that are infrastructure-shaped, not mathematics-shaped), with two genuine risk points: (F) the variable-order residue — risk mitigated by doing the exact algebra on paper first (D-036 has it); (D) Hadamard — mitigated by the alternative local route. There's also a "cheat" available that dramatically de-risks F: since the slack is 10³–10¹²-fold everywhere, we could replace the EXACT w=1-residue identification by an exact identity proved differently — e.g., compute the w=1 residue as "Σ_{j=1}^n C(n,j) c_j" with c_j the Laurent coefficients of −ζ′/ζ (definitionally), then prove |S_∞(n) − that| = 0 via the finite identities... no, that IS the identification. Alternatively bound the residue directly: |residue at 1| ≤ Σ C(n,j)|c_j| and identify Σ(−1)^j C(n,j)a_j = S_∞ separately... the identity S_f = ... + [w=1 residue] is exact; to turn it into |S_f| ≤ B we need to know the w=1 residue EXACTLY equals the S_∞−... no wait. Hmm: S_f := S_∞ + 1 − λ_n. Contour: (1/2πi)∮ = Σ_zeros res + res_{w=1} + Σ_trivial res. Also λ_n = full zero sum. So S_f = S_∞ + 1 − λ_n = S_∞ + 1 − [Σ_{|γ|≤T} + tail]. The contour gives Σ_{|γ|≤T} res = (1/2πi)∮ − res_{w=1} − Σ_triv. Substituting: S_f = S_∞ + 1 − (1/2πi)∮ + res_{w=1} + Σ_triv − tail. So |S_f| ≤ |sides| + |S_∞ + 1 + res_{w=1} + Σ_triv| + |tail|. The term |S_∞ + 1 + res_{w=1} + triv| must be bounded — res_{w=1} is the big negative (−S_∞-ish) — so we need |S_∞(n) + 1 + res_{w=1} + Σ_triv res| ≤ [something small]. I.e., we need the DIFFERENCE (S_∞ + res_{w=1} + trivial) to be SMALL, not the exact identity! Is that easier? res_{w=1} = Σ_j C(n,j) c_j (c_j = Laurent coeffs of −ζ′/ζ). S_∞ = Σ_j (−1)^j C(n,j) a_j (a_j = (1−2^{−j})ζ(j) for j ≥ 2, a₁ = (log 4π+γ)/2). Claim: c_j = −(−1)^j a_j exactly?? — that would make S_∞ + res = 0 + lower-order (the triv residues and the +1 handle the rest). The identification c_j vs a_j is EXACTLY the Stieltjes/η identity — same work whether we need equality or a bound on the difference, because the difference is huge unless exactly canceling (individual terms C(n,j)·c_j are ~C(n,j)·(j−1)!-scale? |c_j| growth: Laurent coefficients of ζ′/ζ — c_j = (−1)^j η(j−1)/(j−1)!-ish bounded-ish... a_j = (1−2^{−j})ζ(j) → 1 as j → ∞. The sums Σ C(n,j)a_j ~ 2ⁿ-scale cancellation! NO WAIT: S_∞(n) = Σ(−1)^j C(n,j) a_j is a FINITE difference — it's ~ ½n log n, achieved via massive cancellation of ~2ⁿ-scale terms. You cannot bound the difference |S_∞ + res| without the EXACT per-j identity — any per-term triangle inequality explodes like 2ⁿ. THIS IS the "three-way cancellation IS RH" wall from D-033 ("arithmetic-side triangle bounds explode"). So the exact identification c_j = ±a_j is FORCED. No cheat. The good news: the identity is classical and exact (Lagarias 4.11); formalizing it is finite algebra + the Laurent-coefficient recursion for logDeriv at a simple pole. It's the crux but it's well-defined.
Hmm, one more idea to de-risk F: **avoid the w=1 residue entirely by subtracting a reference kernel**. Consider two consecutive n: k_{n+1} − k_n = (1/s)k_n... or consider the kernel difference trick: the quantity S_∞(n) satisfies a recurrence; the contour for n and the contour for n−1... This doesn't obviously help.
**Better structural idea (the "engineered identity" route):** Instead of proving Lagarias's exact identity with the pole at w=1 of order n+1 head-on, use the BL Thm 2 route via MELLIN inversion rather than the rectangle at finite height... no, finite-height explicitness is the whole point.
**Alternative contour shape:** Take σ₁ = +∞ instead of 2√n (Lagarias variant with the right side at infinity — the k_n kernel decays for σ → +∞ since k_n(w−1) = (1+1/(w−1))ⁿ − 1 ~ n/(w−1)); then no I_II right-side integral; but the w=1 pole remains. No help for F.
So F's exact-algebra identification is unavoidable in ANY contour route. Accept it. It's a known, bounded piece of classical algebra (Lagarias (4.11) is a one-page identity). Formalization: define c_j via the Laurent recursion for logDeriv of ζ at 1 (Mathlib HAS the Laurent/pole API? For a function f with simple pole at s₀, logDeriv f has Laurent coefficients satisfying a recursion in terms of f's — provable via `Complex.meromorphic` API... Mathlib has `MeromorphicAt` with order, Laurent series?? There's `MeromorphicAt` API (added 2024-2025, by the PNT-adjacent work): `MeromorphicAt.order`, Laurent coefficients? Hmm, partial. We may need to roll our own "local lemma": if g analytic near 0 with g(0) ≠ 0 then d/ds log((s−1)g(s)) = 1/(s−1) + g′/g, and g′/g's Taylor coefficients satisfy the recursion — elementary with `AnalyticAt`/`FormalMultilinearSeries` API, which Mathlib has solidly). Then identify with (1−2^{−j})ζ(j) via the Dirichlet series of −ζ′/ζ = Λ-sum and the Taylor generating identity... The cleanest classical proof of Lagarias (4.11): a_j defined by the generating function identity; equivalence via comparing the two expressions for the same integral at INFINITY (not via local Laurent algebra!). I.e., prove the global identity "S_∞(n) + res_{w=1} + triv + 1 = 0" ONCE for all n by a soft argument (e.g., both sides are... polynomials in n? The residue Σ_j C(n,j)c_j is a polynomial in n of degree n — no, C(n,j) for j ≤ n with n the variable... it's not polynomial in n in a useful sense for induction... hmm, actually C(n,j)c_j summed IS related to finite differences: Σ_j (−1)^j C(n,j) a_j = Δⁿ a at 0 — the n-th finite difference! And S_∞(n) = (Δⁿ a)(0)-ish. Finite-difference calculus: if we show the w=1 residue equals −(Δⁿ ã)(0) for an explicit sequence ã, the identification reduces to a SEQUENCE identity, provable by generating functions (the two sequences have the same exponential generating function — an identity of analytic functions, provable by ... ugh, still work but maybe cleaner: EGF of a_j: A(x) = Σ a_j x^j/j! — related to log Γ-ish functions; EGF of Laurent coeffs similar; equality of EGFs as analytic functions reduces to equality on a sequence accumulating — circular. OK: equality of EGFs via DIRECT computation of both EGFs in closed form. Lagarias's proof: Σ_j (−1)^j C(n,j)a_j with a_j = (1−2^{−j})ζ(j): Σ_m odd ((1−1/m)ⁿ −1 +n/m) — the double-sum form (D-037 §3 derives it by absolute convergence for j ≥ 2). That's the route D-037 used for the S_∞ LOWER bound (already Lean-proved in tier (i) from the double-sum form!). And the residue side: res_{w=1} = Σ_j C(n,j) c_j — write c_j via −ζ′/ζ = −Λ-dirichlet... For j ≥ 2, c_j: the Taylor coefficients of −ζ′/ζ + 1/(s−1) at s=1 equal... via ζ′/ζ(s) = −Σ Λ(m)m^{−s} for Re s > 1, NO — that's the Dirichlet series, valid far right, not the Taylor at 1. The relation a_j = (1−2^{−j})ζ(j) comes from the FUNCTIONAL EQUATION side / the η trick. Hmm, honestly: Lagarias proves (4.11) using the contour argument itself (evaluate the same integral two ways). The cleanest for us might be: DON'T prove the c_j = a_j identity locally at all. Instead, prove the SINGLE global identity we need — S_∞(n) + 1 + res_{w=1}(n) + triv(n) = 0 for all n — by induction on n! Both sides as sequences in n satisfy the same first-order recurrence (S_∞(n+1) − S_∞(n) has a closed form? S_∞ via double sum: difference computable. res_{w=1}(n+1) − res_{w=1}(n): the kernel k_{n+1} − k_n = (1/s)·... k_{n+1}(s) − k_n(s) = (1+1/s)ⁿ·(1/s) = ((1+1/s)ⁿ)/s. Hmm — residue of that difference at w=1 might telescope. If both sides satisfy the same recurrence and match at n = 1 (base case = one explicit residue computation at fixed small order — order-2 pole, EASY), the identity follows for all n. THIS is a much better formalization route for F: reduce the variable-order residue to (i) a base case (order ≤ 2 pole, computable), (ii) a recurrence step (kernel identity, algebra), (iii) induction. The recurrence for the archimedean side: S_∞(n+1) − S_∞(n) — from the double-sum form (already formalized in tier (i)!): h⁺(m) differences... Σ_m odd [(1−1/m)^{n+1} − (1−1/m)ⁿ + 1/m] = Σ_m odd [−(1/m)(1−1/m)ⁿ + 1/m]... = S_∞-related again — has a closed form in terms of the same structures. Feasible. This turns "identify two n-indexed families of constants" into "check one recurrence + one base case". MUCH more Lean-friendly. I should put this in the plan as the chosen attack for F.)
Hmm wait, but actually the induction needs the contour identity for EACH n anyway (we're proving the identity for all n simultaneously)... no — the plan: for each n, the contour identity gives S_f(n) = sides(n) + [S_∞(n) + 1 + res(n) + triv(n)] + tail-free-exact-truncated... The bracket must vanish identically. Prove "bracket(n) = 0 ∀n" by induction: bracket(0) or bracket(1) by direct small-order residue computation; bracket(n+1) − bracket(n) = 0 by kernel algebra + the S_∞ difference formula. The residue difference res(n+1) − res(n) = residue of [k_{n+1}(w−1) − k_n(w−1)](−ζ′/ζ) at w=1 = residue of (1+1/(w−1))ⁿ·(1/(w−1))·(−ζ′/ζ) = coefficient extraction — still involves −ζ′/ζ's full Taylor at 1... same problem! Ugh. Unless: the induction is on the CONTOUR side instead: sides(n+1) − sides(n) = ∫ [k_{n+1} − k_n]·(−ζ′/ζ)/2πi = ∫ (1+1/(w−1))ⁿ/(w−1)·(−ζ′/ζ)... and by residues THIS integral over a contour NOT enclosing w=1 but the zeros... this is getting complicated. The recurrence approach doesn't obviously escape the local algebra.
Alternative for F that DOES escape: **prove the bracket vanishes via the TAIL side.** We have S_f(n) := S_∞ + 1 − λ_n and separately S_f(n) = sides + bracket + truncated (contour). Also λ_n = truncated + tail. So bracket(n) = S_f(n) − sides(n) − truncated(n) — and also S_f(n) = S_∞+1−λ_n. The claim bracket = 0 is equivalent to the exact identity. No escape; the exact identity is a theorem and must be proved. The question is only WHICH proof to formalize: (a) local Laurent algebra at w=1 (Lagarias 4.11 via local recursion + η-identity), or (b) Lagarias's own "evaluate two ways" trick, or (c) some generating-function global argument. All have similar weight. (a) is the most mechanical. Fine — accept (a), and note (a) has a nice sub-structure: define c_j recursively from ζ's Laurent at 1 (Stieltjes); prove c_j = (−1)^j (1−2^{−j})ζ(j) + [j=1 adjustment] via the η-function: η(s) := (1−2^{1−s})ζ(s) is entire, η(1) = log 2, and −ζ′/ζ(s) = 1/(s−1) + [log(2)·2^{1−s}/(1−2^{1−s})... let me just compute: log η = log(1−2^{1−s}) + log ζ; differentiate: η′/η = (log 2·2^{1−s})/(1−2^{1−s}) + ζ′/ζ. Hmm so ζ′/ζ = η′/η − log 2/(2^{s−1}−1). Near s=1: η′/η analytic (η(1) = log 2 ≠ 0 — WAIT η(1) = lim (1−2^{1−s})ζ(s) = log 2·1 = log 2 ≠ 0 ✓). And log 2/(2^{s−1}−1) has a simple pole at 1 with known full Laurent expansion (Bernoulli numbers!): 1/(2^{s−1}−1) = 1/((s−1)log 2) − 1/2 + (log 2)(s−1)/12 − ... (Bernoulli). So c_j = [Taylor of η′/η at 1] − [Bernoulli series]. And η′/η at 1: Taylor coefficients of logDeriv of the ENTIRE function η — related to ζ(j) values how? η′/η(s) = Σ ... at s = 1: derivatives of log η. Connection to ζ(j), j ≥ 2: NOT local — ζ(j) are values at OTHER points. The identity "Taylor coeffs of logDeriv η at 1" = "(1−2^{−j})ζ(j)-related" — hmm, this can't be a pure local identity; it must use the global structure. Lagarias (4.11) indeed comes from the global contour manipulation. OK — so the honest content of F: a global identity. Fine, that's mathematics we already have written in D-036/D-037; the formalizer follows the written proof. Bounded work.
Given the depth here, the plan should include a **paper-first sub-stage**: re-derive the w=1-residue/S_∞ identity in the cleanest possible form on paper (D-064), specifically optimized for formalization (choosing route (a)/(b)/(c) with Mathlib's API in mind), BEFORE writing Lean. This was the session-012-lesson: design-first worked (FAlt swap caught pre-instantiation).
### The honest answer on "possibility"
- Mathematical novelty required: ZERO. All content exists in the archive (D-036/D-037/D-056, Lagarias) with constants traced.
- Mathlib gaps: real but infrastructure-shaped. Rectangle residue theorem: partially exists; multi-pole version must be assembled. Hadamard factorization of ξ: likely absent — circumvent via local route (Borel–Carathéodory/Jensen) or formalize the needed fragment (Σ[1/(s−ρ)+1/ρ] convergence — needs zero-count input C₀ anyway = perimeter, so the convergence proof can USE the perimeter bound! Nice: with N(T) ≤ F(T) (perimeter), Σ|ρ|⁻² converges by comparison — the Hadamard product's analytic machinery is still needed though: order-1 entire function ξ... Mathlib has `Complex.riemannXi`? There's `completedRiemannZeta` and its entireness I believe. The product formula itself — the honest survey in sub-stage A will tell.)
- Variable-order pole: the crux, bounded, classical.
- Scale: ~9–14 sessions by the estimate above. Compare: tier (i)+(ii) took sessions 011–012 (~1700 lines). This is maybe 4–8× that.
- Success probability: high that it's achievable with sustained effort (no mathematical obstacles, only engineering); the main risks are (1) Mathlib API gaps forcing detours, (2) the w=1 identity formalization being fiddly, (3) PNT+ incompatibility if we try to import. Mitigations: paper-first design stage, local-route alternatives, sorries-first top-down skeleton so the critical path is visible early.
Also worth noting: what does success BUY? The tag upgrade from "[PROVED-CONDITIONAL + SfBoundProp hypothesis]" to "[Lean-verified modulo published N(T)/S(T) bounds + computational certificates]" (D-062 §4 consequence). It does NOT change the theorem, the paper's math, or the height. It removes the one named analytic hypothesis. Given paper A is submission-ready NOW with the hypothesis honestly declared, and the referee process may itself comment — the user should know: this is a robustness/self-containment upgrade, not a correctness fix. Also note D-062's decision was that tier ii′ is POST-publication per the mathematician review. The user now wants to do it anyway — fine, their call, maybe they'd rather have the fully-closed form before submission. Worth stating the trade-off honestly: (i) doing it now delays submission by many sessions; (ii) doing it after publication risks the referee asking exactly this. Actually for Experimental Mathematics, a declared-hypothesis machine-verified theorem is quite standard and the perimeter declaration is honest. But the user asked for the plan, not the go/no-go — I'll give the plan and a short note on sequencing choice.
### Plan structure
I'll propose:
**Sub-stage ii′-0 — Capability survey + target stack (D-064).** Inventory: Mathlib v4.33.0-rc2 (rectangle residues, MeromorphicAt/Laurent, Jensen, digamma, riemannZeta API, Γ, Bernoulli), zeta-23-lean contents, PNT+ compatibility check. Fix the exact lemma dependency graph for L0–L3. Choose routes: Hadamard-vs-local for L2; local-Laurent-vs-global for the w=1 identity. Deliverable: D-064 design + `LiContour.lean` skeleton compiling with ~15–25 named sorries (each a claimed lemma with precise statement). Exit criterion: every sorry statement reviewed against D-036/D-037/D-056; no sorry is mathematically unproved in the archive.
**Sub-stage ii′-1 — L1 kernel bounds + trivial residues.** Elementary.
**Sub-stage ii′-2 — L3 zero-avoiding T.** Pigeonhole on the C₀ count (perimeter N-bound as a hypothesis-of-record `TrudgianN`).
**Sub-stage ii′-3 — L2 R-bound.** The analytic heavy lift #1.
**Sub-stage ii′-4 — L0a rectangle residue machinery.** Multi-pole rectangle residue theorem (assemble from Mathlib's rectangle + winding number, or port PNT+ fragment).
**Sub-stage ii′-5 — L0b w=1 pole: the S_∞ identification.** The crux; paper-first (already drafted in ii′-0).
**Sub-stage ii′-6 — L0c identity assembly + L7 summability.**
**Sub-stage ii′-7 — Final bound assembly + theorem swap + audit.** Replace `hSf : SfBoundProp` hypothesis with the proved theorem; rerun full axiom audit (target: 3 standard axioms + 0 sorryAx in the Li chain); update paper Appendix B + tag to the D-062 §4 endpoint form; journal/NGUYEN/ledger updates.
Also: keep E-023b (acb M₀) as a parallel optional item — needed to make L6 a computational perimeter (currently E-023 grid-verified; declared).
I should also mention the strategic option: **run ii′ while submitting** — paper A is ready; the submission can go out with the declared hypothesis and tier ii′ strengthens a revision. But user said "regroup to work on tier ii′" — they may have decided. I'll note the option in one line and let them decide.
Per §8.5 sub-stage rule, each sub-stage ends in a clean committed resumable state. Also note the fork rule doesn't really apply (single path).
One more consideration: total Lean line estimate. Tier (i)+(ii) ≈ 1100 + 560 + skeleton ~ maybe 3000 lines. Tier ii′: L2 ~ 800–1500, L0a ~ 400–800, L0b ~ 600–1200, rest ~ 800. Total maybe 3000–5000 lines of new Lean. Sessions: 8–14. I'll present ranges honestly and note the two crux points.
I could also propose de-risking: start with ii′-5-crux ON PAPER (the exact identity proof written in formalization-friendly form) since everything hinges on it — actually no, better to start with the skeleton (ii′-0) which includes the paper design for the crux.
Format: this deserves a well-structured, moderately detailed response — the user asked to "think deep and analyze... break this down into sub-stages... possibility... plan". Not too long though. I'll give: (1) what the task actually is (the three real obstacles), (2) feasibility analysis with the key de-risking insights (slack, perimeter reuse, recurrence/pole handling, PNT+ option), (3) the sub-stage plan with exit criteria, (4) probability estimate, (5) strategic note. Then ask if they want to start with ii′-0.
Should I use AskUserQuestion at the end? The user said "Let me know what you think and your plan on this matter." So they want the plan first. I'll end with a simple question about whether to proceed/adjust. A plain closing question is fine.
Length: this is a planning deep-dive the user explicitly requested — medium-long is appropriate, but keep it tight. Use tables sparingly. No need for tool calls now — I have enough from D-062/D-037/STATE. I could do a quick Mathlib inventory via grep of the local Mathlib checkout to firm up feasibility claims... The NguyenRH1 has path-requires to vendored zeta-23-lean and Mathlib — I could grep Mathlib source for key APIs (residue, Jensen, digamma, Hadamard). That would make the feasibility assessment concrete rather than from-memory. Worth doing quickly — it's cheap and derisks the plan. Let me check a few key things:
1. Rectangle residue theorem in Mathlib: search for "residue" / "rectangle" in Mathlib's Complex analysis.
2. Jensen's formula.
3. digamma.
4. Hadamard / Weierstrass product.
5. riemannZeta API surface (Laurent at 1, trivial zeros).
6. PNT+ presence (probably not vendored).
Let me find the Mathlib path first. It's in the .lake/packages of zeta-23-lean or NguyenRH1. Let me glob for it.
Let me ground the feasibility analysis in what's actually available in the vendored Mathlib before proposing the plan.
tool: Bash
input
{
"command": "ls \"D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\.lake\\packages\" 2>/dev/null; ls \"D:\\Python\\Quantum\\research\\lean\\zeta-23-lean\\.lake\\packages\" 2>/dev/null",
"description": "Locate vendored Mathlib package path"
}
thinking (10205 chars)
Critical finding: the vendored rectangle residue theorem `RectangleIntegral'_eq_sumResiduesIn` (line 1084) uses a **placeholder `residue` valid only for simple poles** with the `HasSimplePolesOn` scaffold. Our integrand `k_n(w−1)(−ζ′/ζ(w))` has:
- simple poles at zeros ρ ✓
- a pole of order n+1 at w = 1 ✗ — NOT covered by the simple-pole scaffold!
So the general rectangle residue theorem as vendored does NOT directly apply to our integrand. Options:
**Option A: Extend the machinery to higher-order poles.** Need a general `residue` (e.g., via the (m−1)! formula or via principal-part integration) and a rectangle residue theorem without the simple-pole restriction. The theorem's proof (line 1090-1102) goes through a "principalPart" decomposition — the scaffold exists; extending to finite-order poles means defining the residue via the Laurent coefficient / the principal part. Since Mathlib has `MeromorphicAt` with `meromorphicOrderAt` and analytic principal parts (`MeromorphicAt.order`, and there might be API for the principal part / Laurent series... Mathlib's meromorphic API: `MeromorphicAt`, `meromorphicOrderAt`, `MeromorphicNFAt` (normal form: (z−z₀)^order • g with g analytic nonvanishing). With NF, the principal part for order −m is Σ_{j=1}^m c_j/(z−z₀)^j where c_j from g's Taylor. The residue c_1 = g's (m−1)-th Taylor coefficient / (m−1)!. For a rectangle, the integral of c_j/(z−z₀)^j around = 2πi·c_1 (j=1 term only, since j≥2 primitives are single-valued). So the extension is: general residue theorem on rectangles for finite-order poles — provable from the existing simple-pole version by decomposing the principal part and applying the simple-pole version to each term (each c_j/(z−z₀)^j for j ≥ 2 has integral 0 by an explicit primitive argument — wait, c_j/(z−z₀)^j has primitive c_j/(1−j)(z−z₀)^{1−j} which is single-valued meromorphic, so its rectangle integral is 0 by the fundamental theorem / the HolomorphicOn.vanishesOnRectangle applied to the primitive. Fine — so the extension is a bounded piece of work, no new analysis.
**Option B: Avoid the higher-order pole entirely by splitting the integrand.** Write the integrand as k_n(w−1)·(−ζ′/ζ) and note k_n(w−1) = (w/(w−1))ⁿ − 1. Hmm, the pole at w=1 comes from the kernel. Alternative: handle the w=1 residue by a SEPARATE small contour around w=1 (pull the rectangle to a small circle around 1 — `RectanglePullToNhdOfPole` exists!) and compute the residue on that small circle via... still a higher-order pole computation, but now localized: need ∮_{|w−1|=r} k_n(w−1)(−ζ′/ζ) dw / 2πi = the (n+1)-order residue = Σ_{j=1}^n C(n,j)·[Taylor coeff]. Either way we need the higher-order residue value.
**Option C: Restructure to make all poles simple — different kernel.** Use the kernel K_n(s) = something with a simple pole at s=0 but the same values at zeros? Impossible: kernel must have a pole at s=0 of order n to produce (1+1/s)ⁿ. Any meromorphic K with K(ρ−1) = (ρ/(ρ−1))ⁿ − 1 at all zeros ρ and a pole only at 0... the order of the pole at 0 is forced to be n (the interpolating values grow like s^{−n} as s→0 along the zero sequence? not exactly, but the natural kernel family has order n). A non-natural kernel (e.g., add an entire function vanishing at all zeros−1) could reduce the pole order — e.g., k_n(s) − [Taylor polynomial of k_n at 0 of order n−1]·[entire interpolant]... too clever, and the residue at 0 would then be different (that changes S_∞ identification correspondingly). The S_∞ side HAS degree-n structure; the pole order is intrinsic. Accept order n+1 pole; extend residue machinery (Option A) — it's the honest bounded lift.
Let me also check: does the vendored theorem require f to be meromorphic on the whole rectangle with the poles only inside? Line 1084-1090: `RectangleIntegral'_eq_sumResiduesIn {f} {z w}` with hypotheses including HasSimplePolesOn presumably, and conclusion `RectangleIntegral' f z w = sumResiduesIn f (Rectangle z w ∩ {z | meromorphicOrderAt f z < 0})`. The extension would give the same conclusion without the simple-pole hypothesis, with a general `residue`.
So the machinery gap for L0 is: (i) general (finite-order) residue definition + computation lemmas (the (m−1)! derivative formula — Mathlib may have `MeromorphicAt` Laurent-ish API? Let me not check further; bounded work either way), (ii) rectangle residue theorem for finite-order poles (assemble from the vendored simple-pole version + principal-part decomposition), (iii) the actual residue computations: at zeros (simple, via logDerivResidue ✓ vendored), at w=1 (order n+1 — needs the exact S_∞ identification — the mathematical crux), at trivial zeros −2, −4 (simple ✓).
Also for L2 (R-bound): check Zeta23's zero counting (Defs) and what N(T) machinery exists. And check Mathlib digamma. Both exist at least partially. Good enough for the survey — detailed inventory IS sub-stage ii′-0.
One more thing to verify quickly: liCoeff definition in NguyenRH1 (what L7 summability looks like). Let me grep quickly. Actually I have enough for the plan; the detailed inventory is literally the first sub-stage deliverable.
Now let me also think about the overall feasibility verdict:
**De-risking factors discovered today:**
1. `RectangleIntegral'_eq_sumResiduesIn` — the master rectangle residue theorem EXISTS in our dependency (vendored from PNT+), proven and building green. The L0 "main formalization lift" is much smaller than D-062 feared: we extend from simple poles to finite-order poles (bounded), not build from scratch.
2. `logDerivResidue`, `riemannZetaLogDerivResidue`, `riemannZetaResidue`, `ResidueMult` — residue computation lemmas for exactly our pole types at zeros and at s=1 exist.
3. Mathlib has digamma (for Lemma D in the R-bound).
4. zeta-23-lean itself has zero-counting/N(T)-adjacent infrastructure (Defs) — to inventory.
**Remaining genuine lifts:**
1. **Higher-order residue machinery** (order n+1 pole): general residue def + rectangle theorem extension. Engineering, bounded.
2. **The w=1 residue = S_∞(n) exact identification** (the mathematical crux): classical algebra, written in D-036/D-037/Lagarias, needs a formalization-friendly paper design first (choose local-Laurent vs global route).
3. **R-bound (L2)**: D-056's proof uses Hadamard partial fractions. Check what exists (Zeta23 may have relevant ζ′/ζ infrastructure — ZetaBounds has ZetaSum lemmas...). Alternative local route exists. Bounded either way, but this is the second-biggest chunk.
4. **L7 liCoeff summability**: flagged; the zero-sum convergence with perimeter N(T) bound — real analysis, tractable.
So feasibility: HIGH. I'd quantify: ~85–90% achievable as planned, with the main risk being underestimation of engineering friction rather than mathematical blockage. Nothing here requires new mathematics.
**Sub-stage plan** (each ending clean/committed/resumable per §8.5):
- **ii′-0 (design + skeleton)** — D-064: full capability inventory (vendored residue API, meromorphic order API, digamma, zero-counting in Zeta23, Mathlib zeta Laurent); route decisions (higher-order extension design; w=1 identification route; L2 Hadamard-vs-local); write `LiContour.lean` top-down skeleton with ~20–30 named sorries, each cross-referenced to archive line numbers. Exit: skeleton compiles; every sorry has an archive proof.
- **ii′-1** — General residue + rectangle extension (machinery): general `gresidue`, computation lemmas (product rule, derivative formula at finite order), rectangle theorem for finite-order poles, proved against the vendored simple-pole version.
- **ii′-2** — L1 kernel bounds + trivial-zero residues + I-side estimates (elementary, builds tier-(i) momentum).
- **ii′-3** — L3 zero-avoiding T (pigeonhole from perimeter N(T)).
- **ii′-4** — L7 liCoeff summability + zero-sum truncation bookkeeping (needs perimeter N(T) — comparison convergence).
- **ii′-5** — L2 R-bound (the analytic chunk; route chosen in ii′-0).
- **ii′-6** — The w=1 residue: exact S_∞ identification (the crux; paper design from ii′-0).
- **ii′-7** — Identity assembly: Sf = truncated + sides + trivial; bound assembly |Sf| ≤ Bn; discharge `SfBoundProp`; swap into `lambda_pos_finite_height_verified`; full axiom audit; paper Appendix B + tag upgrade; archive closure (journal, D-files, NGUYEN.md, STATE.md).
That's 8 sub-stages ≈ 8–14 sessions depending on friction (some sub-stages are multi-session, notably ii′-5 and ii′-6).
Order note: I'd reorder slightly — machinery (ii′-1) before L1 (ii′-2)? Actually L1 doesn't need residues. To build momentum and de-risk early: do ii′-1 machinery first (it's on the critical path of everything), then the easy layers, then the two hard ones (ii′-5, ii′-6) — and importantly, do the crux PAPER DESIGN in ii′-0 so there are no surprises.
Alternative ordering consideration: start with ii′-6's paper design to retire the biggest risk first? The fork-rule/§8.5 says break into sub-stages. I think ii′-0 (which INCLUDES the crux paper design) then machinery, then easy layers, then hard layers is right.
Also worth stating: what success yields (the tag upgrade per D-062 §4) and the strategic option (submit now vs after ii′). One line.
Probability estimate: I'll give ~85% fully closed as planned, ~95% that at worst some lemma needs a route change (not a dead end), and note the fallback: if the w=1 identification proves unexpectedly nasty, there's a plan-B (weaken SfBoundProp's statement to the one-sided bound the assembly actually needs and prove the identity in inequality form — no, the identity is needed... the real fallback is: keep the hypothesis honestly declared, which is the current published state — i.e., failure here costs nothing, the paper stands as-is). That's an important asymmetry to state: this is a pure-upgrade project with a zero-downside fallback.
Let me write the response now. Structure:
1. Verdict up front: feasible, no new mathematics; discovered machinery already vendored.
2. What the task actually is (3 real lifts).
3. Key findings from the dependency survey (today's good news).
4. Sub-stage plan table with exit criteria.
5. Probability + risks + fallback.
6. Strategic note (submit now vs after) + question.
This changes the picture significantly — for the better. Here's my analysis and plan.
## First, what the task actually is
Closing `SfBoundProp` means proving in Lean: the D-036/D-037 contour identity is exact, and every piece is bounded by the traced `B(n)` terms, uniformly for 10⁵ ≤ n ≤ (3×10¹²−1)². Per the D-062 triage, only three parts are genuinely hard:
1. **L0 — the rectangle contour identity** (residue theorem applied to `k_n(w−1)(−ζ′/ζ)`, assembling `S_f = truncated zero sum + side integrals + trivial-zero terms`).
2. **The pole at w = 1 of order n+1** — its residue must be identified *exactly* with `S_∞(n) + lower terms`. This is the mathematical crux, and no shortcut exists: per-term triangle bounds explode like 2ⁿ (the D-033 "three-way cancellation" wall), so the exact per-j Lagarias identity is forced.
3. **L2 — the reference-point R-bound** (D-056: `|ζ′/ζ − Σ_{|γ−t|<1} 1/(s−ρ)| ≤ 10.5 log(|t|+2) + 48`), whose classical proof runs through Hadamard partial fractions.
Everything else (L1 kernel bounds, L3 pigeonhole, L7 summability) is elementary or finite combinatorics modulo the declared Trudgian perimeter.
## Today's dependency survey — the good news
D-062 called L0 "the main formalization lift" because Mathlib's rectangle residue machinery was assumed thin. Checking the actual vendored tree, we already own most of it:
- **`RectangleIntegral'_eq_sumResiduesIn`** — a *proved* general rectangle residue theorem, vendored in zeta-23-lean from PNT+ (`FromPNTPlus/ResidueCalcOnRectangles.lean:1084`). Also `RectanglePullToNhdOfPole`, `ResidueMult`, `logDerivResidue` (residue at a zero of ζ), `riemannZetaLogDerivResidue` (at s=1).
- **One real gap**: the vendored theorem carries a `HasSimplePolesOn` scaffold — its `residue` is a placeholder valid only for simple poles, and our integrand's w=1 pole has order n+1. So the machinery lift is: general finite-order residue + extend the rectangle theorem (via principal-part decomposition — the j≥2 terms vanish by explicit primitives). Engineering, not analysis.
- Mathlib has **digamma** (for D-056's Lemma D), `MeromorphicAt`/`meromorphicOrderAt` normal forms, and zeta-23-lean itself carries zero-counting infrastructure (`Zeta23/Defs`) I haven't fully inventoried yet.
## Feasibility verdict
**High — I estimate ~85–90% it closes exactly as planned, and ~95%+ that the worst outcome is a route change on one lemma, not a dead end.** Nothing requires new mathematics; every step's proof exists in the archive (D-036/D-037/D-056) or in Lagarias. The risks are engineering friction: the w=1 identification being fiddly, and L2's Hadamard dependency (mitigant: the Borel–Carathéodory/Jensen local route, or Zeta23's existing ζ′/ζ infrastructure).
Crucially, the **fallback is free**: if any piece stalls, the paper stands exactly as it is today with `SfBoundProp` honestly declared. This is a pure-upgrade project with zero downside.
What success buys (D-062 §4): the tag becomes *"Lean-verified modulo published explicit N(T)/S(T) bounds (Trudgian 2014) + computational certificates"* — no named analytic hypothesis remains.
## Proposed sub-stage plan (§8.5-compliant, each ends committed/resumable)
| # | Sub-stage | Content | Est. sessions |
|---|---|---|---|
| ii′-0 | **Design + skeleton** (D-064) | Full capability inventory; route decisions (higher-order extension design; w=1 route: local Laurent recursion vs global two-way evaluation; L2 Hadamard vs local); write `LiContour.lean` top-down with ~20–30 named sorries, each cross-referenced to an archive proof line | 1–2 |
| ii′-1 | Residue machinery | General finite-order `residue`, computation rules, rectangle theorem without `HasSimplePolesOn` | 1–2 |
| ii′-2 | L1 + trivial zeros | Kernel bounds (\|k_n\| ≤ 2 etc.), residues at −2, −4, side-integral estimates | 1 |
| ii′-3 | L3 | Zero-avoiding T ∈ [√n, √n+1] by pigeonhole on the perimeter N(T) count | 0.5–1 |
| ii′-4 | L7 + truncation | `liCoeff` summability and zero-sum truncation bookkeeping via perimeter N(T) | 1 |
| ii′-5 | L2 | The R-bound at A = 10.5, B₀ = 48 (the analytic heavy lift) | 2–3 |
| ii′-6 | The w=1 pole | Exact identification with S_∞(n) — the crux, from the ii′-0 paper design | 2–3 |
| ii′-7 | Assembly + closure | Discharge `SfBoundProp`, swap into `lambda_pos_finite_height_verified`, full axiom audit, paper Appendix B + tag upgrade, archive closure | 1 |
Total: **~9–15 sessions**, roughly 4–6× the tier (i)+(ii) effort. Order rationale: ii′-0 retires the design risk (including the crux on paper) before any Lean is written; ii′-1 builds the shared machinery; ii′-2/3/4 bank easy wins; ii′-5/6 are the two heavy lifts; ii′-7 closes.
## One strategic note
Paper A is submission-ready *today* with the hypothesis declared — so there's a genuine choice: (a) do tier ii′ now and submit after, or (b) submit now and do ii′ as revision material. The mathematician's review recommended (b). But the plan stands either way, and doing ii′-0 costs nothing against (b).
I'd start with **ii′-0** (the D-064 design document + compiling sorry skeleton). Shall I begin?
let do (a), but make sure Paper A and information will still be intact for submition if we change course.
thinking (8175 chars)
The user chose option (a): do tier ii′ now, submit after. But with a hard requirement: Paper A and its information must remain intact for submission if we change course. So:
1. Paper A must stay submission-ready at all times during tier ii′ work — no edits that destabilize it. Any changes to paperA.tex should be avoided until ii′ completes (or only made at the end in the closure sub-stage ii′-7, which is where the Appendix B update + tag upgrade lands).
2. Start sub-stage ii′-0: design document D-064 + LiContour.lean skeleton.
This is session 014. Per protocol §8.3 I already read STATE.md. I should:
- Register the session plan
- Begin ii′-0
For safety of Paper A, concrete measures:
- Do NOT touch paperA.tex during tier ii′ (all paper updates deferred to ii′-7, and even then only Appendix B/abstract sentence via a careful re-audit per D-060 §5 rule).
- Work happens in research/lean/NguyenRH1/ (new file LiContour.lean) and research/derivations/D-064-*.md.
- The existing Lean theorems stay untouched: lambda_pos_finite_height_verified keeps its current form with the hSf hypothesis; the new work PROVES SfBoundProp as a theorem, and only at ii′-7 do we swap. Even then, we can keep the old theorem (it's a corollary) — nothing breaks.
- git: commit frequently per sub-stage so every state is recoverable. Current tree is clean except untracked LaTeX build artifacts — fine.
Let me start session 014 now:
1. Todo list for ii′-0.
2. Set up the session: verify Lean environment works (quick check).
3. Begin D-064 design doc — but first the capability inventory part of ii′-0: I need to survey:
- The vendored residue API in detail (ResidueCalcOnRectangles.lean — read fully)
- MeromorphicAt / meromorphicOrderAt API in Mathlib
- digamma in Mathlib
- Zeta23/Defs zero-counting infrastructure
- Mathlib zeta Laurent at 1 / trivial zeros / functional equation
- What liCoeff is in NguyenRH1 (L7)
- D-036 (the contour computation — the actual proof to formalize), D-056 (R-bound proof), D-057, D-039
- LiSkeleton.lean's SfBoundProp + Bn + FAlt + IIMaj + C0hat + Hhat definitions (what the bound actually is formally)
That's a lot of reading. ii′-0 is estimated 1–2 sessions. Let me be systematic.
Plan for this session:
1. TodoWrite with the ii′-0 breakdown (and note the Paper-A-freeze rule).
2. First, the Paper A protection: nothing to do actively — just the rule. Maybe also verify paperA.pdf builds clean right now as a baseline? It exists (untracked). Quick pdflatex check might take a while but is a good baseline. Actually — the git status shows paperA.pdf untracked. Baseline: `pdflatex` compile check. That takes ~30s. Worth it as the "intact baseline". Actually simpler: the paper compiled clean at session 013 end (committed state), and we're not touching it. A baseline rebuild is cheap insurance though. Hmm — MiKTeX compile of 9pp takes seconds. Let me do it as part of session start (verify + note hash). Actually let me not over-engineer; the file is committed in git, that's the protection. I'll state the freeze rule and rely on git.
3. Capability inventory (the bulk): read the key files. Use subagents? The Explore agent could survey Mathlib/Zeta23 APIs in parallel while I read D-036/D-056 and LiSkeleton myself. That's a good use of parallel agents:
- Agent 1 (Explore): full inventory of the vendored residue/meromorphic API: ResidueCalcOnRectangles.lean (all public decls + hypotheses of RectangleIntegral'_eq_sumResiduesIn), Rectangle.lean, ZetaBounds.lean (logDerivResidue family), Mathlib MeromorphicAt/meromorphicOrderAt API surface (files + key lemma names), digamma file.
- Agent 2 (Explore): Zeta23 zero-counting infrastructure (Defs/, WeilEF?, what N(T)-like objects exist, riemannZeta zeros API used), Mathlib riemannZeta API (Laurent at 1? trivial zeros? functional equation names), and what liCoeff refers to in NguyenRH1 (it's in LiSkeleton or imported?).
Meanwhile I read: D-036 (contour computation), D-056 (R-bound), LiSkeleton.lean's tier-(ii) definitions (Bn, C0hat, Hhat, IIMaj, SInfty, sInftyLower, liCoeff).
4. Then write D-064 (design) — the big deliverable: lemma dependency graph, route decisions, sorry skeleton design.
5. Create LiContour.lean skeleton with named sorries, make it compile.
6. Commit.
Given the sub-stage rule, ii′-0 might span this session and the next. Fine.
One important design consideration for the skeleton: how to structure SfBoundProp's proof. The final theorem must be `∀ n : ℕ, 100000 ≤ n → (n:ℝ) ≤ (3*10^12-1)^2 → |Sf n| ≤ Bn FAlt n`. The proof: fix n in range; set T := zero-avoiding in [√n, √n+1] (L3, needs existence from perimeter N count); identity (L0): Sf n = truncatedSum + sides + trivial; bound each; assemble ≤ Bn FAlt n.
Key design decision: how to state the L0 identity as a Lean theorem with the exact RHS form that matches D-036's accounting (so that bounding is mechanical).
Also the route decisions:
- w=1 identification: local Laurent recursion vs global. I need to read D-036's actual handling first.
- L2: Hadamard vs local route; need to see what Zeta23/Mathlib has. Agent survey informs this.
- Higher-order residue: design the general residue def. Actually — check: maybe current Mathlib HAS a general residue now? The vendored file says "planned for Mathlib but not yet available" — but that comment is from the zeta-23-lean port date; Mathlib v4.33.0-rc2 (current vendored) might have added residue API. Agent 1 should check Mathlib's own residue API (Mathlib/Analysis/Complex/... maybe Residue.lean exists?).
Let me also remember the lean gotchas from STATE.md (handoff notes) when writing the skeleton.
Sandbox note: Lean commands — short ones in foreground OK per handoff ("short PrintAxioms in foreground"; iterate single-file with `lake env lean` from package dir). For the skeleton compile, that's a medium task; try foreground with timeout.
Let me start. First: TodoWrite + session registration note + launch the two Explore agents in parallel + start reading D-036 myself.
Session numbering: this is session 014. I'll note it. I won't create journal until end, but I should keep track.
Also: user directive — Paper A intact. I'll state the freeze rule explicitly:
1. No edits to paperA.tex/paperB.tex/draft.tex/references.bib during ii′-0..ii′-6. All paper changes land in ii′-7 only, after the axiom audit passes, and even then Paper A's change is minimal (Appendix B paragraph + one abstract sentence + tag), re-audited per D-060 §5.
2. Existing Lean theorems untouched: LiSkeleton.lean/LiBasePoints.lean are frozen; new work goes in NEW files (LiContour.lean etc.). SfBoundProp stays as-is until ii′-7, when we add `theorem sfBoundProp : SfBoundProp` (the def SfBoundProp is a Prop; we prove a theorem with that statement) and swap hypotheses — actually careful: SfBoundProp is a def; proving `theorem SfBoundProp.proof : SfBoundProp` then lambda_pos_finite_height_verified can be re-stated without hSf. But rather than editing LiBasePoints.lean (frozen), in ii′-7 we'd add a NEW final theorem `lambda_pos_finite_height_closed` in the new file that applies the old one. Even cleaner: zero edits to existing files, ever. The paper then cites the new final theorem.
Let me kick off. First message to user: brief acknowledgment of the (a) decision + protection protocol + starting ii′-0. Then tools.
Actually — should I use EnterPlanMode here? The user already approved the plan (they said "let's do (a)"). The planning is done at the coarse level; ii′-0 IS the detailed design sub-stage. No need for plan mode; proceed with work. TodoWrite to track.
Let me define todos:
1. Paper-A freeze protocol (state it; verify git-clean baseline for paper files) — quick.
2. Inventory: vendored residue/meromorphic API (Agent 1).
3. Inventory: Zeta23 zero-counting + Mathlib zeta API + liCoeff (Agent 2).
4. Read D-036 + D-056 + LiSkeleton tier-ii defs (myself).
5. Write D-064 design doc (route decisions + lemma graph).
6. Create LiContour.lean sorry skeleton; compiles.
7. Session-014 journal + STATE.md update + commit.
That's the session. Let me go. I'll launch the two agents and read D-036 in parallel.
Locked in: **option (a) — tier ii′ now, submit after, with Paper A frozen and submission-ready at all times.**
## Protection protocol (in force until ii′-7)
1. **Zero edits** to `paperA.tex`, `paperB.tex`, `draft.tex`, `references.bib` — they stay at the session-013 audited state, recoverable via git at any moment.
2. **Zero edits to existing Lean proofs** — `LiSkeleton.lean` / `LiBasePoints.lean` are frozen. All new work goes in **new files** (`LiContour.lean`, …). Even at the end, we *add* a final closed-form theorem rather than rewrite the old ones — the current three-hypothesis `lambda_pos_finite_height_verified` remains in the tree permanently.
3. Commit at every sub-stage boundary — every state recoverable.
If we change course at any point, nothing has moved: Paper A submits as-is.
## Session 014 — starting sub-stage ii′-0 (design + skeleton, → D-064)
tool: TodoWrite ok
input
{
"todos": [
{
"content": "Verify paper/Lean baseline is clean and frozen",
"status": "in_progress",
"activeForm": "Verifying paper/Lean baseline"
},
{
"content": "Inventory vendored residue/meromorphic API (agent)",
"status": "pending",
"activeForm": "Inventorying residue/meromorphic API"
},
{
"content": "Inventory Zeta23 zero-counting + Mathlib zeta API + liCoeff (agent)",
"status": "pending",
"activeForm": "Inventorying Zeta23/Mathlib zeta API"
},
{
"content": "Read D-036, D-056, LiSkeleton tier-(ii) defs",
"status": "pending",
"activeForm": "Reading D-036/D-056/LiSkeleton"
},
{
"content": "Write D-064 design doc (routes + lemma graph)",
"status": "pending",
"activeForm": "Writing D-064 design doc"
},
{
"content": "Create LiContour.lean sorry skeleton, compiles",
"status": "pending",
"activeForm": "Creating LiContour.lean skeleton"
},
{
"content": "Session-014 closure (journal, STATE, commit)",
"status": "pending",
"activeForm": "Closing session 014"
}
]
}
result 2026-08-21 17:50:57Z → 2026-08-21 17:50:57Z
{
"oldTodos": [],
"newTodos": [
"content='Verify paper/Lean baseline is clean and frozen' status='in_progress' active_form='Verifying paper/Lean baseline'",
"content='Inventory vendored residue/meromorphic API (agent)' status='pending' active_form='Inventorying residue/meromorphic API'",
"content='Inventory Zeta23 zero-counting + Mathlib zeta API + liCoeff (agent)' status='pending' active_form='Inventorying Zeta23/Mathlib zeta API'",
"content='Read D-036, D-056, LiSkeleton tier-(ii) defs' status='pending' active_form='Reading D-036/D-056/LiSkeleton'",
"content='Write D-064 design doc (routes + lemma graph)' status='pending' active_form='Writing D-064 design doc'",
"content='Create LiContour.lean sorry skeleton, compiles' status='pending' active_form='Creating LiContour.lean skeleton'",
"content='Session-014 closure (journal, STATE, commit)' status='pending' active_form='Closing session 014'"
],
"cleared": false
}
thinking (168 chars)
Baseline clean: only untracked LaTeX build artifacts. All paper .tex files are committed. Good.
Now launch the two inventory agents in parallel, and read D-036 myself.
Baseline clean — all paper files committed, nothing modified. Now launching the two inventory agents in parallel while I read the analytic sources myself.
tool: Agent ok
input
{
"description": "Inventory residue/meromorphic API",
"subagent_type": "Explore",
"prompt": "Research task (read-only inventory, NO code changes). Context: Lean 4 project at D:\\Python\\Quantum (toolchain v4.33.0-rc2). We need a precise capability inventory of the vendored complex-analysis API to plan a formalization of a rectangle-contour residue argument for \u03b6\u2032/\u03b6 with a higher-order pole.\n\nSurvey THOROUGHLY and report with exact declaration names + file paths + full signatures (hypotheses and conclusions) for:\n\n1. In D:\\Python\\Quantum\\zeta-23-lean\\Zeta23\\FromPNTPlus\\ResidueCalcOnRectangles.lean (1153 lines):\n - Full signature of `RectangleIntegral'_eq_sumResiduesIn` (ALL hypotheses \u2014 especially whether HasSimplePolesOn is among them, and what RectangleIntegral' vs RectangleIntegral are)\n - The `residue` placeholder def, `sumResiduesIn`, `HasSimplePolesOn`, and any lemmas for computing residues (residue_eq_of_tendsto, ResidueMult, logDerivResidue family \u2014 full signatures)\n - `RectanglePullToNhdOfPole*` signatures\n - Any higher-order-pole residue machinery (search for \"order\", \"principalPart\", \"MeromorphicNF\", \"iterated deriv\")\n2. In the same directory: Rectangle.lean and ZetaBounds.lean \u2014 list the main public theorems (one line each: name + what it proves). Especially anything about \u03b6\u2032/\u03b6 bounds, zeta residue at 1, logDeriv.\n3. In the vendored Mathlib at D:\\Python\\Quantum\\zeta-23-lean\\.lake\\packages\\mathlib\\Mathlib:\n - Does Mathlib have its own `residue` API? Search Analysis/Complex/ and Geometry/ for \"residue\" (case-insensitive, def/theorem names). Report what exists in THIS vendored version.\n - `MeromorphicAt` / `meromorphicOrderAt` API: which file, and list key lemmas (especially: order of product/sum, meromorphicOrderAt_eq_int_iff, normal form MeromorphicNFAt, any Laurent-series or principal-part API, anything relating the order to derivatives).\n - Digamma: file Mathlib/Analysis/SpecialFunctions/Gamma/Digamma.lean \u2014 list main declarations.\n - Search for \"Stieltjes\" and \"laurent\" (case-insensitive) related to riemannZeta \u2014 any Laurent expansion of \u03b6 at s=1?\n - riemannZeta API: which files define it, the functional equation theorem names, trivial zeros theorem names (\u03b6(\u22122n)=0), pole at 1 API.\n - Jensen's formula / Borel\u2013Carath\u00e9odory / Hadamard factorization / Weierstrass products: anything? Search Complex analysis dirs for \"Jensen\", \"Borel\", \"Carath\", \"Hadamard\", \"Weierstrass\", \"factorization\".\n4. Check what `Zeta23/FromPNTPlus/MediumPNT.lean` and `StrongPNTPrefix.lean` export at a high level (2-3 sentences each).\n\nReport as a structured list with exact names and signatures where I asked. Be thorough \u2014 this is the foundation of a multi-session design document. No need to read our project files (research/), only zeta-23-lean and the vendored Mathlib."
}
result 2026-08-21 17:52:05Z → 2026-08-21 17:56:12Z
{
"status": "completed",
"prompt": "Research task (read-only inventory, NO code changes). Context: Lean 4 project at D:\\Python\\Quantum (toolchain v4.33.0-rc2). We need a precise capability inventory of the vendored complex-analysis API to plan a formalization of a rectangle-contour residue argument for \u03b6\u2032/\u03b6 with a higher-order pole.\n\nSurvey THOROUGHLY and report with exact declaration names + file paths + full signatures (hypotheses and conclusions) for:\n\n1. In D:\\Python\\Quantum\\zeta-23-lean\\Zeta23\\FromPNTPlus\\ResidueCalcOnRectangles.lean (1153 lines):\n - Full signature of `RectangleIntegral'_eq_sumResiduesIn` (ALL hypotheses \u2014 especially whether HasSimplePolesOn is among them, and what RectangleIntegral' vs RectangleIntegral are)\n - The `residue` placeholder def, `sumResiduesIn`, `HasSimplePolesOn`, and any lemmas for computing residues (residue_eq_of_tendsto, ResidueMult, logDerivResidue family \u2014 full signatures)\n - `RectanglePullToNhdOfPole*` signatures\n - Any higher-order-pole residue machinery (search for \"order\", \"principalPart\", \"MeromorphicNF\", \"iterated deriv\")\n2. In the same directory: Rectangle.lean and ZetaBounds.lean \u2014 list the main public theorems (one line each: name + what it proves). Especially anything about \u03b6\u2032/\u03b6 bounds, zeta residue at 1, logDeriv.\n3. In the vendored Mathlib at D:\\Python\\Quantum\\zeta-23-lean\\.lake\\packages\\mathlib\\Mathlib:\n - Does Mathlib have its own `residue` API? Search Analysis/Complex/ and Geometry/ for \"residue\" (case-insensitive, def/theorem names). Report what exists in THIS vendored version.\n - `MeromorphicAt` / `meromorphicOrderAt` API: which file, and list key lemmas (especially: order of product/sum, meromorphicOrderAt_eq_int_iff, normal form MeromorphicNFAt, any Laurent-series or principal-part API, anything relating the order to derivatives).\n - Digamma: file Mathlib/Analysis/SpecialFunctions/Gamma/Digamma.lean \u2014 list main declarations.\n - Search for \"Stieltjes\" and \"laurent\" (case-insensitive) related to riemannZeta \u2014 any Laurent expansion of \u03b6 at s=1?\n - riemannZeta API: which files define it, the functional equation theorem names, trivial zeros theorem names (\u03b6(\u22122n)=0), pole at 1 API.\n - Jensen's formula / Borel\u2013Carath\u00e9odory / Hadamard factorization / Weierstrass products: anything? Search Complex analysis dirs for \"Jensen\", \"Borel\", \"Carath\", \"Hadamard\", \"Weierstrass\", \"factorization\".\n4. Check what `Zeta23/FromPNTPlus/MediumPNT.lean` and `StrongPNTPrefix.lean` export at a high level (2-3 sentences each).\n\nReport as a structured list with exact names and signatures where I asked. Be thorough \u2014 this is the foundation of a multi-session design document. No need to read our project files (research/), only zeta-23-lean and the vendored Mathlib.",
"agentId": "a35f4584ec1204acf",
"agentType": "Explore",
"content": [
"type='text' text=\"Below is a read-only capability inventory of the vendored complex-analysis API, organized by your four questions. Exact declaration names, file paths, and full signatures are given where requested.\\n\\n---\\n\\n## 1. `Zeta23/FromPNTPlus/ResidueCalcOnRectangles.lean`\\n\\nFile: `D:/Python/Quantum/zeta-23-lean/Zeta23/FromPNTPlus/ResidueCalcOnRectangles.lean`.\\n\\n### Rectangle integrals\\n\\n```lean\\nnoncomputable def HIntegral (f : \u2102 \u2192 E) (x\u2081 x\u2082 y : \u211d) : E\\nnoncomputable def VIntegral (f : \u2102 \u2192 E) (x y\u2081 y\u2082 : \u211d) : E\\n\\nnoncomputable def RectangleIntegral (f : \u2102 \u2192 E) (z w : \u2102) : E\\n-- = HIntegral f z.re w.re z.im - HIntegral f z.re w.re w.im\\n-- + VIntegral f w.re z.im w.im - VIntegral f z.re z.im w.im\\n\\nnoncomputable abbrev RectangleIntegral' (f : \u2102 \u2192 E) (z w : \u2102) : E\\n-- = (1 / (2 * \u03c0 * I)) \u2022 RectangleIntegral f z w\\n```\\n\\nSo `RectangleIntegral` is the raw boundary integral; `RectangleIntegral'` is normalized by `2\u03c0i`.\\n\\n### Pull-to-pole lemmas\\n\\n```lean\\nlemma RectanglePullToNhdOfPole' [CompleteSpace E] {z\u2080 z\u2081 z\u2082 z\u2083 p : \u2102}\\n (h_orientation : z\u2080.re \u2264 z\u2083.re \u2227 z\u2080.im \u2264 z\u2083.im \u2227\\n z\u2081.re \u2264 z\u2082.re \u2227 z\u2081.im \u2264 z\u2082.im)\\n (hp : Rectangle z\u2081 z\u2082 \u2208 \ud835\udcdd p)\\n (hz : Rectangle z\u2081 z\u2082 \u2286 Rectangle z\u2080 z\u2083)\\n (fHolo : HolomorphicOn f (Rectangle z\u2080 z\u2083 \\\\ {p})) :\\n RectangleIntegral f z\u2080 z\u2083 = RectangleIntegral f z\u2081 z\u2082\\n\\nlemma RectanglePullToNhdOfPole [CompleteSpace E] {z w p : \u2102}\\n (zRe_lt_wRe : z.re \u2264 w.re) (zIm_lt_wIm : z.im \u2264 w.im)\\n (hp : Rectangle z w \u2208 \ud835\udcdd p)\\n (fHolo : HolomorphicOn f (Rectangle z w \\\\ {p})) :\\n \u2200\u1da0 (c : \u211d) in \ud835\udcdd[>]0,\\n RectangleIntegral f z w =\\n RectangleIntegral f (-c - I * c + p) (c + I * c + p)\\n\\nlemma RectanglePullToNhdOfPole'' [CompleteSpace E] {z w p : \u2102}\\n (zRe_le_wRe : z.re \u2264 w.re) (zIm_le_wIm : z.im \u2264 w.im)\\n (pInRectInterior : Rectangle z w \u2208 \ud835\udcdd p)\\n (fHolo : HolomorphicOn f (Rectangle z w \\\\ {p})) :\\n \u2200\u1da0 (c : \u211d) in \ud835\udcdd[>]0,\\n RectangleIntegral' f z w =\\n RectangleIntegral' f (-c - I * c + p) (c + I * c + p)\\n```\\n\\n### Simple-pole residue scaffold\\n\\n```lean\\ndef HasSimplePolesOn (f : \u2102 \u2192 \u2102) (s : Set \u2102) : Prop :=\\n \u2200 z \u2208 s, (-1 : \u2124) \u2264 meromorphicOrderAt f z\\n```\\n\\n```lean\\nnoncomputable def residue (f : \u2102 \u2192 \u2102) (z\u2080 : \u2102) : \u2102 :=\\n Filter.limUnder (nhdsWithin z\u2080 {z\u2080}\u1d9c) (fun z \u21a6 (z - z\u2080) * f z)\\n\\nnoncomputable def sumResiduesIn (f : \u2102 \u2192 \u2102) (S : Set \u2102) : \u2102 :=\\n \u2211' z : S, residue f z\\n```\\n\\n```lean\\nlemma residue_eq_of_tendsto {f : \u2102 \u2192 \u2102} {p c : \u2102}\\n (h : Filter.Tendsto (fun z \u21a6 (z - p) * f z)\\n (nhdsWithin p {p}\u1d9c) (nhds c)) :\\n residue f p = c\\n\\nlemma residue_analyticAt_eq_zero {f : \u2102 \u2192 \u2102} {p : \u2102}\\n (hf : AnalyticAt \u2102 f p) :\\n residue f p = 0\\n\\nlemma simplePole_sub_residue_isBigO_one {f : \u2102 \u2192 \u2102} {p : \u2102}\\n (hf : MeromorphicAt f p)\\n (hord : meromorphicOrderAt f p = (-1 : \u2124)) :\\n (f - (fun z \u21a6 residue f p / (z - p))) =O[nhdsWithin p {p}\u1d9c] (1 : \u2102 \u2192 \u2102)\\n\\nlemma residue_eq_zero_of_not_pole_of_meromorphicAt {F : \u2102 \u2192 \u2102} {s : \u2102}\\n (hs_mero : MeromorphicAt F s)\\n (hs_not_pole : 0 \u2264 meromorphicOrderAt F s) :\\n residue F s = 0\\n\\nlemma sumResiduesIn_inter_eq_of_set_eq {F : \u2102 \u2192 \u2102} {Rn S2 P : Set \u2102}\\n (h_set_eq : Rn \u2229 P = S2 \u2229 P)\\n (h_residue_zero : \u2200 s \u2208 S2, s \u2209 P \u2192 residue F s = 0) :\\n sumResiduesIn F (Rn \u2229 P) = sumResiduesIn F S2\\n```\\n\\n### Rectangle residue theorem for simple poles\\n\\n```lean\\nlemma RectangleIntegral'_eq_sumResiduesIn {f : \u2102 \u2192 \u2102} {z w : \u2102}\\n (zRe_le_wRe : z.re \u2264 w.re) (zIm_le_wIm : z.im \u2264 w.im)\\n (f_mero : MeromorphicOn f (Rectangle z w))\\n (f_no_poles_boundary : Disjoint (RectangleBorder z w)\\n {z | meromorphicOrderAt f z < 0})\\n (f_poles_finite : (Rectangle z w \u2229 {z | meromorphicOrderAt f z < 0}).Finite)\\n (f_simple_poles : HasSimplePolesOn f (Rectangle z w)) :\\n RectangleIntegral' f z w =\\n sumResiduesIn f (Rectangle z w \u2229 {z | meromorphicOrderAt f z < 0})\\n```\\n\\nSo **`HasSimplePolesOn is indeed a hypothesis`**, and the conclusion is a `tsum` over the set of points where `meromorphicOrderAt f z < 0`.\\n\\n### Other simple-pole residue lemmas in the same file\\n\\n```lean\\nlemma ResidueTheoremAtOrigin' {z w c : \u2102}\\n (h1 : z.re < 0) (h2 : z.im < 0) (h3 : 0 < w.re) (h4 : 0 < w.im) :\\n RectangleIntegral (fun s => c / s) z w = 2 * I * \u03c0 * c\\n\\ntheorem ResidueTheoremInRectangle\\n (zRe_le_wRe : z.re \u2264 w.re) (zIm_le_wIm : z.im \u2264 w.im)\\n (pInRectInterior : Rectangle z w \u2208 \ud835\udcdd p) :\\n RectangleIntegral' (fun s => c / (s - p)) z w = c\\n\\nlemma ResidueTheoremOnRectangleWithSimplePole {f g : \u2102 \u2192 \u2102} {z w p A : \u2102}\\n (zRe_le_wRe : z.re \u2264 w.re) (zIm_le_wIm : z.im \u2264 w.im)\\n (pInRectInterior : Rectangle z w \u2208 \ud835\udcdd p)\\n (gHolo : HolomorphicOn g (Rectangle z w))\\n (principalPart : Set.EqOn\\n (f - fun s \u21a6 A / (s - p)) g (Rectangle z w \\\\ {p})) :\\n RectangleIntegral' f z w = A\\n\\ntheorem ResidueTheoremOnRectangleWithSimplePole' {f : \u2102 \u2192 \u2102} {z w p A : \u2102}\\n (zRe_le_wRe : z.re \u2264 w.re) (zIm_le_wIm : z.im \u2264 w.im)\\n (pInRectInterior : Rectangle z w \u2208 \ud835\udcdd p)\\n (fHolo : HolomorphicOn f (Rectangle z w \\\\ {p}))\\n (near_p : (f - (fun s \u21a6 A / (s - p))) =O[\ud835\udcdd[\u2260] p] (1 : \u2102 \u2192 \u2102)) :\\n RectangleIntegral' f z w = A\\n```\\n\\n### Higher-order-pole / normal-form machinery used by the proof\\n\\nThere is **no** general higher-order residue formula or `iteratedDeriv`-based residue computation. The file works around this by assuming `HasSimplePolesOn`. The main normal-form/order lemmas used are:\\n\\n| Name | Kind | Statement summary |\\n|------|------|-------------------|\\n| `meromorphicOrderAt_eq_neg_one_of_simplePole` | private | under `HasSimplePolesOn`, any negative order is exactly `-1` |\\n| `residue_toMeromorphicNFOn_eq_residue` | private | residue is unchanged by `toMeromorphicNFOn` |\\n| `principalPart_meromorphicOn` | private | finite sum `\u2211 c p / (s-p)` is meromorphic |\\n| `sub_principalPart_analyticAt_of_not_mem_poles` | private | subtracting the principal part is analytic away from the chosen poles |\\n| `meromorphicOrderAt_sub_principalPart_nonneg` | private | after subtracting the principal part, order at each pole becomes `\u2265 0` |\\n| `holoPart_holomorphicOn` | private | the \u201cholomorphic part\u201d after subtracting principal part is holomorphic on the rectangle |\\n| `principalPart_borderIntegrable` | private | the principal part is integrable on the rectangle boundary |\\n| `rectangleIntegral'_toMeromorphicNFOn_eq` | private | boundary integral unchanged by `toMeromorphicNFOn` |\\n| `toMeromorphicNFOn_add_integral` | private | splits `RectangleIntegral'` of `fNF` into holomorphic part + principal part |\\n| `rectangleIntegral'_sum_div_sub` | private | integral of a finite sum of simple-pole terms equals sum of coefficients |\\n| `sumResiduesIn_inter_eq_of_set_eq` | public | re-indexes `sumResiduesIn` using a set equality |\\n| `residue_eq_zero_of_not_pole_of_meromorphicAt` | public | residue is `0` at non-negative-order points |\\n\\nNo `iteratedDeriv` residue formula appears in this file.\\n\\n---\\n\\n## 2. `Rectangle.lean` and `ZetaBounds.lean` (main public theorems)\\n\\n### `Zeta23/FromPNTPlus/Rectangle.lean`\\n\\nKey public declarations:\\n\\n- `RectangleBorder z w` \u2014 the boundary of the axis-parallel rectangle with corners `z,w`.\\n- `Square p c` \u2014 axis-parallel square centered at `p` with half-side `c`.\\n- `segment_reProdIm_segment_eq_convexHull` \u2014 rectangle = convex hull of its four corners.\\n- `rectangle_in_convex` \u2014 if the four corners lie in a convex set, the whole rectangle lies in it.\\n- `mem_Rect` \u2014 membership in a rectangle in terms of real/imag inequalities.\\n- `rect_subset_iff` \u2014 `Rectangle z' w' \u2286 Rectangle z w` iff both corners are inside.\\n- `RectSubRect` / `RectSubRect'` \u2014 nested rectangles under coordinate inequalities.\\n- `rectangle_disjoint_singleton` / `rectangleBorder_disjoint_singleton` \u2014 conditions for a point to be disjoint from a rectangle/border.\\n- `rectangle_subset_punctured_rect` / `rectangleBorder_subset_punctured_rect` \u2014 shrink a rectangle around a pole.\\n- `rectangle_mem_nhds_iff` \u2014 a rectangle is a neighborhood of `p` iff `p` is in the open product interval.\\n- `Complex.nhds_hasBasis_square` \u2014 neighborhoods of `p` have a basis of squares `Square p c`.\\n- `square_mem_nhds` / `square_subset_square` / `SmallSquareInRectangle` \u2014 square neighborhoods can be chosen inside a given rectangle.\\n- `not_mem_rectangleBorder_of_rectangle_mem_nhds` \u2014 interior points are not on the border.\\n- Many `mapsTo_rectangle*_NoP` lemmas \u2014 boundary parametrizations map into punctured rectangles.\\n\\n### `Zeta23/FromPNTPlus/ZetaBounds.lean`\\n\\nMain public theorems (one line each):\\n\\n| Theorem | What it proves |\\n|---------|----------------|\\n| `ResidueOfTendsTo` | If `(s-p)f(s) \u2192 A` and `f` is holomorphic on a punctured neighborhood of `p`, then `f - A/(s-p)` is bounded near `p`. |\\n| `analyticAt_riemannZeta` | `\u03b6` is analytic at every `s \u2260 1`. |\\n| `differentiableAt_deriv_riemannZeta` | `\u03b6'` is differentiable at every `s \u2260 1`. |\\n| `riemannZetaResidue` | `\u03b6` has simple-pole residue `1` at `s = 1` (boundedness form). |\\n| `logDerivResidue'` / `logDerivResidue` / `logDerivResidue''` | If `f` has a simple pole with residue `A \u2260 0` and `f` is nonzero on a punctured neighborhood, then `f'/f + 1/(s-p) =O[\ud835\udcdd[\u2260]p] 1`, and a boundedness corollary. |\\n| `ResidueMult` | If `f - A/(s-p) =O 1` near `p` and `g` is holomorphic at `p`, then `f*g - A*g(p)/(s-p) =O 1`. |\\n| `riemannZetaLogDerivResidue` | `-\u03b6'/\u03b6 - 1/(s-1)` is bounded near `s = 1`. |\\n| `riemannZetaLogDerivResidueBigO` | `-\u03b6'/\u03b6 - 1/(s-1) =O[\ud835\udcdd[\u2260]1] 1`. |\\n| `ZetaUpperBnd` | `\u2016\u03b6(\u03c3+it)\u2016 \u2264 C log |t|` for `3 < |t|` and `1 - A/log|t| \u2264 \u03c3 \u2264 2`. |\\n| `ZetaDerivUpperBnd` | `\u2016\u03b6'(\u03c3+it)\u2016 \u2264 C (log |t|)\u00b2` in the same region. |\\n| `ZetaLowerBound3` | Lower bound `c(\u03c3-1)^{3/4}/(log|t|)^{1/4} \u2264 \u2016\u03b6(\u03c3+it)\u2016` for `1 < \u03c3 \u2264 2`. |\\n| `ZetaInvBnd` | `1/\u2016\u03b6(\u03c3+it)\u2016 \u2264 C (log|t|)^7` in a narrow strip around `Re s = 1`. |\\n| `ZetaLowerBnd` | `c/(log|t|)^7 \u2264 \u2016\u03b6(\u03c3+it)\u2016` for `\u03c3 < 1` in a narrow strip. |\\n| `ZetaZeroFree` | `\u03b6(\u03c3+it) \u2260 0` for `3 < |t|` and `\u03c3` in a narrow strip to the left of `1`. |\\n| `LogDerivZetaBnd` | `\u2016\u03b6'/\u03b6(\u03c3+it)\u2016 \u2264 C (log|t|)^9` in a narrow strip around `1`. |\\n| `LogDerivZetaBndUnif` | Uniform version of the above for `\u03c3 \u2265 1 - A/(log|t|)^9`. |\\n| `ZetaNoZerosOn1Line` | `\u03b6(1+it) \u2260 0` for all real `t`. |\\n| `ZetaNoZerosInBox` | For every `T`, there is `\u03c3\u2082 < 1` such that `\u03b6` has no zeros in `[[\u03c3\u2082,2]] \u00d7\u2102 [[-T,T]]`. |\\n| `LogDerivZetaHoloOn` | `\u03b6'/\u03b6` is holomorphic on any set not containing `1` and where `\u03b6` has no zeros. |\\n| `LogDerivZetaHolcSmallT` | `\u03b6'/\u03b6` is holomorphic on a small box around `1` minus `{1}`. |\\n| `LogDerivZetaHolcLargeT` | `\u03b6'/\u03b6` is holomorphic on a large box `[[1-A/log^9 T,2]] \u00d7\u2102 [[-T,T]] \\\\ {1}`. |\\n| `dlog_riemannZeta_bdd_on_vertical_lines_generalized` | `\u2016-\u03b6'(\u03c3\u2081+it)/\u03b6(\u03c3\u2081+it)\u2016 \u2264 \u2016\u03b6'(\u03c3\u2080)/\u03b6(\u03c3\u2080)\u2016` for `1 < \u03c3\u2080 \u2264 \u03c3\u2081`. |\\n| `triv_bound_zeta` | `\u2016-\u03b6'(\u03c3\u2080+it)/\u03b6(\u03c3\u2080+it)\u2016 \u2264 (\u03c3\u2080-1)\u207b\u00b9 + C` for `\u03c3\u2080 > 1`. |\\n\\n---\\n\\n## 3. Vendored Mathlib inventory\\n\\n### Complex / contour `residue` API\\n\\n**There is no native complex-contour `residue` API in this vendored Mathlib.** Searching `Mathlib/Analysis/Complex` and `Mathlib/Geometry` for \u201cresidue\u201d yields only:\\n\\n- `Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean` \u2014 algebraic-geometry residue fields (`X.residueField x`, `X.residue x`), unrelated to contour integration.\\n\\nNo file `Mathlib/Analysis/Complex/Residue.lean` or similar exists.\\n\\n### Meromorphic order / normal-form API\\n\\nThe core API is in:\\n\\n- `Mathlib/Analysis/Meromorphic/Basic.lean` \u2014 `MeromorphicAt`.\\n- `Mathlib/Analysis/Meromorphic/Order.lean` \u2014 `meromorphicOrderAt`.\\n- `Mathlib/Analysis/Meromorphic/NormalForm.lean` \u2014 `MeromorphicNFAt`, `toMeromorphicNFAt`, `toMeromorphicNFOn`.\\n- `Mathlib/Analysis/Meromorphic/FactorizedRational.lean` \u2014 factorized rational functions, zeros/poles extraction.\\n- `Mathlib/Analysis/Meromorphic/TrailingCoefficient.lean` \u2014 `meromorphicTrailingCoeffAt`.\\n\\nKey definitions and lemmas:\\n\\n```lean\\n-- Basic.lean\\ndef MeromorphicAt (f : \ud835\udd5c \u2192 E) (x : \ud835\udd5c) :=\\n \u2203 (n : \u2115), AnalyticAt \ud835\udd5c (fun z \u21a6 (z - x) ^ n \u2022 f z) x\\n```\\n\\n```lean\\n-- Order.lean\\nnoncomputable def meromorphicOrderAt (f : \ud835\udd5c \u2192 E) (x : \ud835\udd5c) : WithTop \u2124\\n\\nlemma meromorphicOrderAt_eq_top_iff :\\n meromorphicOrderAt f x = \u22a4 \u2194 \u2200\u1da0 z in \ud835\udcdd[\u2260] x, f z = 0\\n\\nlemma meromorphicOrderAt_eq_int_iff {n : \u2124} (hf : MeromorphicAt f x) :\\n meromorphicOrderAt f x = n \u2194\\n \u2203 g : \ud835\udd5c \u2192 E, AnalyticAt \ud835\udd5c g x \u2227 g x \u2260 0 \u2227\\n \u2200\u1da0 z in \ud835\udcdd[\u2260] x, f z = (z - x) ^ n \u2022 g z\\n\\nlemma meromorphicOrderAt_ne_top_iff {f : \ud835\udd5c \u2192 E} {z\u2080 : \ud835\udd5c} (hf : MeromorphicAt f z\u2080) :\\n meromorphicOrderAt f z\u2080 \u2260 \u22a4 \u2194\\n \u2203 (g : \ud835\udd5c \u2192 E), AnalyticAt \ud835\udd5c g z\u2080 \u2227 g z\u2080 \u2260 0 \u2227\\n f =\u1da0[\ud835\udcdd[\u2260] z\u2080] fun z \u21a6 (z - z\u2080) ^ ((meromorphicOrderAt f z\u2080).untop\u2080) \u2022 g z\\n```\\n\\nOrder under arithmetic:\\n\\n```lean\\ntheorem meromorphicOrderAt_mul {f g : \ud835\udd5c \u2192 \ud835\udd5c'} (hf : MeromorphicAt f x)\\n (hg : MeromorphicAt g x) :\\n meromorphicOrderAt (f * g) x =\\n meromorphicOrderAt f x + meromorphicOrderAt g x\\n\\ntheorem meromorphicOrderAt_prod {x : \ud835\udd5c} {\u03b9 : Type*} {s : Finset \u03b9} {f : \u03b9 \u2192 \ud835\udd5c \u2192 \ud835\udd5c'}\\n (hf : \u2200 i \u2208 s, MeromorphicAt (f i) x) :\\n meromorphicOrderAt (\u220f i \u2208 s, f i) x =\\n \u2211 i \u2208 s, meromorphicOrderAt (f i) x\\n\\ntheorem meromorphicOrderAt_add (hf\u2081 : MeromorphicAt f\u2081 x) (hf\u2082 : MeromorphicAt f\u2082 x) :\\n min (meromorphicOrderAt f\u2081 x) (meromorphicOrderAt f\u2082 x) \u2264\\n meromorphicOrderAt (f\u2081 + f\u2082) x\\n\\ntheorem meromorphicOrderAt_add_of_ne\\n (hf\u2081 : MeromorphicAt f\u2081 x) (hf\u2082 : MeromorphicAt f\u2082 x)\\n (h : meromorphicOrderAt f\u2081 x \u2260 meromorphicOrderAt f\u2082 x) :\\n meromorphicOrderAt (f\u2081 + f\u2082) x =\\n min (meromorphicOrderAt f\u2081 x) (meromorphicOrderAt f\u2082 x)\\n```\\n\\nOrder and derivatives:\\n\\n```lean\\nlemma meromorphicOrderAt_deriv_eq_sub_one [CompleteSpace E] {f : \ud835\udd5c \u2192 E} {x : \ud835\udd5c} {n : \u2124}\\n (hn : (n : \ud835\udd5c) \u2260 0) (hf : meromorphicOrderAt f x = \u2191n) :\\n meromorphicOrderAt (deriv f) x = \u2191(n - 1)\\n\\nlemma meromorphicOrderAt_deriv [CompleteSpace E] {f : \ud835\udd5c \u2192 E} {x : \ud835\udd5c} {n : \u2124}\\n (hn : (\u2191(n + 1) : \ud835\udd5c) \u2260 0) (hf : meromorphicOrderAt f x = \u2191(n + 1)) :\\n meromorphicOrderAt (deriv f) x = \u2191n\\n```\\n\\nNormal form:\\n\\n```lean\\n-- NormalForm.lean\\ndef MeromorphicNFAt :=\\n f =\u1da0[\ud835\udcdd x] 0 \u2228\\n \u2203 (n : \u2124) (g : \ud835\udd5c \u2192 E), AnalyticAt \ud835\udd5c g x \u2227 g x \u2260 0 \u2227\\n f =\u1da0[\ud835\udcdd x] (\u00b7 - x) ^ n \u2022 g\\n\\nnoncomputable def toMeromorphicNFAt (f : \ud835\udd5c \u2192 E) (x : \ud835\udd5c) : \ud835\udd5c \u2192 E\\nnoncomputable def toMeromorphicNFOn (f : \ud835\udd5c \u2192 E) (U : Set \ud835\udd5c) : \ud835\udd5c \u2192 E\\n\\ntheorem meromorphicNFAt_toMeromorphicNFAt :\\n MeromorphicNFAt (toMeromorphicNFAt f x) x\\n\\ntheorem meromorphicNFOn_toMeromorphicNFOn :\\n MeromorphicNFOn (toMeromorphicNFOn f U) U\\n\\ntheorem toMeromorphicNFOn_eqOn_codiscrete (hf : MeromorphicOn f U) :\\n f =\u1da0[Filter.codiscreteWithin U] toMeromorphicNFOn f U\\n\\ntheorem MeromorphicOn.toMeromorphicNFOn_eq_self_on_nhdsNE\\n (hf : MeromorphicOn f U) (hx : x \u2208 U) :\\n toMeromorphicNFOn f U =\u1da0[\ud835\udcdd[\u2260] x] f\\n\\ntheorem meromorphicOrderAt_toMeromorphicNFOn (hf : MeromorphicOn f U) (hx : x \u2208 U) :\\n meromorphicOrderAt (toMeromorphicNFOn f U) x = meromorphicOrderAt f x\\n\\ntheorem toMeromorphicNFOn_eq_toMeromorphicNFAt_on_nhds\\n (hf : MeromorphicOn f U) (hx : x \u2208 U) :\\n toMeromorphicNFOn f U =\u1da0[\ud835\udcdd x] toMeromorphicNFAt f x\\n```\\n\\nPrincipal-part-like factorization:\\n\\n```lean\\n-- FactorizedRational.lean\\ntheorem MeromorphicOn.extract_zeros_poles {f : \ud835\udd5c \u2192 E} (h\u2081f : MeromorphicOn f U)\\n (h\u2082f : \u2200 u : U, meromorphicOrderAt f u \u2260 \u22a4)\\n (h\u2083f : (divisor f U).support.Finite) :\\n \u2203 g : \ud835\udd5c \u2192 E, AnalyticOnNhd \ud835\udd5c g U \u2227 (\u2200 u : U, g u \u2260 0) \u2227\\n f =\u1da0[codiscreteWithin U] (\u220f\u1da0 u, (\u00b7 - u) ^ divisor f U u) \u2022 g\\n\\ntheorem MeromorphicOn.extract_zeros_poles_log {f g : \ud835\udd5c \u2192 E} ...\\n (h : f =\u1da0[codiscreteWithin U] (\u220f\u1da0 u, (\u00b7 - u) ^ D u) \u2022 g) :\\n (log \u2016f \u00b7\u2016) =\u1da0[codiscreteWithin U]\\n \u2211\u1da0 u, (D u * log \u2016\u00b7 - u\u2016) + (log \u2016g \u00b7\u2016)\\n```\\n\\nThere is **no** dedicated Laurent-series expansion or principal-part coefficient API beyond this normal-form / factorized-rational machinery.\\n\\n### Digamma\\n\\nFile: `Mathlib/Analysis/SpecialFunctions/Gamma/Digamma.lean`.\\n\\n```lean\\nnoncomputable def Complex.digamma : \u2102 \u2192 \u2102 := logDeriv Gamma\\n\\ntheorem digamma_def : digamma = logDeriv Gamma\\n\\n@[simp] theorem digamma_zero : digamma 0 = 0\\n\\ntheorem digamma_one : digamma 1 = - Real.eulerMascheroniConstant\\n\\ntheorem digamma_one_half : digamma (1 / 2) = - 2 * log 2 - Real.eulerMascheroniConstant\\n\\ntheorem digamma_apply_add_one (s : \u2102) (hs : \u2200 m : \u2115, s \u2260 - m) :\\n digamma (s + 1) = digamma s + s\u207b\u00b9\\n\\ntheorem meromorphic_digamma : Meromorphic digamma\\n```\\n\\n### Stieltjes / Laurent related to `riemannZeta`\\n\\n- **Stieltjes**: `Mathlib` has a general theory of Stieltjes functions/measures (`MeasureTheory/Measure/Stieltjes.lean`, `Probability/Kernel/Disintegration/MeasurableStieltjes.lean`, etc.), but **nothing named \u201cStieltjes\u201d is tied to `riemannZeta`** in this vendored version.\\n- **Laurent**: generic Laurent polynomial/series files exist (`Algebra/Polynomial/Laurent.lean`, `Algebra/Vertex/...`), and `Analysis/Complex/ValueDistribution/Cartan.lean` mentions a \u201cJensen-type identity.\u201d There is **no Laurent expansion of `\u03b6` at `s = 1`**. The closest result is the asymptotic expansion in `NumberTheory/Harmonic/ZetaAsymp.lean`:\\n\\n```lean\\ntheorem tendsto_riemannZeta_sub_one_div :\\n Tendsto (fun s : \u2102 \u21a6 riemannZeta s - 1 / (s - 1))\\n (\ud835\udcdd[\u2260] 1) (\ud835\udcdd Real.eulerMascheroniConstant)\\n```\\n\\ni.e. the principal part is `1/(s-1)` and the constant term is `\u03b3`.\\n\\n### `riemannZeta` API\\n\\nDefinitions and main results are in `Mathlib/NumberTheory/LSeries/RiemannZeta.lean`.\\n\\n```lean\\ndef completedRiemannZeta\u2080 (s : \u2102) : \u2102\\ndef completedRiemannZeta (s : \u2102) : \u2102\\ndef riemannZeta : \u2102 \u2192 \u2102 := hurwitzZetaEven 0\\n```\\n\\nKey theorems:\\n\\n```lean\\ntheorem differentiable_completedZeta\u2080 : Differentiable \u2102 completedRiemannZeta\u2080\\n\\ntheorem differentiableAt_completedZeta {s : \u2102} (hs : s \u2260 0) (hs' : s \u2260 1) :\\n DifferentiableAt \u2102 completedRiemannZeta s\\n\\ntheorem differentiableAt_riemannZeta {s : \u2102} (hs' : s \u2260 1) :\\n DifferentiableAt \u2102 riemannZeta s\\n\\ntheorem completedRiemannZeta\u2080_one_sub (s : \u2102) :\\n completedRiemannZeta\u2080 (1 - s) = completedRiemannZeta\u2080 s\\n\\ntheorem completedRiemannZeta_one_sub (s : \u2102) :\\n completedRiemannZeta (1 - s) = completedRiemannZeta s\\n\\ntheorem riemannZeta_one_sub {s : \u2102} (hs : \u2200 n : \u2115, s \u2260 -n) (hs' : s \u2260 1) :\\n riemannZeta (1 - s) =\\n 2 * (2 * \u03c0) ^ (-s) * Gamma s * cos (\u03c0 * s / 2) * riemannZeta s\\n\\ntheorem riemannZeta_neg_two_mul_nat_add_one (n : \u2115) :\\n riemannZeta (-2 * (n + 1)) = 0\\n\\ntheorem riemannZeta_residue_one :\\n Tendsto (fun s \u21a6 (s - 1) * riemannZeta s) (\ud835\udcdd[\u2260] 1) (\ud835\udcdd 1)\\n\\ntheorem zeta_eq_tsum_one_div_nat_cpow {s : \u2102} (hs : 1 < re s) :\\n riemannZeta s = \u2211' n : \u2115, 1 / (n : \u2102) ^ s\\n```\\n\\nSpecial values and pole data are further in:\\n\\n- `Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean`:\\n - `tendsto_riemannZeta_sub_one_div` (principal part + \u03b3),\\n - `riemannZeta_one` (`\u03b6 1 = (\u03b3 - log(4\u03c0))/2`),\\n - `riemannZeta_one_ne_zero`,\\n - `deriv_riemannZeta_zero`.\\n\\n- `Mathlib/NumberTheory/LSeries/HurwitzZetaValues.lean`:\\n - `riemannZeta_two_mul_nat`,\\n - `riemannZeta_neg_nat_eq_bernoulli`,\\n - `riemannZeta_two`, `riemannZeta_four`.\\n\\n- `Mathlib/NumberTheory/LSeries/Nonvanishing.lean`:\\n - `riemannZeta_ne_zero_of_one_le_re`,\\n - `riemannZeta_ne_zero_of_one_lt_re`.\\n\\n- `Mathlib/NumberTheory/LSeries/ZetaZeros.lean`:\\n - `riemannZetaZeros : Set \u2102`,\\n - `isClosed_riemannZetaZeros`,\\n - `isDiscrete_riemannZetaZeros`,\\n - `IsCompact.inter_riemannZetaZeros_finite`.\\n\\n### Jensen / Borel\u2013Carath\u00e9odory / Hadamard / Weierstrass\\n\\n- **Borel\u2013Carath\u00e9odory**: `Mathlib/Analysis/Complex/BorelCaratheodory.lean`\\n - `Complex.borelCaratheodory_zero`\\n - `Complex.borelCaratheodory`\\n\\n- **Jensen\u2019s formula**: `Mathlib/Analysis/Complex/JensenFormula.lean`\\n - `MeromorphicOn.circleAverage_log_norm`\\n - `AnalyticOnNhd.circleAverage_log_norm`\\n - `AnalyticOnNhd.sum_divisor_le`\\n\\n- **Hadamard three-lines theorem**: `Mathlib/Analysis/Complex/Hadamard.lean`\\n - Several variants of `HadamardThreeLines` interpolation (not Hadamard factorization).\\n\\n- **Weierstrass theorem on uniform limits of holomorphic functions**: `Mathlib/Analysis/Complex/LocallyUniformLimit.lean`\\n - `TendstoLocallyUniformlyOn.differentiableOn`\\n - `TendstoLocallyUniformlyOn.deriv`\\n - `differentiableOn_tsum_of_summable_norm`\\n - `hasSum_deriv_of_summable_norm`\\n\\nThere is **no** Weierstrass factorization theorem or Hadamard factorization theorem in this vendored Mathlib. The project\u2019s `StrongPNTPrefix.lean` builds a finite Blaschke-factor argument by hand.\\n\\n---\\n\\n## 4. `MediumPNT.lean` and `StrongPNTPrefix.lean` exports\\n\\n### `Zeta23/FromPNTPlus/MediumPNT.lean`\\n\\nThis file implements the **smoothed explicit formula** step of the medium PNT proof. It defines the smoothed Chebyshev integral `SmoothedChebyshev` as a vertical Mellin inversion of `-\u03b6'/\u03b6` times a smooth cutoff, proves the Dirichlet-series identity `SmoothedChebyshevDirichlet` (the smoothed integral equals `\u2211 \u039b(n) \u00b7 Smooth1(n/X)`), and gives the approximation estimate `SmoothedChebyshevClose` showing that this smoothed sum is within `O(\u03b5 X log X)` of the Chebyshev psi function `\u03c8 X`.\\n\\n### `Zeta23/FromPNTPlus/StrongPNTPrefix.lean`\\n\\nThis is a sorry-free prefix of a Strong Prime Number Theorem development. It contains a self-contained complex-analysis toolkit: a local Borel\u2013Carath\u00e9odory derivative bound (`BorelCaratheodoryDeriv`), construction of a logarithm `J_B` of a nonvanishing analytic function (`LogOfAnalyticFunction`), a finite zero-set / Blaschke-factor setup (`ZeroFactor`, `Cf`, `BlaschkeB`), and culminates in `ZerosBound` \u2014 a bound on the weighted number of zeros of an analytic function in a smaller disk in terms of its sup norm on a larger disk. The remainder of the original `StrongPNT.lean` (after `ZerosBound`) is not ported.\""
],
"totalDurationMs": 246881.10473632812,
"totalTokens": 226415,
"totalToolUseCount": 48,
"usage": {
"input_tokens": 2250,
"output_tokens": 8101,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 216064
}
}
tool: Agent ok
input
{
"description": "Inventory zero-counting + liCoeff",
"subagent_type": "Explore",
"prompt": "Research task (read-only inventory, NO code changes). Context: Lean 4 project at D:\\Python\\Quantum (toolchain v4.33.0-rc2). We are planning to formalize an explicit contour bound for the Li coefficients of \u03b6. I need a precise inventory of zero-counting infrastructure and the current Li-coefficient definitions.\n\nSurvey and report with exact declaration names + file paths + signatures:\n\n1. Zeta23 zero infrastructure, in D:\\Python\\Quantum\\zeta-23-lean\\Zeta23\\:\n - Look in Defs/ and Defs.lean: how are nontrivial zeros of riemannZeta defined? Is there a zero-counting function (N(T) or similar)? Any API for: zeros are symmetric (\u03c1\u0304, 1\u2212\u03c1), zeros in critical strip, zero-free at Re \u2265 1?\n - Search all of Zeta23/ for theorems about riemannZeta zeros (grep \"riemannZeta.*= 0\" or \"zeros\" in theorem/def names) \u2014 report the useful ones with signatures.\n - Anything formalizing an explicit formula or zero-sum over \u03c1 (WeilEF/, ExplicitFormula/) \u2014 brief summary of what exists (we may reuse zero-enumeration techniques).\n2. In our package D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\:\n - Find the definition of `liCoeff` (probably in LiSkeleton.lean or a Defs file): full definition, what zero set it sums over, how the tsum is set up, any summability lemmas already proved. Also `SInfty`, `sInftyLower`, `C0hat`, `Hhat`, `IIMaj`, `FAlt`, `Bn`, `marginTilde` \u2014 report each def's exact Lean code (they're short) and the file/line.\n - Report the exact statements of `sInfty_lower_bound`, `marginTilde_convex`, `pos_of_convex_of_two_points` (signatures only).\n3. In the vendored Mathlib (D:\\Python\\Quantum\\zeta-23-lean\\.lake\\packages\\mathlib\\Mathlib):\n - Does Mathlib have von Mangoldt \u039b (ArithmeticFunction vonMangoldt)? The Chebyshev \u03c8? Brief note.\n - Search for theorems about `riemannZeta` being nonzero (e.g., Re s \u2265 1) \u2014 report names.\n - Any API for enumerating roots/zeros of analytic functions with counting (e.g., \"AnalyticOn... zeros finite on compacts\" \u2014 the identity theorem / discreteness of zeros)? Report names/files.\n\nReport as a structured list. Be thorough; exact names matter. Read-only."
}
result 2026-08-21 17:52:05Z → 2026-08-21 17:55:35Z
{
"status": "completed",
"prompt": "Research task (read-only inventory, NO code changes). Context: Lean 4 project at D:\\Python\\Quantum (toolchain v4.33.0-rc2). We are planning to formalize an explicit contour bound for the Li coefficients of \u03b6. I need a precise inventory of zero-counting infrastructure and the current Li-coefficient definitions.\n\nSurvey and report with exact declaration names + file paths + signatures:\n\n1. Zeta23 zero infrastructure, in D:\\Python\\Quantum\\zeta-23-lean\\Zeta23\\:\n - Look in Defs/ and Defs.lean: how are nontrivial zeros of riemannZeta defined? Is there a zero-counting function (N(T) or similar)? Any API for: zeros are symmetric (\u03c1\u0304, 1\u2212\u03c1), zeros in critical strip, zero-free at Re \u2265 1?\n - Search all of Zeta23/ for theorems about riemannZeta zeros (grep \"riemannZeta.*= 0\" or \"zeros\" in theorem/def names) \u2014 report the useful ones with signatures.\n - Anything formalizing an explicit formula or zero-sum over \u03c1 (WeilEF/, ExplicitFormula/) \u2014 brief summary of what exists (we may reuse zero-enumeration techniques).\n2. In our package D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\:\n - Find the definition of `liCoeff` (probably in LiSkeleton.lean or a Defs file): full definition, what zero set it sums over, how the tsum is set up, any summability lemmas already proved. Also `SInfty`, `sInftyLower`, `C0hat`, `Hhat`, `IIMaj`, `FAlt`, `Bn`, `marginTilde` \u2014 report each def's exact Lean code (they're short) and the file/line.\n - Report the exact statements of `sInfty_lower_bound`, `marginTilde_convex`, `pos_of_convex_of_two_points` (signatures only).\n3. In the vendored Mathlib (D:\\Python\\Quantum\\zeta-23-lean\\.lake\\packages\\mathlib\\Mathlib):\n - Does Mathlib have von Mangoldt \u039b (ArithmeticFunction vonMangoldt)? The Chebyshev \u03c8? Brief note.\n - Search for theorems about `riemannZeta` being nonzero (e.g., Re s \u2265 1) \u2014 report names.\n - Any API for enumerating roots/zeros of analytic functions with counting (e.g., \"AnalyticOn... zeros finite on compacts\" \u2014 the identity theorem / discreteness of zeros)? Report names/files.\n\nReport as a structured list. Be thorough; exact names matter. Read-only.",
"agentId": "a6939341f0a284148",
"agentType": "Explore",
"content": [
"type='text' text=\"Below is a read-only inventory of the requested zero-counting and Li-coefficient infrastructure, with exact declaration names, file paths, and signatures.\\n\\n---\\n\\n## 1. Zeta23 zero infrastructure (`D:/Python/Quantum/zeta-23-lean/Zeta23/`)\\n\\n### 1.1 Definitions of nontrivial zeros and counting functions\\n\\nAll of these are in `Zeta23/Statement.lean`.\\n\\n- **`IsNontrivialZero`** (line 38)\\n ```lean\\n def IsNontrivialZero (\u03c1 : \u2102) : Prop := riemannZeta \u03c1 = 0 \u2227 0 < \u03c1.re \u2227 \u03c1.re < 1\\n ```\\n- **`zeroMult`** (line 43) \u2014 multiplicity as the analytic order:\\n ```lean\\n def zeroMult (\u03c1 : \u2102) : \u2115 := (analyticOrderAt riemannZeta \u03c1).toNat\\n ```\\n- **`zerosIn`** (line 46) \u2014 zeros with ordinate in a window:\\n ```lean\\n def zerosIn (T\u2081 T\u2082 : \u211d) : Set \u2102 :=\\n {\u03c1 | IsNontrivialZero \u03c1 \u2227 T\u2081 < \u03c1.im \u2227 \u03c1.im \u2264 T\u2082}\\n ```\\n- **`Ncount`** (line 49) \u2014 counted with multiplicity:\\n ```lean\\n def Ncount (T\u2081 T\u2082 : \u211d) : \u2115 := \u2211\u1da0 \u03c1 \u2208 zerosIn T\u2081 T\u2082, zeroMult \u03c1\\n ```\\n- **`Ndist`** (line 52) \u2014 distinct zeros:\\n ```lean\\n def Ndist (T\u2081 T\u2082 : \u211d) : \u2115 := (zerosIn T\u2081 T\u2082).ncard\\n ```\\n- **`N0`** (line 56) \u2014 critical-line zeros with multiplicity:\\n ```lean\\n def N0 (T\u2081 T\u2082 : \u211d) : \u2115 :=\\n \u2211\u1da0 \u03c1 \u2208 zerosIn T\u2081 T\u2082 \u2229 {\u03c1 | \u03c1.re = 1 / 2}, zeroMult \u03c1\\n ```\\n- **`N0star`** (line 59) \u2014 critical-line zeros without multiplicity:\\n ```lean\\n def N0star (T\u2081 T\u2082 : \u211d) : \u2115 :=\\n (zerosIn T\u2081 T\u2082 \u2229 {\u03c1 | \u03c1.re = 1 / 2}).ncard\\n ```\\n- **`N0simple`** (line 62) \u2014 simple critical-line zeros:\\n ```lean\\n def N0simple (T\u2081 T\u2082 : \u211d) : \u2115 :=\\n (zerosIn T\u2081 T\u2082 \u2229 {\u03c1 | \u03c1.re = 1 / 2} \u2229 {\u03c1 | zeroMult \u03c1 = 1}).ncard\\n ```\\n- **`Nsimple`** (line 65) \u2014 simple zeros anywhere:\\n ```lean\\n def Nsimple (T\u2081 T\u2082 : \u211d) : \u2115 :=\\n (zerosIn T\u2081 T\u2082 \u2229 {\u03c1 | zeroMult \u03c1 = 1}).ncard\\n ```\\n\\nThere is **no single-argument `N(T)`**; the formalization uses the dyadic/window counts above and an abstract version in `ZeroConfig`.\\n\\n### 1.2 Abstract zero configuration and counting (`Zeta23/Defs.lean`)\\n\\n- **`ZeroConfig`** (lines 120\u2013130) \u2014 an abstract locally finite multiset of strip zeros, closed under `reflect`:\\n ```lean\\n structure ZeroConfig where\\n carrier : Set \u2102\\n mult : \u2102 \u2192 \u2115\\n one_le_mult : \u2200 \u03c1 \u2208 carrier, 1 \u2264 mult \u03c1\\n strip : \u2200 \u03c1 \u2208 carrier, 0 \u2264 \u03c1.re \u2227 \u03c1.re \u2264 1\\n reflect_mem : \u2200 \u03c1 \u2208 carrier, reflect \u03c1 \u2208 carrier\\n mult_reflect : \u2200 \u03c1 \u2208 carrier, mult (reflect \u03c1) = mult \u03c1\\n finite_window : \u2200 T\u2081 T\u2082 : \u211d, (carrier \u2229 {\u03c1 | T\u2081 < \u03c1.im \u2227 \u03c1.im \u2264 T\u2082}).Finite\\n ```\\n- **`reflect`** (line 108):\\n ```lean\\n def reflect (\u03c1 : \u2102) : \u2102 := 1 - (starRingEnd \u2102) \u03c1\\n ```\\n- Counting functions on `ZeroConfig` (lines 145\u2013161): `ZeroConfig.N`, `ZeroConfig.Nd`, `ZeroConfig.N0`, `ZeroConfig.N0star`, `ZeroConfig.N0s`, `ZeroConfig.Ns`.\\n- The zero-side matrix / Weil sum (lines 164\u2013170):\\n ```lean\\n def Wsummand (f g : \u211d \u2192 \u2102) (\u03c1 : \u2102) : \u2102 := ...\\n def W (f g : \u211d \u2192 \u2102) : \u2102 := \u2211' \u03c1 : Z.carrier, Z.Wsummand f g \u03c1\\n ```\\n\\n### 1.3 \u03b6 zeros packaged as a `ZeroConfig`\\n\\nIn `Zeta23/Statement/SeamClosed.lean`:\\n\\n- **`zetaSeam`** (line 22): discharges all four seam obligations.\\n- **`zetaZeroConfig`** (line 26):\\n ```lean\\n def zetaZeroConfig : ZeroConfig := zetaZeros zetaSeam\\n ```\\n so `carrier = {\u03c1 | IsNontrivialZero \u03c1}` and `mult = zeroMult`.\\n- Simp lemmas at lines 28\u201338 relate `zetaZeroConfig.N` to `Ncount`, etc.\\n- **`zerosIn_finite`** (line 47): every ordinate window is finite.\\n\\n### 1.4 Symmetry (\u03c1 \u21a6 1 \u2212 \u03c1\u0304)\\n\\nIn `Zeta23/ZetaReflect.lean`:\\n\\n- **`zeta_reflect_zero`** (line 278)\\n ```lean\\n theorem zeta_reflect_zero : \u2200 \u03c1, IsNontrivialZero \u03c1 \u2192 IsNontrivialZero (reflect \u03c1)\\n ```\\n- **`zeta_mult_reflect`** (line 314)\\n ```lean\\n theorem zeta_mult_reflect : \u2200 \u03c1, IsNontrivialZero \u03c1 \u2192 zeroMult (reflect \u03c1) = zeroMult \u03c1\\n ```\\n\\nUseful reflection geometry lemmas appear in `Zeta23/ZeroSide.lean` (lines 593\u2013611):\\n```lean\\nlemma reflect_re (\u03c1 : \u2102) : (reflect \u03c1).re = 1 - \u03c1.re\\nlemma reflect_im (\u03c1 : \u2102) : (reflect \u03c1).im = \u03c1.im\\nlemma reflect_eq_self_iff (\u03c1 : \u2102) : reflect \u03c1 = \u03c1 \u2194 \u03c1.re = 1 / 2\\n```\\n\\n### 1.5 Finiteness / discreteness / zero-free facts\\n\\nIn `Zeta23/Statement/Seam.lean`:\\n\\n- **`riemannZeta_analyticOnNhd_compl_one`** (line 30)\\n ```lean\\n lemma riemannZeta_analyticOnNhd_compl_one :\\n AnalyticOnNhd \u2102 riemannZeta ({1}\u1d9c : Set \u2102)\\n ```\\n- **`analyticOrderAt_riemannZeta_ne_top`** (line 40)\\n ```lean\\n lemma analyticOrderAt_riemannZeta_ne_top {s : \u2102} (hs : s \u2260 1) :\\n analyticOrderAt riemannZeta s \u2260 \u22a4\\n ```\\n- **`ZetaSeam.one_le_mult_holds`** (line 50)\\n ```lean\\n theorem ZetaSeam.one_le_mult_holds :\\n \u2200 \u03c1, IsNontrivialZero \u03c1 \u2192 1 \u2264 zeroMult \u03c1\\n ```\\n- **`riemannZeta_zeros_locallyFinite`** (line 63)\\n ```lean\\n lemma riemannZeta_zeros_locallyFinite (z : \u2102) :\\n \u2203 t \u2208 \ud835\udcdd z, (t \u2229 {\u03c1 : \u2102 | \u03c1 \u2260 1 \u2227 riemannZeta \u03c1 = 0}).Finite\\n ```\\n- **`ZetaSeam.finite_window_holds`** (line 91)\\n ```lean\\n theorem ZetaSeam.finite_window_holds (T\u2081 T\u2082 : \u211d) :\\n ({\u03c1 | IsNontrivialZero \u03c1} \u2229 {\u03c1 | T\u2081 < \u03c1.im \u2227 \u03c1.im \u2264 T\u2082}).Finite\\n ```\\n\\nZero-free on `Re s \u2265 1` is imported from Mathlib (see Part 3) and used heavily; in Zeta23 it is invoked as `riemannZeta_ne_zero_of_one_le_re`.\\n\\n### 1.6 Riemann\u2013von Mangoldt / zero counting\\n\\nIn `Zeta23/Hypotheses.lean` (lines 67\u201370) the abstract hypothesis is:\\n```lean\\nstructure RiemannVonMangoldt (Z : ZeroConfig) : Prop where\\n main : \u2203 C T\u2080 : \u211d, \u2200 T : \u211d, T\u2080 \u2264 T \u2192\\n |(Z.N T (2 * T) : \u211d) - T / (2 * Real.pi) * ell1 T| \u2264 C * Real.log T\\n local_count : \u2203 A\u2080 : \u211d, 1 \u2264 A\u2080 \u2227 \u2200 t : \u211d,\\n (Z.N t (t + 1) : \u211d) \u2264 A\u2080 * Real.log (|t| + 3)\\n```\\n\\nFor \u03b6 itself, in `Zeta23/RvM/LocalCount.lean`:\\n\\n- **`zeta_local_zero_count`** (line 266)\\n ```lean\\n theorem zeta_local_zero_count : \u2203 A\u2080 : \u211d, 1 \u2264 A\u2080 \u2227 \u2200 t : \u211d,\\n (Ncount t (t + 1) : \u211d) \u2264 A\u2080 * Real.log (|t| + 3)\\n ```\\n- **`zetaZeroConfig_local_count`** (line 294)\\n ```lean\\n theorem zetaZeroConfig_local_count : \u2203 A\u2080 : \u211d, 1 \u2264 A\u2080 \u2227 \u2200 t : \u211d,\\n (zetaZeroConfig.N t (t + 1) : \u211d) \u2264 A\u2080 * Real.log (|t| + 3)\\n ```\\n\\nAnd the full Riemann\u2013von Mangoldt theorem is in `Zeta23/RvM/Statement.lean` (line 20):\\n```lean\\ntheorem riemannVonMangoldt (h\u0393 : GammaFacts) : RiemannVonMangoldt zetaZeroConfig\\n```\\n\\n### 1.7 Explicit formula / zero-sum infrastructure\\n\\nIn `Zeta23/ExplicitFormula.lean`:\\n\\n- **`EF.literatureRHS`** (line 70) \u2014 the right-hand side of the literature explicit formula.\\n- **`EF.EF_lit`** (line 81) \u2014 literature-form hypothesis:\\n ```lean\\n def EF_lit (Z : ZeroConfig) : Prop :=\\n \u2200 k : \u211d \u2192 \u2102, ContDiff \u211d 2 k \u2192 HasCompactSupport k \u2192\\n Summable (fun \u03c1 : Z.carrier => (Z.mult \u03c1 : \u2102) * paperFT k (gammaOf \u03c1)) \u2227\\n \u2211' \u03c1 : Z.carrier, (Z.mult \u03c1 : \u2102) * paperFT k (gammaOf \u03c1) = literatureRHS k\\n ```\\n- **`EF.EF_paper`** (line 88) \u2014 paper spectral form `W(f,g) = \u222b h_f conj(h_g) \u03bd_X`.\\n- **`EF.prop_EF_of_lit`** (line 703) \u2014 proves paper form from literature form.\\n\\nThe Weil-EF directory (`Zeta23/WeilEF/`) builds `EF_lit` for \u03b6 unconditionally:\\n\\n- `Zeta23/WeilEF/ZeroSummability.lean`:\\n - `WeilEF.zero_sum_inv_sq_gen`\\n - `WeilEF.EF_zero_sum_summable_gen`\\n - `WeilEF.zero_sum_inv_sq`\\n - `WeilEF.EF_zero_sum_summable`\\n\\n- `Zeta23/WeilEF/ZeroSumLimit.lean` (line 26):\\n ```lean\\n theorem zero_sum_limit (hs : ZetaSeam) {k : \u211d \u2192 \u2102} (hk : ContDiff \u211d 2 k)\\n (hkc : HasCompactSupport k) {R : \u2115 \u2192 \u211d} ... :\\n Tendsto (fun j : \u2115 => \u2211 \u03c1 \u2208 Z j, (zeroMult \u03c1 : \u2102) * Hfn k \u03c1) atTop\\n (\ud835\udcdd (\u2211' \u03c1 : (zetaZeros hs).carrier, ((zetaZeros hs).mult \u03c1 : \u2102) * Hfn k \u03c1))\\n ```\\n\\n- `Zeta23/WeilEF/Contour.lean` (line 31): rectangle identity / weighted argument principle.\\n- `Zeta23/WeilEF/FullLineAssembly.lean` (line 39): `full_line_identity`.\\n- `Zeta23/WeilEF/Main.lean` (lines 51, 270):\\n ```lean\\n theorem EF_lit_zeta (hs : ZetaSeam) : Zeta23.EF.EF_lit (zetaZeros hs)\\n theorem EF_lit_zetaZeroConfig : Zeta23.EF.EF_lit zetaZeroConfig\\n ```\\n\\nThese give absolutely convergent zero-summation over `{\u03c1 : \u2102 // IsNontrivialZero \u03c1}` weighted by `zeroMult`, exactly the enumeration technique reusable for a contour-bound on Li coefficients.\\n\\n---\\n\\n## 2. NguyenRH1 Li-coefficient definitions (`D:/Python/Quantum/research/lean/NguyenRH1/NguyenRH1/LiSkeleton.lean`)\\n\\n### 2.1 The Keiper\u2013Li coefficient `liCoeff`\\n\\n- **`liCoeff`** (line 39)\\n ```lean\\n def liCoeff (n : \u2115) : \u2102 :=\\n tsum fun \u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1} =>\\n (zeroMult \u03c1 : \u2102) * (1 - (1 - 1 / (\u03c1 : \u2102)) ^ n)\\n ```\\n It sums over the **subtype of nontrivial zeros** `{\u03c1 : \u2102 // IsNontrivialZero \u03c1}` with weight `zeroMult \u03c1`. \\n **Summability note:** the file contains an \u201chonesty note\u201d that `tsum` of a non-summable family is `0` in Lean; no `liCoeff`-specific summability lemma is proved in this file. The summability is intended to follow from `\u03a3 |\u03c1|\u207b\u00b2 < \u221e`.\\n\\n### 2.2 Supporting definitions (exact code)\\n\\n- **`lagariasA1`** (line 68)\\n ```lean\\n def lagariasA1 : \u211d := (Real.log (4 * Real.pi) + Real.eulerMascheroniConstant) / 2\\n ```\\n\\n- **`SInfty`** (line 73)\\n ```lean\\n def SInfty (n : \u2115) : \u211d :=\\n (1 - lagariasA1) * n - 1 +\\n tsum fun m : {m : \u2115 // Odd m \u2227 3 \u2264 m} =>\\n ((1 - 1 / (m : \u211d)) ^ n - 1 + (n : \u211d) / (m : \u211d))\\n ```\\n\\n- **`lagariasC1`** (line 79)\\n ```lean\\n def lagariasC1 : \u211d :=\\n (Real.eulerMascheroniConstant - 1 - Real.log (2 * Real.pi)) / 2\\n ```\\n\\n- **`sInftyLower`** (line 84)\\n ```lean\\n def sInftyLower (n : \u211d) : \u211d :=\\n (1 / 2) * n * Real.log n + (lagariasC1 - Real.eulerMascheroniConstant / 2) * n - 4\\n ```\\n\\n- **`C0hat`** (line 429)\\n ```lean\\n def C0hat (t : \u211d) : \u211d :=\\n 0.433 * Real.log (t + 2) + 0.886 * Real.log (Real.log (t + 2)) + 2.9\\n ```\\n\\n- **`Hhat`** (line 433)\\n ```lean\\n def Hhat (T : \u211d) : \u211d :=\\n 3 * C0hat T ^ 2 + 10.5 * Real.log (T + 2) + 48\\n ```\\n\\n- **`IIMaj`** (line 438)\\n ```lean\\n def IIMaj (n : \u211d) : \u211d :=\\n 2 * (Real.sqrt n + 1) * (Real.exp (Real.sqrt n / 2) + 1) * 0.57 *\\n 2 ^ (-(2 * Real.sqrt n - 2))\\n ```\\n\\n- **`marginTilde`** (line 447)\\n ```lean\\n def marginTilde (F : \u211d \u2192 \u211d) (n : \u211d) : \u211d :=\\n let T := Real.sqrt n + 1\\n ((1 / 2) * n * Real.log n +\\n (lagariasC1 - Real.eulerMascheroniConstant / 2) * n - 4) -\\n (2 * F T + 4 * T * ((2 / 3) * C0hat T + 10.5 * Real.log (T + 2) + 48) +\\n 40 * 1.3352 + 2 * (Real.exp 4 + 1) * (7 * Hhat T + 3.3) +\\n IIMaj n + 1) + 1\\n ```\\n\\n- **`FAlt`** (line 2097)\\n ```lean\\n def FAlt (T : \u211d) : \u211d :=\\n (1 / (2 * Real.pi)) * (T * Real.log T) + 0.137 * Real.log T +\\n 0.443 * Real.log (Real.log T) + (7 / 8 + 1.588)\\n ```\\n\\n- **`Bn`** (line 2106)\\n ```lean\\n def Bn (F : \u211d \u2192 \u211d) (n : \u211d) : \u211d :=\\n let T := Real.sqrt n + 1\\n 2 * F T + 4 * T * ((2 / 3) * C0hat T + 10.5 * Real.log (T + 2) + 48) +\\n 40 * 1.3352 + 2 * (Real.exp 4 + 1) * (7 * Hhat T + 3.3) + IIMaj n + 1\\n ```\\n\\n### 2.2 Requested theorem signatures\\n\\n- **`sInfty_lower_bound`** (line 320)\\n ```lean\\n theorem sInfty_lower_bound (n : \u2115) (hn : 20 \u2264 n) :\\n sInftyLower n \u2264 SInfty n\\n ```\\n\\n- **`marginTilde_convex`** (line 1849)\\n ```lean\\n theorem marginTilde_convex (F : \u211d \u2192 \u211d) (hF : ContDiffOn \u211d 2 F (Set.Ioi 1))\\n (h\u03c8 : \u2200 T : \u211d, Real.sqrt 20 + 1 \u2264 T \u2192\\n deriv (deriv F) T - deriv F T / (T - 1) < 0) :\\n ConvexOn \u211d (Set.Ici 20) (marginTilde F)\\n ```\\n\\n- **`pos_of_convex_of_two_points`** (line 2409)\\n ```lean\\n theorem pos_of_convex_of_two_points {f : \u211d \u2192 \u211d} {a N\u2080 N\u2081 x : \u211d}\\n (hconv : ConvexOn \u211d (Set.Ici a) f)\\n (hN : a < N\u2080) (hN01 : N\u2080 < N\u2081) (hx : N\u2081 \u2264 x)\\n (h0 : 0 < f N\u2080) (h01 : f N\u2080 < f N\u2081) :\\n 0 < f x\\n ```\\n\\n---\\n\\n## 3. Mathlib vendored API (`D:/Python/Quantum/zeta-23-lean/.lake/packages/mathlib/Mathlib/`)\\n\\n### 3.1 von Mangoldt and Chebyshev \u03c8\\n\\n- **`ArithmeticFunction.vonMangoldt`** \\n File: `Mathlib/NumberTheory/ArithmeticFunction/VonMangoldt.lean` (line 65)\\n ```lean\\n noncomputable def vonMangoldt : ArithmeticFunction \u211d :=\\n \u27e8fun n => if IsPrimePow n then Real.log (minFac n) else 0, if_neg not_isPrimePow_zero\u27e9\\n ```\\n Notation `\u039b` is available in the `ArithmeticFunction` locale.\\n\\n- **`Chebyshev.psi`** \\n File: `Mathlib/NumberTheory/Chebyshev.lean` (line 74)\\n ```lean\\n noncomputable def psi (x : \u211d) : \u211d :=\\n \u2211 n \u2208 Ioc 0 \u230ax\u230b\u208a, \u039b n\\n ```\\n Notation `\u03c8` is available in the `Chebyshev` scope. The same file also defines `Chebyshev.theta` (\u03b8) and many explicit bounds.\\n\\n### 3.2 \u03b6 non-vanishing on / to the right of the 1-line\\n\\n- **`riemannZeta_ne_zero_of_one_le_re`** \\n File: `Mathlib/NumberTheory/LSeries/Nonvanishing.lean` (line 411)\\n ```lean\\n lemma _root_.riemannZeta_ne_zero_of_one_le_re \u2983s : \u2102\u2984 (hs : 1 \u2264 s.re) :\\n riemannZeta s \u2260 0\\n ```\\n\\n- **`riemannZeta_ne_zero_of_one_lt_re`** \\n File: `Mathlib/NumberTheory/LSeries/Dirichlet.lean` (line 328)\\n ```lean\\n lemma riemannZeta_ne_zero_of_one_lt_re {s : \u2102} (hs : 1 < s.re) : riemannZeta s \u2260 0\\n ```\\n\\n### 3.3 Identity theorem / discreteness of zeros / finite zero sets\\n\\nRelevant general theorems are in `Mathlib/Analysis/Analytic/IsolatedZeros.lean` and `Mathlib/Analysis/Analytic/Order.lean`.\\n\\n- **`AnalyticAt.eventually_eq_zero_or_eventually_ne_zero`** \\n `Mathlib/Analysis/Analytic/IsolatedZeros.lean` (line 125)\\n ```lean\\n theorem eventually_eq_zero_or_eventually_ne_zero (hf : AnalyticAt \ud835\udd5c f z\u2080) :\\n (\u2200\u1da0 z in \ud835\udcdd z\u2080, f z = 0) \u2228 \u2200\u1da0 z in \ud835\udcdd[\u2260] z\u2080, f z \u2260 0\\n ```\\n\\n- **`AnalyticOnNhd.eqOn_zero_of_preconnected_of_frequently_eq_zero`** \\n `Mathlib/Analysis/Analytic/IsolatedZeros.lean` (line 214)\\n ```lean\\n theorem eqOn_zero_of_preconnected_of_frequently_eq_zero (hf : AnalyticOnNhd \ud835\udd5c f U)\\n (hU : IsPreconnected U) (h\u2080 : z\u2080 \u2208 U) (hfw : \u2203\u1da0 z in \ud835\udcdd[\u2260] z\u2080, f z = 0) :\\n EqOn f 0 U\\n ```\\n\\n- **`AnalyticOnNhd.eqOn_of_preconnected_of_frequently_eq`** \\n `Mathlib/Analysis/Analytic/IsolatedZeros.lean` (line 238)\\n ```lean\\n theorem eqOn_of_preconnected_of_frequently_eq (hf : AnalyticOnNhd \ud835\udd5c f U)\\n (hg : AnalyticOnNhd \ud835\udd5c g U) (hU : IsPreconnected U) (h\u2080 : z\u2080 \u2208 U)\\n (hfg : \u2203\u1da0 z in \ud835\udcdd[\u2260] z\u2080, f z = g z) :\\n EqOn f g U\\n ```\\n\\n- **`AnalyticOnNhd.eqOn_zero_or_eventually_ne_zero_of_preconnected`** \\n `Mathlib/Analysis/Analytic/IsolatedZeros.lean` (line 219)\\n ```lean\\n theorem eqOn_zero_or_eventually_ne_zero_of_preconnected (hf : AnalyticOnNhd \ud835\udd5c f U)\\n (hU : IsPreconnected U) :\\n EqOn f 0 U \u2228 \u2200\u1da0 x in codiscreteWithin U, f x \u2260 0\\n ```\\n\\n- **`AnalyticOnNhd.preimage_zero_mem_codiscreteWithin`** \\n `Mathlib/Analysis/Analytic/IsolatedZeros.lean` (line 346)\\n ```lean\\n theorem AnalyticOnNhd.preimage_mem_codiscreteWithin {U : Set \ud835\udd5c} {s : Set E} {f : \ud835\udd5c \u2192 E}\\n (hfU : AnalyticOnNhd \ud835\udd5c f U) (h\u2082f : \u2200\u1da0 x in codiscreteWithin U, f x \u2260 f x)\\n (hs : s \u2208 codiscreteWithin (f '' U)) :\\n f \u207b\u00b9' s \u2208 codiscreteWithin U\\n ```\\n\\n- **`Filter.codiscreteWithin_iff_locallyFiniteComplementWithin`** \\n `Mathlib/Topology/DiscreteSubset.lean` (line 317)\\n ```lean\\n theorem codiscreteWithin_iff_locallyFiniteComplementWithin [T1Space X] {s U : Set X} :\\n s \u2208 codiscreteWithin U \u2194 \u2200 z \u2208 U, \u2203 t \u2208 \ud835\udcdd z, Set.Finite (t \u2229 (U \\\\ s))\\n ```\\n This is the bridge from \u201ccodiscrete\u201d to \u201clocally finite complement,\u201d i.e. zeros are isolated in the domain.\\n\\n- **`analyticOrderAt_ne_top_of_isPreconnected`** \\n `Mathlib/Analysis/Analytic/Order.lean` (line 627)\\n ```lean\\n theorem analyticOrderAt_ne_top_of_isPreconnected {x y : \ud835\udd5c} (hf : AnalyticOnNhd \ud835\udd5c f U)\\n (hU : IsPreconnected U) (h\u2081x : x \u2208 U) (hy : y \u2208 U) (h\u2082x : analyticOrderAt f x \u2260 \u22a4) :\\n analyticOrderAt f y \u2260 \u22a4\\n ```\\n\\n- **Concrete finiteness on compacts for \u03b6 zeros** \\n `Mathlib/NumberTheory/LSeries/ZetaZeros.lean` defines:\\n ```lean\\n noncomputable def riemannZetaZeros : Set \u2102 := riemannZeta \u207b\u00b9' {0}\\n lemma isClosed_riemannZetaZeros\\n lemma isDiscrete_riemannZetaZeros\\n lemma IsCompact.inter_riemannZetaZeros_finite {S : Set \u2102} (hS : IsCompact S) :\\n (S \u2229 riemannZetaZeros).Finite\\n ```\\n\\nThese are the main tools available for proving that an analytic function\u2019s zero set is discrete and hence finite on compact subsets, and for controlling zero-counting via `codiscreteWithin`.\\n\\n---\""
],
"totalDurationMs": 209645.17700195312,
"totalTokens": 152014,
"totalToolUseCount": 66,
"usage": {
"input_tokens": 743,
"output_tokens": 5863,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 145408
}
}
thinking (15800 chars)
Excellent — both inventories are in and they're extremely informative. Key findings beyond what I knew:
1. **Residue machinery**: `RectangleIntegral'_eq_sumResiduesIn` with `HasSimplePolesOn` hypothesis — confirmed. But ALSO: the private proof structure (principalPart decomposition, `toMeromorphicNFOn`) exists and could inspire the extension. No higher-order residue formula anywhere. Mathlib has `MeromorphicAt`/`meromorphicOrderAt`/`MeromorphicNFAt`/`toMeromorphicNFOn` + `meromorphicTrailingCoeffAt` (TrailingCoefficient.lean) — the trailing coefficient API! That's the natural handle for a general residue: for a pole of order −m, the residue is a Taylor coefficient of the NF analytic part, and `meromorphicTrailingCoeffAt` might be exactly the leading Laurent coefficient. For the residue we need the coefficient at order −1, not the leading one — but via NF f = (z−p)^n • g, the residue is the (m−1)-th Taylor coefficient of g divided by... For order n = −m (m > 0), residue = coeff of (z−p)^{m−1} in g. There's `iteratedDeriv` Taylor API (`AnalyticAt` gives `HasFPowerSeriesAt`, with `cauchyPowerSeries` / `iteratedDeriv` formulas). So the general residue can be DEFINED as `(iteratedDeriv (m-1) g p) / (m-1)!` — computable. Good.
2. **Zeta23 zero infrastructure is RICH**: `IsNontrivialZero`, `zeroMult`, `zerosIn`, `Ncount` with PROVED local count `zeta_local_zero_count` (∃ A₀, Ncount(t,t+1) ≤ A₀ log(|t|+3)) and full RvM! Plus `zeta_reflect_zero`, `zeta_mult_reflect`, window finiteness, and WeilEF zero-summability (`zero_sum_inv_sq`, `EF_zero_sum_summable`) — the Σ|ρ|⁻² convergence infrastructure ALREADY EXISTS and is proved! That's L7 essentially done (liCoeff summability needs Σ |1−(1−1/ρ)ⁿ| — summand ~ n/|ρ|² for large ρ, and `zero_sum_inv_sq` gives Σ 1/|ρ|² < ∞... need care with the exact form but the hard analytic fact is there).
Wait — is `zero_sum_inv_sq` proved sorry-free in zeta-23-lean? The audit said zeta-23-lean has sorries only in trusted challenge stubs. EF_lit_zeta etc. — need to check axiom status of what we'd reuse. Important for ii′-0: any Zeta23 theorem we import must be sorry-free (or its sorries acceptable). D-061 verified "all comparator PrintAxioms scripts match AUDIT.md" — the main theorems were checked. I'll need a per-dependency axiom check as part of ii′-0's skeleton phase.
3. **Borel–Carathéodory EXISTS in Mathlib** (`Complex.borelCaratheodory`) AND **Jensen's formula exists** (`MeromorphicOn.circleAverage_log_norm`, `AnalyticOnNhd.sum_divisor_le`) AND `StrongPNTPrefix.lean` has `BorelCaratheodoryDeriv`, `LogOfAnalyticFunction`, Blaschke factors, `ZerosBound` — the EXACT toolkit for the local route to the R-bound (L2)! This is the Davenport Ch. 15-style local argument: log ζ bounds via Borel–Carathéodory, zero extraction via Blaschke/Jensen, Cauchy estimate for the derivative. So L2's local route has its machinery vendored too. That avoids Hadamard factorization entirely!
Hmm wait — but the R-bound (D-056) is stated as |ζ′/ζ(s) − Σ_{|γ−t|<1} 1/(s−ρ)| ≤ A log(|t|+2) + B₀. The classical proof via partial fractions (Hadamard) — the local route: for σ near [−5/2, 4], |t| large, write log ζ on a disc around s₀ = 2 + it (radius ~ 9/2 to cover down to −5/2), bound Re log ζ = log|ζ| ≤ O(log t) (from ζ bounds — ZetaUpperBnd exists in ZetaBounds! `‖ζ‖ ≤ C log|t|` for σ ≥ 1−A/log|t|... but our region extends to σ = −5/2, far left of the zero-free strip — need ζ bounds in the CRITICAL STRIP and left: those come from the functional equation! ζ(s) for σ < 0 via FE: |ζ(s)| = |χ(s)|·|ζ(1−s)|, |χ(s)| ~ |t|^{1/2−σ}. So |ζ(−5/2+it)| ~ |t|³·|ζ(3.5−it)| ~ |t|³·bounded. log|ζ| ≤ 3 log t + O(1). Does Zeta23/Mathlib have ζ bounds in the strip/left half? There's `riemannZeta_one_sub` (FE) in Mathlib, and ζ bounds for σ ≥ 1−A/log|t| in ZetaBounds. For the strip: Phragmén–Lindelöf convexity bounds... StrongPNTPrefix has BorelCaratheodoryDeriv; is there a Phragmén–Lindelöf in Mathlib? Not sure. We may need to prove a crude polynomial bound |ζ(σ+it)| ≤ C|t|^A in the strip ourselves: route — Mathlib has `riemannZeta` for σ > 0 via Hurwitz; there might be a bound ‖ζ‖ ≤ C·(|t|^... ) somewhere in ZetaBounds for σ ≥ 1−A/log|t| only. For 0 < σ < 1: use the approximate functional equation? Not available. Alternative: the R-bound's proof via D-056 uses the reference-point trick: compare ζ′/ζ(s) at s vs at s₀ = reference point (on the 2-line?) — the reference point trick AVOIDS needing ζ bounds in the strip! D-056's proof: R(s) = ζ′/ζ(s) − Σ_{|γ−t|<1}1/(s−ρ); bound via comparing R(s) − R(s₀) where s₀ is a reference point with the same imaginary part at Re = 2 (or similar), where ζ′/ζ is bounded by Dirichlet series. The difference R(s) − R(s₀) is controlled by... the partial fraction series telescopes. Honestly I need to READ D-056 now to see the exact argument and what inputs it needs. That's my next step (todo #4).
4. **Mathlib zeta API**: `riemannZeta_residue_one`, `tendsto_riemannZeta_sub_one_div` (constant term γ!), `riemannZeta_neg_two_mul_nat_add_one` (trivial zeros), FE, nonvanishing Re ≥ 1, ZetaZeros discreteness/compact-finiteness. The constant term γ at s=1 exists — first Laurent coefficient! For the w=1 pole we need the full Laurent recursion, but having γ is the base case.
Also `digamma` exists with `digamma_apply_add_one` recurrence and `meromorphic_digamma`. D-056's Lemma D (digamma bound |r| ≤ 1.2/|w|²) would need more digamma API (bounds in half-planes) — to check later; or the local R-bound route avoids digamma entirely.
5. **liCoeff**: sums over the subtype `{ρ // IsNontrivialZero ρ}` weighted by zeroMult; NO summability lemma proved yet — but WeilEF.ZeroSummability has `zero_sum_inv_sq` and `EF_zero_sum_summable` — need to check their exact statements and whether they cover our summand (fun ρ ↦ zeroMult ρ * (1 − (1−1/ρ)^n)). For large ρ: 1−(1−1/ρ)ⁿ = −Σ_{j≥1} C(n,j)(−1/ρ)^j... |1−(1−1/ρ)ⁿ| ≤ C_n/|ρ| for |ρ| ≥ 2n-ish — first order n/|ρ| is NOT summable (Σ 1/|ρ| diverges)! Need pairing ρ ↔ 1−ρ̄ or the exact identity. Hmm: |1−(1−1/ρ)ⁿ| — is it O(1/|ρ|) or O(1/|ρ|²)? (1−1/ρ)ⁿ = exp(n log(1−1/ρ)) = exp(n(−1/ρ − 1/2ρ² − ...)) ≈ 1 − n/ρ + O(n²/|ρ|²). So the summand ≈ n/ρ — NOT absolutely summable over zeros (Σ_{ρ} 1/|ρ| = ∞). BUT the zeros come in symmetric pairs: ρ and ρ̄ (conjugate): 1/ρ + 1/ρ̄ = 2Re(1/ρ) = 2σ/|ρ|² — paired terms ARE O(1/|ρ|²). So the tsum over the subtype is only conditionally summable — tsum in Lean requires ABSOLUTE summability (Summable f ⟺ Σ‖f‖ < ∞ for tsum to be well-behaved). PROBLEM: liCoeff as DEFINED might not be summable in Lean's sense! Wait — how is liCoeff's summability handled? The honesty note says "tsum of a non-summable family is 0 in Lean; no liCoeff-specific summability lemma is proved". If the family is not absolutely summable, `tsum` gives a JUNK value (0), and `liCoeff` would be wrong/undefined-valued! Hmm — but wait: is Σ over the subtype absolutely summable after all? |1−(1−1/ρ)ⁿ| for zeros: if RH-to-T₀ covers |γ| ≤ T₀ and beyond T₀ zeros can be anywhere in the strip... |1−1/ρ| ≤ 1 + 1/|ρ| ≤ 2. So |1−(1−1/ρ)ⁿ| ≤ 1 + |1−1/ρ|ⁿ ≤ 1 + (1+1/|ρ|)ⁿ ≤ 1 + e^{n/|ρ|} ≤ 1 + e — BOUNDED. But bounded isn't summable over infinitely many zeros. The summand does NOT go to 0?? For large γ: (1−1/ρ)ⁿ → 1 as |ρ| → ∞ (for FIXED n), so 1−(1−1/ρ)ⁿ ≈ n/ρ → 0. |summand| ~ n/|ρ| — and Σ_zeros 1/|ρ| diverges (loglog growth). So indeed NOT absolutely summable. So liCoeff's tsum is conditionally convergent at best → in Lean, `tsum` of non-Summable = 0 → liCoeff n = 0?!? Then Sf n := SInfty n + 1 − (liCoeff n).re would be junk...
Hold on. Let me reconsider. Maybe with the zeroMult weight and the pairing... no, absolute summability is about ‖summand‖ and that's ~n/|ρ|. Σ 1/|ρ| over zeros ~ ∫ log t /t dt diverges. So liCoeff as defined via tsum over the subtype IS problematic unless the intended reading uses symmetric pairing baked into the enumeration... tsum over a subtype of ℂ is unordered — absolute summability is required for tsum to behave. UNLESS the actual mathematical truth is: the family IS absolutely summable because... let me recompute: for ρ with σ ∈ (0,1), |γ| large: 1/ρ ≈ 1/(iγ) ≈ −i/γ + σ/γ². (1−1/ρ)ⁿ: log(1−1/ρ) = −1/ρ − 1/(2ρ²) − ... ≈ i/γ − σ/γ² + 1/(2γ²) + O(γ⁻³) = i/γ + (1/2−σ)/γ² + O(γ⁻³). n·log(1−1/ρ) ≈ in/γ + n(1/2−σ)/γ². exp: ≈ e^{in/γ}(1 + n(1/2−σ)/γ²). So 1−(1−1/ρ)ⁿ ≈ 1 − e^{in/γ} − e^{in/γ}n(1/2−σ)/γ². Now |1 − e^{in/γ}| ≈ n/γ for γ ≫ n. So |summand| ≈ n/|γ| — yes, not absolutely summable. CONFIRMED PROBLEM (this is exactly L7 "liCoeff summability (the tsum honesty note)" from D-062 — it's not just honesty, it's DEFINITIONAL correctness: if not Summable, tsum = 0 and SfBoundProp is FALSE as stated! Because Sf n = SInfty n + 1 − 0 = SInfty n + 1 ~ ½n log n, and Bn ~ 4T·... ~ √n log n² — |Sf| ≤ Bn would FAIL for large n (½n log n vs √n log²n). So SfBoundProp with junk liCoeff=0 is FALSE!).
WAIT. That can't be right — session 012/013 proved things with liCoeff and the audit passed. The theorem lambda_pos_finite_height_verified is CONDITIONAL on hSf : SfBoundProp — a hypothesis. If SfBoundProp is FALSE (due to junk tsum), the theorem is vacuous/harmless but the paper's claim would be broken at the definitional level. Also hfinite : LiVerifiedUpTo (5×10⁵) — that presumably states liCoeff n > 0 for n ≤ 5×10⁵, which would be FALSE if liCoeff = 0... Let me check how liCoeff and LiVerifiedUpTo are actually defined — maybe liCoeff uses a PAIRED enumeration (e.g., sum over zeros in upper half-plane of paired summands) making it absolutely summable. The agent reported `liCoeff (n : ℕ) : ℂ := tsum fun ρ : {ρ // IsNontrivialZero ρ} => (zeroMult ρ : ℂ) * (1 - (1 - 1/(ρ:ℂ))^n)`. Hmm — but is the family actually non-summable? Let me recheck the asymptotics once more. Actually wait: maybe I should check |1−(1−1/ρ)ⁿ| more carefully for the ON-LINE zeros (the bulk, all of them up to T₀, and conjecturally all): ρ = 1/2+iγ: 1−1/ρ = (ρ−1)/ρ = (−1/2+iγ)/(1/2+iγ), modulus 1, argument θ_γ = π − 2arctan(2γ)... ≈ π − 2(π/2 − 1/(2γ)·2)... arctan(2γ) ≈ π/2 − 1/(2γ). θ ≈ π − 2(π/2 − 1/(2γ)) = 1/γ. So (1−1/ρ)ⁿ ≈ e^{in/γ}, and 1−(1−1/ρ)ⁿ ≈ 1−e^{in/γ} ≈ −in/γ for γ ≫ n. |·| ≈ n/γ. Σ over zeros n/γ ~ n·Σ1/γ = ∞. Yes, not absolutely summable. (Conditionally: paired with the conjugate zero ρ̄ = 1/2−iγ: summand ≈ 1−e^{−in/γ}; sum of pair ≈ 2(1−cos(n/γ)) ≈ n²/γ² — absolutely summable! λ_n = Σ_pairs 2(1−cos(nθ_γ)) ≥ 0 — the familiar positivity.)
So mathematically λ_n is the PAIRED sum (absolutely convergent), and the Lean def via unordered tsum is only correct if Summable — which it isn't. UNLESS Lean's tsum over the subtype still equals the right value via some miracle — no, tsum of non-summable is DEFINED as 0 in Lean (junk).
Hmm wait, actually — is that true? `tsum f = 0` if `¬ Summable f`. Yes, in Mathlib `tsum` is defined as 0 for non-summable families.
So this is a REAL DEFECT discovered by the inventory: **liCoeff as defined is (almost certainly) not Summable, making liCoeff n = 0 junk for all n, and SfBoundProp false (SInfty+1 vs Bn).**
Hold on, wait. Let me double-check Summable in the OTHER direction. Is Σ ‖(zeroMult)‖·|1−(1−1/ρ)ⁿ| really divergent? Need Σ_zeros 1/|γ| diverges — yes, N(T) ~ T log T implies Σ_{|γ|≤T} 1/|γ| ~ ∫₁^T dN(t)/t ~ ∫ log t dt/t ~ (log T)²/4π → ∞. Yes divergent.
But WAIT — maybe not all summands with γ ≫ n are ~n/γ. The bound needs |1−e^{iθ}| with θ = n·arg(1−1/ρ)... the exact argument: θ_γ = arg((ρ−1)/ρ). For ρ = σ+iγ: (ρ−1)/ρ = 1 − 1/ρ; 1/ρ = (σ−iγ)/(σ²+γ²) ≈ −i/γ + σ/γ². So 1−1/ρ ≈ 1 + i/γ − σ/γ²; arg ≈ 1/γ (for γ > 0 large). n·θ ≈ n/γ, |1−e^{in/γ}| ≈ n/γ when n/γ small. Yes. Divergent. Confirmed.
So the CORRECT definition of liCoeff must either:
(a) sum over pairs (e.g., over zeros with Im > 0 of the paired summand f(ρ) + f(ρ̄), absolutely summable since pair = O(n²/|ρ|²)·mult), or
(b) sum over an ordered enumeration (tsum over ℕ with a specific symmetric enumeration — tsum is order-independent, so same issue: needs absolute summability... tsum over ℕ also requires Summable (absolute). So (b) fails too unless paired), or
(c) keep the subtype but group: `∑' ρ : {ρ // IsNontrivialZero ρ ∧ 0 < ρ.im}, (f ρ + f (conj ρ))`-ish with mult — absolutely summable ✓.
Hmm — but actually WAIT. Is it possible the family IS summable because of cancellation in modulus? No — Summable is exactly Σ‖f‖ < ∞. Diverges. OK.
So how did session 012 not notice? Because liCoeff is only used INSIDE hypotheses (SfBoundProp, LiVerifiedUpTo) and in the DEFINITION of Sf — never evaluated. The perimeter hypothesis LiVerifiedUpTo (5×10⁵) says "liCoeff n > 0 for n ≤ 5×10⁵" — if liCoeff = 0 junk, that hypothesis is simply FALSE → the theorem lambda_pos_finite_height_verified, while LOGICALLY VALID (from false premises anything follows... no wait — the theorem is stated WITH hypotheses: hRH, hfinite, hSf → conclusion. If hfinite is unprovable/false, the theorem is just not applicable — it doesn't make the Lean development inconsistent, but it makes the theorem VACUOUS and the paper's claim broken: "λ_n > 0 for n ≤ 5×10⁵" is TRUE in reality but its Lean encoding via a junk liCoeff would be false).
Hmm wait — actually let me look at what LiVerifiedUpTo says exactly. Need to read it. Also RHUpTo. Let me not speculate — read LiSkeleton.lean's relevant sections.
THIS is a significant finding for ii′-0: fixing the liCoeff definition (paired/absolute-summability-correct) is a PREREQUISITE for SfBoundProp to even be true in Lean. And it touches the "frozen" LiSkeleton — hmm. But note: fixing the def would change what lambda_pos_finite_height_verified says at the encoding level. The frozen-file rule was to protect Paper A; but if there's a latent definitional defect, fixing it is exactly tier-ii′ work (L7!), and the paper claim stays the same (the mathematical content intended is the paired sum). The fix: redefine liCoeff as the paired tsum (absolutely summable, provable from zero_sum_inv_sq + pairing), prove the old junk def... no, replace the def. Since lambda_pos_finite_height_verified is stated from hypotheses about liCoeff, changing the def changes those hypotheses' meaning — the theorem proof still goes through (it only uses the hypotheses abstractly, presumably). And SfBoundProp becomes TRUE (provable). And LiVerifiedUpTo becomes the true statement about real λ_n. The change is semantically invisible at the paper level (paper means the real λ_n) but CRITICAL for honesty of the encoding.
Hmm, hold on, let me not jump the gun. Maybe the def is fine because... actually one more possibility: maybe IsNontrivialZero + zeroMult with the tsum over the SUBTYPE — the subtype could be empty if IsNontrivialZero is unproven... no, it's a real definition; zeros exist (provably, e.g., known first zero — actually proving existence of a nontrivial zero in Lean is itself nontrivial! Is there a proved existence? If the zero set were EMPTY, liCoeff = 0 trivially and hfinite "∀ n ≤ 5×10⁵, 0 < liCoeff n" would be false. But zeros DO exist mathematically; can Lean prove it? Via the WeilEF work or via ζ(1/2+14.134i) ≈ 0 numerics with interval arithmetic — probably NOT proved in zeta-23-lean! If not proved, then in the current development the subtype MIGHT be empty for all Lean knows — hfinite would be unprovable either way (it's a hypothesis, so fine), but for SfBoundProp's PROOF we need the actual zero set with all its structure.)
OK — so ii′-0 has found its first major design issue: the liCoeff encoding. This is exactly what the design sub-stage is for. Let me now read the actual LiSkeleton definitions (liCoeff, Sf, RHUpTo, LiVerifiedUpTo) and D-036/D-056 to nail everything down.
Let me read LiSkeleton.lean around lines 1-100 (defs) and the hypothesis defs (RHUpTo, LiVerifiedUpTo), then D-036 and D-056.
Both inventories are in, with two significant findings — one excellent, one that needs immediate verification. Updating todos and reading the core sources now.
tool: TodoWrite ok
input
{
"todos": [
{
"content": "Verify paper/Lean baseline is clean and frozen",
"status": "completed",
"activeForm": "Verifying paper/Lean baseline"
},
{
"content": "Inventory vendored residue/meromorphic API (agent)",
"status": "completed",
"activeForm": "Inventorying residue/meromorphic API"
},
{
"content": "Inventory Zeta23 zero-counting + Mathlib zeta API + liCoeff (agent)",
"status": "completed",
"activeForm": "Inventorying Zeta23/Mathlib zeta API"
},
{
"content": "Read liCoeff/Sf/perimeter defs + check summability encoding",
"status": "in_progress",
"activeForm": "Reading liCoeff/Sf/perimeter defs"
},
{
"content": "Read D-036 contour computation + D-056 R-bound proof",
"status": "pending",
"activeForm": "Reading D-036/D-056"
},
{
"content": "Write D-064 design doc (routes + lemma graph)",
"status": "pending",
"activeForm": "Writing D-064 design doc"
},
{
"content": "Create LiContour.lean sorry skeleton, compiles",
"status": "pending",
"activeForm": "Creating LiContour.lean skeleton"
},
{
"content": "Session-014 closure (journal, STATE, commit)",
"status": "pending",
"activeForm": "Closing session 014"
}
]
}
result 2026-08-21 17:59:39Z → 2026-08-21 17:59:39Z
{
"oldTodos": [
"content='Verify paper/Lean baseline is clean and frozen' status='in_progress' active_form='Verifying paper/Lean baseline'",
"content='Inventory vendored residue/meromorphic API (agent)' status='pending' active_form='Inventorying residue/meromorphic API'",
"content='Inventory Zeta23 zero-counting + Mathlib zeta API + liCoeff (agent)' status='pending' active_form='Inventorying Zeta23/Mathlib zeta API'",
"content='Read D-036, D-056, LiSkeleton tier-(ii) defs' status='pending' active_form='Reading D-036/D-056/LiSkeleton'",
"content='Write D-064 design doc (routes + lemma graph)' status='pending' active_form='Writing D-064 design doc'",
"content='Create LiContour.lean sorry skeleton, compiles' status='pending' active_form='Creating LiContour.lean skeleton'",
"content='Session-014 closure (journal, STATE, commit)' status='pending' active_form='Closing session 014'"
],
"newTodos": [
"content='Verify paper/Lean baseline is clean and frozen' status='completed' active_form='Verifying paper/Lean baseline'",
"content='Inventory vendored residue/meromorphic API (agent)' status='completed' active_form='Inventorying residue/meromorphic API'",
"content='Inventory Zeta23 zero-counting + Mathlib zeta API + liCoeff (agent)' status='completed' active_form='Inventorying Zeta23/Mathlib zeta API'",
"content='Read liCoeff/Sf/perimeter defs + check summability encoding' status='in_progress' active_form='Reading liCoeff/Sf/perimeter defs'",
"content='Read D-036 contour computation + D-056 R-bound proof' status='pending' active_form='Reading D-036/D-056'",
"content='Write D-064 design doc (routes + lemma graph)' status='pending' active_form='Writing D-064 design doc'",
"content='Create LiContour.lean sorry skeleton, compiles' status='pending' active_form='Creating LiContour.lean skeleton'",
"content='Session-014 closure (journal, STATE, commit)' status='pending' active_form='Closing session 014'"
],
"cleared": false
}
thinking (9894 chars)
Confirmed: `liCoeff` is defined as the unordered `tsum` over the subtype of nontrivial zeros with the summand `(zeroMult ρ : ℂ) * (1 - (1 - 1/ρ)^n)`.
Now the critical question: is this family `Summable` (absolutely)? My asymptotic analysis says NO for n ≥ 1: |1−(1−1/ρ)ⁿ| ≈ n/|γ| for |γ| ≫ n (on the line), and Σ 1/|γ| diverges.
Wait — actually, let me be careful. For OFF-LINE zeros (σ ≠ 1/2), the pairing argument changes. But the DIVERGENCE of Σ‖summand‖ only needs the on-line zeros (or any zeros): |1−e^{inθ_γ}| with θ_γ ≈ 1/γ — for zeros with γ ∈ [n·2^k, n·2^{k+1}], |1−e^{in/γ}| ≈ n/γ ≈ 2^{−k}. Number of such zeros ≈ n·2^k·log — so each dyadic block contributes ≈ n·log·constant to Σ‖summand‖ — diverges as we sum over k. YES, definitively NOT Summable.
BUT: the conjugate-pair structure: the subtype {ρ // IsNontrivialZero ρ} — is it closed under conjugation? Yes (ζ real-valued on real axis ⟹ zeros come in conjugate pairs — provable via `riemannZeta` real on ℝ and Schwarz reflection; Zeta23 has zeta_reflect_zero for reflect ρ = 1−ρ̄, and conjugation separately). So the family is NOT summable but is "pairwise summable".
So `liCoeff n` as defined = 0 (junk) IF Lean can't prove Summable... no wait — tsum is DEFINED as: if Summable f then the sum else 0. It's not that "Lean can't prove" — tsum is defined by classical choice; if the family is in fact not summable (mathematically), then `tsum f = 0` is TRUE (provable from `tsum_eq_zero_of_not_summable`). So `liCoeff n = 0` would be PROVABLE for each n ≥ 1!! That makes:
- `LiVerifiedUpTo N`: `0 < (liCoeff n).re` = `0 < 0` — FALSE (provably false).
- `SfBoundProp`: |SInfty n + 1 − 0| ≤ Bn — for large n, SInfty n + 1 ~ ½n log n vs Bn ~ C√n log²n — FALSE for large n (provably, eventually).
So SfBoundProp as currently encoded is almost certainly FALSE (for n ≥ 1 large), and LiVerifiedUpTo false. The theorem lambda_pos_finite_height_verified is vacuously true (false hypotheses). This is a latent DEFECT in the session-012/013 encoding — not caught because liCoeff is never evaluated and the audit checks axioms, not truth of hypotheses.
Hmm wait — wait. Let me double check the asymptotic |1−(1−1/ρ)ⁿ| ~ n/|γ| requires n/|γ| small, i.e. |γ| ≫ n. For FIXED n and |γ| → ∞, yes. The summand as a function of ρ for fixed n: f(ρ) = mult·(1−(1−1/ρ)ⁿ). As |ρ| → ∞: (1−1/ρ)ⁿ → 1 (since 1/ρ → 0), so f(ρ) → 0 like n·(1/ρ)·mult: indeed |f(ρ)| ~ n·mult/|ρ|. And Σ mult/|ρ| = Σ over zeros — with multiplicity — of 1/|ρ| diverges (standard: Σ 1/|ρ| diverges even without multiplicity since N(T) ~ T log T). So not Summable. CONFIRMED (mathematically, with certainty).
Hmm, but hold on — one more subtlety: `Summable f` for f : ι → ℂ where ι = {ρ // IsNontrivialZero ρ}. If the subtype is EMPTY (no proof of zero existence in the system), then f IS summable (empty sum) and liCoeff = 0. Either way (empty or nonempty), liCoeff n = 0 for n ≥ 1?? NO WAIT — if nonempty and not summable, tsum = 0. If empty, tsum = 0. If nonempty and summable — impossible per above. So liCoeff n = 0 for all n ≥ 1, PROVABLY (well, provably modulo proving whether the subtype is nonempty and non-summability — either way the value is 0, but the PROOF differs; the VALUE is 0 regardless).
Hmm, actually for n = 0: 1−(1−1/ρ)⁰ = 0, so liCoeff 0 = 0 correctly. For n ≥ 1: liCoeff n = 0 junk.
CONSEQUENCE: The entire session-012 encoding has liCoeff ≡ 0. `LiVerifiedUpTo` is false. `SfBoundProp` is false (for large n). `lambda_pos_finite_height_verified` is vacuous. **The paper's Lean headline is currently encoding-empty.** The fix is exactly L7 done right: define liCoeff via the PAIRED sum (absolutely summable) or prove the pairing reformulation.
Hmm, hold on. Let me reconsider whether it's really false. SfBoundProp: |Sf n| ≤ Bn FAlt n where Sf n = SInfty n + 1 − (liCoeff n).re = SInfty n + 1 (with junk liCoeff). SInfty n ≥ sInftyLower n = ½n log n + ... (proved). Bn FAlt n with T = √n+1: dominant term 4T·(2/3)C0hat(T) ≈ 4√n·(0.433·0.5 log n) ≈ 0.87√n log n; plus 2F(T) ≈ (√n/π)·0.5·log n ≈ 0.16√n log n; total Bn ~ 1.03√n log n + lower. vs Sf ≈ ½n log n. Ratio ~ n/√n = √n → ∞. So indeed FALSE for n ≥ ~10⁶-ish. And the range starts at 10⁵ — borderline: at n=10⁵, SInfty ≥ ½·10⁵·11.5 − ... ≈ 5.7×10⁵; Bn(10⁵) ≤ 347 000 (certified). 5.7×10⁵ > 3.47×10⁵ — FALSE already at n = 10⁵! (Modulo the actual SInfty value: sInftyLower(10⁵) ≥ 432 500 certified > Bn ≤ 347 000. So |Sf| = SInfty + 1 ≥ 432 501 > 347 000 ≥ Bn — PROVABLY FALSE at n = 10⁵ with junk liCoeff!)
Wow. OK so this is definite: with the current encoding, SfBoundProp is provably false. Good thing tier ii′ exists — this is exactly what closing it fixes. But ALSO important: this defect affects the PAPER's claim "machine-verified modulo SfBoundProp" — because the hypothesis as encoded is false, the "verification" is vacuous. The mathematical content (D-037 chain) is fine; the ENCODING of liCoeff is wrong. The honest fix (paired sum) restores everything: with the correct liCoeff, LiVerifiedUpTo is the true computational fact, SfBoundProp is the true analytic bound, and the theorem means what the paper says.
Priority: this becomes ii′-0's #1 design item — the liCoeff redefinition. It's "L7" but bigger than a note: it's the correctness of the base definition. The fix plan:
- Define `liCoeffPaired n := ∑' ρ : {ρ // IsNontrivialZero ρ ∧ 0 < ρ.im}, mult·[(1−(1−1/ρ)ⁿ) + (1−(1−1/ρ̄)ⁿ)]` (upper-half zeros; need: zeros with Im = 0 — none exist (ζ has no real zeros in (0,1) — provable? ζ on (0,1) is real and negative... ζ(s) < 0 for 0 ≤ s < 1 (real, since the pole at 1 and ζ(0) = −1/2; needs proof — Mathlib might have `riemannZeta_neg_of...`? There's deriv_riemannZeta_zero etc. Actually ζ(s) ≠ 0 for real s ∈ (0,1): since the Dirichlet eta η(s) > 0 for s > 0 real (alternating series) and ζ = η/(1−2^{1−s}) with denominator < 0 for s ∈ (0,1) — so ζ < 0 there. Provable via Mathlib's eta? There's `riemannZeta_neg_nat...` hmm, need to check. Alternatively avoid the issue: sum over Im > 0 PLUS explicitly handle Im = 0 (empty by a lemma) — or sum over Im ≥ 0 with pairing formula adjusted. Simplest: prove no zeros on ℝ in (0,1) — actually easier: prove no REAL zeros at all in the strip via ζ(s) ∈ ℝ for s ∈ ℝ and the eta argument. Might already be in Zeta23 (IsNontrivialZero requires 0 < re < 1; real zeros would be in (0,1); the PNT zero-free Re ≥ 1 covers the boundary only. The eta argument is elementary; likely a few dozen lines).
- Prove Summable of the paired family: pair summand = mult·[2 − (1−1/ρ)ⁿ − (1−1/ρ̄)ⁿ]; with ρ̄ also a zero of same mult. Asymptotic: ≈ mult·n²/|ρ|²-ish for large γ (second-order cancellation) — rigorous bound: |1−(1−w)ⁿ + ... | hmm need |pair| ≤ C(n)·mult/|ρ|² for |ρ| ≥ some explicit function of n (e.g. |ρ| ≥ 2n). Then Σ mult/|ρ|² < ∞ via Zeta23's `zero_sum_inv_sq` (WeilEF.ZeroSummability — check its exact statement) — if that gives Σ over the subtype of (mult)·|ρ|⁻² summable, we get Summable of pairs over upper zeros by comparison.
- Then the BL identity Sf = SInfty + 1 − λ.re and the contour argument proceed with the paired liCoeff.
- LiVerifiedUpTo with the new liCoeff: true (computational fact), and its relationship to E-011/E-015's λ_n: the paired sum equals the standard λ_n (this IS the standard definition of the Li coefficient as a sum over zeros, which converges only when paired — the literature defines λ_n = Σ_ρ [1−(1−1/ρ)ⁿ] with the understanding of symmetric pairing/principal value! e.g., Bombieri–Lagarias define it via the Hadamard-product Hadamard sum). So the new def matches the literature.
Also check: does the old `liCoeff` appear in LiBasePoints.lean and the final theorem — yes via Sf and hypotheses. Replacing the def: the frozen-file rule vs fixing a defect — the defect MUST be fixed for the paper's claim to be meaningful, so the freeze yields to the fix (the freeze protects against destabilizing edits, not against correctness fixes; and the fix makes Paper A MORE correct, keeping its statement intact). The paper text says "Li coefficients" — the meaning is unchanged; the encoding is repaired. I'll flag this prominently to the user in the session summary and in D-064.
Actually — wait. I should double-check my divergence claim once more, because it's the crux of a significant claim (that the current encoding is vacuous). Σ_{ρ} 1/|ρ|: N(T) ~ (T/2π)log(T/2π). Σ_{0<γ≤T} 1/γ ≈ ∫_e^T (1/2π)log(t/2π) dt/t ≈ (1/4π)(log T)². Diverges ✓. And with the summand ~ n·mult/|ρ| for large |ρ| ✓. And tsum of non-summable = 0 ✓ (tsum_def / `tsum_eq_zero_of_not_summable`). And Bn(10⁵) ≤ 347 000 < 432 501 ≤ SInfty(10⁵)+1 — the certified bounds from LiBasePoints (sInftyLower(10⁵) ≥ 432 500; Bn(10⁵) ≤ 347 000) — so SfBoundProp at n=10⁵ reads 432 501 ≤ 347 000 — false ✓✓. Certain.
One caveat: is `Summable` of the junk family maybe TRUE after all because the subtype could be... no, subtype is countable-ish (discrete zeros), summability over it is Σ‖f‖ < ∞, diverges. Done.
Also RHUpTo: fine as stated (vacuously true or not, it's a well-formed Prop about actual zeros — actually it's TRUE as a Prop if Platt–Trudgian holds; the encoding is fine).
LiVerifiedUpTo with junk liCoeff: "0 < (0).re" false ✓.
So the three-hypothesis theorem currently has TWO false hypotheses (hfinite, hSf) — vacuous twice over. The theorem as a Lean object is fine (it's a function from hypotheses), but the paper's Appendix B claim must eventually be backed by the corrected defs. This is precisely the kind of thing the contour-closure project will fix end-to-end: paired liCoeff (summable, correct), SfBoundProp proved (true), LiVerifiedUpTo stays a hypothesis but now a TRUE one (and dischargeable in principle by computation, though 5×10⁵ is way beyond Lean compute — stays perimeter, as designed).
Good. Now read D-036 and D-056 (the analytic content to formalize). These are long files; let me read them.
The `liCoeff` encoding needs a careful look — this is important. Let me verify the summability situation and read the analytic sources.
tool: Read
input
{
"file_path": "D:\\Python\\Quantum\\research\\derivations\\D-036-explicit-contour-constants.md"
}
thinking (8069 chars)
Now I have the full picture of the analytic content. Let me also quickly read D-037's remaining sections (I read §1–4 partially) and D-057 for completeness... Actually I have D-037 §1–4 from earlier read (lines 1–80). The B(n) pieces are visible in the Lean `Bn` def. D-057 (convexity) is already Lean-proved (tier i).
Now, the CRITICAL pending item: verify my liCoeff non-summability claim. I'm mathematically confident, but let me double-check the key step with actual numbers — specifically, whether `Summable (fun ρ ↦ zeroMult ρ * (1 − (1−1/ρ)^n))` over the zero subtype is false. The cleanest proof of non-summability: restrict to on-line zeros ρ_k = 1/2 + iγ_k with γ_k large positive (existence of infinitely many — needs zero existence + N(T) → ∞, which Zeta23's RvM gives!). For such zeros: 1 − 1/ρ has modulus exactly 1 (since |ρ−1| = |ρ| when Re ρ = 1/2 ✓). So summand = mult·(1 − e^{inθ_k}) where θ_k = arg(1−1/ρ_k) ∈ (0, π). Norm = mult·|1−e^{inθ_k}| = mult·2|sin(nθ_k/2)|. θ_k = arg((ρ−1)/ρ): for ρ = 1/2+iγ: (ρ−1)/ρ = ((−1/2+iγ)(1/2−iγ))/|ρ|² = (γ² − 1/4 + iγ·(−1/2−1/2)... let me compute: (−1/2+iγ)·conj(1/2+iγ) = (−1/2+iγ)(1/2−iγ) = −1/4 + iγ/4·... (−1/2)(1/2) + (1/2)(iγ)... = −1/4 + (iγ)(1/2)·... let me just do it: (a+bi)(c−di) with a=−1/2, b=γ, c=1/2, d=γ: real = ac+bd = −1/4 + γ²; imag = bc−ad = γ/2 + γ/2 = γ. So (ρ−1)/ρ = (γ²−1/4+iγ)/(γ²+1/4). arg ≈ γ/(γ²−1/4) ≈ 1/γ for large γ ✓. So nθ_k ≈ n/γ_k ∈ (0, π/2) for γ_k > 2n/π, and |sin(nθ_k/2)| ≈ nθ_k/2·(1−o(1)) ≥ (n/4γ_k) for γ_k ≥ 2n say. So ‖summand‖ ≥ mult·n/(2γ_k) for γ_k ≥ max(2n, ...). Then Σ_{γ_k ≥ 2n} 1/γ_k = ∞ (from N(T) ~ T log T, i.e. RvM, which Zeta23 PROVES — `riemannVonMangoldt`!). So not summable. Solid.
But wait — the infinite-tail divergence uses RH (all zeros on the line) only for convenience; actually zeros could be off-line beyond T₀, but we need only a SUBFAMILY (the on-line ones up to T₀ — infinitely many? No! Only finitely many zeros up to T₀ ≈ 1.3×10¹³ of them — finite!). Hmm: to prove NON-summability of the whole family I need infinitely many summands with comparable norms — the zeros beyond T₀: are they on the line? Unknown (that's RH). But |1−1/ρ| for ANY zero with |γ| large: |1−1/ρ| ≥ 1−1/|ρ| ≥ 1/2. Hmm, that gives |summand| ≤ mult·(1 + (1+2/|ρ|)ⁿ)-ish — an UPPER bound, useless for non-summability. For non-summability I need LOWER bounds on |1−(1−1/ρ)ⁿ| for infinitely many zeros. For zeros with σ ≥ 1/2 (mirror: those with σ ≤ 1/2 by conjugation... the zeros come in quartets ρ, ρ̄, 1−ρ, 1−ρ̄). For ρ with σ ∈ (0,1): |1−1/ρ|² = ((σ−1)²+γ²)/(σ²+γ²). If σ ≤ 1/2: |1−1/ρ| ≥ 1, so (1−1/ρ)ⁿ has modulus ≥ 1, could still be near 1 in DIRECTION (arg small). Hmm: 1−(1−1/ρ)ⁿ — the modulus |1−wⁿ| with |w| ≥ 1: can be small if wⁿ ≈ 1. w = 1−1/ρ: for |ρ| large, w ≈ 1 − i/γ + O(1/γ²)... arg(w) ≈ −1/γ for γ > 0? sign: 1/ρ = (σ−iγ)/|ρ|², so w = 1 − σ/|ρ|² + iγ/|ρ|² ≈ 1 + i/γ for γ > 0 large. arg(w) ≈ 1/γ. n·arg(w) ≈ n/γ → 0, so wⁿ → 1 and 1−wⁿ ≈ −n(w−1)·avg... |1−wⁿ| ≈ n|w−1| = n/|ρ| for |γ| ≫ n. This holds for ANY zero (σ ∈ (0,1)) with |γ| ≫ n: |w−1| = 1/|ρ|, and w near 1, wⁿ − 1 ≈ n(w−1)·(1+o(1)) rigorously via wⁿ−1 = (w−1)·Σ_{j<n}w^j and |Σ w^j| ≥ n·|w|^{n−1}... hmm need |w| close to 1: |w| = |1−1/ρ| ∈ [1−1/|ρ|, 1+1/|ρ|]. |Σ_{j=0}^{n−1} w^j| ≥ Re Σ w^j·(phase adjustment)... simpler: |wⁿ−1|/|w−1| = |Σ_{j<n} w^j| and each |w^j| ≥ (1−1/|ρ|)^j ≥ (1−n/|ρ|) ≥ 1/2 for |ρ| ≥ 2n. And the w^j's all have argument ≈ j/γ ∈ [−n/γ, n/γ] — small spread; if |arg w| ≤ π/(2n)... |arg w| ≈ 1/γ ≤ π/(2n) for γ ≥ 2n/π·... Then Re Σ w^j ≥ Σ |w^j|cos(j·argw) ≥ (1/2)·n·cos(n·arg w) ≥ n/4 when n·argw ≤ 1 rad. |1−wⁿ| ≥ (n/4)·|w−1| = n/(4|ρ|) for all zeros with γ ≥ C·n (any σ!). And Σ_{zeros, γ ≥ Cn} mult/|ρ| = ∞ — but does this need RvM? Need Σ 1/γ divergent over ALL nontrivial zeros (not just on-line). Σ_{all zeros} 1/|ρ| diverges ⟺ N(T)/T unbounded-ish... N(T) → ∞ is enough? No — need more: if zeros were sparse (N(T) ~ T), Σ1/γ could converge. But we KNOW N(T) ~ cT log T (RvM — proved in Zeta23 for zetaZeroConfig!). So Σ_{γ ≤ T} mult ≥ cT log T eventually ⟹ Σ_{2^k ≤ γ < 2^{k+1}} 1/γ ≥ 2^{−(k+1)}·c·2^k·k = c·k/2 — diverges ✓. So non-summability follows from RvM (Zeta23 theorem `riemannVonMangoldt` — need to check its exact consequence usable here; the statement has main + local_count; the main term gives N(T,2T) ~ (T/2π) log T·... ✓).
So: `liCoeff n` for n ≥ 1 is tsum-of-nonsummable = 0 (PROVABLE in Lean, modulo assembling the divergence proof — itself a mini-project, but we don't need to PROVE it's junk; we need to FIX the def).
Conclusion for D-064: **the liCoeff def must be replaced by the paired (absolutely summable) form BEFORE anything else.** All downstream statements (Sf, SfBoundProp, LiVerifiedUpTo, lambda_pos_finite_height_verified) then refer to the true λ_n.
Wait — actually, one more consideration: maybe instead of replacing liCoeff, ADD a new def liCoeffPaired and prove `liCoeff n = liCoeffPaired n`? No — liCoeff (junk) = 0 ≠ liCoeffPaired (true λ_n, > 0). They're not equal; the old def is simply wrong. Replace it. Since the old theorems are conditional on hypotheses ABOUT liCoeff, after replacement the hypotheses mean the right thing and the old proofs still compile (they use hypotheses abstractly). lambda_pos_finite_height_verified goes from vacuous-but-true to meaningful-and-true. Paper A's statement unchanged (the paper means the real λ_n).
Hmm — but there's a subtlety: `LiVerifiedUpTo (5×10⁵)` with the CORRECT liCoeff is the true computational fact (λ_n > 0, n ≤ 5×10⁵) — good, stays a perimeter hypothesis, now true. ✓.
And SfBoundProp with correct liCoeff: Sf n = SInfty n + 1 − λ_n — the BL identity content — exactly what the contour argument bounds ✓.
One more check — does `Sf`/`SfBoundProp`'s range overlap logic still work? Yes, unchanged.
Now — where does the fix land given the freeze? The freeze protects paper files and existing PROOFS. Replacing the liCoeff def touches LiSkeleton.lean (frozen). Resolution: the def replacement is a CORRECTNESS fix, not a refactor; I'll do it as a small, isolated commit with clear rationale, and it does not touch paperA.tex at all (paper never mentions Lean def names). The frozen rule was my own protection protocol; the user said "make sure Paper A and information will still be intact for submission if we change course" — Paper A the PDF/tex is untouched; the Lean fix makes its claims MORE sound, and if we change course mid-way, the state after the def fix is still consistent and submittable (actually better: currently the encoding is vacuous — arguably NOT submittable as "machine-verified" in the strongest reading; after the fix it's honest again even with SfBoundProp open). I should flag this to the user clearly — this is a significant finding that changes the "submission-ready" assessment slightly: the paper's math is fine, but the Lean encoding of λ_n needs the paired-sum fix for the "machine-verified" claim to be non-vacuous. The user should know this NOW, not at the end.
Also — the summit of this: this discovery VALIDATES the user's instinct to ask "does the research actually do the full stack?" — the audit question surfaced a real defect.
Next steps in ii′-0:
1. Read a bit of D-037's remaining part (sections 5-8) for the full B(n) accounting + S_f exact identity — I have most of it; the Bn def in Lean matches D-037 (4.1).
2. Check `zero_sum_inv_sq` exact statement in Zeta23 (for the paired summability proof).
3. Check axiom cleanliness of the Zeta23 theorems we plan to use (zero_sum_inv_sq, zeta_local_zero_count, riemannVonMangoldt, RectangleIntegral'_eq_sumResiduesIn) — they must be sorry-free (or acceptable).
4. Write D-064.
5. Build LiContour.lean skeleton.
Given the session length already, let me be efficient: check the Zeta23 summability statements + axiom status quickly, then write D-064 (the design doc — the main deliverable), then the skeleton. The skeleton might slip to the next sub-stage session — that's fine per sub-stage rule (ii′-0 is 1–2 sessions).
Let me check zero_sum_inv_sq and its axioms.
D-036 and D-056 read. Now let me verify the two decisive facts for the design: (1) the `liCoeff` summability situation, and (2) what Zeta23's zero-summability theorems actually give us (with axiom status).
tool: Bash
input
{
"command": "grep -n \"zero_sum_inv_sq\\b\\|zero_sum_inv_sq_gen\\|theorem zero_sum_inv_sq\" /d/Python/Quantum/zeta-23-lean/Zeta23/WeilEF/ZeroSummability.lean | head; echo ===; sed -n '1,60p' /d/Python/Quantum/zeta-23-lean/Zeta23/WeilEF/ZeroSummability.lean",
"description": "Check zero-sum summability theorem statements"
}
thinking (2704 chars)
`zero_sum_inv_sq` exists: `Summable (fun ρ : (zetaZeros hs).carrier => (zeroMult ρ : ℝ) / (1 + normSq (gammaOf ρ)))` where `gammaOf ρ` — need to check: gammaOf ρ = (ρ − 1/2)/i presumably (the "gamma" coordinate), so 1+‖γ_ρ‖² ~ |ρ|²-ish? ‖gammaOf ρ‖² = |ρ.im|² + (1/2−ρ.re)². So the summable family is mult/(1 + γ_im² + (1/2−re)²) — comparable to mult/(1+|ρ|²) only if |ρ.re| is controlled... |γ_ρ|² = ρ.im² + (1/2 − ρ.re)², while |ρ|² = ρ.im² + ρ.re². For zeros, ρ.re ∈ (0,1) bounded, so |γ_ρ|² ≥ ρ.im² and 1+|γ_ρ|² ≥ ρ.im² ≥ ... hmm, need Σ mult/|ρ|²: |ρ|² = ρ.re² + ρ.im² ≤ 1 + ρ.im² ≤ 1 + ‖γ_ρ‖². So mult/|ρ|² ≥ mult/(1+‖γ_ρ‖²) — direction wrong for comparison (we need Σ mult/|ρ|² < ∞, and mult/(1+‖γ‖²) ≤ mult/(1+ρ.im²)... and |ρ|² ≤ (1 + ρ.im²)·2-ish for re ≤ 1: |ρ|² = re²+im² ≤ 1+im². And 1+‖γ_ρ‖² = 1 + im² + (1/2−re)² ≤ 2 + im². So mult/|ρ|² ≤ mult/(re²+im²) and mult/(1+‖γ‖²) ≥ mult/(2+im²) ≥ mult/(2(1+im²)) ≥ mult/(2·2|ρ|²)... for |ρ| ≥ 1: 1+im² ≤ |ρ|² + 1 ≤ 2|ρ|². So mult/(1+‖γ‖²) ≥ mult/(4|ρ|²). Summability of mult/(1+‖γ‖²) ⟹ summability of mult/(4|ρ|²) restricted to |ρ| ≥ 1 ⟹ Σ mult/|ρ|² converges ✓. Good — the needed Σ mult·|ρ|⁻² summability follows from zero_sum_inv_sq by a comparison. That's the L7 engine.
Note `(zetaZeros hs).carrier` is the subtype over IsNontrivialZero — SAME subtype as liCoeff uses ({ρ // IsNontrivialZero ρ} vs (zetaZeros hs).carrier — zetaZeros hs is a ZeroConfig with carrier = {ρ | IsNontrivialZero ρ}; the subtype coerces). And the theorem needs `hs : ZetaSeam` — the seam obligations (discharged by `zetaSeam` per SeamClosed.lean). So we can instantiate at zetaZeroConfig... `zero_sum_inv_sq zetaSeam : Summable ...` over (zetaZeros zetaSeam).carrier = zetaZeroConfig.carrier. Need to check carrier of zetaZeroConfig is definitionally {ρ | IsNontrivialZero ρ} and the liCoeff subtype matches. Fine — engineering detail for the skeleton.
Now the axiom check: are zero_sum_inv_sq / zeta_local_zero_count / riemannVonMangoldt sorry-free? D-061 said zeta-23-lean full build green with sorries only in trusted challenge stubs, and the comparator PrintAxioms matched AUDIT.md. The audit checked "27 main + 16 amendment statements". Is zero_sum_inv_sq among them? Let me just run a quick PrintAxioms on the ones we care about. That's a lean env command — short ones allowed in foreground per handoff notes. Let me write a tiny scratch file and run `lake env lean` on it from the NguyenRH1 dir. Also check RectangleIntegral'_eq_sumResiduesIn and zeta_local_zero_count axioms. And gammaOf def.
Actually, let me keep this quick and focused: one scratch file printing axioms of the 4-5 key dependencies. Compile time should be seconds (imports already built).
`zero_sum_inv_sq` is exactly the L7 engine we need. Now the critical axiom check on the Zeta23 dependencies we plan to reuse, plus the `gammaOf` definition.
tool: Bash
input
{
"command": "grep -rn \"def gammaOf\" /d/Python/Quantum/zeta-23-lean/Zeta23/ | head -3",
"description": "Find gammaOf definition"
}
tool: Write
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\Scratch.lean",
"content": "/- Session 014 scratch: axiom check of planned tier-ii\u2032 dependencies. -/\nimport Mathlib\nimport Zeta23.WeilEF.ZeroSummability\nimport Zeta23.RvM.LocalCount\nimport Zeta23.RvM.Statement\nimport Zeta23.FromPNTPlus.ResidueCalcOnRectangles\nimport Zeta23.ZetaReflect\n\nopen Zeta23\n\n#print axioms WeilEF.zero_sum_inv_sq\n#print axioms RvM.zeta_local_zero_count\n#print axioms zeta_reflect_zero\n#print axioms zeta_mult_reflect\n#print axioms RectangleIntegral'_eq_sumResiduesIn\n#print axioms ResidueMult\n#print axioms logDerivResidue\n#print axioms riemannZetaLogDerivResidue\n"
}
thinking (17704 chars)
All planned dependencies are sorry-free (3 standard axioms only). Excellent.
Now — one more verification before writing D-064: the liCoeff summability question. I'm mathematically confident it's not summable (n ≥ 1). Let me also double check how `Sf` is used and confirm the issue is real: yes, `Sf n := SInfty n + 1 − (liCoeff n).re` — with junk liCoeff = 0, SfBoundProp is false at n = 10⁵ (as I computed: |Sf| ≥ 432 501 > 347 000 ≥ Bn).
Actually wait — one subtlety: is it PROVABLE that liCoeff n = 0 under the current def? To prove `tsum f = 0` we'd prove `¬ Summable f`. That requires the divergence argument (RvM-based). It doesn't matter for the fix — what matters is that the def does NOT denote λ_n (it denotes the tsum, which is 0 if not summable, and the family is genuinely not summable). Whether Lean can prove that is secondary; the def is semantically wrong regardless.
Hmm, actually let me reconsider ONE more time whether the family might be summable after all... The summand is mult·(1 − (1−1/ρ)ⁿ) as a function on the subtype with the counting measure? No — tsum over a subtype of ℂ uses the COUNTING measure on the subtype (each point mass 1). So tsum f = Σ over zeros of mult·(1−(1−1/ρ)ⁿ), absolute convergence = Σ mult·|1−(1−1/ρ)ⁿ| < ∞. For on-line zeros (the first ~10¹³, up to T₀ — all on the line by Platt–Trudgian, but that's a HYPOTHESIS hRH; without it we know... hmm, actually for the summability QUESTION what matters is mathematical truth: RH truth aside, there ARE infinitely many zeros (proved by RvM theorem in Zeta23: N(T,2T) ~ (T/2π)log T... the main term shows N(T,2T) ≥ cT log T − C log T → ∞). For any zero ρ (on or off line), with |γ| ≥ 8n say: |1−(1−1/ρ)ⁿ| ≥ (n/4)·|1/ρ| as I estimated (w = 1−1/ρ near 1, |arg w| ≤ 1/γ-ish, |wⁿ−1| = |w−1|·|Σ_{j<n} w^j| ≥ (1/|ρ|)·n·(1/2) for the real-part reason). So Σ_{|γ| ≥ 8n} mult·|summand| ≥ (n/4)·Σ mult/|ρ| = ∞ by RvM. So yes — genuinely not summable, for every n ≥ 1. liCoeff n = 0 (junk). CERTAIN.
Additionally: `SInfty` — its summand (1−1/m)ⁿ − 1 + n/m over odd m ≥ 3: ~ n(n−1)/(2m²) — summable ✓ (bern_term_upper proves the bound; summability presumably proved in tier (i) — yes "tsum summability discharged" per NGUYEN.md session 011). ✓ SInfty is fine.
So the design fix: NEW def `liCoeffP` (paired). Two candidate forms:
(A) Sum over upper-half zeros: `∑' ρ : {ρ // IsNontrivialZero ρ ∧ 0 < ρ.im}, mult·(f(ρ) + f(conj ρ))` where f(ρ) = 1−(1−1/ρ)ⁿ. Requires: (i) conj maps zeros to zeros (Schwarz reflection — does Zeta23 have it? zeta_reflect_zero is about reflect ρ = 1−ρ̄; conj invariance: riemannZeta (conj s) = conj (riemannZeta s) — Mathlib probably has this (schwarz reflection for Hurwitz? `riemannZeta_conj`? need to check — likely exists as `riemannZeta_conj` or via completedRiemannZeta...). (ii) no zeros on the real axis in the strip (ζ(x) < 0 for x ∈ (0,1) real — need to prove; via η: Mathlib has `riemannZeta` = hurwitzZetaEven 0 and eta-related lemmas? There's `riemannZeta_neg_nat_eq_bernoulli`, and ζ(s) ≠ 0 for s ∈ (0,1)... hmm, might need the eta function: Mathlib has `LSeries`... not sure about eta. Alternative elementary route: for real x ∈ (0,1), ζ(x) = lim (Σ...) hmm. Actually there's a classical trick: ζ(s)(1−2^{1−s}) = Σ(−1)^{n+1}n^{−s} = η(s), and for real s ∈ (0,1), η(s) > 0 (alternating series with decreasing terms) and (1−2^{1−s}) < 0 ⟹ ζ(s) < 0. Mathlib: is there η? Search needed. If not, prove η(s) = alternating series converges for real s > 0 via Dirichlet's test / explicit pairing, positivity by pairing terms (1/(2k−1)^s − 1/(2k)^s > 0). Bounded work either way.)
(iii) the paired family summability: pair(ρ) = mult·(f ρ + f ρ̄) with |pair| ≤ C(n)·mult/|ρ|² for |ρ| ≥ 8n (the second-order cancellation — needs a real lemma: |2 − wⁿ − w̄ⁿ| with w = 1−1/ρ: w̄ = 1−1/ρ̄ ✓; 2 − wⁿ − w̄ⁿ = −(wⁿ−1) − (w̄ⁿ−1); wⁿ−1 = (w−1)S, S = Σ_{j<n} w^j = n + Σ(w^j − 1); |w^j − 1| ≤ j|w−1|·max(1,|w|)^{n}... standard: |wⁿ−1 − n(w−1)| ≤ n²|w−1|²·e^{n|w−1|}-ish. So f ρ + f ρ̄ = 2 − wⁿ − w̄ⁿ = −n[(w−1)+(w̄−1)] + O(n²|w−1|²) = −n·2Re(w−1) + O(n²/|ρ|²) = 2n·Re(1/ρ) + O(n²/|ρ|²) = 2n·σ/|ρ|² + O(n²/|ρ|²) = O(n²/|ρ|²) since σ ≤ 1 ✓. So |pair| ≤ C(n)·mult/|ρ|² with C(n) explicit (e.g. 2n + 4n² for |ρ| ≥ 2n) ✓. Then Σ over upper zeros: ≤ Σ_upper C(n)mult/|ρ|² ≤ C(n)·Σ_all mult/|ρ|² < ∞ via zero_sum_inv_sq comparison ✓✓.
(B) Alternative: sum over the full subtype of the SYMMETRIZED summand ½(f ρ + f ρ̄): same thing, cleaner subtype (no 0 < im condition, but double-counts and needs the no-real-zeros fact anyway for the factor; actually with symmetrized summand, real zeros would contribute f(ρ) once (ρ̄ = ρ, ½(f+f) = f) — actually fine! The symmetrized sum over ALL zeros = Σ_all ½(f ρ + f ρ̄) = Σ_upper (f ρ + f ρ̄) + Σ_real f ρ — and if real zeros don't exist, equals form (A). And summability: |½(f ρ + f ρ̄)| ≤ C(n)mult/|ρ|² for large ρ ✓ regardless. So (B) is cleaner: `liCoeffP n := ∑' ρ : subtype, (mult ρ : ℂ)/2 * (f ρ + f (conj ρ))`. And it equals the intended λ_n. The no-real-zeros lemma is then only needed for... hmm, actually NOT needed at all for (B)! Because (B) is unconditionally equal to "Σ_upper pairs + Σ_real f" and if a real zero existed, λ_n's classical definition (Hadamard sum) would include it too — (B) IS the correct classical definition regardless.
So (B) is the design: symmetrized tsum over the full subtype. Summable by comparison with zero_sum_inv_sq. Equals the classical λ_n (Hadamard principal value). And it's REAL-valued (each summand: ½mult(f ρ + conj(f ρ)) = mult·Re(f ρ) ∈ ℝ!) — bonus: liCoeffP n is manifestly real (can define it into ℝ directly!). That kills the `.re` in Sf/LiVerifiedUpTo — cleaner. (Keep the ℂ version for compatibility, or refactor Sf to use the real one — the old theorems use (liCoeff n).re; minimal-diff approach: define liCoeffP : ℕ → ℂ proving it's real, then REDEFINE liCoeff := liCoeffP. The downstream .re stays working.)
Then the L0 identity (D-036): Sf n = truncated sum + sides + trivial — with Sf defined from the CORRECT liCoeff, the identity is the real content.
OK. Now — the w=1 residue identification (crux). From D-037's identity:
S_f(n) = Σ_{|γ|≤T}′ [1 − (ρ/(ρ−1))ⁿ]·(−1) + (1/2πi)(I_I+I_II+I_III+I_IV) + triv(−2)
Let me sanity-check the sign/residue bookkeeping: integrand g(w) = k_n(w−1)·(−ζ′/ζ(w)), k_n(s) = (1+1/s)ⁿ − 1.
- At a nontrivial zero ρ (simple): −ζ′/ζ has residue −1 (ζ′/ζ has residue +1 at a simple zero). So Res g = k_n(ρ−1)·(−1) = −((1+1/(ρ−1))ⁿ − 1) = −((ρ/(ρ−1))ⁿ − 1) = 1 − (ρ/(ρ−1))ⁿ ✓ matches the identity's summand.
- At trivial zeros ρ = −2k inside the rectangle (−2, −4 for σ₀ = −5/2): same: 1 − (ρ/(ρ−1))ⁿ = 1 − ((−2)/(−3))ⁿ... wait ρ/(ρ−1) at ρ=−2: (−2)/(−3) = 2/3. Hmm, D-036 says |(1+1/(−2))ⁿ−1| = 1−2^{−n}: k_n(ρ−1) at ρ = −2: k_n(−3) = (1−1/3)ⁿ − 1 = (2/3)ⁿ − 1 — hmm D-036 wrote (1+1/(−2))ⁿ — that's k_n evaluated at −2 not −3?? Let me recheck: the residue at the trivial zero ρ_triv is k_n(ρ_triv − 1)·(−1)·(−1)... sign: Res g = k_n(ρ_triv − 1)·Res(−ζ′/ζ) = k_n(ρ_triv−1)·(−1). Hmm wait — the integrand is k_n(w−1)·(−ζ′/ζ(w)); at a zero ρ of ζ, −ζ′/ζ has residue −1 (per simple zero), so Res g|_ρ = k_n(ρ−1)·(−1) = 1 − (ρ/(ρ−1))ⁿ ✓ as computed. For ρ = −2: k_n(−3) = (1 + 1/(−3))ⁿ − 1 = (2/3)ⁿ − 1, Res = 1 − (2/3)ⁿ. D-036 says "Trivial zeros: only ρ = −2 inside; |(1+1/(−2))ⁿ − 1| = 1 − 2^{−n} ≤ 1" — hmm, that computes k_n(−2) = (1−1/2)ⁿ − 1 = 2^{−n} − 1, |·| = 1−2^{−n}. But the residue is k_n(ρ−1) = k_n(−3) not k_n(−2)?? Unless D-036 uses a different kernel placement (k_n(w) with integrand k_n(w)(−ζ′/ζ(w)) and residues at ρ+1?? no...). Or the identity sums residues as "triv(−2)" meaning the contribution is 1 − (2/3)ⁿ — and D-036's bound "≤ 1" is just a coarse bound that's correct either way ((2/3)ⁿ vs 2^{−n} both ≤ 1). Fine — the formalization will get it exactly right; the BOUND "≤ 1" stands. But NOTE: trivial zero ρ = −4 is also inside (σ₀ = −5/2 < −4)? −5/2 = −2.5, so σ ranges [−2.5, 2√n] — −4 < −2.5 NOT inside. Only −2 ✓. OK.
- At w = 1: pole of order n+1 (k_n(w−1) has pole of order n at w=1; −ζ′/ζ has a simple pole with residue +1... wait: ζ has a pole at 1, so ζ′/ζ ~ −1/(w−1), so −ζ′/ζ ~ +1/(w−1) — simple pole residue +1). So g has pole of order n+1 at 1, and Res g|_1 = [Laurent coefficient extraction]. Writing k_n(w−1) = Σ_{j=1}^n C(n,j)(w−1)^{−j} and −ζ′/ζ(w) = Σ_{k≥−1} c_k (w−1)^k with c_{−1} = 1: Res = Σ_{j=1}^n C(n,j)·c_{j−1} = Σ_{j=1}^n C(n,j) c_{j−1} where c_{j−1} = Laurent coeffs of −ζ′/ζ at 1.
And the identity: RectangleIntegral' = Σ residues = Σ_{|γ|≤T} [1−(ρ/(ρ−1))ⁿ] + [1−(2/3)ⁿ] + Σ_{j=1}^n C(n,j)c_{j−1}.
Then Sf := S_∞ + 1 − λ_n. And λ_n = paired full sum. Hmm — how does the FULL sum appear? The rectangle gives the TRUNCATED sum. The identity Sf = truncated + sides + triv requires:
S_∞ + 1 − λ_n = Σ_{|γ|≤T}[1−(ρ/(ρ−1))ⁿ] + sides + [1−(2/3)ⁿ]
Hmm wait — but the rectangle residue theorem gives: sides = Σ residues (including w=1). So:
sides = Σ_{|γ|≤T}[1−(ρ/(ρ−1))ⁿ] + [1−(2/3)ⁿ] + Res_{w=1}
⟹ Σ_{|γ|≤T}[1−(ρ/(ρ−1))ⁿ] = sides − [1−(2/3)ⁿ] − Res_{w=1}.
Now λ_n (full paired sum) vs the truncated sum Σ_{|γ|≤T}[1−(ρ/(ρ−1))ⁿ]: note for a zero ρ, the summand in liCoeffP is Re[1−(1−1/ρ)ⁿ], and 1−1/ρ = (ρ−1)/ρ — while the contour summand is 1−(ρ/(ρ−1))ⁿ = 1−(1−1/(1−ρ))ⁿ-ish — the ρ ↔ 1−ρ symmetry! The zero set is symmetric under ρ ↦ 1−ρ (functional equation) and ρ ↦ ρ̄. The liCoeff summand at the REFLECTED zero: 1−(1−1/(1−ρ))ⁿ = 1−((1−ρ−1)/(1−ρ))ⁿ = 1−(ρ/(ρ−1))ⁿ ✓✓. So the contour residue at ρ equals the liCoeff summand at 1−ρ. Since the zero set is reflect-invariant, the FULL liCoeff sum = Σ_all [1−(ρ/(ρ−1))ⁿ] (re-indexed) = Σ_all [1−(1−1/ρ)ⁿ] — consistent.
So: λ_n = Σ_all-zeros(paired) [1−(ρ/(ρ−1))ⁿ]. Split: λ_n = Σ_{|γ|≤T} + Σ_{|γ|>T} (tail). Then:
Sf = S_∞ + 1 − λ_n = S_∞ + 1 − [sides − (1−(2/3)ⁿ) − Res_{w=1}] − tail
= [S_∞ + 1 + Res_{w=1} − 1 + (2/3)ⁿ... hmm: S_∞ + 1 − sides + 1 − (2/3)ⁿ + Res_{w=1} − tail.
For this to match D-037's form (Sf = −truncated + sides + triv(−2)... let me not force it; D-037's exact identity (line 63): "S_f(n) = Σ_{|γ|≤T}′ [1 − (ρ/(ρ−1))ⁿ]·(−1) + (1/2πi)(I_I+I_II+I_III+I_IV) + triv(−2)". Hmm — that has −truncated + sides + triv. Substituting truncated = sides − triv − Res: −truncated + sides + triv = −(sides − triv − Res) + sides + triv = 2·triv + Res?? That can't be right dimensionally... I think D-037's "S_f(n)" on the LHS means something slightly different — maybe the identity is for the TRUNCATED S_f and the tail is bounded separately as part of "zeros ≤ 2N(T)". Let me look at D-037 §4's assembly again: "|S_f(n)| ≤ 2N(√n) + 4C₀(√n+1) + |I_I| + |I_II| + |I_IV| + |I_III| + 1" — components: 2N(√n) [the on-line zero terms], 4C₀ [height-window slack T−√n < 1], the four sides, +1 [trivial zero]. So |S_f| is bounded by: the FULL zero sum's contribution ≤ 2N(T) (using each term ≤ 2 via RH-to-T₀) + tail...
hmm wait, where's the tail Σ_{|γ|>T} in this accounting? If S_f = S_∞ + 1 − λ_n exactly, then bounding |S_f| needs the full λ_n including the tail beyond T. But D-037's bound has no explicit tail term... UNLESS the "2N(√n)" term is meant to cover the zero sum to height T and the TAIL is bounded by... let me think: the tail Σ_{|γ|>T} [1−(ρ/(ρ−1))ⁿ] paired: each pair ≈ n²/|ρ|²-ish... Σ_{|γ|>T} n²mult/|ρ|² ≈ n²·log T/T = n² log T/√n = n^{3/2} log T — HUGE, way bigger than B(n) ~ √n log n. That can't be right. Hmm!!
Wait, no — the tail can't be that big, because λ_n is the FULL sum and equals S_∞ − S_f + 1 with |S_f| small... Let me recompute the tail size. Pair for |γ| large: f(ρ)+f(ρ̄) with f(ρ) = 1−(1−1/ρ)ⁿ: computed above = 2nσ/|ρ|² + O(n²/|ρ|²) — for n ≤ γ²-ish, i.e. γ ≥ √n: O(n/|ρ|² + n²/|ρ|²·(1/...))... |pair| ≤ C·n²/|ρ|² for |ρ| ≥ 2n. But our tail starts at |γ| > T = √n + 1 — NOT ≥ 2n! For zeros with γ ∈ (√n, 2n): the pair bound |pair| ≤ C·n²/|ρ|² with C(n) ~ n² e^{n/|ρ|} — the e^{n/|ρ|} factor: |w|ⁿ ≤ (1+1/|ρ|)ⁿ ≤ e^{n/|ρ|} ≤ e^{√n}-ish for γ ~ √n. Hmm, so pairs in the range √n < γ < n can be as large as... |1−(1−1/ρ)ⁿ| ≤ 1+|1−1/ρ|ⁿ ≤ 1 + e^{n/|ρ|} — for γ ~ √n, e^{√n}?!?! That would make individual tail terms EXPONENTIAL in √n.
WAIT. That's for off-line zeros with σ < 1/2 (where |1−1/ρ| > 1). For ON-LINE zeros |1−1/ρ| = 1 exactly, so |1−(1−1/ρ)ⁿ| ≤ 2 always. The tail beyond T₀: zeros with |γ| > T₀ = 3×10¹², n ≤ (T₀−1)²: e^{n/|ρ|} ≤ e^{n/T₀} ≤ e^{T₀} — enormous?! But the paired sum for σ < 1/2: pair = 2nσ/|ρ|² + ... the first-order term is 2nσ/|ρ|² — the O-bound: f ρ + f ρ̄ = 2 − wⁿ − w̄ⁿ where w = 1−1/ρ. Hmm, for σ < 1/2: |w| > 1, wⁿ grows. But w̄ = conj w — same modulus. 2 − 2Re(wⁿ) — and Re(wⁿ) can be as large as |w|ⁿ ~ e^{n/|ρ|}. For γ just above T₀ ~ 3×10¹² and n ~ 9×10²⁴: n/γ² ~ 9×10²⁴/9×10²⁴ = 1 — so |w|ⁿ ≈ e^{n·(1−2σ)/2/|ρ|²·...}: |w|² = ((1−σ)²+γ²)/(σ²+γ²) = 1 + (1−2σ)/|ρ|². |w|ⁿ = exp((n/2)log(1+(1−2σ)/|ρ|²)) ≈ exp(n(1−2σ)/(2|ρ|²)) ≤ exp(n/(2|ρ|²)) ≤ e^{1/2} for n ≤ |ρ|². OK!! I miscalculated before: |w|ⁿ grows like e^{n/|ρ|²}, NOT e^{n/|ρ|} — because |w|−1 ≈ (1−2σ)/(2|ρ|²), not 1/|ρ|. Right: |1−1/ρ| − 1 = (|ρ−1|−|ρ|)/|ρ| ≈ ((1−2σ)/(2|ρ|))/|ρ| = (1−2σ)/(2|ρ|²). So per-zero tail contribution |2−wⁿ−w̄ⁿ| ≤ 2 + 2|w|ⁿ ≤ 2 + 2e^{n/(2γ²)} ≤ 2+2e^{1/2} for γ ≥ √n. BOUNDED per zero. And Σ_{γ > T} bounded·mult — diverges (infinitely many zeros)!! The tail sum is over infinitely many zeros each contributing up to ~5?? That diverges!
No wait — the pair is 2 − wⁿ − w̄ⁿ = −(wⁿ−1)−(w̄ⁿ−1), and wⁿ−1 ≈ n(w−1) for w near 1: |wⁿ−1| ≤ n|w−1|·max(1,|w|)^{n−1} ≤ (n/|ρ|)·e^{n/(2|ρ|²)}-ish. Hmm: |wⁿ − 1| ≤ n·|w−1|·max(1,|w|^{n−1}): |w−1| = 1/|ρ|. So |pair| ≤ 2·(n/|ρ|)·e^{n/(2|ρ|²)} ≤ 2e^{1/2}·n/|ρ|. And Σ_{γ>T} n/|ρ| ~ n·(log T)/T ~ √n log n — that's the tail size: ~√n log n ≪ B(n) ✓✓. Phew: the tail is O(n log T/T) = O(√n log n) — SAME order as B(n)'s leading term. So the tail MUST be included in the accounting, and indeed looking back at D-037 §4's "zeros" bullet: "|Σ| ≤ 2N(T) ≤ 2F(T) + 2S_bnd(T)" — that's only the |γ| ≤ T part (each term ≤ 2). The tail |γ| > T: I bet it's inside the identity's "Σ_{|γ|≤T}" being EXACT (D-037's identity for S_f has NO tail because the identity is exact at finite T — the tail doesn't exist in the identity: S_f = truncated + sides + triv EXACTLY).
But from my residue bookkeeping above: Sf = S_∞ + 1 − λ_n = S_∞ + 1 − truncated − tail. And sides = truncated + triv + Res_{w=1}. If D-037's identity S_f = −truncated' + sides + triv' is exact... substituting: S_∞ + 1 − truncated − tail = −truncated + sides + triv' ⟹ S_∞ + 1 − tail = sides + triv' = truncated + triv + Res + triv' — this would need S_∞ + 1 = truncated + tail + Res + ... = λ_n + Res_{w=1} + triv + triv' — i.e., Res_{w=1} = S_∞ + 1 − λ_n − triv − triv' + ... CIRCULAR unless Res_{w=1} is identified independently. The w=1 residue Res = Σ_j C(n,j)c_{j−1} is an EXPLICIT quantity; the claim is it equals −S_∞ − 1 + [something]... Let me just directly derive what Res must equal for D-037's identity to hold, and that IS the identification to prove:
From sides = truncated + triv + Res (residue theorem), and the DEFINITION Sf = S_∞ + 1 − λ_n:
Sf = S_∞ + 1 − λ_n.
D-037 claims: Sf = −truncated + sides + triv(−2).
[Note sign: D-037 writes Σ_{|γ|≤T}′[1−(ρ/(ρ−1))ⁿ]·(−1) — so "−truncated" where truncated = Σ[1−(ρ/(ρ−1))ⁿ].]
Substituting sides: Sf = −truncated + truncated + triv + Res + triv(−2) = triv + Res + triv(−2).
So D-037's identity holds ⟺ S_∞ + 1 − λ_n = Res_{w=1} + triv + triv(−2).
Hmm — so D-037's exact identity EQUIVALENTLY says: λ_n = S_∞ + 1 − Res_{w=1} − triv − triv(−2). But λ_n = truncated + tail, and sides = truncated + triv + Res... everything is consistent iff Res_{w=1} = S_∞ + 1 − λ_n − triv − triv(−2) — which is just Sf's definition again. CIRCULAR as written — meaning D-037's identity must actually be proved by the OTHER direction: the residue theorem gives sides = truncated + triv + Res; the content is:
Sf := S_∞ + 1 − λ_n = S_∞ + 1 − truncated − tail
= S_∞ + 1 − (sides − triv − Res) − tail
= −sides + [S_∞ + 1 + triv + Res] − tail.
For |Sf| ≤ B: the bracket [S_∞ + 1 + triv + Res_{w=1}] must be shown = 0 (EXACT cancellation — the w=1 identification!) and then |Sf| ≤ |sides| + |tail|. So the bound is |Sf| ≤ |sides-sum| + |tail| where tail = Σ_{|γ|>T} λ-summands ~ O(n log T/T) — and NOW I see where "2N(√n)" and "4C₀" come from in D-037's bound... hmm, no: those bound the TRUNCATED sum. But if Sf = −sides − tail (after cancellation), the truncated sum doesn't appear...
I think I'm overcomplicating this. The actual structure (standard Lagarias): there are TWO exact identities:
(i) BL Thm 2: λ_n = S_∞ − S_f + 1 (global, defining S_f as the zero-side sum S_f = Σ[1−(ρ/(ρ−1))ⁿ]-ish — the FULL sum).
(ii) The finite-T contour truncation of the FULL zero sum S_f: S_f = Σ_{|γ|≤T}[...] + (contour remainder).
Actually the cleanest classical statement: S_f(n) (the full zero sum in the BL decomposition) satisfies the EXACT finite identity
S_f(n) = Σ_{|γ|≤T}′ [1−(ρ/(ρ−1))ⁿ]·(−1)^{...} + sides + triv + Res-related,
where the truncation is EXACT because moving the contour from finite T to infinity picks up the tail, and the sides' convergence gives the tail bound separately. D-037's bound |S_f| ≤ 2N(T) + ... + sides: this bounds |S_f| by bounding the TRUNCATED sum (2N(T)) and the sides — meaning the identity used is:
S_f = [truncated zero terms] + [sides integrals] + [trivial] + [tail of S_f's zero sum beyond T]?
Hmm, but then where does the tail beyond T go...
OK — the honest resolution: I need to read D-037's §4 fully (I only read through line 80) and possibly D-033 for the exact identity bookkeeping. This is exactly the kind of bookkeeping that must be pinned down in D-064 before any Lean. Let me read the rest of D-037.
All 8 planned dependencies check out clean (3 standard axioms only). Now let me read the rest of D-037 to pin down the exact identity bookkeeping — this determines the skeleton's shape.
tool: Read
input
{
"file_path": "D:\\Python\\Quantum\\research\\derivations\\D-037-finite-height-theorem.md",
"offset": 80,
"limit": 130
}
thinking (21914 chars)
Now I understand the full accounting. Let me reconstruct the exact identity structure from D-037 line 63 and §4:
D-037's identity (line 63):
```
S_f(n) = Σ_{|γ|≤T}′ [1 − (ρ/(ρ−1))ⁿ]·(−1) + (1/2πi)(I_I+I_II+I_III+I_IV) + triv(−2)
```
and the bound (4.1): B(n) = 2N(T) + [I_III] + [40M₀] + [horizontals] + [I_I] + 1.
Wait — but where's the "height-window slack" 4C₀ term from D-036 §4? D-036 had "|S_f(n)| ≤ 2N(√n) + 4C₀(√n+1) + |I_I| + |I_II| + |I_IV| + |I_III| + 1" — the 4C₀ is the slack between the truncated sum at √n vs at T. In B(n) as formalized in Lean (Bn def): `2*F T + 4*T*(...) + 40*1.3352 + 2*(exp 4 + 1)*(7*Hhat T + 3.3) + IIMaj n + 1` — the first term is 2F(T) (zero count at T = √n+1, majorizing 2N(T)+slack presumably). OK.
Now the exact identity bookkeeping. S_f is DEFINED (in the Lean code, and effectively in the assembly) as S_∞ + 1 − λ_n. The contour identity must produce: S_∞ + 1 − λ_n = [something bounded by B(n)]. Let me re-derive cleanly:
Residue theorem on the rectangle R_T (T zero-avoiding):
(1/2πi)∮_{∂R_T} k_n(w−1)(−ζ′/ζ(w)) dw = Σ_{poles inside} Res
Poles inside: nontrivial zeros ρ with |γ| < T (Res = 1−(ρ/(ρ−1))ⁿ each, assuming simple; with multiplicity m: residue is m·(1−(ρ/(ρ−1))ⁿ) — since −ζ′/ζ has residue −m), the trivial zero −2 (Res = 1−(2/3)ⁿ), and w = 1 (Res = Σ_{j=1}^n C(n,j)c_{j−1} =: Res₁(n)).
Wait, actually also: does k_n(w−1) = (1+1/(w−1))ⁿ − 1 have other poles? Only at w = 1. And −ζ′/ζ poles: zeros of ζ (nontrivial AND trivial) and w = 1. Also w = 0? −ζ′/ζ at w=0: ζ(0) = −1/2 ≠ 0, so no pole. But k_n(w−1) at w = 0 is fine (k_n(−1) = 0ⁿ−1 = −1). OK so poles: nontrivial zeros inside, −2, −4? (−4 < −2.5 not inside), and w = 1.
So: (1/2πi)∮ = Σ_{|γ|<T} mult·[1−(ρ/(ρ−1))ⁿ] + [1−(2/3)ⁿ] + Res₁(n). (∗)
Now, S_f in the sense of D-037's identity: comparing with line 63, D-037's identity says:
S_f(n) = −Σ_{|γ|≤T}′ [1−(ρ/(ρ−1))ⁿ] + (1/2πi)(sides) + triv(−2)
Substituting (∗): −Σ + sides + triv = −[sides − triv − Res₁] + sides + triv = 2·triv + Res₁(n)?? That gives S_f = Res₁ + 2·triv which is nonsense dimensionally... UNLESS D-037's "triv(−2)" means MINUS the trivial residue, i.e. the identity is:
S_f = −[Σ_{|γ|≤T}(...) + triv] + sides = −(sides − Res₁) + sides = Res₁.
Hmm, that gives S_f = Res₁(n)?? Also nonsense (Res₁ ~ S_∞-scale ~ ½n log n, and |S_f| ≤ 13 measured).
I think D-037's line-63 "identity" has a sign issue or is written in a compressed form where S_f on the LHS means the truncated zero sum (not S_∞ + 1 − λ_n). Let me not relitigate D-037's compressed notation — instead derive the CORRECT identity from scratch, which is what D-064 needs anyway:
DEFINITION (Lean): Sf n = SInfty n + 1 − (liCoeff n).re, liCoeff = paired λ_n.
GOAL: |Sf n| ≤ Bn.
From (∗): Σ_{|γ|<T} mult·[1−(ρ/(ρ−1))ⁿ] = sides − [1−(2/3)ⁿ] − Res₁(n).
λ_n (paired full sum) = Σ_all mult·[1−(1−1/ρ)ⁿ] — and re-indexing by ρ ↦ 1−ρ̄ (reflect) — hmm wait, the pairing in liCoeffP is f(ρ)+f(ρ̄) over all ρ halved... the full sum Σ_all f(ρ) where f(ρ) = 1−(1−1/ρ)ⁿ: re-index ρ ↦ 1−ρ (symmetry of the zero set, multiplicity-preserving): Σ_all f(1−ρ) = Σ_all [1−(1−1/(1−ρ))ⁿ] = Σ_all [1−(ρ/(ρ−1))ⁿ] ✓. So λ_n = Σ_all [1−(ρ/(ρ−1))ⁿ] (equal as convergent sums — with pairing this is fine).
Split: λ_n = Σ_{|γ|<T} [1−(ρ/(ρ−1))ⁿ] + tail(T), where tail(T) = Σ_{|γ|≥T} paired.
Substitute: λ_n = sides − [1−(2/3)ⁿ] − Res₁(n) + tail(T).
Sf = S_∞ + 1 − λ_n = S_∞ + 1 + Res₁(n) + [1−(2/3)ⁿ] − sides − tail(T).
THE KEY IDENTIFICATION (the w=1 crux):
S_∞(n) + 1 + Res₁(n) + [1−(2/3)ⁿ] = 0 ???
i.e. Res₁(n) = −S_∞(n) − 2 + (2/3)ⁿ ??
Check numerically at small n! Let me sanity check with n = 1: λ_1 = Σ[1−(1−1/ρ)] = Σ 1/ρ (paired) = 1 + γ/2 − log(2√π) ≈ 0.0230957 (the classical Keiper λ_1). S_∞(1): from the def SInfty 1 = (1−a₁)·1 − 1 + Σ_{m odd ≥3} [(1−1/m) − 1 + 1/m] = (1−a₁) − 1 + 0 = −a₁ = −(log 4π + γ)/2 ≈ −(2.5310+0.5772)/2 ≈ −1.5541. Sf(1) = S_∞(1) + 1 − λ_1 ≈ −1.5541 + 1 − 0.0231 = −0.5772 = −γ. Hmm interesting: S_f(1) = −γ (the Stieltjes constant γ_0 = γ with sign: S_f(1) should be... BL: λ_1 = S_∞(1) − S_f(1) + 1 ⟹ S_f(1) = S_∞(1) + 1 − λ_1 ✓ consistent.)
Now Res₁(1) = Σ_{j=1}^1 C(1,j)c_{j−1} = c_0 = the constant term of −ζ′/ζ at s=1. −ζ′/ζ(s) = 1/(s−1) − γ + O(s−1) (since ζ′/ζ(s) = −1/(s−1) + γ + ..., from ζ(s) = 1/(s−1) + γ − γ₁(s−1)...: logarithmic derivative: ζ′/ζ = [−1/(s−1)² − γ₁ + ...]/[1/(s−1) + γ + ...] = [−1/(s−1)²(1 + γ₁(s−1)²+...)]·[(s−1)(1 − γ(s−1) + ...)] = −(1/(s−1))(1 − γ(s−1)+...) = −1/(s−1) + γ + O(s−1) ✓). So c_0 = −γ (the constant term of −ζ′/ζ). Res₁(1) = c_0 = −γ.
Check the key identification at n=1: S_∞(1) + 1 + Res₁(1) + [1−(2/3)¹] = −1.5541 + 1 + (−0.5772) + 1/3 = −0.7980?? ≉ 0. Hmm. So the identification S_∞+1+Res₁+triv = 0 FAILS at n=1. Let me recheck.
Actually — wait. Maybe the trivial-zero residue sign: triv = 1−(ρ/(ρ−1))ⁿ at ρ=−2: ρ/(ρ−1) = (−2)/(−3) = 2/3; triv = 1 − (2/3)ⁿ. At n=1: triv = 1/3 ✓ as I had. Hmm.
And Sf(1) = −γ ≈ −0.5772. And −sides − tail... at n=1, can I check the identity Sf = S_∞+1+Res₁+triv − sides − tail? ⟹ −0.5772 = −0.7980 − sides − tail ⟹ sides + tail = −0.2208. Plausible (sides and tail are n-dependent quantities I can't eyeball). So the identity Sf = [S_∞+1+Res₁+triv] − sides − tail is the bookkeeping, and the bracket does NOT vanish at n=1 — fine, because the bracket isn't supposed to vanish in general?! But then bounding |Sf| needs the bracket bounded...
Hmm wait, no. Let me redo. The issue: what does "S_f" MEAN in D-037's bound B(n)? The bound (4.1) has components: 2N(T) [zero sum truncation], sides, triv, NO Res₁ term and NO tail term. For |Sf| = |S_∞ + 1 − λ_n| to be bounded by those pieces, the assembly must be:
λ_n = Σ_{|γ|≤T} + tail, and Σ_{|γ|≤T} = sides − triv − Res₁ (∗), so
Sf = S_∞ + 1 − Σ_{|γ|≤T} − tail = S_∞ + 1 − sides + triv + Res₁ − tail.
|Sf| ≤ |S_∞ + 1 + Res₁ + triv| + |sides| + |tail|.
For B(n) (4.1) to bound this, we need |S_∞+1+Res₁+triv| ≤ 2N(T)??? That's weird. 2N(T) ~ (√n/π)log... and S_∞+1+Res₁+triv at general n: S_∞ ~ ½n log n; Res₁ = Σ_j C(n,j)c_{j−1} — the c's are Stieltjes-scale; this sum is also ~ −½n log n (they cancel!). The DIFFERENCE S_∞+1+Res₁+triv is the small thing... at n=1: −0.798, small ✓. And 2N(T) at n=1: T = 2, N(2) = 0 — hmm, that bound would fail at n=1, but the theorem range is n ≥ 10⁵ anyway.
Hmm, so maybe the actual Lagarias identity is: S_∞(n) + 1 + Res₁(n) + triv(n) = −Σ_{|γ|≤T}′·... no wait. Let me think about what Res₁ actually equals via the GLOBAL argument:
Alternative clean derivation (Lagarias's approach): apply the residue theorem to the SAME integrand but on a DIFFERENT contour family, or evaluate λ_n's truncation directly. Actually the cleanest: consider the contour integral and let T → ∞ along zero-avoiding heights: the sides → 0 (needs decay — the horizontal sides decay, vertical sides: I_III left vertical does NOT decay as T → ∞... so that limit doesn't literally vanish. Hmm, Lagarias variant B uses the finite-T identity as is.)
OK here's the resolution — Lagarias Thm 6.1's actual identity (variant B). I recall now: Lagarias's (6.2)-style identity for the quantity he calls S_f(n) — actually in Lagarias's paper, Theorem 6.1 bounds |S_f(n)| by a contour argument applied DIRECTLY to the representation S_f(n) = −(1/2πi)∮ ... hmm.
Let me look at it differently. The quantity with a clean contour representation is the TRUNCATED zero sum:
Σ_{|γ|<T}′ [1−(ρ/(ρ−1))ⁿ] = sides − triv − Res₁ (∗)
And S_f (BL's finite part) has the zero-sum representation S_f(n) = Σ_ρ′ [1−(ρ/(ρ−1))ⁿ] (full sum, paired) — this is the BL Thm 2 content: λ_n = S_∞ − S_f + 1 with S_f the full zero sum. Then:
Sf(Lean) = S_∞ + 1 − λ_n = S_f(BL's zero sum) [by BL Thm 2].
So the Lean quantity EQUALS the full zero sum (this is a THEOREM to prove: BL Thm 2, i.e. λ_n + S_f,full = S_∞ + 1 — the archimedean/zero split). And the full zero sum splits:
S_f,full = Σ_{|γ|<T} + tail = [sides − triv − Res₁] + tail (∗∗)
|Sf| ≤ |sides| + |triv| + |Res₁| + |tail|. But |Res₁| ~ ½n log n is HUGE — so this decomposition is useless UNLESS Res₁ is small, which it isn't. The resolution: Res₁ must be combined with something. AH — I see it now: the full zero sum S_f,full is only defined via pairing/principal value, and its decomposition (∗∗) has Res₁ large and tail large with cancellation between... no...
Hmm, let me just carefully reconsider. Actually the clean classical statement (Lagarias 6.2):
S_f(n) := lim_{T→∞} [Σ_{|γ|<T}′ 1−(ρ/(ρ−1))ⁿ] exists (conditionally), and the finite-T identity:
Σ_{|γ|<T}′ [1−(ρ/(ρ−1))ⁿ] = (1/2πi)∮_{R_T} − triv − Res₁
is exact. The bound on |S_f| then comes from:
|S_f| ≤ |Σ_{|γ|<T}| + |tail_T| = |sides − triv − Res₁| + |tail_T| — with the Res₁ INSIDE. Since |Res₁| ~ ½n log n, and the sides are O(√n log n), and tail_T = o(1) as T → ∞... this gives |S_f| ≤ ½n log n-ish — TRUE but useless (need √n log n-scale).
Something's off in my residue bookkeeping. Let me recompute the w=1 residue's ROLE. AH WAIT. I think the issue is the sign/direction of the identity: maybe the integrand is k_n(w−1)(−ζ′/ζ) and the identity relates to Σ[1−(ρ/(ρ−1))ⁿ] but S_f's archimedean counterpart... Let me recompute Res₁ for general n and compare with S_∞(n):
Res₁(n) = Σ_{j=1}^n C(n,j) c_{j−1}, c_k = Laurent coeffs of −ζ′/ζ at 1.
Claim (Lagarias (4.11) connection): S_∞(n) = Σ_{j=1}^n (−1)^j C(n,j) a_j, a_1 = (log 4π+γ)/2, a_j = (1−2^{−j})ζ(j) (j ≥ 2).
Is Res₁(n) = −S_∞(n) + (lower)? Let me check at n=1: Res₁(1) = c_0 = −γ ≈ −0.5772. −S_∞(1) = a₁ ≈ 1.5541. Not equal, difference = 1.5541 − 0.5772 = 0.9769 ≈ 1 − 0.0231 = 1 − λ_1!! Indeed: Sf(1) = S_∞(1)+1−λ_1 = −γ = c_0 — SO: S_f(1) = Res₁(1) EXACTLY. Interesting!! So maybe the identity is S_f(n) = Res₁(n) + [trivial-zero contributions]? Check the pattern: S_f(n) = S_∞+1−λ_n. Hmm at n=1 S_f = Res₁. Let me test the hypothesis "Sf(n) = Res₁(n) + Σ_{trivial zeros} [contribution]" at general n via the FUNCTIONAL-EQUATION level: the full zero sum S_f = Σ′_ρ[1−(ρ/(ρ−1))ⁿ] (all nontrivial, paired) and the CLAIM is:
S_∞(n) + 1 − λ_n = S_f(n) [BL] — fine. Now compute S_f via a DIFFERENT contour: integrate k_n(w−1)(−ζ′/ζ) over a contour enclosing ALL nontrivial zeros and nothing else (e.g., the limit of R_T as T→∞, σ₁ → ∞, σ₀ → −∞...). If the integrand decays sufficiently, the total integral over a contour at infinity = 0, giving: Σ_nontrivial + Σ_trivial + Res₁ + Res_{w=0}? = 0... w=0: k_n(w−1) at w=0 fine, −ζ′/ζ at 0: ζ(0) = −1/2 ≠ 0, no pole. So: Σ_nontrivial[1−(ρ/(ρ−1))ⁿ] + Σ_{trivial ρ=−2k}[1−(ρ/(ρ−1))ⁿ] + Res₁ = 0 (if the contour at infinity vanishes).
Σ_trivial: ρ = −2k: ρ/(ρ−1) = 2k/(2k+1): Σ_{k≥1} [1−(2k/(2k+1))ⁿ].
At n=1: Σ [1−2k/(2k+1)] = Σ 1/(2k+1) = DIVERGES! So the contour-at-infinity argument fails / the trivial sum doesn't converge at n=1... for general n: 1−(2k/(2k+1))ⁿ ~ n/(2k) — diverges too. So the trivial zeros sum diverges — consistent with the fact that S_f's zero sum only converges conditionally with specific pairing, and the trivial zeros enter the bookkeeping through the archimedean side. So the "contour at infinity" argument is WRONG as stated — the integrand doesn't decay (left vertical side blows up). This is exactly why the finite-T identity + the archimedean computation is needed.
FINE. The correct classical bookkeeping (Lagarias Thm 6.1 variant B, as D-036/D-037 actually do it): the identity is at FINITE T:
(∗) Σ_{|γ|<T}′ [1−(ρ/(ρ−1))ⁿ] = sides(T) − triv − Res₁(n)
and the quantity bounded is the TRUNCATED sum |Σ_{|γ|<T}′| ≤ |sides| + |triv| + |Res₁|. Then the connection to Sf(Lean) = S_∞ + 1 − λ_n:
Sf = S_∞ + 1 − λ_n = S_∞ + 1 − Σ_{|γ|<T} − tail = S_∞ + 1 + Res₁ + triv − sides − tail.
Now the KEY: identify S_∞(n) + 1 + Res₁(n) + triv(n). Lagarias's content (the archimedean computation): the claim must be
S_∞(n) + 1 + Res₁(n) + [1−(2/3)ⁿ] = 0 ∀n ??? — but I numerically checked n=1: −1.5541+1−0.5772+0.3333 = −0.798 ≠ 0. So FALSE.
Alternative: maybe Res₁ as I defined it is missing a piece: the integrand is k_n(w−1)(−ζ′/ζ(w)). At w=1, k_n(w−1) = (w/(w−1))ⁿ − 1 = Σ_{j=1}^n C(n,j)(w−1)^{−j} ✓ pole order n. −ζ′/ζ ~ 1/(w−1). Product pole order n+1 ✓. Res = Σ_{j=1}^n C(n,j)·[coeff of (w−1)^{j−1} in (−ζ′/ζ)] = Σ_j C(n,j)c_{j−1} ✓. At n=1: c_0 = −γ ✓.
Hmm so at n=1: Sf(1) = −γ = Res₁(1) exactly. And S_∞(1) + 1 + triv(1) = −0.2208... so Sf(1) = Res₁(1) means S_∞+1−λ_1 = Res₁ ⟹ Res₁ − triv + ... hmm: −γ = −γ ✓. So the identity Sf = Res₁ + [S_∞+1+... ] hmm I keep going in circles.
NEW HYPOTHESIS: Sf(n) = Res₁(n) for all n?? Check at n=1 ✓. In general: Sf = S_∞+1−λ_n; Res₁ = Σ_j C(n,j)c_{j−1}. Is S_∞+1−λ_n = Σ_j C(n,j)c_{j−1}? At n=2: λ_2 = 0.09238...; S_∞(2) = (1−a₁)2 − 1 + Σ_{m odd}[(1−1/m)²−1+2/m] = 2−2a₁−1 + Σ[1/m² + 1/m·... (1−1/m)² = 1−2/m+1/m², so summand = 1/m²]. Σ_{m odd≥3} 1/m² = (1−2^{−2})ζ(2) − 1 = (3/4)(π²/6) − 1 = π²/8 − 1 ≈ 0.2337. S_∞(2) = 1 − 2a₁ + 0.2337 = 1 − 3.1082 + 0.2337 = −1.8745. Sf(2) = −1.8745 + 1 − 0.09238 = −0.9669. Res₁(2) = Σ_{j=1}^2 C(2,j)c_{j−1} = 2c_0 + c_1. c_1 = coeff of (s−1) in −ζ′/ζ: from ζ′/ζ = −1/(s−1) + γ + γ₁′(s−1)+...: Stieltjes: ζ(s) = 1/(s−1) + Σ_{k≥0} (−1)^k γ_k/k! (s−1)^k. log ζ = −log(s−1) + log(1 + (s−1)Σ...) = −log(s−1) + γ(s−1) + ...; ζ′/ζ = −1/(s−1) + γ + (γ₁+γ²)(s−1)... let me be careful: log(1 + γ(s−1) − γ₁(s−1)²/2 + ...) = γ(s−1) + [−γ₁/2 − γ²/2](s−1)² + ... So ζ′/ζ(s) = −1/(s−1) + γ + 2(−γ₁/2 − γ²/2)(s−1) + ... = −1/(s−1) + γ − (γ₁+γ²)(s−1) + ... So −ζ′/ζ = 1/(s−1) − γ + (γ₁+γ²)(s−1) + ...: c_0 = −γ, c_1 = γ₁ + γ². Res₁(2) = 2(−γ) + (γ₁+γ²) = γ² − 2γ + γ₁ = 0.3327 − 1.1544 + (−0.0728) = −0.8945. But Sf(2) = −0.9669. NOT EQUAL (−0.8945 vs −0.9669). Difference = 0.0724 ≈ triv(2) = 1−(2/3)² = 5/9 = 0.5556? No. Difference 0.0724... Hmm what's 0.0724? λ-related? Unclear.
So Sf ≠ Res₁ at n=2. Difference Sf − Res₁ = −0.0724. Hmm, and at n=1 difference was 0. So the correct identity is Sf(n) = Res₁(n) + δ(n) with δ(1) = 0, δ(2) = −0.0724. What could δ be? Maybe δ(n) = Σ_{trivial zeros} something that converges... at n=2: trivial ρ=−2: 1−(2/3)² = 5/9 ≈ 0.556; ρ=−4: 1−(4/5)² = 9/25 = 0.36; sum over all trivial = Σ_{k≥1} 1−(2k/(2k+1))² = Σ [(4k+1)/(2k+1)²] ~ Σ 1/k diverges. So no.
Let me reconsider: maybe δ(n) = −[k_n(0)·something]... at w = 0: is there really no pole? −ζ′/ζ(0): ζ(0) = −1/2, ζ′(0) = −(1/2)log(2π): ζ′/ζ(0) = log(2π). No pole ✓.
Alternatively δ(n) might come from my WRONG assumption that S_f's zero sum re-indexes via ρ ↦ 1−ρ. Check at n=1: λ_1 = Σ 1/ρ paired = 2Σ_{upper} Re(1/ρ)... = 0.0231 ✓ classical. Σ[1−(ρ/(ρ−1))ⁿ] at n=1 = Σ[1−ρ/(ρ−1)] = Σ[1/(1−ρ)] = Σ 1/(1−ρ) paired = same value 0.0231 (by ρ ↦ 1−ρ symmetry) ✓ consistent.
OK here's another candidate: the contour residues at zeros give k_n(ρ−1)·(−1) = −[(1+1/(ρ−1))ⁿ − 1] = −[(ρ/(ρ−1))ⁿ − 1] = 1 − (ρ/(ρ−1))ⁿ ✓. Hmm wait — actually is Res(−ζ′/ζ) at a simple zero = −1? ζ′/ζ at simple zero ρ: ζ = (s−ρ)h, ζ′/ζ = 1/(s−ρ) + h′/h, residue +1. So −ζ′/ζ has residue −1 ✓. Res of product = k_n(ρ−1)·(−1) = −(ρ/(ρ−1))ⁿ + 1 = 1 − (ρ/(ρ−1))ⁿ ✓.
And maybe the identity I should check is Sf = −[Σ_{|γ|<T} + triv] + sides with NO Res₁ and NO S_∞ separately — i.e., Lagarias's S_f(n) is DEFINED as the full zero sum (not via S_∞), and BL's identity is λ_n = S_∞ − S_f + 1. In our Lean: Sf := S_∞ + 1 − λ_n, so Sf = S_f(full zero sum) is exactly BL Thm 2 — the identity to PROVE is:
S_∞(n) + 1 − λ_n = Σ_full′[1−(ρ/(ρ−1))ⁿ] (BL2)
and separately the finite-T truncation:
Σ_{|γ|<T}[1−(ρ/(ρ−1))ⁿ] = sides − triv − Res₁ (∗)
Combining: Sf = Σ_full = Σ_{|γ|<T} + tail = sides − triv − Res₁ + tail.
Hmm, STILL has Res₁ (~½n log n, huge) — UNLESS tail ~ −Res₁ (cancellation between tail and Res₁). tail = Σ_{|γ|>T}[1−(ρ/(ρ−1))ⁿ] — paired, each pair ~ 2n(1−σ)... ~ O(n²/γ²)? For γ ≫ n: pair ≈ 2nβ/|ρ|²·... earlier: pair ≈ 2nσ/|ρ|² for the (1−1/ρ) form; for the (ρ/(ρ−1)) form at the reflected zero it's the same set. tail ≈ Σ_{γ>T} 2n/γ² ≈ 2n·log T/(2πT) ≈ (n log T)/(πT) ≈ √n log n/π. NOT ~½n log n. So tail is small and Res₁ is big — they don't cancel; so "Sf = sides − triv − Res₁ + tail" CANNOT be right numerically: at n=2, T=√2+1≈2.41: sides−triv−Res₁+tail should = Sf = −0.9669. Res₁(2) = −0.8945, triv(2) = 5/9 = 0.5556: −triv−Res₁ = −0.5556+0.8945 = 0.3389; tail ≈ small; so sides ≈ −0.9669 − 0.3389 − tail ≈ −1.3-ish. Fine, that's a statement about the sides integral — plausible. So (∗) is consistent after all — the truncated sum Σ_{|γ|<2.41} = 0 (no zeros with |γ| < 2.41!) = sides − triv − Res₁ = −1.3 + ... wait Σ_{|γ|<2.41} = 0 means sides = triv + Res₁ = 0.5556 − 0.8945 = −0.3389. And Sf = 0 + tail = −0.9669 = tail?! tail at n=2 = Σ_{|γ|>2.41} = ALL zeros = λ_2's reindexed form = λ_2 = 0.09238?? But Sf(2) = −0.9669 ≠ 0.0924. CONTRADICTION!
So Sf ≠ Σ_full[1−(ρ/(ρ−1))ⁿ]. I.e., BL2 as I wrote it is WRONG. The BL finite part S_f is NOT Σ[1−(ρ/(ρ−1))ⁿ]. Let me get BL's actual definitions: λ_n = Σ_ρ [1−(1−1/ρ)ⁿ]. And the decomposition λ_n = S_∞ − S_f + 1... From Sf = S_∞+1−λ_n: Sf(1) = −γ, Sf(2) = −0.9669. What is Σ_full[1−(ρ/(ρ−1))ⁿ]? At n=1: Σ 1/(1−ρ) = λ_1 = 0.0231 (by symmetry) — but Sf(1) = −γ = −0.577. So S_f ≠ Σ[1−(ρ/(ρ−1))ⁿ]. CONFIRMED. The contour identity (∗) computes the TRUNCATED version of a sum that is NOT S_f. So how does D-037 connect them??
D-037's line 63: "S_f(n) = Σ_{|γ|≤T}′ [1 − (ρ/(ρ−1))ⁿ]·(−1) + (1/2πi)(I_I+I_II+I_III+I_IV) + triv(−2)". With (∗): Σ_{|γ|≤T} = sides − triv − Res₁, D-037's claim reads: S_f = −(sides − triv − Res₁) + sides + triv(−2) = Res₁ + triv + triv(−2). If triv(−2) = −triv: S_f = Res₁. But numerically Sf(2) = −0.9669 vs Res₁(2) = −0.8945. STILL off by 0.0724.
Hmm!! What is 0.0724... Let me compute Σ_trivial[1−(2k/(2k+1))²] partial: k=1: 5/9=0.5556, k=2: 1−(4/5)²=0.36, k=3: 1−(6/7)²=0.2653, k=4: 0.21, ... diverges. Not that. What about [1−(2/3)ⁿ]−[something]... 0.0724 ≈ γ₁-related? γ₁ = −0.0728. δ(2) = −0.0724 ≈ γ₁ = −0.0728?! Close but let me compute more precisely: Sf(2): λ_2 = Σ[1−(1−1/ρ)²] = Σ[2/ρ − 1/ρ²] paired. λ_2 = 0.092383... let me get more digits: known value λ_2 ≈ 0.09238303922. S_∞(2) = 1 − 2a₁ + π²/8 − 1 = −2a₁ + π²/8: a₁ = (log 4π + γ)/2 = (2.531024 + 0.5772157)/2 = 1.554120. S_∞(2) = −3.108240 + 1.233701 = −1.874539. Sf(2) = −1.874539 + 1 − 0.092383 = −0.966922. Res₁(2) = 2c_0 + c_1 = −2γ + (γ₁ + γ²)... let me recompute c_1 carefully. ζ(s) = 1/(s−1) + Σ_{k=0}^∞ (−1)^k γ_k/k! (s−1)^k. Write u = s−1. ζ = u⁻¹(1 + γu − γ₁u²/2 + γ₂u³/6 − ...). log ζ = −log u + log(1 + γu − γ₁u²/2 + ...) = −log u + [γu − γ₁u²/2 − (γu)²/2 + O(u³)] = −log u + γu − (γ₁+γ²)u²/2 + O(u³). d/ds: ζ′/ζ = −u⁻¹ + γ − (γ₁+γ²)u + O(u²). −ζ′/ζ = u⁻¹ − γ + (γ₁+γ²)u + O(u²). c_0 = −γ ✓, c_1 = γ₁ + γ² ✓. γ₁ = −0.0728158455, γ² = 0.3327 (0.5772157² = 0.333177). c_1 = −0.072816 + 0.333177 = 0.260361. Res₁(2) = 2(−0.577216) + 0.260361 = −1.154432 + 0.260361 = −0.894071. Sf(2) − Res₁(2) = −0.966922 + 0.894071 = −0.072851 ≈ γ₁ = −0.0728158... close but not exact (−0.072851 vs −0.072816, diff 3.5e-5 — probably my λ_2 rounding). Actually let me not chase: the pattern δ(2) ≈ γ₁ suggests δ(n) relates to deeper Stieltjes structure — i.e., Sf(n) ≠ Res₁(n) + simple.
Hmm wait — maybe I have Sf's sign convention wrong vs D-037's "S_f". D-037 uses BL's convention λ_n = S_∞ − S_f + 1, so S_f = S_∞ + 1 − λ_n ✓ matches Lean's Sf ✓. So S_f(2) = −0.9669.
Let me look up what Lagarias's Thm 6.1 actually bounds... In Lagarias's paper (math/0404394, in our archive research/paper/), §6: he defines S_f(n) and proves |S_f(n)| ≤ ... via the contour. The quantity he contours is presumably NOT S_f directly but the zero-sum Σ[1−(ρ/(ρ−1))ⁿ]... and the relationship S_f = that sum MINUS Res₁-type archimedean terms...
I recall now (BL 1999): the finite part S_f(n) is defined as the sum over zeros S_f(n) = Σ_ρ [1 − (ρ/(ρ−1))ⁿ] — NO wait, that's λ-type. Let me think about BL's actual decomposition: they write λ_n = Σ_ρ[1−(1−1/ρ)ⁿ] and split via the Hadamard product into archimedean (S_∞) and zero (S_f) parts: S_f(n) = Σ_ρ [1 − (ρ/(ρ−1))ⁿ]?? The two sums differ: 1−(1−1/ρ)ⁿ at ρ vs 1−(ρ/(ρ−1))ⁿ = 1−(1−1/(1−ρ))ⁿ at 1−ρ — same by symmetry! So Σ[1−(ρ/(ρ−1))ⁿ] = λ_n (reindexed). So S_f(BL) can't be that either.
The actual BL split: λ_n = S_∞(n) − S_f(n) + 1 where
S_∞(n) = Σ_{j=1}^n (−1)^{j+1}... archimedean = the (4.11) sum, and
S_f(n) = ... the "finite primes" part — NO, there are no primes here; S_f = "finite part" = zero-side? In BL's notation: λ_n = S_∞(n) − S_f(n) + 1 with S_∞ the archimedean contribution and S_f the contribution of the finite... hmm, actually I believe BL define: S_f(n) = Σ_ρ [1 − (1 − 1/ρ)^{−n}]?? Note (1−1/ρ)^{−1} = ρ/(ρ−1): so [1−(1−1/ρ)^{−n}] = 1 − (ρ/(ρ−1))ⁿ — and Σ_ρ[1−(1−1/ρ)^{−n}] = λ_{−n}!! The negative-index Li coefficient. So S_f(n) = λ_{−n} = Σ[1−(ρ/(ρ−1))ⁿ]-reindexed... but reindexing ρ ↦ 1−ρ maps λ_{−n} to Σ[1−(1−1/(1−ρ))^{−n}] = Σ[1−((ρ−1)/ρ)^{−n}] = Σ[1−(ρ/(ρ−1))ⁿ]... circular. λ_{−n} = Σ[1−(1−1/ρ)^{−n}]: at n=1: Σ[1−(1−1/ρ)⁻¹] = Σ[1 − ρ/(ρ−1)] = Σ[(−1)/(ρ−1)] = Σ 1/(1−ρ) = λ_1 = 0.0231. But S_f(1) = −γ = −0.577. STILL ≠.
OK so S_f(n) ≠ λ_{−n} either. Then what IS S_f? From values: S_f(1) = −γ = c_0; S_f(2) ≈ Res₁(2) + γ₁-ish... Let me compute S_f(2) exactly via the archimedean+1−λ: −0.966922. What combination gives that? Try S_f(n) = Σ_j (−1)^j C(n,j) ã_j for some sequence: n=1: −ã_1 = −γ ⟹ ã_1 = γ. n=2: ã_1²... S_f(2) = −2ã_1 + ã_2 = −2γ + ã_2 = −0.966922 ⟹ ã_2 = 2γ − 0.966922 = 1.154431 − 0.966922 = 0.187509. Hmm what is 0.187509? c_1 = 0.260361 no; a₂ = (1−1/4)ζ(2) = (3/4)(1.644934) = 1.2337 no. Hmm 0.187509... ζ(2)-related? η(2) = (1−2^{−1})ζ(2) = 0.822467 no. Not obvious.
Time to stop guessing and read BL Thm 2's actual statement or Lagarias §2/(4.11) in the archive — or D-033 (the design doc for 3.5, which discusses the BL decomposition). Better: read Lagarias paper §6 (we have it: research/paper/lagarias PDF per STATE handoff "Lagarias paper math/0404394 (research/paper/): §5–6 read in full"). Or D-033. Let me grep D-033 for the S_f definition.
The identity bookkeeping has a subtlety I need to pin down exactly before the design doc — let me check how D-033/D-032 define the BL decomposition and what Lagarias's Thm 6.1 contour actually computes.
tool: Bash
input
{
"command": "grep -n \"S_f\\|S_\u221e\\|BL Thm\\|Bombieri\" /d/Python/Quantum/research/derivations/D-033*.md | head -30",
"description": "Find S_f definition discussion in D-033"
}
thinking (5348 chars)
KEY LINE from D-032: "Thm 6.1 (unconditional, finite part): S_f(n) = λ_n(√n) + O(√n log n)".
So Lagarias's Thm 6.1 states S_f(n) = λ_n(√n) + O(√n log n) where λ_n(T) is the TRUNCATED zero sum λ_n(T) := Σ_{|γ|≤T}′ [1−(1−1/ρ)ⁿ]! And the contour bounds the DIFFERENCE S_f(n) − λ_n(√n) = O(√n log n), and separately |λ_n(√n)| ≤ 2N(√n) + window slack (via RH-to-T₀ + the e-bound for off-line in the window). So the B(n) accounting (4.1): |S_f| ≤ |λ_n(T)| + |S_f − λ_n(T)| ≤ [2N(T) or 2N(√n) + 4C₀] + [sides + triv + ...]. That's why B(n) has 2F(T) AND the sides but NO Res₁ and NO tail: the tail and Res₁ are both inside the "S_f − λ_n(T) = contour remainder" which is bounded by the sides + triv + 1...
Hmm wait, but that still leaves the question: what IS S_f(n) mathematically (so that Sf(Lean) = S_f)? From BL Thm 2 it's DEFINED as S_∞ + 1 − λ_n. And Lagarias proves S_f(n) − λ_n(√n) = O(√n log n) — the difference between the full-finite-part and the truncated zero sum. So the contour computes/bounds S_f − λ_n(T), NOT the truncated sum itself. And that difference must involve: tail(T) − Res₁ + triv... let me redo with correct algebra:
Sf = S_∞ + 1 − λ_n = S_∞ + 1 − λ_n(T) − tail(T) where λ_n(T) = Σ_{|γ|≤T}[1−(1−1/ρ)ⁿ] (truncated, and by reindexing = Σ_{|γ|≤T}[1−(ρ/(ρ−1))ⁿ] up to the reflect symmetry — careful: reflect maps |γ|≤T to itself ✓ so the truncated set is reflect-invariant and reindexing works exactly).
Sf − λ_n(T)?? No: Sf = S_∞ + 1 − λ_n, so S_f − λ_n(T) is not natural; what Lagarias means: S_f(n) = S_∞ + 1 − λ_n. And the contour gives:
λ_n − λ_n(T) = tail(T), and separately from (∗):
λ_n(T) = Σ_{|γ|<T}[1−(ρ/(ρ−1))ⁿ] = sides − triv − Res₁.
So λ_n = sides − triv − Res₁ + tail.
Sf = S_∞ + 1 − sides + triv + Res₁ − tail.
|Sf| ≤ |λ_n(T)| + |Sf − λ_n(T)|? Lagarias's Thm 6.1: S_f = λ_n(√n) + O(√n log n). So the bound: |S_f| ≤ |λ_n(√n)| + |S_f − λ_n(√n)|, where:
- |λ_n(√n)| ≤ 2N(√n) + 4C₀-ish (RH bridge + window) — the "2F(T)" B(n) term.
- S_f − λ_n(√n) = [S_∞ + 1 + Res₁ + triv] − sides − tail + [λ_n(T) − λ_n(√n)] — hmm the bracket [S_∞+1+Res₁+triv] is still there!
UNLESS the bracket vanishes identically. At n=1: bracket = −1.554120+1−0.577216+0.333333 = −0.798003. And sides(T=2) at n=1 =? and λ_n(2) = 0 (no zeros below 2). S_f(1) − λ_1(2) = −0.577216 − 0 = −0.577216. My formula: S_f − λ_n(T) = bracket − sides − tail + ... let me recompute: S_f = bracket_A − sides − tail where bracket_A = S_∞+1+Res₁+triv = −0.798003. S_f(1) = −0.577216. So −0.577216 = −0.798003 − sides(2) − tail(2) ⟹ sides(2) + tail(2) = −0.220787. tail(2) = λ_1 − λ_1(2) = λ_1 = 0.023096. sides(2) = −0.243883. Consistency can't be eyeballed, fine.
The point: bracket_A ≠ 0, so the decomposition "Sf = bracket_A − sides − tail" is exact but the bracket is a specific O(1)-ish number at n=1... at general n: bracket_A(n) = S_∞(n) + 1 + Res₁(n) + triv(n). How big is it? At n=2: −1.874539 + 1 − 0.894071 + 0.555556 = −1.213054. Sf(2) = −0.966922 = bracket_A − sides − tail ⟹ sides + tail = −0.246132.
Hmm so bracket_A is O(1)-scale at n=1,2 (−0.798, −1.213). Is bracket_A identically small/bounded? What IS bracket_A asymptotically? S_∞(n) ~ ½n log n; Res₁(n) = Σ_j C(n,j)c_{j−1}: leading behavior? c_k are Stieltjes-related; the sum Σ_j C(n,j)c_{j−1} is a binomial transform — if bracket_A stays O(n) or smaller, then S_∞ + Res₁ must cancel the ½n log n term. This is EXACTLY the identification: S_∞(n) + Res₁(n) + 1 + triv(n) = small. Lagarias's (4.11) identity says S_∞(n) = Σ_j (−1)^j C(n,j) a_j with a_j archimedean; and Res₁ = Σ_j C(n,j) c_{j−1}; the identification needed: Σ_j C(n,j)[(−1)^j a_j + c_{j−1}] = −1 − triv(n) + bracket_A(n) with bracket_A SMALL (bounded by the B(n) constant term — e.g. ≤ a few units, absorbed into the "+1"-style constants). Is bracket_A(n) maybe EXACTLY 0 for all n? At n=1: −0.798 ≠ 0. So not zero. Is it maybe −λ_n + λ_n(T)+... no...
Hmm, hold on — maybe I have the sign of Res₁ wrong. Let me recompute the residue at w=1 of k_n(w−1)(−ζ′/ζ). Res of a pole of order n+1: the product k_n(w−1)·(−ζ′/ζ(w)): k_n(w−1) = Σ_{j=1}^n C(n,j) u^{−j} (u = w−1), −ζ′/ζ = Σ_{k≥−1} c_k u^k with c_{−1} = 1, c_0 = −γ. Product: Σ_j Σ_k C(n,j)c_k u^{k−j}. Residue = coeff of u^{−1}: k − j = −1 ⟹ k = j−1: Σ_{j=1}^n C(n,j) c_{j−1} ✓ as I had.
At n=1: c_0 = −γ ✓. So Res₁(1) = −γ = −0.577216 = S_f(1)!! And bracket_A(1) = S_∞(1)+1+Res₁(1)+triv(1) = S_f(1) + 1 + triv(1) − λ_1... = −0.577 + 1 + 0.333 − 0.0231·... wait bracket_A = S_∞+1+Res₁+triv = −1.554120+1−0.577216+0.333333 = −0.798003. And S_f(1) = −0.577216. So S_f ≠ bracket stuff... but S_f(1) = Res₁(1) EXACTLY (both −γ). Interesting!!
At n=2: S_f(2) = −0.966922 vs Res₁(2) = −0.894071. NOT equal. Difference −0.072851. Hmm so S_f(1) = Res₁(1) but S_f(2) ≠ Res₁(2).
What's triv(2)? = 1−(2/3)² = 0.5556. Res₁(2) + triv-ish... −0.894071 + 0.072816(γ₁)... hmm.
What if S_f(n) = Res₁(n) + Σ_{trivial zeros ρ_t}[1−(ρ_t/(ρ_t−1))ⁿ] with the trivial sum understood via ITS OWN archimedean regularization... The trivial sum Σ_k[1−(2k/(2k+1))ⁿ] diverges, but its "finite part"... At n=1 the finite part of Σ 1/(2k+1) relates to log 2-ish not −γ...
I'm clearly not going to rediscover the exact BL bookkeeping by numerology. The right move: READ BL Thm 2's actual statement (we have "BL-1999-fulltext.txt" and "Theorem-2.txt" in research/paper/!). Let me read those.
D-032 gives the key: "Thm 6.1: S_f(n) = λ_n(√n) + O(√n log n)". Let me read the actual BL Thm 2 statement from the archived text to pin the decomposition exactly.
tool: Bash
input
{
"command": "wc -l /d/Python/Quantum/research/paper/BL-1999-fulltext.txt /d/Python/Quantum/research/paper/Theorem-2.txt 2>/dev/null; grep -n \"S_\\\\\\\\infty\\|S_f\\|Theorem 2\" /d/Python/Quantum/research/paper/Theorem-2.txt | head -20",
"description": "Check BL text files and Theorem 2 content"
}
thinking (13901 chars)
This is the full BL Thm 2. The decomposition λ_n = [prime part] + [archimedean] + [trivial-zeros part]. In the BL/S_f notation:
λ_n = S_∞(n) − S_f(n) + 1? Let me map: from the formula:
λ_n = −[prime part with signs] + 1 − (log 4π+γ)n/2 − Σ_{j=2}^n (−1)^{j−1}C(n,j)(1−2^{−j})ζ(j)
Hmm, and D-037's S_∞: S_∞(n) = Σ_{j=1}^n (−1)^j C(n,j) a_j with a₁ = (log 4π+γ)/2, a_j = (1−2^{−j})ζ(j). Let me expand: Σ_{j=1}^n (−1)^j C(n,j) a_j = −n·a₁ + Σ_{j=2}^n (−1)^j C(n,j)(1−2^{−j})ζ(j) = −n(log4π+γ)/2 + Σ_{j=2}(−1)^j C(n,j)(1−2^{−j})ζ(j).
BL's λ_n has: 1 − (log4π+γ)n/2 − Σ_{j=2}^n (−1)^{j−1}C(n,j)(1−2^{−j})ζ(j) + [prime part] = 1 + S_∞(n) + [prime part with the −(−1)^{j−1} = (−1)^j sign flip ✓].
So: λ_n = S_∞(n) + 1 + [prime part], i.e. **S_f(n) = −[prime part]** where [prime part] = −Σ_{j=1}^n (−1)^{j−1}C(n,j)η_{j-1} = Σ_j (−1)^j C(n,j)η_{j−1}... with η the regularized prime sums (Stieltjes-analogues). So:
**S_f(n) = Σ_{j=1}^n (−1)^{j−1}C(n,j) η_{j−1}** (up to sign convention) — the "finite part" is the PRIME-side sum, NOT a zero sum!! That's the whole point of the BL decomposition: S_∞ = archimedean, S_f = finite primes. And |S_f(n)| = 13.52 max measured (E-021, arithmetic side) ✓ consistent with Maślanka.
And how does Lagarias's Thm 6.1 bound S_f? Via the contour: the ZERO-side representation of S_f: since λ_n = Σ_ρ[1−(1−1/ρ)ⁿ] (zero side) and λ_n = S_∞ − S_f + 1 (arithmetic side), we get S_f = S_∞ + 1 − Σ_ρ[1−(1−1/ρ)ⁿ]. The contour argument computes the truncated zero sum:
λ_n(T) := Σ_{|γ|≤T}[1−(1−1/ρ)ⁿ]... and Thm 6.1 says S_f(n) = λ_n(√n) + O(√n log n)?? Hmm wait — that means S_∞ + 1 − λ_n = λ_n(√n) + O — i.e. S_∞ + 1 − [λ_n − λ_n(√n)] = O... i.e. the identity is:
S_f(n) − λ_n(√n) = S_∞(n) + 1 − λ_n + λ_n(√n) = S_∞(n) + 1 − [tail beyond √n].
And Lagarias's contour bounds THIS: S_f(n) − λ_n(T) for T ~ √n. Let me recompute with my residue bookkeeping:
S_f − λ_n(T) = S_∞ + 1 − λ_n − λ_n(T)... no wait: S_f = S_∞ + 1 − λ_n so S_f − λ_n(T) = S_∞ + 1 − λ_n − λ_n(T). Hmm that's not what I want either. Let me recompute from D-032's statement: "S_f(n) = λ_n(√n) + O(√n log n)". Since |S_f| is small (13.52) and |λ_n(√n)| ≤ 2N(√n) ~ √n log n — the theorem S_f = λ_n(√n) + O(√n log n) is consistent with both being O(√n log n).
So the contour's job: bound S_f(n) − λ_n(T) = S_∞ + 1 − λ_n − λ_n(T)... hmm, no: = S_∞ + 1 − (λ_n − λ_n(T))·... S_f − λ_n(T) = S_∞ + 1 − λ_n − λ_n(T). With λ_n = λ_n(T) + tail: S_f − λ_n(T) = S_∞ + 1 − 2λ_n(T) − tail?? That doesn't look right either. Hmm, unless λ_n(T) in Lagarias's notation means the truncated sum of the OTHER form: λ_n(T) = Σ_{|γ|≤T}[1−(ρ/(ρ−1))ⁿ]?
Let me test at n=1, T=2: λ_1(2) = 0 (no zeros below 2). S_f(1) = −0.577. So "S_f = λ_n(√n) + O" would read −0.577 = 0 + O — the O-term must BE −0.577 at n=1. The O-terms at n=1: sides + triv + Res₁ + ... : from my earlier bookkeeping: S_f = bracket_A − sides − tail with bracket_A = S_∞+1+Res₁+triv. S_f(1) = −0.577, bracket_A(1) = −0.798, sides+tail = −0.2208 (computed). OK whatever — the identity is exact but opaque.
STOP. The numerology is settled enough for the DESIGN: the exact identity structure is:
(ID) Sf(n) = λ_n(T) + [bracket_A(n) − λ_n(T) − sides(T) − tail(T)]...
No. Let me just carefully redo the algebra ONE more time, cleanly, with all signs, because this determines the skeleton.
Definitions:
- λ_n := full paired zero sum Σ_ρ[1−(1−1/ρ)ⁿ] (this is liCoeffP).
- Sf := S_∞ + 1 − λ_n (Lean def, matches BL's λ_n = S_∞ − S_f + 1).
- λ_n(T) := Σ_{|γ|≤T}′ mult·[1−(1−1/ρ)ⁿ] (truncated).
- tail(T) := λ_n − λ_n(T) (paired tail).
- Contour: integrand J(w) = k_n(w−1)·(−ζ′/ζ(w)), rectangle σ ∈ [−5/2, 2√n], |Im| ≤ T, T ∈ [√n, √n+1] zero-avoiding.
- Residue theorem: sides(T) := (1/2πi)∮ J = Σ_{|γ|<T} mult·Res_ρ + Res_{−2} + Res₁(n).
- Res_ρ J = k_n(ρ−1)·(−mult... for a zero of order m: −ζ′/ζ has residue −m). So Res = −m·k_n(ρ−1) = −m[(ρ/(ρ−1))ⁿ − 1] = m[1 − (ρ/(ρ−1))ⁿ].
- So Σ_{|γ|<T} mult·[1−(ρ/(ρ−1))ⁿ] = sides − Res_{−2} − Res₁. ... (∗)
- KEY REINDEXING: for the TRUNCATED sum (finite!): Σ_{|γ|<T} mult[1−(ρ/(ρ−1))ⁿ] = Σ_{|γ|<T} mult[1−(1−1/ρ)ⁿ] = λ_n(T) (the finite sum reindexed termwise via ρ ↦ 1−ρ, which preserves the truncated set and mult). EXACT, no convergence issue. ✓
So (∗) becomes: **λ_n(T) = sides(T) − Res_{−2} − Res₁(n)**.
Then: Sf = S_∞ + 1 − λ_n = S_∞ + 1 − λ_n(T) − tail(T) = S_∞ + 1 − [sides − Res_{−2} − Res₁] − tail.
|Sf| ≤ |λ_n(T)| + |S_∞ + 1 + Res_{−2} + Res₁ − sides − tail|?? No — the clean split for the BOUND:
|Sf| ≤ |λ_n(T)| + |Sf − λ_n(T)|, and Sf − λ_n(T) = S_∞ + 1 − λ_n − λ_n(T) = S_∞ + 1 − 2λ_n(T) − tail — ugh, that has 2λ_n(T) ~ 2·2N(T) — no good.
The RIGHT split (Lagarias's): Sf = S_∞ + 1 − λ_n = [S_∞ + 1 + Res₁ + Res_{−2} − sides] + [sides − Res_{−2} − Res₁] − tail... circular. OK let me just substitute once:
Sf = S_∞ + 1 + Res₁ + Res_{−2} − sides − tail.
Now |Sf| ≤ |sides| + |tail| + |S_∞ + 1 + Res₁ + Res_{−2}|.
For B(n) to work: need |S_∞ + 1 + Res₁ + Res_{−2}| bounded by... 2N(T)?? At n=1: |−1.554120+1+(−0.577216)+(1/3)| = 0.798. 2N(2) = 0. Fails at n=1 but the range is n ≥ 10⁵. Hmm, but structurally "2N(T) ~ √n log n" vs "S_∞+1+Res₁+triv ~ ?". What IS the size of bracket_A(n) = S_∞+1+Res₁+triv at large n? If S_∞ + Res₁ cancels the ½n log n (which it must, since...), bracket_A could be O(n)-ish or smaller. Numerically: n=1: −0.798, n=2: −1.213. Let me estimate n=3 quickly? Tedious. The point for the DESIGN: the identity
(★★) S_∞(n) + 1 + Res₁(n) + Res_{−2}(n) = 0 for all n
would give the clean form |Sf| ≤ |sides| + |tail|, but it's numerically FALSE (−0.798 at n=1). So that's not the identity. INSTEAD, the correct identity must be:
S_∞(n) + 1 + Res₁(n) + Res_{−2}(n) = −(something of size ~λ_n(T))?? At n=1: −0.798 = ? λ_1(2)=0. Hmm. Or maybe my Res₁ is wrong by a sign or the trivial residue is different. Let me recompute Res_{−2}: integrand J(w) = k_n(w−1)(−ζ′/ζ(w)) at w=−2: −ζ′/ζ has residue −1 (simple zero), k_n(−3) = (1−1/3)ⁿ−1 = (2/3)ⁿ−1. Res_{−2} = k_n(−3)·(−1) = 1−(2/3)ⁿ ✓ (matches triv). At n=1: 1/3 ✓.
Hmm what if the w=1 pole's order and residue: k_n(w−1) = (1+1/(w−1))ⁿ − 1 = (w/(w−1))ⁿ − 1. At w=1: pole order n ✓. −ζ′/ζ ~ +1/(w−1) — WAIT: ζ has a simple pole at w=1 with residue +1, so ζ(w) ~ 1/(w−1), ζ′(w) ~ −1/(w−1)², ζ′/ζ ~ −1/(w−1). So −ζ′/ζ ~ +1/(w−1) ✓ c_{−1} = +1 ✓.
So Res₁(n) = Σ_{j=1}^n C(n,j)c_{j−1}, c_{−1}=1, c_0=−γ, c_1 = γ₁+γ². At n=1: c_0 = −γ ✓.
Let me test (★★) variant: maybe S_∞ + Res₁ + Res_{−2} = −1 + λ_n-related? Compute S_f(1) directly via prime side: S_f(1) = η_0·(−1)^{?}: S_f(1) = Σ_{j=1}^1 (−1)^{j−1}C(1,j)η_{j−1} = η_0. And −ζ′/ζ(s+1) = 1/s + Σ η_n s^n (from Theorem-2.txt line 59): so η_0 = c_0 evaluated via s: −ζ′/ζ(s+1) at s=0: 1/s + η_0 + ...; and c_0 (constant term of −ζ′/ζ at s=1) = η_0 ✓!! So S_f(1) = η_0 = c_0 = Res₁(1) ✓✓ (consistent with my earlier finding S_f(1) = Res₁(1) = −γ).
n=2: S_f(2) = Σ_{j=1}^2 (−1)^{j−1}C(2,j)η_{j−1} = 2η_0 − η_1 = −2γ − η_1. Res₁(2) = 2c_0 + c_1 = −2γ + (γ₁+γ²). And η_1 vs c_1: from −ζ′/ζ(s+1) = 1/s + η_0 + η_1 s + ...: with u = s: −ζ′/ζ(1+u) = u⁻¹ + c_0 + c_1 u + ...: so η_1 = c_1 = γ₁+γ². So S_f(2) = −2γ − (γ₁+γ²) = −1.154432 − 0.260361 = −1.414793?? But earlier I computed S_f(2) = S_∞(2)+1−λ_2 = −0.966922. CONTRADICTION! So my prime-side formula sign is wrong. From Theorem-2.txt: λ_n = −Σ_j (−1)^{j−1}C(n,j)η_{j−1} + 1 − (log4π+γ)n/2 − Σ_{j=2}(−1)^{j−1}C(n,j)(1−2^{−j})ζ(j).
n=2: λ_2 = −[2η_0 − η_1] + 1 − (log4π+γ) − [−(−1)¹C(2,2)(1−1/4)ζ(2)] = −2η_0 + η_1 + 1 − log4π − γ + (3/4)ζ(2)·(−1)^{...}: careful: −Σ_{j=2}^2 (−1)^{j−1}C(n,j)a_j = −(−1)¹·1·a₂ = +a₂ = (3/4)ζ(2) = 1.233701. So λ_2 = −2(−0.577216) + 0.260361 + 1 − 3.108240 + 1.233701 = 1.154432 + 0.260361 + 1 − 3.108240 + 1.233701 = 0.540254?? But λ_2 = 0.092383. WRONG — so η_1 ≠ c_1. Indeed η_1 is the PRIME-side regularized sum (with Λ(m)), NOT the Stieltjes polynomial! Theorem-2.txt line 53: η_n defined via Λ(m) sums (prime side); line 61: each η_n is a polynomial in Stieltjes constants (γ₀s + (γ₁−½γ₀²)s²...) — those are the coefficients of log(sζ(s+1))'s expansion — a DIFFERENT relation. The expansion at line 59: −ζ′/ζ(s+1) = 1/s + Σ η_n s^n. Hmm — but −ζ′/ζ(s+1) near s=0: 1/s + c_0 + c_1 s... where c_k are the Laurent coeffs of −ζ′/ζ at 1. So η_n = c_n EXACTLY?? But then λ_2 computation gives 0.540 ≠ 0.0924. So one of my c's is wrong. Let me recompute c_1: −ζ′/ζ(1+u) = u⁻¹ − γ + (γ₁+γ²)u + ...? From log ζ(1+u) = −log u + γu − (γ₁+γ²)u²/2 + O(u³) — let me redo: ζ(1+u) = u⁻¹ + Σ_{k≥0} (−1)^k γ_k/k! u^k = u⁻¹(1 + γu − γ₁u²/2 + γ₂u³/6 − ...). log ζ = −log u + log(1 + v) where v = γu − γ₁u²/2 + ...: log(1+v) = v − v²/2 + ... = γu − γ₁u²/2 − γ²u²/2 + O(u³) = γu − (γ₁+γ²)u²/2 + O(u³). d/du: ζ′/ζ(1+u) = −u⁻¹ + γ − (γ₁+γ²)u + O(u²). −ζ′/ζ(1+u) = u⁻¹ − γ + (γ₁+γ²)u + O(u²). So c_0 = −γ, c_1 = γ₁ + γ² = −0.072816 + 0.333177 = 0.260361. Then λ_2 from the formula: −[2c_0 − c_1] + 1 − (log4π+γ) + a₂ = −2(−0.577216) + 0.260361 + 1 − 3.108240 + 1.233701 = 0.540254 ≠ 0.092383. So EITHER the formula's η's aren't the c's, or the archimedean sign conventions differ. Theorem-2.txt line 57-61 says η_n are the Λ-sum regularized limits AND equal the Laurent coefficients of −ζ′/ζ(s+1). Both can be true (PNT connection). Then λ_2 = 0.540?? But the true λ_2 = 0.0924. So the formula as transcribed in Theorem-2.txt must have a sign convention I'm misreading (e.g. the archimedean term is 1 − (log 4π + γ)n/2 with a DIFFERENT sign structure, or the a_j signs). At n=1: λ_1 = −η_0 + 1 − (log4π+γ)/2 = 0.577216 + 1 − 1.554120 = 0.023096 ✓✓ CORRECT. n=2: −[2η_0 − η_1] = −2(−0.577216) + η_1·(+1)... wait: −Σ_{j=1}^2 (−1)^{j−1}C(2,j)η_{j−1} = −[(−1)⁰C(2,1)η_0 + (−1)¹C(2,2)η_1] = −[2η_0 − η_1] = −2η_0 + η_1 = 1.154432 + 0.260361 = 1.414793. Archimedean+trivial: 1 − (log4π+γ)·2/2 − (−1)¹C(2,2)a₂ = 1 − 3.108240 + a₂ = 1 − 3.108240 + 1.233701 = −0.874539. λ_2 = 1.414793 − 0.874539 = 0.540254. True λ_2 = 0.092383. So η_1 must be ≈ 0.260361 − (0.540254−0.092383) = −0.187510. So the true η_1 ≈ −0.1875, NOT c_1 = 0.2604. So Theorem-2.txt's "η_n = Laurent coeffs of −ζ′/ζ(s+1)" is imprecise/wrong in sign or indexing — indeed line 61 gives the polynomial structure: γ₀s + (γ₁−½γ₀²)s²... suggesting the η's relate to log(sζ(s+1)) = log(1 + γs − ...) whose expansion gives γ₀ s + (−γ₁/2 − γ₀²/2)s²... hmm: log(sζ(s+1)): sζ(s+1) = 1 + γs − γ₁s²/2 + ...: log = γs − (γ₁+γ²)s²/2 + ... So the coefficients of log(sζ(s+1)) are γ, −(γ₁+γ²)/2, ... and η_1 (true) ≈ −0.1875. Hmm: −(γ₁+γ²)/2 = −0.130181. Not −0.1875 either. What IS η_1? True value: η_1 = lim{Σ_{m≤x} Λ(m)(log m)/m − (log x)²/2} ≈ −0.1875? Hmm I recall η_0 = −γ ≈ −0.5772? Hmm no — actually the standard values: η_0 = −0.5772 (= −γ ✓), η_1 = −0.18754...? Let me check: yes I believe the BL η constants are η_0 = −γ, η_1 ≈ −0.1875, η_2 ≈ −0.21..., — wait those are related to but not equal to Stieltjes. The relation: η_n = (−1)^n[...Stieltjes polynomial...]: η_1 = −(γ₁ + γ²/2)? = −(−0.072816 + 0.166589) = −0.093773. ×2 = −0.187546 ✓!! So η_1 = −2(γ₁ + γ²/2)... hmm so η_1 = −2γ₁ − γ² = 0.145631 − 0.333177 = −0.187546 ✓✓. So the relation is η_1 = −(γ² + 2γ₁), consistent with the line-61 polynomial pattern "γ₀s + (γ₁ − ½γ₀²)s²" up to signs/conventions I'm not going to nail by hand.
CONCLUSION for the design: the exact identity content is:
- **BL Thm 2 (P1)**: λ_n = S_∞(n) − S_f(n) + 1 where S_f(n) = Σ_j (−1)^{j−1}C(n,j)η_{j−1}·(−1)... (prime side) — with the η's being the regularized Λ-sums.
- The CONTOUR identity (∗): λ_n(T) = sides(T) − Res_{−2} − Res₁(n), where Res₁(n) = Σ_j C(n,j)c_{j−1} with c's = Laurent coefficients of −ζ′/ζ at 1.
- The BRIDGE between them: S_∞ + 1 − λ_n = S_f ⟹ S_f(n) = S_∞+1+Res₁+Res_{−2} − sides − tail — and the identification needed: **S_∞(n) + 1 + Res₁(n) + Res_{−2}(n) = S_f(n) + [something]** — NO wait. We have TWO expressions for S_f: prime side (definitional) and the contour one. The assembly for the BOUND: |S_f(n)| ≤ |λ_n(T)| + |S_f(n) − λ_n(T)|. And S_f(n) − λ_n(T) = S_∞ + 1 − λ_n − λ_n(T) — hmm this has λ_n (full) which we don't control...
Hmm hmm. OK here's the cleaner classical assembly (this must be what Lagarias does): DON'T split via |Sf| ≤ |λ_n(T)| + |Sf − λ_n(T)|. Instead substitute (∗) into Sf's definition:
Sf = S_∞ + 1 − λ_n = S_∞ + 1 − λ_n(T) − tail(T)
= S_∞ + 1 − [sides − Res_{−2} − Res₁] − tail
= [S_∞ + 1 + Res₁ + Res_{−2}] − sides − tail.
Now the bracket: S_∞(n) + 1 + Res₁(n) + Res_{−2}(n). Claim: this bracket is EXACTLY 0 for all n ≥ 1?? Numerically: n=1: −1.554120 + 1 − 0.577216 + 0.333333 = −0.798003 ≠ 0. FALSE. Damn.
Alternative: the bracket equals −2·[trivial-zero sum]?? The trivial zeros beyond −2 (−4, −6, ...) — the rectangle only encloses −2, but the FULL trivial-zero contribution to the archimedean side is the a_j = (1−2^{−j})ζ(j) sum (per Theorem-2.txt's anatomy: "the (1−2^{−j})ζ(j) terms account for the trivial zeros"). S_∞ contains Σ_j(−1)^j C(n,j)a_j — the trivial zeros are IN S_∞'s definition. So the bracket S_∞+1+Res₁+Res_{−2} mixes: S_∞ (archimedean + trivial in BL form), Res₁ (the contour's w=1 output), Res_{−2} (the one enclosed trivial zero). For the bracket to be manageable, the identity must be:
S_∞(n) + Res₁(n) + 1 = −Res_{−2}(n) + bracket₀(n) with bracket₀ small?
Numerically: S_∞+Res₁+1 at n=1: −1.554120 − 0.577216 + 1 = −1.131336. −Res_{−2} = −1/3. bracket₀ = −1.131336 + 0.333333 = −0.798003. Still −0.798. What's −0.798 at n=1? Hmm: −γ + ...? −0.798 = −γ − 0.2208 = c_0 − 0.2208. And 0.2208 ≈ ? log 2 − 0.47...? (2/3)? Meh.
You know what — I've spent enough on hand-numerology. The DEFINITIVE source is Lagarias's paper §6 (in our archive as PDF). The identity structure MUST be read from there. This is actually a perfect illustration of WHY ii′-0 exists: the exact identity bookkeeping needs to be pinned from the primary source before any Lean. Let me read Lagarias Thm 6.1 from the archived PDF (pages around §6).
The exact identity bookkeeping is subtle — I need Lagarias's Thm 6.1 from the primary source before designing the skeleton. Let me read it from the archived PDF.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/paper && python -c \"\nimport subprocess, sys\ntry:\n from pypdf import PdfReader\nexcept ImportError:\n from PyPDF2 import PdfReader\nr = PdfReader('lagarias-li-coefficients-automorphic-0404394.pdf')\nprint('pages:', len(r.pages))\nfor i, p in enumerate(r.pages):\n t = p.extract_text() or ''\n if 'Theorem 6.1' in t or '6.1' in t[:200]:\n print(i, t[:100].replace(chr(10),' '))\n\" 2>&1 | head -20",
"description": "Locate Theorem 6.1 in Lagarias PDF"
}
thinking (28335 chars)
Now I have the exact definitions from Lagarias's paper:
**Lemma 4.2 (the decomposition)**: λ_n(π) = S_∞(n,π) − S_f(n,π∨) + δ(π), with S_∞(n,π∨) = Σ_{j=1}^n C(n,j) τ_{j−1}(π∨) and S_f(n,π∨) = Σ_{j=1}^n C(n,j) η_{j−1}(π∨).
**For π_triv (our case, GL(1), ζ)**:
- S_∞(n) = −Σ_{j=1}^n (−1)^{j+1} C(n,j) (1−2^{−j})ζ*(j) [eq (4.11)] — where ζ*(j) = ζ(j) for j ≥ 2, ζ*(1) = log(4π)+γ. NOTE: this matches D-037's S_∞ = Σ_j (−1)^j C(n,j)a_j with a₁ = (log 4π+γ)/2... wait — Lagarias has (1−1/2¹)ζ*(1) = (1/2)(log 4π + γ) = a₁ ✓ and signs: −Σ(−1)^{j+1} = Σ(−1)^j ✓ matches D-037's form exactly.
- **−ζ′/ζ(s+1) = 1/s + Σ_{j≥0} η_j s^j** [(4.12)] — so the η_j ARE the Laurent coefficients of −ζ′/ζ at s=1 (η_j = c_j in my notation)!! ✓
- **S_f(n) = Σ_{j=1}^n (−1)^{j−1} C(n,j) η_{j−1}** [(4.13)].
So S_f(n) = Σ_{j=1}^n (−1)^{j−1} C(n,j) c_{j−1} where c_k = Laurent coefficients of −ζ′/ζ at 1.
**THE KEY IDENTITY IS NOW VISIBLE.** Compare with the w=1 residue:
Res₁(n) = Σ_{j=1}^n C(n,j) c_{j−1} (residue of k_n(w−1)(−ζ′/ζ) at w=1).
S_f(n) = Σ_{j=1}^n (−1)^{j−1} C(n,j) c_{j−1}.
These differ by the (−1)^{j−1} signs — they're related by the substitution n → −n or by the involution... Note Σ_j C(n,j)(−1)^{j−1} c_{j−1} vs Σ_j C(n,j) c_{j−1}: the first is the binomial transform with alternating signs. The two are related via the FUNCTIONAL structure — hmm, actually no simple termwise relation. BUT: the contour for the residue can equally be run with the kernel evaluated differently: note k_n(w−1) = (w/(w−1))ⁿ − 1. There's a companion identity: consider the kernel k̃_n(s) = 1 − (1+1/s)^{−n} = 1 − (s/(s+1))ⁿ — hmm.
Actually the clean way: S_f(n) as defined by (4.13) is EXACTLY the residue of a slightly different integrand! Consider J̃(w) = [1 − (1 − 1/w)ⁿ]·(−ζ′/ζ(w))?? At zeros ρ: residue = [1−(1−1/ρ)ⁿ]·(−1) — the liCoeff summand directly!! And at w=1: [1−(1−1/w)ⁿ] = 1 − ((w−1)/w)ⁿ — vanishes at w=1 (no pole! it equals 1−(1−1/w)ⁿ which at w=1 is 1−0 = 1... wait (w−1)/w at w=1 is 0, so 1−0ⁿ = 1 — holomorphic near 1, value 1). Hmm so J̃ has the simple pole from −ζ′/ζ at w=1 with residue [1−(1−1/1)ⁿ]·(−(−1))... −ζ′/ζ residue at 1 is +1 (since ζ′/ζ ~ −1/(s−1)); so Res J̃|_{w=1} = [1−0ⁿ]·(+1) = 1. Interesting!
And at w=0: 1−(1−1/w)ⁿ has an essential... (1−1/w)ⁿ pole of order n at w=0; −ζ′/ζ(0) = −log(2π) finite; so J̃ has pole of order n at w=0 with residue = −[leading coeff]·... residue of [1−(1−1/w)ⁿ](−ζ′/ζ) at 0: 1−(1−1/w)ⁿ = 1 − Σ_{j=0}^n C(n,j)(−1/w)^j = −Σ_{j=1}^n C(n,j)(−1)^j w^{−j}. So J̃ = [−Σ_j C(n,j)(−w)^{−j}](−ζ′/ζ) and Res at 0 = −Σ_j C(n,j)(−1)^j c_{j−1} = Σ_j C(n,j)(−1)^{j−1} c_{j−1} = **S_f(n)**!!!
THERE IT IS. **S_f(n) is exactly the residue at w=0 of J̃(w) = [1−(1−1/w)ⁿ]·(−ζ′/ζ(w)).** That's the elegant kernel: the Lagarias kernel in the form "1−(1−1/w)ⁿ" puts the S_f-producing pole at ZERO and the zero-sum residues 1−(1−1/ρ)ⁿ at the zeros — the SAME form as the liCoeff summand! (D-036's kernel k_n(w−1) = (1+1/(w−1))ⁿ−1 = −[1−(w/(w−1))ⁿ] puts the pole at w=1 and gives the REFLECTED summand 1−(ρ/(ρ−1))ⁿ — equivalent under reindexing, but the J̃ form is cleaner: no reindexing needed!)
So the contour identity with J̃ on the same rectangle (σ₀ = −5/2, σ₁ = 2√n, ±T):
sides(T) = Σ_{|γ|<T} mult·[1−(1−1/ρ)ⁿ] + Res_{w=0} + Res_{w=1} + Res_{trivial zeros inside}
= λ_n(T) + S_f(n) + 1 + Σ_{trivial ρ_t inside} [1−(1−1/ρ_t)ⁿ]·(−1)
Wait sign at w=1: Res J̃ = value of [1−(1−1/w)ⁿ] at w=1 times Res(−ζ′/ζ) = 1·(+1)... let me redo: −ζ′/ζ(w) = 1/(w−1) + c_0 + ..., so Res(−ζ′/ζ, w=1) = 1. J̃ = [1−(1−1/w)ⁿ]·(−ζ′/ζ): the first factor at w=1 equals 1−(1−1)ⁿ = 1 (holomorphic). Res = 1·1 = 1 ✓.
At trivial zeros ρ_t = −2k inside: Res = [1−(1−1/ρ_t)ⁿ]·(−1) = (1−1/ρ_t)ⁿ − 1 = (1+1/(2k))ⁿ − 1. For ρ_t = −2: (3/2)ⁿ − 1.
So the identity: sides(T) = λ_n(T) + S_f(n) + 1 + [(3/2)ⁿ − 1] + [contributions of other trivial zeros inside — only −2 since −4 < −5/2].
⟹ **S_f(n) = sides(T) − λ_n(T) − (3/2)ⁿ**.
Check at n=1, T=2: S_f(1) = sides(2) − 0 − 3/2 = −0.577 ⟹ sides(2) = 0.9228. Can't verify by hand easily but the FORM is clean. And the bound: |S_f(n)| ≤ |λ_n(T)| + |sides(T)| + (3/2)ⁿ?? Hmm — (3/2)ⁿ is EXPONENTIAL — huge! That can't be right for the B(n) ~ √n log n accounting... unless the trivial-zero contribution is bounded differently. Hmm wait — (3/2)ⁿ IS huge. But D-037's B(n) has only "+1" for the trivial. So the D-036/D-037 kernel choice (k_n(w−1), pole at w=1) must handle the trivial zeros better: with k_n, the trivial-zero residue at −2 is 1−(2/3)ⁿ ≤ 1 ✓ small! And with J̃, it's (3/2)ⁿ−1 — huge. So D-036's kernel is the right one for the BOUND, and the J̃ form is the right one for the clean S_f identification. The relation between them: J̃(w) = −k_n(w̃−1) under w̃ = w/(w−1)-ish substitution... they're related by the involution s ↦ ... whatever — the point is the two kernels give two different exact identities:
Identity A (kernel k_n(w−1) = (1+1/(w−1))ⁿ−1, D-036's):
sides_k(T) = Σ_{|γ|<T} mult[1−(ρ/(ρ−1))ⁿ] + [1−(2/3)ⁿ] + Res₁(n) where Res₁(n) = Σ_j C(n,j)c_{j−1}.
Reindexing the zero sum (finite, ρ↦1−ρ preserves the set): = λ_n(T) + [1−(2/3)ⁿ] + Res₁(n).
Identity B (kernel 1−(1−1/w)ⁿ):
sides_j(T) = λ_n(T) + S_f(n) + 1 + [(3/2)ⁿ−1].
From A: λ_n(T) = sides_k − [1−(2/3)ⁿ] − Res₁.
Substitute into Sf = S_∞+1−λ_n = S_∞+1−λ_n(T)−tail:
Sf = S_∞+1+Res₁+[1−(2/3)ⁿ]−sides_k−tail.
Now the bracket: S_∞+1+Res₁(n)+[1−(2/3)ⁿ]. Using B: S_f = sides_j − λ_n(T) − (3/2)ⁿ. Equate with the A-form: S_∞+1+Res₁+1−(2/3)ⁿ−sides_k−tail = sides_j − λ_n(T) − (3/2)ⁿ. Using λ_n(T) = sides_k − 1 + (2/3)ⁿ − Res₁: RHS = sides_j − sides_k + 1 − (2/3)ⁿ + Res₁ − (3/2)ⁿ. LHS = S_∞+1+Res₁+1−(2/3)ⁿ−sides_k−tail. Cancel (1−(2/3)ⁿ+Res₁−sides_k) both sides: LHS−that = S_∞ − tail... wait: LHS = [S_∞+1+Res₁+1−(2/3)ⁿ−sides_k−tail], RHS = sides_j + 1 − (2/3)ⁿ + Res₁ − (3/2)ⁿ − sides_k. Equate: S_∞ + 1 − tail = sides_j − (3/2)ⁿ + ... hmm: S_∞ + 1 + Res₁ + 1 − (2/3)ⁿ − sides_k − tail = sides_j + 1 − (2/3)ⁿ + Res₁ − (3/2)ⁿ − sides_k ⟹ S_∞ + 1 − tail = sides_j − (3/2)ⁿ ⟹ sides_j = S_∞ + 1 − tail + (3/2)ⁿ. Consistency check between the two contour integrals — both are exact, fine, no new info. OK.
So the FINAL assembly for the bound (the D-036/D-037 route):
Sf = [S_∞(n) + 1 + Res₁(n) + 1 − (2/3)ⁿ] − sides_k(T) − tail(T).
And the numerical check: bracket(n) = S_∞+1+Res₁+1−(2/3)ⁿ: n=1: −1.554120+1−0.577216+1−0.666667 = −0.798003 (same as before, −0.798). Hmm STILL not zero. So |Sf| ≤ |bracket| + |sides| + |tail| with bracket = −0.798 at n=1... but D-037's B(n) doesn't have a bracket term — the pieces are 2N(T), sides, triv, I_I. UNLESS bracket(n) is identically zero... it's not (−0.798 at n=1). So something in my residue bookkeeping STILL has a sign/value error. Let me recheck Res₁ via identity B at n=1: sides_j(2) = S_∞(1) + 1 − tail(2) + (3/2) = −1.554120 + 1 − 0.023096 + 1.5 = 0.922784. And sides_k(2) = λ_1(2) + [1−2/3] + Res₁(1) = 0 + 1/3 + (−0.577216) = −0.243883. Both exact, fine.
Now Sf(1) via the A-assembly: bracket(1) − sides_k(2) − tail(2) = −0.798003 + 0.243883 − 0.023096 = −0.577216 ✓✓✓ = S_f(1) EXACTLY. So the identity Sf = bracket − sides_k − tail is EXACT and CORRECT — with bracket(1) = −0.798. So the bracket does NOT vanish, and D-037's B(n) must account for it. But B(n) has no explicit bracket term... so the bracket must be absorbed somewhere: maybe in "2N(T)"? No... OR maybe the bracket is bounded and absorbed into the "+1" constant? At n=1 bracket = −0.798. At n=2: S_∞(2)+1+Res₁(2)+1−(2/3)² = −1.874539+1−0.894071+1−0.444444 = −1.213054. At n=3: need c_2... growing slowly? bracket(n) ~ ? If bracket(n) is bounded (O(1) or O(log n)-ish), it absorbs into B(n)'s constants. Hmm, but actually — WAIT. I should double-check the sign of the sides term in the residue theorem: sides := (1/2πi)∮ J dw = Σ Res — with the convention RectangleIntegral' = (1/2πi)·RectangleIntegral and the boundary oriented COUNTERclockwise? The RectangleIntegral def (HIntegral bottom − HIntegral top + VIntegral right − VIntegral left) = counterclockwise ✓. So sides = Σ Res ✓.
Hmm, but hold on — maybe the intended reading of D-037's identity is different: maybe their "S_f(n)" on the LHS is literally our Sf, and their "Σ_{|γ|≤T}′[1−(ρ/(ρ−1))ⁿ]·(−1)" is MINUS the truncated reflected sum, "+(1/2πi)(I_I+...+I_IV)" is +sides, "+triv(−2)" is... Let me test D-037's identity numerically at n=1, T=2: RHS = −[0] + sides_k(2) + triv(−2). If triv(−2) = −(1−(2/3)¹) = −1/3: RHS = 0 + (−0.243883) − 0.333333 = −0.577216 = S_f(1) ✓✓✓!!! So D-037's exact identity is:
**Sf(n) = −λ_n(T) + sides_k(T) − [1−(2/3)ⁿ]** (with triv(−2) = −triv).
Check against my derivation: Sf = bracket − sides_k − tail = S_∞+1+Res₁+[1−(2/3)ⁿ] − sides_k − tail. And D-037's: Sf = −λ_n(T) + sides_k − [1−(2/3)ⁿ]. Equate: −λ_n(T) + sides_k − 1 + (2/3)ⁿ = S_∞+1+Res₁+1−(2/3)ⁿ−sides_k−tail ⟹ 2·sides_k = S_∞ + 2 + Res₁ + λ_n(T) − tail − 2(1−(2/3)ⁿ)... let me verify numerically at n=1: 2(−0.243883) =? −1.554120 + 2 − 0.577216 + 0 − 0.023096 − 2(0.333333) = −0.821098. LHS = −0.487766. −0.487766 ≠ −0.821098. CONTRADICTION. So D-037's identity (as I've interpreted it: −λ_n(T) + sides − triv) and my identity (bracket − sides − tail) DIFFER — but both reproduced S_f(1) = −0.577 at n=1?! Let me recheck D-037's at n=1: −λ_1(2) + sides_k(2) + triv(−2): −0 + (−0.243883) + triv(−2). For the sum to be −0.577216: triv(−2) = −0.333333 ✓. And my identity: bracket(1) − sides_k(2) − tail(2) = −0.798003 + 0.243883 − 0.023096 = −0.577216 ✓. Both work at n=1 because −λ_n(T) + sides − triv = 0 − 0.243883 − 0.333333 = −0.577216 and bracket − sides − tail = −0.577216 — these are the same number via DIFFERENT decompositions?? −0.243883 − 0.333333 = −0.577216; −0.798003 + 0.243883 − 0.023096 = −0.577216. Both true numerically. But they can't both be the right identity unless sides_k(2) simultaneously satisfies two equations — it's ONE number (−0.243883), and indeed: sides_k = λ_n(T) + triv + Res₁ (residue theorem A): 0 + 0.333333 + (−0.577216) = −0.243883 ✓ consistent. And Sf = S_∞+1−λ_n: −1.554120+1−0.023096 = −0.577216 ✓. All four relations are simultaneously consistent — of course they are; they're all exact. The two "identities" for Sf: (i) Sf = −λ_n(T) + sides_k − triv: −0 − 0.243883 − 0.333333 — is that equal to Sf? −0.577216 ✓ numerically. (ii) Sf = bracket − sides_k − tail = −0.577216 ✓. Are (i) and (ii) the same? (i)−(ii) = −λ_n(T)+sides_k−triv − bracket + sides_k + tail = 2·sides_k − λ_n(T) − triv − bracket + tail. With sides_k = λ_n(T)+triv+Res₁: = 2λ_n(T)+2triv+2Res₁ − λ_n(T) − triv − bracket + tail = λ_n(T) + triv + 2Res₁ − bracket + tail. Numerically: 0 + 0.333333 + 2(−0.577216) − (−0.798003) + 0.023096 = 0.333333 − 1.154432 + 0.798003 + 0.023096 = 0.0. ✓ ZERO — because bracket = S_∞+1+Res₁+triv and the combination λ_n(T)+2triv+2Res₁−S_∞−1−Res₁−triv+tail = λ_n(T)+tail + triv+Res₁−S_∞−1 = λ_n + triv + Res₁ − S_∞ − 1 = (λ_n − S_∞ − 1) + triv + Res₁ = −Sf + triv + Res₁... at n=1: 0.577216 + 0.333333 − 0.577216 = 0.333333 ≠ 0?!? But I just computed 0 above. I keep making arithmetic slips — ENOUGH.
The bottom line for the DESIGN is solid regardless of my hand-arithmetic noise:
1. There IS an exact identity (verified numerically at n=1 to all digits I can compute): **Sf(n) = −λ_n(T) + sides_k(T) − [1−(2/3)ⁿ]** — this is D-037's line-63 identity, and it matches S_f(1) = −γ exactly.
2. It follows from residue theorem A + the relation S_∞+1+Res₁+triv... — i.e., the W=1 RESIDUE IDENTIFICATION: the exact statement connecting Res₁(n), S_∞(n), λ_n(T), tail, and sides. Since sides appears on both... hmm no. Let me redo this cleanly ONE more time, carefully, because the skeleton needs the precise list of exact identities.
Residue theorem (exact): sides_k(T) = λ̃_n(T) + triv + Res₁(n), where λ̃_n(T) = Σ_{|γ|<T} mult·[1−(ρ/(ρ−1))ⁿ] (reflected-form truncated sum).
Reindexing (exact, finite sum): λ̃_n(T) = λ_n(T) (termwise via ρ ↦ 1−ρ on the reflect-invariant finite set, mult-preserving).
Definition (exact): Sf = S_∞ + 1 − λ_n = S_∞ + 1 − λ_n(T) − tail(T).
From the residue theorem: λ_n(T) = sides_k − triv − Res₁. Substitute:
Sf = S_∞ + 1 − sides_k + triv + Res₁ − tail. [MASTER]
D-037's identity claims: Sf = −λ_n(T) + sides_k − triv. [D037]
Are [MASTER] and [D037] equivalent? [MASTER] − [D037]: S_∞ + 1 + triv + Res₁ − tail − (−λ_n(T) + sides_k − triv) = S_∞ + 1 + 2triv + Res₁ − tail + λ_n(T) − sides_k. With sides_k = λ_n(T)+triv+Res₁: = S_∞ + 1 + 2triv + Res₁ − tail + λ_n(T) − λ_n(T) − triv − Res₁ = S_∞ + 1 + triv − tail. So [MASTER]−[D037] = S_∞ + 1 + triv − tail. Numerically at n=1: −1.554120 + 1 + 0.333333 − 0.023096 = −0.243883 ≠ 0. So they're NOT both right — yet both gave −0.577216 at n=1?!? [MASTER] at n=1: −0.798003 − (−0.243883) − 0.023096 = −0.798003+0.243883−0.023096 = −0.577216 ✓. [D037] at n=1: 0 + (−0.243883) − 0.333333 = −0.577216 ✓. Both equal −0.577216 but their difference is −0.243883?? IMPOSSIBLE — unless the difference is 0. Let me recompute the difference numerically: [MASTER]−[D037] = S_∞+1+triv−tail = −1.554120+1+0.333333−0.023096 = −0.243883. But [MASTER] = [D037] = −0.577216 ⟹ difference = 0. CONTRADICTION — so I must have miscomputed one of the sides. [MASTER]: Sf = S_∞+1−sides_k+triv+Res₁−tail = −1.554120+1−(−0.243883)+0.333333+(−0.577216)−0.023096 = −1.554120+1+0.243883+0.333333−0.577216−0.023096 = let me add step by step: −1.554120+1 = −0.554120; +0.243883 = −0.310237; +0.333333 = 0.023096; −0.577216 = −0.554120; −0.023096 = −0.577216 ✓. [D037]: −λ_n(T)+sides_k−triv = 0 + (−0.243883) − 0.333333 = −0.577216 ✓. Difference: [MASTER]−[D037] = −0.577216 − (−0.577216) = 0 ✓✓. And my "difference formula" gave −0.243883 — so the difference formula is wrong, meaning my substitution had an error: [MASTER] = S_∞+1−sides_k+triv+Res₁−tail; [D037] = −λ_n(T)+sides_k−triv. [MASTER]−[D037] = S_∞+1+2triv+Res₁−tail+λ_n(T)−2·sides_k. Substituting sides_k = λ_n(T)+triv+Res₁: −2·sides_k = −2λ_n(T)−2triv−2Res₁. Total: S_∞+1+2triv+Res₁−tail+λ_n(T)−2λ_n(T)−2triv−2Res₁ = S_∞+1−Res₁−tail−λ_n(T) = S_∞+1−Res₁−λ_n = −Sf + (2 − 2Res₁... no: S_∞+1−λ_n = Sf so S_∞+1−Res₁−λ_n = Sf − Res₁. So [MASTER]−[D037] = Sf − Res₁(!!). At n=1: −0.577216 − (−0.577216) = 0 ✓ because S_f(1) = Res₁(1) (the coincidence I found earlier!). So [MASTER] and [D037] differ by Sf − Res₁, which vanishes at n=1 by coincidence (S_f(1) = c_0 = −γ since S_f(1) = η_0·C(1,1)·(−1)⁰ = η_0 = c_0 ✓ and Res₁(1) = c_0 ✓ — not a coincidence: at n=1 both sums have one term). At n=2: S_f(2) = −0.966922, Res₁(2) = −0.894071, difference −0.072851 ≠ 0 — so [MASTER] and [D037] CANNOT both be exact identities. [MASTER] is derived from the residue theorem + definitions only — it MUST be right. So D-037's line-63 identity is WRONG (or my reading of its signs is wrong). This is exactly the kind of thing D-064 must flag: **D-037's stated identity has a sign/transcription issue; the correct exact identity is [MASTER]: Sf = S_∞+1+Res₁+triv−sides−tail, with the w=1 residue identification Res₁(n) = Σ_j C(n,j)c_{j−1} remaining as the quantity to be related to S_f's prime-side definition.**
Hmm wait — but then how does the BOUND work? |Sf| ≤ |S_∞+1+Res₁+triv| + |sides| + |tail|. The bracket S_∞+1+Res₁+triv: at n=1: −0.798; n=2: −1.213. For B(n) ~ √n log n to bound |Sf|, we need |bracket| ≤ something in B(n). What IS bracket(n) asymptotically?? Let me compute bracket via the prime side: Sf(n) = Σ_j (−1)^{j−1}C(n,j)c_{j−1} (Lagarias 4.13, with η = c) and Res₁(n) = Σ_j C(n,j)c_{j−1}: bracket = S_∞+1+triv + Σ_j C(n,j)c_{j−1}. Using Sf = Σ_j(−1)^{j−1}C(n,j)c_{j−1} and the MASTER: bracket = Sf + sides + tail. Circular. The QUESTION is just: how big is bracket(n) = S_∞(n)+1+triv(n)+Res₁(n)?
From [MASTER]: bracket = Sf + sides + tail. At the chosen T ~ √n: |sides| ≤ B(n)-sides-pieces ~ √n log n-ish (the I_III term dominates: 4T[(2/3)C₀+A log+B₀] ~ 4√n·(0.29 log n + 5.25·0.5 log n + 48)·... ~ big√n log n), |tail| ~ √n log n-ish, |Sf| ≤ 13-ish (small). So bracket ~ √n log n too — the bracket is NOT small!! So bounding |Sf| via [MASTER] directly: |Sf| ≤ |bracket| + |sides| + |tail| would need a bound on |bracket| — and bracket = S_∞+1+Res₁+triv involves the archimedean sum S_∞ (~½n log n) and Res₁ (~−½n log n presumably) canceling to O(√n log n). PROVING that cancellation is EXACTLY the w=1 identification problem — it's the same difficulty as before, just relocated. There's no free lunch: the exact relation Res₁(n) = −S_∞(n) − 1 − triv(n) + [Sf + sides + tail](n) is circular; the INDEPENDENT identification needed is:
**Res₁(n) = −S_∞(n) − 1 − triv(n) + S_f(n)** where S_f(n) = Σ_j (−1)^{j−1}C(n,j)c_{j−1} (Lagarias 4.13) — i.e.,
Σ_j C(n,j)c_{j−1} = −S_∞(n) − 1 − triv(n) + Σ_j (−1)^{j−1}C(n,j)c_{j−1}
⟹ **S_∞(n) + 1 + triv(n) = Σ_j C(n,j)c_{j−1}·[(−1)^{j−1} − 1] = −2·Σ_{j even} C(n,j)c_{j−1}**?
Hmm interesting: Σ_j C(n,j)c_{j−1}[(−1)^{j−1}−1] = −2Σ_{j even ≥2} C(n,j)c_{j−1}. So the identification is: S_∞(n) + 1 + triv(n) = −2Σ_{j even} C(n,j)c_{j−1}?? At n=1: RHS = 0 (no even j ≤ 1). LHS = −1.554120+1+0.333333 = −0.220787 ≠ 0. FAIL. Hmm! But wait — S_f(n) = Σ_j (−1)^{j−1}C(n,j)c_{j−1} — let me verify at n=1: S_f(1) = c_0 = −γ ✓ (matches!). At n=2: 2c_0 − c_1 = −1.154432 − 0.260361 = −1.414793 vs true S_f(2) = −0.966922. FAIL!! So Lagarias's (4.13) with η = Laurent-coeffs-of-−ζ′/ζ does NOT reproduce S_f(2) = S_∞(2)+1−λ_2?! Let me recompute S_f(2): S_∞(2)+1−λ_2. S_∞(2) = −Σ_{j=1}^2 (−1)^{j+1}C(2,j)(1−2^{−j})ζ*(j) = −[(−1)²·2·(1/2)(log4π+γ) + (−1)³·1·(3/4)ζ(2)] = −[2a₁ − (3/4)ζ(2)] = −2a₁ + (3/4)ζ(2)·... wait: −[1·2·a₁·(−1)^{2}...] careful: j=1: (−1)^{j+1} = (−1)² = 1: term = C(2,1)·(1−1/2)·ζ*(1) = 2·(1/2)(log4π+γ) = a₁·2 = 3.108240. j=2: (−1)³ = −1: term = −C(2,2)(3/4)ζ(2) = −1.233701. Sum = 3.108240 − 1.233701 = 1.874539. S_∞(2) = −[that] = −1.874539 ✓ matches my earlier. S_f(2) = S_∞(2) + 1 − λ_2 = −1.874539 + 1 − 0.092383 = −0.966922. Lagarias (4.13): S_f(2) = Σ_{j=1}^2 (−1)^{j−1}C(2,j)η_{j−1} = 2η_0 − η_1. If this must equal −0.966922: with η_0 = c_0 = −0.577216: η_1 = 2η_0 + 0.966922 = −1.154432 + 0.966922 = −0.187510. And c_1 = 0.260361. So η_1 ≠ c_1!! η_1 = −0.1875 vs c_1 = 0.2604. So Lagarias's η_j (4.12) — "−ζ′/ζ(s+1) = 1/s + Σ η_j s^j" — should give η_1 = c_1 = 0.260361 by definition!! Unless Lagarias's η has different signs: (4.12) says −ζ′/ζ(s+1) = 1/s + Σ_{j≥0} η_j s^j — that IS c_j. η_1 = c_1 = γ₁+γ² = 0.260361. But then S_f(2) = 2η_0−η_1 = −1.414793 ≠ −0.966922 = S_∞(2)+1−λ_2. So either λ_2 ≠ S_∞−S_f+1 with these S's, or λ_2's value... λ_2 = 0.092383 — let me double check: λ_2 = Σ[1−(1−1/ρ)²]. Known values: λ_1 = 0.0230957, λ_2 = 0.09238... hmm — hmm, actually let me double-check λ_2: some sources: λ_2 ≈ 0.09238303922. Yes. And S_∞(2) − S_f(2) + 1 should = λ_2: −1.874539 − (−0.966922) + 1 = 0.092383 ✓. So Lagarias's Lemma 4.2 with (4.13) gives S_f(2) = −1.414793, but consistency needs −0.966922. UNLESS Lagarias's λ_n has a different normalization (e.g. λ_n^Lagarias = Σ over Z(π) with multiplicity... or the π_triv δ terms). (4.6): λ_n(π) = S_∞(n,π) − S_f(n,π∨) + δ(π) with δ(π_triv) = 1. And (4.13) is S_f(n,π_triv). λ_2^Lagr = S_∞(2) − S_f(2) + 1 = −1.874539 + 1.414793 + 1 = 0.540254. But true λ_2 = 0.092383. So Lagarias's own formula gives 0.540?!? Unless Lagarias's λ_n(π_triv) ≠ standard λ_n... OR the η_j are NOT c_j. Hold on — maybe I mis-assigned c_1. Let me recompute c_1 NUMERICALLY: −ζ′/ζ(s) near s=1: ζ′/ζ(1.001) ≈ −1000-ish + ...: −ζ′/ζ(1+u) = 1/u − γ + c_1 u + ...: at u = 0.001: 1000 − 0.577216 + c_1·0.001. Actual −ζ′/ζ(1.001): ζ′/ζ(1.001) ≈ −1/0.001 + γ − (γ₁+γ²)... sign: ζ′/ζ(1+u) = −1/u + γ − (γ₁+γ²)u: at u=0.001: −1000 + 0.577216 − 0.000260 = −999.423. −ζ′/ζ = 999.423 = 1/u − γ + (γ₁+γ²)u = 1000 − 0.577216 + 0.000260 = 999.423 ✓. So c_1 = γ₁ + γ² = 0.260361 ✓.
So Lagarias's (4.6)+(4.13) appears to give λ_2 = 0.540 ≠ 0.0924 — meaning I'm misreading something in (4.6): "λ_n(π) = S_∞(n,π) − S_f(n,π∨) + δ(π)" — with S_f(n, π∨) on the RIGHT but defined by (4.13) as S_f(n, π_triv)... π_triv∨ = π_triv ✓ same. Hmm, and S_∞(n, π∨) vs S_∞(n,π): remark says S_∞(n,π) = S_∞(n,π∨) ✓. So λ_2 = S_∞(2) − S_f(2) + 1 with S_f(2) = 2η_0 − η_1 = 2(−0.577216) − 0.260361 = −1.414793: λ_2 = −1.874539 + 1.414793 + 1 = 0.540254. The true λ_2 (zero side) = 0.092383. These disagree — so the η_j in (4.12)-(4.13) can NOT be the plain Laurent coefficients of −ζ′/ζ at 1, OR the trivial-zero part of S_∞'s (4.11) has different content than I think. Let me recompute S_∞(2) from (4.11): S_∞(n,π_triv) = −Σ_{j=1}^n (−1)^{j+1}C(n,j)(1−2^{−j})ζ*(j). j=1: (−1)²=1: C(2,1)(1/2)ζ*(1) = 2·(1/2)(log4π+γ) = log4π+γ = 3.108240. j=2: (−1)³=−1: −C(2,2)(3/4)ζ(2) = −1.233701. Sum = 1.874539. S_∞ = −1.874539 ✓. Hmm so S_∞ matches D-037's (they're consistent). Then λ_2 = S_∞ − S_f + 1 needs S_f(2) = −0.966922. So Lagarias's (4.13) MUST evaluate to −0.966922, requiring η_1 = −0.187510 — NOT c_1. So (4.12)'s "η_j" are NOT the Laurent coefficients of −ζ′/ζ as printed?? OR (4.12) is −ζ′/ζ(s+1) = 1/s + Σ η_j s^j with η_1 = −0.1875?? Direct numeric check: −ζ′/ζ(1.001) ≈ 999.423; 1/s + η_0 + η_1 s at s=0.001: 1000 − 0.577216 + η_1·0.001: if η_1 = −0.1875: 999.422596; if η_1 = 0.260361: 999.423476... let me get −ζ′/ζ(1.001) precisely: ζ(1.001) ≈ 1000.577...: ζ(1+u) = 1/u + γ − γ₁u + ... = 1000 + 0.577216 + 0.0000728 = 1000.577289. ζ′(1+u) = −1/u² − γ₁ + ... = −10⁶ + 0.072816 = −999999.927. ζ′/ζ = −999999.927/1000.577289 = −999.42298...: compute: 999999.927/1000.577289 ≈ 999.422984. So −ζ′/ζ(1.001) ≈ 999.422984. Model with c_1: 1000 − 0.577216 + c_1·0.001 = 999.422784 + c_1·0.001. 999.422984 − 999.422784 = 0.000200 ⟹ c_1 ≈ 0.200?? Hmm that's neither 0.260361 nor −0.1875. My approximations are too crude (higher-order terms c_2 u² ~ 10⁻⁶·c_2 contribute at this scale). Ugh — 0.0002 discrepancy could be c_2·10⁻⁶ with c_2 ~ 200?? No, c_2 is O(1)-ish. Let me not do this by hand — precision is insufficient.
DECISION: this hand-verification has hit its limit; the exact identity web will be settled in D-064 with mpmath (we have E-021's exact S_∞/λ_n machinery at dps 1000+ — trivial to verify any candidate identity to 50 digits). The DESIGN doesn't depend on which sign convention is right: the structure is clear — (i) exact residue theorem, (ii) exact finite reindexing, (iii) the w=1 residue Res₁(n) = Σ_j C(n,j)c_{j−1} with c's defined AS Laurent coefficients (no identification needed with prime sums if we take Lagarias's (4.13) as the DEFINITION of S_f... but wait — our Sf is DEFINED as S_∞+1−λ_n, so the BL identity Sf = Σ_j (−1)^{j−1}C(n,j)c_{j−1} is CONTENT (BL Thm 2), not definition).
Hmm OK. So what IS the minimal exact-identity chain for SfBoundProp? Let me lay it out:
GOAL: |S_∞(n) + 1 − λ_n| ≤ B(n).
Chain:
1. λ_n = λ_n(T) + tail(T) [definition + convergence; L7].
2. λ_n(T) = sides_k(T) − triv(n) − Res₁(n) [residue theorem; L0].
3. So Sf = S_∞(n) + 1 + triv(n) + Res₁(n) − sides_k(T) − tail(T).
4. Bound each: |sides_k| ≤ [side pieces from D-036/D-037 §4]; |tail| ≤ [tail bound]; |S_∞+1+triv+Res₁| ≤ [???].
For step 4's bracket: what is it EXACTLY? bracket = S_∞+1+triv+Res₁ = Sf + sides + tail (from 3). So bounding |bracket| requires knowing Sf already — circular. INSTEAD, the right decomposition must put λ_n(T) with a PLUS on the other side... Let me look at D-037's identity once more, in the form that's actually useful for the bound:
D-037: |S_f| ≤ 2N(T) + 4C₀ + sides-pieces + 1. The "2N(T) + 4C₀" bounds |λ_n(T)| (via RH bridge) — so the identity used must be:
Sf = −λ_n(T) + [everything else], with [everything else] = sides-pieces + small constants. From [MASTER]: Sf = S_∞+1+triv+Res₁−sides−tail — for this to read "−λ_n(T) + sides + small", we'd need S_∞+1+triv+Res₁ = λ_n(T) + 2·sides... no. We need bracket ≈ 0. bracket(n) at n=1 is −0.798, n=2: −1.213. NOT small... but wait, maybe I mis-derived [MASTER]'s signs. Let me redo very carefully:
sides_k(T) = Σ Res inside = λ̃_n(T) + triv + Res₁ where λ̃_n(T) = Σ_{|γ|<T}mult[1−(ρ/(ρ−1))ⁿ], triv = Res at −2 = 1−(2/3)ⁿ, Res₁ = residue at 1.
λ̃_n(T) = λ_n(T) (finite reindexing). So λ_n(T) = sides_k − triv − Res₁. ✓
Sf := S_∞ + 1 − λ_n. λ_n = λ_n(T) + tail.
Sf = S_∞ + 1 − λ_n(T) − tail = S_∞ + 1 − (sides_k − triv − Res₁) − tail = S_∞ + 1 − sides_k + triv + Res₁ − tail. ✓ [MASTER]
Hmm so bracket = S_∞+1+triv+Res₁. Now evaluate bracket using the ARCHIMEDEAN identity for Res₁. The crucial classical fact (Lagarias (4.10)): (−1)^j σ_{j+1}(π) = τ_j(π∨) − η_j(π∨) + (−1)^j δ(π∨) — relating power sums of zeros σ_n to τ (archimedean) and η (finite). And (2.18) is presumably λ_n = Σ_j C(n,j)(−1)^{j+1}σ_{j+1}·... The point: Res₁(n) = Σ_j C(n,j)c_{j−1} where c_j = η_j. And S_f = Σ_j (−1)^{j−1}C(n,j)η_{j−1}. And S_∞ = Σ_j C(n,j)τ_{j−1}·(−1)...
So: Res₁(n) = Σ_j C(n,j)η_{j−1}; S_f(n) = Σ_j (−1)^{j−1}C(n,j)η_{j−1}; S_∞(n) = −Σ_j (−1)^{j+1}C(n,j)τ*_{j−1} with τ* the ζ*/digamma-side.
The combination in bracket: S_∞ + Res₁ + 1 + triv = Σ_j C(n,j)[−(−1)^{j+1}τ*_{j−1} + η_{j−1}] + 1 + triv. Using (4.10): τ_j − η_j = (−1)^j σ_{j+1} − (−1)^j δ... = (−1)^j(σ_{j+1} − 1) for π_triv (δ=1). Hmm: (−1)^j σ_{j+1} = τ_j − η_j + (−1)^j ⟹ τ_j = η_j + (−1)^j σ_{j+1} − (−1)^j = η_j + (−1)^j(σ_{j+1} − 1).
This is the power-sum/zero-side relation: σ_{j+1} = Σ_ρ 1/ρ^{j+1} (paired power sums). So Res₁ = Σ_j C(n,j)η_{j−1} = Σ_j C(n,j)[τ_{j−1} − (−1)^{j−1}(σ_j − 1)] = Σ_j C(n,j)τ_{j−1} + Σ_j (−1)^j C(n,j)(σ_j−1).
And Σ_j C(n,j)(σ_j − 1)(−1)^j = Σ_j (−1)^j C(n,j)σ_j − Σ_j (−1)^j C(n,j) = Σ_j (−1)^j C(n,j)σ_j + 1 (since Σ_{j=1}^n (−1)^j C(n,j) = −1).
And λ_n = Σ_ρ[1−(1−1/ρ)ⁿ] = Σ_ρ Σ_j (−1)^{j+1}C(n,j)(−1/ρ)^j·... 1−(1−1/ρ)ⁿ = −Σ_{j=1}^n C(n,j)(−1/ρ)^j = Σ_j (−1)^{j+1}C(n,j)ρ^{−j}·... (−1/ρ)^j = (−1)^j ρ^{−j}: 1−(1−1/ρ)ⁿ = −Σ_j C(n,j)(−1)^j ρ^{−j} = Σ_j (−1)^{j+1}C(n,j)ρ^{−j}. So λ_n = Σ_j (−1)^{j+1}C(n,j)σ_j (with σ_j = Σ_ρ ρ^{−j} — needs care for j=1 convergence but paired OK). So Σ_j (−1)^j C(n,j)σ_j = −λ_n.
So Res₁ = Σ_j C(n,j)τ_{j−1} + (−λ_n) + 1 = [τ-sum] − λ_n + 1.
And S_∞ = −Σ_j (−1)^{j+1}C(n,j)τ*_{j−1} = Σ_j (−1)^j C(n,j)τ*_{j−1}. Hmm — but the τ* in S_∞'s (4.11) form: S_∞ = −Σ_j (−1)^{j+1}C(n,j)(1−2^{−j})ζ*(j) — vs the τ-form S_∞ = Σ_j C(n,j)τ_{j−1} (4.7: S_∞(n,π∨) = Σ_j C(n,j)τ_{j−1}(π∨) — NO alternating signs!). And (4.11) says S_∞(n,π_triv) = −Σ_j (−1)^{j+1}C(n,j)(1−2^{−j})ζ*(j) — WITH signs. So Σ_j C(n,j)τ_{j−1} = −Σ_j (−1)^{j+1}C(n,j)a_j: i.e., τ_{j−1} = −(−1)^{j+1}a_j = (−1)^j a_j. So τ-sum Σ_j C(n,j)τ_{j−1} = S_∞ ✓ (consistent — S_∞ = τ-sum).
Then: Res₁ = S_∞ − λ_n + 1. SO: bracket = S_∞ + 1 + triv + Res₁ = S_∞ + 1 + triv + S_∞ − λ_n + 1 = 2S_∞ + 2 + triv − λ_n?!? At n=1: 2(−1.554120)+2+0.333333−0.023096 = −3.108240+2+0.333333−0.023096 = −0.798003 ✓✓ MATCHES bracket(1)!
So Res₁(n) = S_∞(n) − λ_n + 1 = Sf(n) + triv... wait: S_∞ − λ_n + 1 = Sf + ... Sf = S_∞+1−λ_n: so **Res₁(n) = Sf(n)**??? At n=1: Res₁ = −0.577216 = S_f(1) ✓✓!! At n=2: Res₁(2) = −0.894071 vs S_f(2) = −0.966922 — DIFFER (−0.072851)!! But my derivation just said Res₁ = S_∞ − λ_n + 1 = Sf. Contradiction with n=2?! Let me recheck the derivation: Res₁ = Σ_j C(n,j)η_{j−1}; η_{j−1} = τ_{j−1} − (−1)^{j−1}(σ_j−1) [from (4.10) rearranged: τ_j − η_j = (−1)^j(σ_{j+1}−1) ⟹ η_j = τ_j − (−1)^j(σ_{j+1}−1)]. Res₁ = Σ_j C(n,j)[τ_{j−1} − (−1)^{j−1}(σ_j − 1)] = S_∞ − Σ_j (−1)^{j−1}C(n,j)(σ_j−1) = S_∞ + Σ_j (−1)^j C(n,j)σ_j − Σ_j (−1)^j C(n,j) = S_∞ + (−λ_n) − (−1) = S_∞ − λ_n + 1 ✓. So Res₁ = S_∞ − λ_n + 1 = Sf EXACTLY?? But numerically at n=2 they differ by 0.0728... — UNLESS my numeric Res₁(2) is wrong: Res₁(2) = 2c_0 + c_1 with c_j = η_j... is c_1 = η_1? If η_1 = −0.187510 (as required for S_f(2)): Res₁(2) = 2η_0 + η_1 = −1.154432 − 0.187510 = −1.341942?? Then Res₁ ≠ −0.894071. I previously computed Res₁(2) = 2c_0 + c_1 with c_1 = γ₁+γ² = 0.260361 — but if the actual Laurent coefficient of −ζ′/ζ at 1 is c_1 = η_1 = −0.187510, then my c_1 was WRONG. Which is it?! Direct numeric: −ζ′/ζ(1.001) ≈ 999.422984 (computed above). Model: 1/u + c_0 + c_1 u = 1000 − 0.577216 + c_1·0.001. 999.422984 = 999.422784 + c_1·0.001 ⟹ c_1 = 0.200. Hmm — neither. My numeric is too imprecise (c_2 u² terms: c_2·10⁻⁶ shifts by ~0.000001·c_2 — negligible unless c_2 ~ 200). So c_1 ≈ 0.2?? Conflicting with both candidates (0.260361, −0.187510). My hand numerics are too sloppy at the 10⁻⁴ level. Let me just compute properly with mpmath — 30 seconds of work — instead of spiraling.
The identity web needs precise numerical settling, not hand arithmetic. Let me compute the Laurent coefficients and all candidate identity components exactly with the project venv.
tool: Bash
input
{
"command": "cd /d/Python/Quantum && ./.venv/Scripts/python.exe -c \"\nimport mpmath\nmpmath.mp.mp.dps = 50\nz = mpmath.zeta\n# Laurent coefficients of -zeta'/zeta at s=1: -z'/z(1+u) = 1/u + c0 + c1 u + c2 u^2 + ...\ndef negld(u):\n return -mpmath.diff(z, 1+u)/z(1+u)\n# extract c0..c3 by fitting at geometric points (Richardson-ish)\nus = [mpmath.mpf(10)**(-k) for k in [2,3,4,5]]\n# series: negld(u) - 1/u = c0 + c1 u + c2 u^2 + c3 u^3\nimport mpmath as m\ndef A(u): return negld(u) - 1/u\n# extrapolate A(u) to u->0 via polynomial fit on 4 points\ncs = []\nvals = [(u, A(u)) for u in us]\n# fit c0 + c1 u + c2 u^2 + c3 u^3\nM = m.matrix([[u**j for j in range(4)] for u,_ in vals])\nb = m.matrix([v for _,v in vals])\nsol = m.lu_solve(M, b)\nc0,c1,c2,c3 = [sol[i] for i in range(4)]\nprint('c0 =', m.nstr(c0,30))\nprint('c1 =', m.nstr(c1,30))\nprint('c2 =', m.nstr(c2,20))\ngamma = m.euler\ng1 = m.stieltjes(1)\nprint('euler =', m.nstr(gamma,20), ' stieltjes1 =', m.nstr(g1,20))\nprint('candidate c1 = g1 + gamma^2 =', m.nstr(g1 + gamma**2,20))\nprint('candidate c1 = -(g1 + gamma^2) =', m.nstr(-(g1 + gamma**2),20))\n# S_f via archimedean: S_inf(n) + 1 - lambda_n needs lambda_n; use known small-n lambda\n# lambda_1, lambda_2 from zero side is costly; instead check BL identity consistency:\n# S_inf(n) for n=1,2\na1 = (m.log(4*m.pi)+gamma)/2\ndef Sinf(n):\n tot = (1-a1)*n - 1\n s = m.mpf(0)\n for mm in range(3, 20001, 2):\n s += (1-1/m)**n - 1 + n/m\n # tail ~ C(n,2)/2 * sum_{m>20000 odd} 1/m^2 ~ C(n,2)/(4*10000)\n return tot + s\nfor n in [1,2]:\n print('Sinf(%d) ='%n, m.nstr(Sinf(n),20))\n\"\n",
"description": "Compute Laurent coefficients of -zeta'/zeta at 1 numerically",
"timeout": 180000
}
thinking (11993 chars)
CRITICAL correction: **c₁ = +0.1875462** — so c₁ = −(γ₁ − ...)? Let's see: c₁ = 0.1875462. And −0.1875462 was my "η₁" candidate from the S_f(2) consistency requirement. So c₁ = +0.1875462, meaning η₁ = c₁ = +0.1875462 and S_f(2) = 2η₀ − η₁ = −1.154432 − 0.1875462 = −1.341978?? But S_∞(2)+1−λ₂ = −0.966922. STILL inconsistent!
Wait — actually let me recompute. c₁ = +0.1875462. What combination of Stieltjes is that? γ₁ = −0.0728158, γ² = 0.333177. c₁ = 0.1875462 = γ² − 2γ₁·...? γ² − 2γ₁ = 0.333177 + 0.145632 = 0.478809. No. −(γ₁ + γ²/2) = −(−0.072816 + 0.166589) = −0.093773. ×(−2) = 0.187546 ✓!! c₁ = −2(γ₁ + γ²/2)·(−1)... i.e., c₁ = −(2γ₁ + γ²)·(−1) = 2γ₁ + γ² = −0.145632 + 0.333177 = 0.187546 ✓. So c₁ = γ² + 2γ₁ (NEGATIVE of what I guessed for η₁).
Hmm so c₁ = γ² + 2γ₁ = 0.1875462. Then Res₁(2) = 2c₀ + c₁ = −1.154432 + 0.1875462 = −0.966886 ≈ −0.966922 = S_f(2) (diff 3.6e-5 — my λ₂ was imprecise!). And S_f(2) = Σ(−1)^{j−1}C(2,j)c_{j−1} = 2c₀ − c₁ = −1.154432 − 0.1875462 = −1.341978 ≠ S_f(2). So:
**Res₁(n) = S_f(n) = S_∞(n) + 1 − λ_n** EXACTLY (n=1: −0.577216 ✓, n=2: −0.966886 ✓ vs −0.966922, diff from λ₂ truncation error)!!
Let me verify: Res₁(n) = Σ_j C(n,j)c_{j−1}, and S_f(n) = Σ_j (−1)^{j−1}C(n,j)c_{j−1}. At n=2: Res₁(2) = 2c₀+c₁ = −0.966886; S_f-form = 2c₀−c₁ = −1.341978. True S_f(2) = −0.966922. So **Res₁(2) ≈ S_f(2)** and the (4.13)-form with alternating signs is WRONG for our S_f. So D-037's "S_f = Σ(−1)^{j−1}C(n,j)η_{j−1}" — wait no, that's Lagarias's (4.13). Hmm, but the numbers say S_f(2) ≈ Res₁(2) = Σ C(n,j)c_{j−1} WITHOUT alternating signs.
Hmm, wait — maybe Lagarias's η_j include the sign: (4.12): −ζ′/ζ(s+1) = 1/s + Σ η_j s^j — η_j = c_j by definition. Then (4.13): S_f(n,π_triv) = Σ_j (−1)^{j−1}C(n,j)η_{j−1} = 2c₀ − c₁ at n=2 = −1.341978. But the TRUE S_f(2) = −0.966922. So Lagarias's (4.13) as printed does not match S_∞−λ+1?! Unless λ_n in Lagarias's convention differs (e.g. λ_n = Σ[1−(1−1/ρ)ⁿ] vs Σ over Z(π∨)...). Whatever — the literature conventions are treacherous here; what matters for US is the NUMERICALLY VERIFIED identity:
**Res₁(n) = Σ_{j=1}^n C(n,j)c_{j−1} = S_∞(n) + 1 − λ_n = Sf(n)** ✓ (verified n=1,2 to ~4e-5, and the c-extraction is exact to 25 digits; will re-verify to full precision in D-064).
Hmm wait, let me double-check with n=2 more precisely: need λ₂ precisely. λ₂ (true) = 0.0923830392... Let me compute S_∞(2)+1−λ₂ = −1.87453936173 + 1 − 0.09238303922 = −0.96692240095. And Res₁(2) = 2c₀+c₁ = −1.15443132980 + 0.18754623283 = −0.96688509697. Difference: −0.96692240 vs −0.96688510 = 3.73e-5. NOT exactly equal — off by 3.7e-5. Hmm! So Res₁(2) ≠ Sf(2) exactly either. 3.7e-5 discrepancy — what's that? c₂/2-ish? Or my c-extraction error? c-extraction: fit on u = 1e-2..1e-5 with c₃ u³ terms: at u=1e-2, c₃·1e-6 ~ few e-8·c₃ — the fit should be fine to ~1e-10 relative... unless the diff(z,1+u) numerical derivative loses precision. mpmath diff default step ~ 1e-(dps/2)-ish; at dps 50 fine.
Alternatively the relation is Res₁(n) = Sf(n) + δ(n) with δ(1) = 0, δ(2) = +3.73e-5?? Weird. OR my λ₂ is off: λ₂ true = 0.09238303922? From Maślanka's table: λ_2 = 0.092383039...? Let me get λ₂ exactly via E-015's value: λ_2 = 0.092383039225... I think it's right. Then Sf(2) = −0.966922401. Res₁(2) = −0.966885097. δ = +3.73e-5.
Hmm — so Res₁(n) ≠ Sf(n) exactly. What is δ(2) = 3.73e-5? Maybe related to c-extraction error after all: let me test c-extraction accuracy: the fit used 4 unknowns and 4 points at u = 1e-2,...,1e-5; the u=1e-2 point has c₃u³ ~ c₃e-6 and c₄u⁴ ~ c₄e-8 — unmodeled c₄ term biases c₀ by ~c₄·1e-8-ish and c₁ by ~c₄·1e-6·... condition number of the Vandermonde-ish system at u=1e-2..1e-5: moderate. c₁ error ~1e-4·|c₄|? Possible. So δ might be pure extraction error in c₁ (c₁ = 0.1875462 vs true maybe 0.1875835?). 2c₀+c₁ needs c₁ to ~1e-7. My extraction: c₁ to ~1e-6-ish maybe not.
ENOUGH — the design doesn't hinge on 4e-5. The STRUCTURAL conclusion is now clear and solid:
**The exact identity chain:**
1. Residue theorem: sides_k(T) = λ̃_n(T) + triv + Res₁(n) — exact.
2. Finite reindexing: λ̃_n(T) = λ_n(T) — exact.
3. Definition: Sf = S_∞ + 1 − λ_n(T) − tail(T).
4. ⟹ Sf = [S_∞ + 1 + triv + Res₁] − sides_k − tail — exact, [MASTER].
And the numerical evidence says: S_∞+1+triv+Res₁ ≈ [small]: at n=1: −0.798?! NO WAIT — if Res₁ ≈ Sf, then [MASTER] reads Sf = S_∞+1+triv+Sf−sides−tail ⟹ 0 = S_∞+1+triv−sides−tail ⟹ sides = S_∞+1+triv−tail. At n=1: sides_k(2) = −0.243883; S_∞(1)+1+triv(1)−tail(2) = −1.554120+1+0.333333−0.023096 = −0.243883 ✓✓✓ EXACT!!! So the relation "Res₁ = Sf" is EQUIVALENT to "sides_k = S_∞ + 1 + triv − tail" — and the latter is numerically EXACT at n=1 (to my 6-digit precision). So:
**THE W=1 IDENTIFICATION: Res₁(n) = S_∞(n) + 1 − λ_n(n)... i.e., Σ_{j=1}^n C(n,j)c_{j−1} = S_∞(n) + 1 − λ_n** — and equivalently the contour integral sides_k(T) = S_∞(n) + 1 + triv(n) − tail(T) for EVERY zero-avoiding T. Both sides of the latter are T-dependent (sides and tail) with the T-dependence canceling.
Hmm wait, but that can't be the right way to state it — sides_k(T) is T-dependent, S_∞+1+triv is T-independent, tail(T) is T-dependent. Fine.
But hold on — is "Res₁ = Sf" a COINCIDENCE at these small n or the true identity? Let me test n=3: Sf(3) = S_∞(3)+1−λ₃. λ₃ ≈ 0.2076389205 (known). S_∞(3) = (1−a₁)3 − 1 + Σ_odd[(1−1/m)³−1+3/m]. And Res₁(3) = 3c₀ + 3c₁ + c₂ = 3(−0.577216) + 3(0.1875462) + (−0.05168858) = −1.731647 + 0.562639 − 0.051689 = −1.220697. S_∞(3) ≈ ? Σ term: (1−1/m)³−1+3/m = 3/m²−3/m³+... ≈ 3/m²: Σ_odd 3/m² ≈ 3(π²/8−1) = 0.7011 plus corrections −3Σ1/m³ ~ −3(0.268...)·... ≈ 0.7011 − 0.6 + ... ≈ 0.1-0.2. S_∞(3) ≈ 3(−0.554120) − 1 + ~0.15 ≈ −1.662359 − 1 + 0.15 = −2.51. Sf(3) ≈ −2.51 + 1 − 0.2076 = −1.72. But Res₁(3) = −1.22. NOT CLOSE. So "Res₁ = Sf" FAILS at n=3!! (My S_∞(3) is a rough estimate, ±0.05 — but the gap is ~0.5.) So the n=1,2 agreements were... at n=2 the agreement was to 3.7e-5 (suspicious but roughly consistent), at n=3 it's WAY off. So Res₁ ≠ Sf in general. Hmm!!
OK so what IS the true identity? From [MASTER] (exact): Sf = S_∞+1+triv+Res₁−sides−tail. The BOUND needs |Sf| ≤ |S_∞+1+triv+Res₁| + |sides| + |tail|. The bracket at n=1: −0.798, n=2: −1.213, n=3: S_∞(3)+1+triv(3)+Res₁(3) ≈ −2.51+1+0.7037−1.220697 = −2.03. Growing. And D-037's B(n) accounts: |Sf| ≤ 2N(T) + sides + 1. So the intended identity must convert bracket into λ_n(T)-form. From the exact λ_n(T) = sides − triv − Res₁: bracket = S_∞+1+triv+Res₁ = S_∞+1+triv + (sides − triv − λ_n(T)) = S_∞ + 1 + sides − λ_n(T). So [MASTER] becomes: Sf = S_∞ + 1 + sides − λ_n(T) − sides − tail = S_∞ + 1 − λ_n(T) − tail — which is just the definition again (Sf = S_∞+1−λ_n). CIRCULAR — of course; the residue theorem merely rewrites λ_n(T). The CONTENT is: to bound |Sf| = |S_∞+1−λ_n|, use λ_n = λ_n(T) + tail with λ_n(T) = sides−triv−Res₁:
|Sf| ≤ |S_∞ + 1 − λ_n(T)| + |tail| — and S_∞+1−λ_n(T) = S_∞+1−sides+triv+Res₁ — hmm.
The structure that makes D-037's B(n) work: |Sf| ≤ |λ_n(T)| + |tail| + |S_∞ + 1 + Res₁ + triv − λ_n(T) − sides + ... | — I keep going in circles because the residue theorem relates λ_n(T) to sides, and Sf = S_∞+1−λ_n(T)−tail; substituting: Sf = S_∞+1+Res₁+triv−sides−tail — the bracket B0 := S_∞+1+Res₁+triv is a FIXED function of n (no T!). And Sf = B0(n) − sides(T) − tail(T) for EVERY zero-avoiding T. Since Sf is T-independent: sides(T) + tail(T) = B0(n) − Sf(n) is T-independent ✓ consistency.
For the BOUND: choose T = the zero-avoiding height in [√n, √n+1]:
|Sf| ≤ |B0(n)| + |sides(T)| + |tail(T)|.
D-037's B(n) = 2N(T) + sides-pieces + 40M₀ + 1 + I_I. So D-037's accounting must be: |B0(n)| ≤ 2N(T)?? At n=1: |B0| = 0.798 vs 2N(2) = 0 — false at n=1 but n ≥ 10⁵ range... At large n: B0(n) = S_∞+1+triv+Res₁. How big is B0(n)? Since Sf = B0 − sides − tail and |Sf| ≤ ~14 (measured small), |sides| ≤ ~√n log n·(big const), |tail| ≤ ~√n log n — B0 could be as big as √n log n. In fact B0(n) = Sf(n) + sides(T) + tail(T) — evaluating at any T: B0(n) ≈ sides + tail ~ O(√n log n). So |B0| ≤ |Sf| + |sides| + |tail| — again circular for an independent bound!
The ONLY non-circular bound: |Sf| ≤ |λ_n(T)| + |Sf − λ_n(T)| where Sf − λ_n(T) = S_∞+1−λ_n−λ_n(T)... no.
Hmm, let me think about Lagarias's Thm 6.1 statement again (D-032 line 39): "S_f(n) = λ_n(√n) + O(√n log n)". So Lagarias bounds |S_f − λ_n(√n)| = O(√n log n) — THAT difference is the contour output! S_f(n) − λ_n(T) = S_∞+1−λ_n−λ_n(T) = S_∞+1−λ_n(T)−tail−λ_n(T)?? No: S_f − λ_n(T) = (S_∞+1−λ_n) − λ_n(T) = S_∞+1−2λ_n(T)−tail?? That has 2λ_n(T) ~ 4N(T) — too big. Unless λ_n in Lagarias's 6.1 means something else — λ_n(√n) might be the truncated sum with a DIFFERENT sign/form. OR the statement is S_f(n) = −λ_n(√n) + O(...)? With S_f = S_∞+1−λ_n and λ_n = λ_n(√n)+tail: S_f + λ_n(√n) = S_∞+1−tail — and S_∞+1 ~ ½n log n — no.
I clearly cannot resolve the exact classical bookkeeping by pure thought at 11pm-brain — BUT I don't need to for the design! The DESIGN conclusion is robust:
**Whatever the exact final identity, the formalization needs these exact components:**
(i) Residue theorem for the integrand on the rectangle (L0 machinery) — giving sides_k(T) = λ_n(T) + triv + Res₁(n) EXACTLY.
(ii) The bridge |λ_n(T)| ≤ 2N(T) (+ window) from hRH.
(iii) The w=1 residue Res₁(n) = Σ_j C(n,j)c_{j−1} — computable EXACTLY as a finite sum ONCE c_j are defined as Laurent coefficients; NO Stieltjes identification needed if we keep c_j abstract!
(iv) The tail bound |tail(T)| ≤ [explicit].
(v) THE CRUX: relate Res₁(n) to S_∞(n): from [MASTER], Sf = [S_∞+1+triv+Res₁] − sides − tail. Since |Sf| is what's bounded, and |sides|, |tail| are bounded by contour pieces, the bracket S_∞+1+triv+Res₁ must be bounded by ~2N(T)+... — and since bracket is T-independent, we can evaluate it... AT A SPECIFIC T?! **KEY INSIGHT: bracket(n) = Sf(n) + sides(T) + tail(T) holds for EVERY T. Choose T = T₀-side evaluation... no — bracket(n) is a specific real number; we need |bracket(n)| ≤ [something explicit]. The only way to bound it is to know what it IS. And the answer from the numerics: bracket(1) = −0.798, bracket(2) = −1.213, bracket(3) ≈ −2.03 — hmm these look like they might be −λ_n − ...? −λ_1−0.77? Let me test: bracket(n) =? −Σ_j (−1)^{j−1}C(n,j)a_j-type... Actually: bracket = S_∞+1+triv+Res₁; using Res₁ = S_∞−λ_n+1 (my earlier derivation which numerically failed at n=2 — let me re-examine WHY: Res₁ = Σ_j C(n,j)η_{j−1} with η = c: at n=2: 2c₀+c₁ = −0.966886. S_∞−λ₂+1 = −1.874539−0.092383+1 = −0.966922. Difference 3.6e-5 — SMALL but nonzero. At n=3: Res₁(3) = 3c₀+3c₁+c₂ = −1.220697; S_∞(3)−λ₃+1 ≈ −2.51−0.2076+1 = −1.72. NOT close. So Res₁ = S_∞−λ_n+1 fails at n=3. My S_∞(3) estimate was rough (±0.1?) — let me not trust it. Hmm, if S_∞(3) were −1.72+... let me refine: actually the failure at n=3 vs agreement at n=2 (3.6e-5) — the n=2 near-agreement suggests c-extraction noise at n=2 AND a real failure at n=3. OR my rough S_∞(3) is off by 0.5 — unlikely (the nsum converges well).
I need to stop the hand-analysis and compute all pieces precisely for n = 1..6. THEN the exact identity will reveal itself. This is exactly D-064's job ("make the o(eᵃ)... the exact bookkeeping quantitative"). Let me do the precise numeric NOW since everything hinges on it — compute for n = 1..6: c₀..c₅ (Laurent coeffs of −ζ′/ζ at 1, high precision), Res₁(n) = Σ C(n,j)c_{j−1}, S_∞(n) exact, λ_n exact-ish (via E-015's arithmetic route would be heavy; instead use the PRIME-side η definition? OR use the identity λ_n = S_∞+1−Sf with Sf = Σ(−1)^{j−1}C(n,j)c_{j−1} IF Lagarias's 4.13 holds... circular. Use λ_n from zeros with many zeros + tail bound: λ_n = Σ_{k} pair + tail; with 10⁴ zeros (E-021 cache exists: E-021-zeros-cache.npy 4624 zeros!) the tail beyond γ_4624 ~ 5500: for n ≤ 6 the tail Σ 2n/γ²·n? |tail| ≤ Σ_{γ>5500} 2n·|1/ρ|·e^{...} ≈ 2n·log(5500)/(2π·5500) ~ n·2.5e-4 — small enough for 4-digit checks of n ≤ 6.
Let me just do it — load the E-021 zeros cache.
The hand bookkeeping has hit its limit — let me settle the exact identity numerically with the cached zeros (E-021's 4624-zero cache) before designing.
tool: Bash
input
{
"command": "cd /d/Python/Quantum && ls research/numerics/data/ | grep -i \"zeros\" | head; ./.venv/Scripts/python.exe -c \"\nimport mpmath as m\nm.mp.dps = 50\n# Laurent coefficients c0..c6 of -zeta'/zeta at s=1 via mpmath taylor\nz = m.zeta\nf = lambda u: -m.diff(z, 1+u)/z(1+u) - 1/u\nts = m.taylor(f, 0, 6)\nprint('taylor of -z\\'/z(1+u)-1/u:')\nfor j,c in enumerate(ts):\n print(' c%d ='%j, m.nstr(c, 20))\n\"",
"description": "High-precision Laurent coefficients via mpmath taylor",
"timeout": 180000
}
thinking (5422 chars)
The u=0 evaluation hits the pole even though multiplied by u (0·pole is NaN). Guard: define h(u) with a piecewise at u=0 returning 1... but diff samples near 0, not at 0, usually — the k=1 worked (c₀ = −γ to 25 digits ✓). For k≥2 it seems to evaluate at 0. Let me use a small offset: compute the series at u0 = 0.05 instead of 0 and shift? Simpler: extract via least-squares fit at many small points with higher-order model, at dps 50 with u ~ 1e-3..1e-2 — but that's what I did before with 25-digit c₁. The earlier fit gave c₁ = 0.18754623283535631474 — I'll trust that (it matched γ² + 2γ₁? γ²+2γ₁ = 0.333177 + (−0.145632) = 0.1875462 — EXACT match to the fit). So c₁ = γ² + 2γ₁·(−1)... wait: γ₁ = −0.0728158455; 2γ₁ = −0.1456316910; γ² = 0.333177... γ² + 2γ₁ = 0.1875454... let me not; the fit value 0.18754623283535631 is solid.
Hmm wait, actually earlier I derived c₁ should be γ₁+γ² = 0.26036208 from the Stieltjes expansion — but the fit says 0.18754623, and γ²+2γ₁ = 0.18754623?? γ² = 0.5772156649² = 0.3331779559; 2γ₁ = −0.1456316910; sum = 0.1875462649. The fit: 0.18754623283535631. Close (diff 3.2e-8 — fit error). Hmm interesting. So c₁ = γ² + 2γ₁?? But my Laurent derivation gave c₁ = γ₁ + γ². Let me recheck: ζ(1+u) = u⁻¹ + γ − γ₁u + γ₂u²/2 − ... Stieltjes convention: ζ(s) = 1/(s−1) + Σ_{k=0}∞ (−1)^k γ_k/k! (s−1)^k ✓. log ζ(1+u) = −log u + log(1 + γu − γ₁u²/2 + γ₂u³/6 − ...) = −log u + γu + [−γ₁/2 − γ²/2]u² + [γ₂/6 + γγ₁/2 + γ³/3]u³ + ... So d/du log ζ = −1/u + γ − (γ₁+γ²)u + (γ₂/2 + γγ₁ + γ³)u²·... wait derivative of [γ₂/6+γγ₁/2+γ³/3]u³ is 3[...]u² = (γ₂/2 + 3γγ₁/2 + γ³)u². So −ζ′/ζ = 1/u − γ + (γ₁+γ²)u − (γ₂/2 + 3γγ₁/2 + γ³)u² + ... So c₁ = γ₁ + γ² = 0.26036208. But the fit says 0.18754623! These disagree by 0.0728 ≈ −γ₁!! Curious: γ₁+γ² = 0.26036 vs γ²+2γ₁ = 0.18755 — difference = −γ₁ = 0.0728. One of them is wrong — the fit is EMPIRICAL (0.1875462 from actual function values), so my Stieltjes algebra must be wrong. Let me recheck numerically: −ζ′/ζ(1.001): model 1/u + c₀ + c₁u: u=0.001: 1000 − 0.5772157 + c₁·0.001. From the h-diff computation c₀ = −0.57721566490153 ✓. Actual −ζ′/ζ(1.001) = ? compute numerically: I'll trust the fit: c₁ ≈ 0.18754623. Check my algebra: v = γu − γ₁u²/2 + γ₂u³/6. log(1+v) = v − v²/2 + v³/3. v²/2 = (γ²u² − γγ₁u³ + ...)/2. v³/3 = γ³u³/3. Coefficient of u² in log(1+v): −γ₁/2 − γ²/2 ✓. d/du: 2·(−γ₁/2 − γ²/2)u = −(γ₁+γ²)u. So ζ′/ζ = −1/u + γ − (γ₁+γ²)u + O(u²). −ζ′/ζ = 1/u − γ + (γ₁+γ²)u + ... c₁ = γ₁+γ² = 0.26036. But empirical fit: 0.18755. Contradiction with the empirical... UNLESS the empirical fit was contaminated. The fit: 4 points u = 1e-2..1e-5, model c₀+c₁u+c₂u²+c₃u³, exact solve. At u = 1e-2 the c₄u⁴ ~ c₄·1e-8 unmodeled — fine. Hmm, but mpmath's diff(z, 1+u) — numerical derivative of zeta at u=1e-5: default diff h ~ 1e-(dps/3)? The earlier fit at dps 50 gave c1 = 0.18754623283535631474 — and γ²+2γ₁ = 0.18754626?? wait let me compute γ² + 2γ₁ precisely: γ² = 0.333177955... γ = 0.57721566490153286061; γ² = 0.333177955... let me: 0.5772156649² = 0.333177(0.5772² = 0.33316). 2γ₁ = −0.1456316909673534. γ²+2γ₁ = 0.3331780 − 0.1456317 = 0.1875463. The fit 0.1875462328. And γ₁+γ² = −0.0728158455 + 0.333177955 = 0.260362109. Fit says neither exactly but closest to 0.1875463 (diff 3e-8) — so c₁ = γ² + 2γ₁ EMPIRICALLY. So my Stieltjes algebra is wrong somewhere — irrelevant! The empirical wins. And c₂ from the fit: −0.05168858148. Check candidates: −(γ₂/2 + 3γγ₁/2 + γ³): γ₂ = −0.0096903636; γ₂/2 = −0.004845; 3γγ₁/2 = 3(0.5772)(−0.0728)/2 = −0.063037; γ³ = 0.192426. Sum: −0.004845 − 0.063037 + 0.192426 = 0.124544. Negative: −0.124544 ≠ −0.0517. Alternative c₂ = −(γ₂ + 3γγ₁ + γ³)?: −0.009690 − 0.126074 − 0.192426 = −0.328190 no. c₂ = −0.0516886... what combination? −(γ₂/2+γγ₁·2+...)? −0.004845 + 0.084... γγ₁ = −0.042025: −2γγ₁ = 0.084050: −0.004845+0.084050−0.192426·...? Meh. Empirics rule; symbolic Stieltjes relations can be sorted out in D-064 with flint-grade precision.
Now the KEY test — the exact identity. Let me set up the full numeric test:
- c₀..c₅ via the h-diff at higher order (the u=0 pole issue: use m.diff with h explicitly nonzero, e.g. diff(h, 0, n=k, h=1e-3)? or evaluate the fit more carefully at dps 60 with 6 points).
- Res₁(n) = Σ_{j=1}^n C(n,j)c_{j−1} for n = 1..6.
- S_∞(n) exact (nsum odd form).
- λ_n: compute from zeros (4624 zeros from E-021 cache) + tail estimate.
- Then test candidate identities:
(a) Sf = S_∞+1−λ_n vs [MASTER]: S_∞+1+triv+Res₁ − sides − tail — can't compute sides easily; instead test the T-independent consequence: Res₁(n) vs S_∞+1−λ_n+triv...
Actually the cleanest testable: from [MASTER], B0(n) := S_∞(n)+1+triv(n)+Res₁(n) should equal Sf(n)+sides(T)+tail(T) — not directly testable without sides. BUT sides_k(T) = λ_n(T)+triv+Res₁ (residue theorem) IS testable if I can compute the contour integral numerically! I CAN: integrate k_n(w−1)(−ζ′/ζ) around the rectangle numerically at small n (n ≤ 6, T = √n + 0.5 say — zero-avoiding check by hand) with mpmath. That's the definitive test of the whole chain.
Given time, let me do exactly that: full numerical verification of the exact identity at n = 2 and n = 3: compute sides (contour integral), λ_n(T) (from zeros), triv, Res₁; verify sides = λ_n(T) + triv + Res₁ to ~1e-20; and separately verify Sf = S_∞+1−λ_n decomposition; and then compute B0 = S_∞+1+triv+Res₁ and see how big it is / whether it has a closed form.
Good — c₀ = −γ to 25 digits. Let me run the definitive numerical test of the full identity chain (contour integral vs residue sum) at small n.
tool: Bash
input
{
"command": "cd /d/Python/Quantum && ./.venv/Scripts/python.exe -c \"\nimport mpmath as m\nm.mp.dps = 40\nz = m.zeta\nld = lambda w: -m.diff(z, w)/z(w) # -zeta'/zeta\ngamma = m.euler\n# Laurent c0..c3 (from prior fit, dps-50 verified): c0=-gamma, c1=0.18754623283535631...\n# refit at dps 40 with 5 unknowns for safety\nus = [m.mpf(10)**(-k) for k in [3,4,5,6,7]]\nA = lambda u: ld(1+u) - 1/u\nM = m.matrix([[u**j for j in range(5)] for u in us])\nb = m.matrix([A(u) for u in us])\nsol = m.lu_solve(M, b)\ncs = [sol[i] for i in range(5)]\nprint('c0..c4:', [m.nstr(c,18) for c in cs])\ndef kn(s, n): return (1+1/s)**n - 1\ndef Res1(n):\n return m.nsum(lambda j: 0, [1,0]) + sum(m.binomial(n,j)*cs[j-1] for j in range(1,n+1))\ndef triv(n): return 1 - (m.mpf(2)/3)**n\na1 = (m.log(4*m.pi)+gamma)/2\ndef Sinf(n):\n return (1-a1)*n - 1 + m.nsum(lambda k: (1-1/(2*k+1))**n - 1 + n/(2*k+1), [1, m.inf], tol=m.mpf('1e-30'))\n# zeros from cache\nimport numpy as np\ngam = np.load('research/numerics/data/E-021-zeros-cache.npy')\nprint('zeros:', len(gam), 'max:', gam[-1])\ndef lam_n(n, T=None):\n tot = m.mpf(0)\n for g in gam:\n if T is not None and g > T: break\n rho = m.mpc(m.mpf('0.5'), m.mpf(float(g)))\n # pair: rho and conj(rho)\n tot += (1 - (1-1/rho)**n).real*2\n return tot\ndef sides(n, T):\n J = lambda w: kn(w-1, n)*ld(w)\n s0, s1 = m.mpf('-2.5'), 2*m.sqrt(n)\n I1 = m.quad(lambda t: J(m.mpc(s1,t)), [-T, T]) # right vertical\n I3 = m.quad(lambda t: J(m.mpc(s0,t)), [-T, T]) # left vertical\n I2 = m.quad(lambda x: J(m.mpc(x,T)), [s0, s1]) # top\n I4 = m.quad(lambda x: J(m.mpc(x,-T)), [s0, s1]) # bottom\n # CCW: bottom (left->right), right (bottom->top), top (right->left), left (top->bottom)\n total = I4 + 1j*I1 - I2 - 1j*I3\n return total/(2*m.pi*1j)\nfor n in [2, 3]:\n T = m.sqrt(n) + m.mpf('0.5')\n S = sides(n, T)\n lamT = lam_n(n, T)\n print(f'n={n}: sides={m.nstr(S,16)}')\n print(f' lam_n(T)={m.nstr(lamT,16)} triv={m.nstr(triv(n),10)} Res1={m.nstr(Res1(n),16)}')\n print(f' lam_n(T)+triv+Res1 = {m.nstr(lamT+triv(n)+Res1(n),16)}')\n print(f' sides - (lam+triv+Res1) = {m.nstr(S-(lamT+triv(n)+Res1(n)),8)}')\n Si = Sinf(n); lamF = lam_n(n)\n Sf = Si + 1 - lamF\n B0 = Si + 1 + triv(n) + Res1(n)\n print(f' Sinf={m.nstr(Si,14)} lambda_full(approx)={m.nstr(lamF,12)} Sf={m.nstr(Sf,12)}')\n print(f' B0 = Sinf+1+triv+Res1 = {m.nstr(B0,14)}')\n print(f' check MASTER: B0 - sides - tail = {m.nstr(B0 - S - (lamF-lamT),14)} vs Sf')\n\"",
"description": "Numerically verify the full contour identity chain at n=2,3",
"timeout": 300000
}
thinking (22539 chars)
Now everything is verified numerically:
1. **The residue theorem [EXACT]**: sides(T) = λ_n(T) + triv + Res₁(n) — verified to 2e-21 (n=2) and 1.7e-15 (n=3) ✓✓✓. (λ_n(T) = 0 since T < γ₁ = 14.13.)
2. **[MASTER] holds**: B0 − sides − tail = Sf exactly ✓.
3. **B0(n) = S_∞+1+triv+Res₁(n)**: n=2: −1.2859, n=3: −1.5300. NOT small, NOT zero. And Sf(2) = −0.9659, Sf(3) = −1.2185.
So the honest picture: |Sf| ≤ |B0(n)| + |sides| + |tail| would need a bound on B0 — but B0 = Sf + sides + tail (tautology). The way D-037's bound actually works must be DIFFERENT. Since |Sf| ≤ |B0| + |sides| + |tail| is useless without controlling B0, the actual assembly must be:
|Sf| = |S_∞+1−λ_n| ≤ |S_∞+1−λ_n(T)| + |tail|? No — that swaps one unknown for another.
Hmm, wait. Let's reconsider. What does Lagarias's Thm 6.1 actually prove (per D-032): "S_f(n) = λ_n(√n) + O(√n log n)". So S_f − λ_n(√n) = O(√n log n). With our numbers: S_f(2) − λ_2(√2) = −0.9659 − 0 = −0.9659 = O(·) ✓ trivially at this size. And S_f = S_∞+1−λ_n = S_∞+1−λ_n(T)−tail. So the claim "S_f − λ_n(T) = O(√n log n)" reads S_∞+1−2λ_n(T)−tail = ... at n=2: −1.8745+1−0−0.0914 = −0.9659 ✓ (equals S_f since λ_n(T)=0). So the CONTENT of Thm 6.1: **S_∞(n) + 1 − 2λ_n(T) − tail(T) is O(√n log n)**?? That doesn't factor through the contour nicely...
Hmm wait — actually maybe it does: S_f − λ_n(T) = [B0 − sides − tail] − λ_n(T) = [S_∞+1+triv+Res₁] − sides − tail − λ_n(T). With λ_n(T) = sides−triv−Res₁: = S_∞+1+triv+Res₁−sides−tail−sides+triv+Res₁ = S_∞+1+2triv+2Res₁−2·sides−tail. Messy. NOT the right combination.
Alternatively: maybe Lagarias's contour bounds λ_n(T) − [something]... Let me think about what the contour identity gives DIRECTLY: λ_n(T) = sides − triv − Res₁. Res₁ = Σ_j C(n,j)c_{j−1} is EXPLICIT (given the c's). So:
**λ_n(T) + Res₁(n) + triv(n) = sides(T)** — an exact identity. And Sf = S_∞+1−λ_n(T)−tail. Combining: Sf = S_∞+1+Res₁+triv−sides−tail. To bound |Sf|:
- |sides| ≤ [D-036's I_I..I_IV pieces] ✓ explicit.
- |tail| ≤ [explicit bound needed — D-037's accounting must have it somewhere or it's handled by the bridge... hmm].
- |S_∞+1+Res₁+triv| = |B0| — the remaining piece. How does D-037 bound B0?? B0(2) = −1.286, B0(3) = −1.530, B0(1) = −0.798. What's B0(10)? If B0 grows like... B0 = S_∞+1+triv+Res₁ where S_∞ ~ ½n log n and Res₁ = ΣC(n,j)c_{j−1} — for B0 to be bounded by 2N(T)+... ~ √n log n, we need S_∞ + Res₁ to cancel the ½n log n down to O(√n log n). I.e., **Res₁(n) = −S_∞(n) + O(√n log n)**. Check: n=2: Res₁ = −0.9669, −S_∞ = 1.8745 — NOT close (B0 = −1.286 not small). Hmm!! So S_∞ + Res₁ does NOT cancel to o(n). B0(2) = −1.286, B0(3) = −1.530, B0(1) = −0.798 — these are all ≈ S_f(n) − 0.3-ish. Actually: B0 = Sf + sides + tail: n=2: Sf = −0.9659, sides = −0.4113, tail = 0.0914: −0.9659 − 0.4113 + 0.0914 = −1.2858 ✓. So B0 ≈ Sf + sides − ... B0 is just as big as sides ~ O(1) at small n; at n = 10⁵ sides ~ √n log n·(const ~ 20?) — so B0(n) ~ 2×10⁶-ish at n=10⁵. So |Sf| ≤ |B0| + |sides| + |tail| is useless (B0 is as big as the things we're bounding).
CONCLUSION: [MASTER] as assembled does NOT directly give a useful bound. The useful decomposition must avoid B0 entirely. How?? Go back to: Sf = S_∞ + 1 − λ_n, λ_n = λ_n(T) + tail. The bridge bounds |λ_n(T)| ≤ 2N(T) (RH). The tail: |tail(T)| ≤ [bound]. So **|Sf| ≤ |S_∞(n) + 1| + 2N(T) + |tail|**?? But S_∞+1 ~ ½n log n — HUGE — that gives |Sf| ≲ ½n log n which is TRUE (Sf = S_∞+1−λ_n and both terms ~ ½n log n... wait no — Sf is SMALL (≤ 13 measured) because λ_n ≈ S_∞+1 to leading order!). The whole subtlety: Sf = S_∞+1−λ_n is a DIFFERENCE of two ~½n log n quantities. Bounding |Sf| needs the CANCELLATION between S_∞+1 and λ_n — and the contour's job is to exhibit λ_n = S_∞+1+O(√n log n)... no wait — λ_n = λ_n(T)+tail = sides−triv−Res₁+tail: |λ_n + Res₁| ≤ |sides|+|triv|+|tail| — so λ_n ≈ −Res₁ with error O(√n log n). Then Sf = S_∞+1−λ_n = S_∞+1+Res₁ + (λ_n+Res₁)·(−1)... = B0 − (λ_n+Res₁) − tail·... hmm: Sf = S_∞+1−λ_n = (S_∞+1+Res₁) − (λ_n+Res₁) = B0 − triv − (λ_n+Res₁) where |λ_n+Res₁| ≤ |sides|+|triv|+|tail|. So |Sf| ≤ |S_∞+1+Res₁| + |sides| + 2|triv| + |tail|. STILL has S_∞+1+Res₁ (= B0 − triv). So everything hinges on:
**THE CORE ID: S_∞(n) + 1 + Res₁(n) is SMALL** (bounded by the B(n) pieces). And the numerics say: S_∞+1+Res₁ at n=2: −1.8745+1−0.9669 = −1.8414; n=3: −2.0131+1−1.2207 = −2.2338; n=1: −1.5541+1−0.5772 = −1.1313. Growing ~ −(0.3..0.7)n-ish? Not small!!
But |Sf| IS small (−0.9659, −1.2185). So |S_∞+1+Res₁| ~ 1.8–2.2 at n=2,3 and |sides| ~ 0.4–0.5, and Sf = (S_∞+1+Res₁) − (λ_n+Res₁): −0.9659 = −1.8414 − (λ_2 + Res₁(2)) ⟹ λ_2+Res₁(2) = −0.8755; λ_2 = 0.0914 (approx full), Res₁(2) = −0.9669: sum = −0.8755 ✓. So the cancellation for small Sf comes from (λ_n+Res₁), NOT from S_∞+1+Res₁ being small. So the bound structure:
|Sf| ≤ |S_∞+1+Res₁(n)| + |λ_n + Res₁(n)|, with |λ_n+Res₁| ≤ |sides|+|triv|+|tail|.
This needs |S_∞+1+Res₁(n)| ≤ [B(n) piece]. Numerically S_∞+1+Res₁(2) = −1.8414, (3) = −2.2338 — for the theorem's bound B(n) ~ √n log n ~ 20·√n log n... at n=10⁵, B ~ 3.4×10⁵. How big is S_∞+1+Res₁(n) at n=10⁵? If it grows like ~n/10 it's 10⁴ — fits. If ~n it's 10⁵ — fits (margin 9.3×10⁴... hmm tight-ish). What IS the asymptotic of S_∞+1+Res₁?
S_∞(n) = ½n log n + C₁n − ¼ − 1/(24n) + o(1/n) (E-021 V3!). And Res₁(n) = Σ_j C(n,j)c_{j−1}: what's ITS asymptotic? If Res₁(n) = −½n log n − C₁n + O(1), then S_∞+1+Res₁ = O(1). At n=2: −S_∞−1 = 0.8745 vs Res₁ = −0.9669 — not converged yet. The asymptotic of the binomial transform Σ_j C(n,j)c_{j−1}: for large n, dominated by... c_j are specific constants (Laurent of −ζ′/ζ). Hmm — Σ_j C(n,j)c_{j−1}: if c_j were (j−1)!·a^j-ish the sum would be huge; c_j = η_j are the BL eta constants ~ known to be ~ −(1−2^{−j})... hmm η_j ~ O(1)? Then Σ_j C(n,j)c_{j−1} ~ up to 2ⁿ·max|c| — the cancellation inside is enormous. The ASYMPTOTIC of Res₁(n): since Res₁(n) = sides(T) − λ_n(T) − triv for any T (exact), choose T = √n: Res₁(n) = sides(√n) − λ_n(√n) − triv, and |sides(√n)| ≤ B-pieces ~ √n log n, |λ_n(√n)| ≤ 2N(√n) ~ √n log n. So **|Res₁(n)| ≤ O(√n log n)** via the contour! And S_∞(n)+1+Res₁(n) = S_∞+1 + [sides − λ_n − triv] — circular again for bounding.
OK the smoke is clearing — the correct, non-circular assembly is:
**Sf = S_∞+1−λ_n = [S_∞+1+Res₁] − [λ_n+Res₁]**
and
- λ_n + Res₁(n) = λ_n(T) + tail + Res₁ = sides(T) − triv + tail ⟹ |λ_n+Res₁| ≤ |sides| + |triv| + |tail| — CONTOUR-BOUNDED ✓.
- S_∞+1+Res₁(n) =: the "archimedean-pole bracket" — must be bounded DIRECTLY.
What is it exactly? S_∞(n) + 1 + Σ_j C(n,j)c_{j−1}. Numerically −1.13, −1.84, −2.23 for n=1,2,3. Hmm — growing roughly linearly? For B(n) ~ 20√n log n at n=10⁵ ~ 2.3×10⁶, a linear growth ~n/2 = 5×10⁴ fits comfortably. But we need its EXACT bound. What is it structurally??
Res₁(n) = Σ_j C(n,j)c_{j−1} where the c's are Laurent of −ζ′/ζ. S_∞(n) = Σ_j (−1)^j C(n,j)a_j (a_j = (1−2^{−j})ζ(j), a₁ special). So:
S_∞+1+Res₁ = 1 + Σ_j C(n,j)[c_{j−1} + (−1)^j a_j].
At j=1: c₀ + (−1)a₁ = −γ − a₁ = −γ − (log4π+γ)/2 = −1.554120−0.577216·... = −(log4π+γ)/2 − γ = −1.554120−0.577216 = −2.131336? Hmm wait: −γ − a₁ = −0.577216 − 1.554120 = −2.131336. n=1: 1 + C(1,1)·(−2.131336) = −1.131336 ✓ matches B0(1)−triv(1) = −1.131336−... wait earlier S_∞+1+Res₁(1) = −1.1313 ✓ (1 + [c₀−a₁] = 1−2.131336 = −1.131336 ✓✓).
So **S_∞(n)+1+Res₁(n) = 1 + Σ_{j=1}^n C(n,j)[c_{j−1} + (−1)^j a_j]** — a pure finite-difference object! Define d_j := c_{j−1} + (−1)^j a_j (j ≥ 1): d_1 = c₀ − a₁ = −2.131336. d_2 = c₁ + a₂ = 0.187546 + 1.233701 = 1.421247. Then n=2: 1 + 2d_1 + d_2 = 1 − 4.262672 + 1.421247 = −1.841425 ✓✓ matches!
So the bracket is EXACTLY 1 + Σ_j C(n,j)d_j with d_j = c_{j−1} + (−1)^j a_j. NOW — what is d_j?? c_{j−1} = Laurent coeff of −ζ′/ζ; a_j = (1−2^{−j})ζ(j). The claim from Lagarias's structure (the τ decomposition (4.3)-(4.5)): ξ′/ξ = Γ-part + L′/L-part − e/s..., and the τ_j (archimedean) vs η_j (finite): (4.10): (−1)^j σ_{j+1} = τ_j − η_j + (−1)^jδ. For π_triv: τ_j relates to digamma values: τ_n(π_triv) = (−1/2)^{n+1}ζ(n+1,1/2) = (−1)^{n+1}(2^{n+1}−1)ζ(n+1)-ish... from the Remark after Lemma 4.3: τ_n(π_triv) = (−1)^{n+1}(1−2^{−(n+1)})ζ(n+1)!! So τ_{j−1} = (−1)^j(1−2^{−j})ζ(j) = (−1)^j a_j (for j ≥ 2). And d_j = c_{j−1} + (−1)^j a_j = c_{j−1} + τ_{j−1} = η_{j−1} + τ_{j−1} (with c = η). From (4.10): τ_j − η_j = (−1)^j σ_{j+1} − (−1)^j ⟹ τ_j + η_j = ... different combination. Hmm: d_j = η_{j−1} + τ_{j−1} and (4.10) gives τ−η. So d_j = 2τ_{j−1} − (−1)^{j−1}(σ_j − 1) = ... or d_j = 2η_{j−1} + (−1)^{j−1}(σ_j−1). Not obviously simpler.
The important point: **the bracket 1 + Σ_j C(n,j)d_j is a clean, closed, finite object** — and bounding |Sf| requires |1 + Σ_j C(n,j)d_j| ≤ [part of B(n)]. How big is it? At n=1,2,3: −1.13, −1.84, −2.23. Hmm — wait, but actually, let me reconsider. Is the bracket maybe EXACTLY equal to something like −Σ_j C(n,j)(−1)^j(σ_j−1)...? From Res₁ = ΣC η, S_∞ = ΣC τ (no signs — Lagarias 4.7!): S_∞+1+Res₁ = 1 + Σ_j C(n,j)[τ_{j−1} + η_{j−1}]. And (4.10): τ_j − η_j = (−1)^j(σ_{j+1}−1). So τ+η is NOT directly given...
Hmm, hold on, wait. I had S_∞ = Σ_j C(n,j)τ_{j−1} from Lagarias (4.7) — but D-037's S_∞ = Σ_j (−1)^j C(n,j)a_j. With τ_{j−1} = (−1)^j a_j — consistent. So S_∞ = Σ_j C(n,j)τ_{j−1} ✓ (no signs). Then S_∞+1+Res₁ = 1 + Σ_j C(n,j)(τ_{j−1}+η_{j−1}). Now Lagarias (4.10) for π∨ vs π... and Lemma 4.2's proof: "substituting (4.10) into (2.18)": (2.18) is presumably λ_n = Σ_j (−1)^{j+1}C(n,j)σ_j·... something. Let me compute τ+η numerically: τ₀ = −(log4π+γ)/2 = −1.554120 (from the Remark); η₀ = c₀ = −0.577216. τ₀+η₀ = −2.131336 = d_1 ✓ (consistent with above!). τ₁ = (−1)²(1−2^{−2})ζ(2)·... wait τ_{j−1} = (−1)^j a_j: τ₁ = (+1)a₂ = 1.233701. η₁ = c₁ = 0.187546. τ₁+η₁ = 1.421247 = d_2 ✓✓.
So d_j = τ_{j−1} + η_{j−1}, and the bracket = 1 + Σ_j C(n,j)(τ_{j−1}+η_{j−1}). Is there a closed form? τ+η = 2τ − (τ−η) = 2τ_{j−1} − (−1)^{j−1}(σ_j−1). Bracket = 1 + 2Σ_j C(n,j)τ_{j−1} − Σ_j (−1)^{j−1}C(n,j)(σ_j−1) = 1 + 2S_∞ + [Σ_j (−1)^j C(n,j)σ_j + Σ_j (−1)^{j−1}C(n,j)]·... Σ_j (−1)^{j−1}C(n,j)(σ_j−1) = Σ_j(−1)^{j−1}C(n,j)σ_j − Σ_j(−1)^{j−1}C(n,j) = (−λ_n)·(−1)... λ_n = Σ_j (−1)^{j+1}C(n,j)σ_j so Σ_j (−1)^{j−1}C(n,j)σ_j = λ_n. And Σ_j (−1)^{j−1}C(n,j) = 1. So Σ(−1)^{j−1}C(σ−1) = λ_n − 1. Bracket = 1 + 2S_∞ − (λ_n − 1) = 2S_∞ + 2 − λ_n. At n=2: 2(−1.874539)+2−0.091384 = −1.840462 ✓ (≈ −1.841425, λ-approx error) ✓✓. So bracket = 2S_∞+2−λ_n — CONSISTENCY CHECK, circular again (contains λ_n)! Of course: because η and τ both relate to σ via (4.10), any such combination reduces to λ_n. The algebra is: bracket = S_∞+1+Res₁ and Sf = S_∞+1−λ_n ⟹ bracket = Sf + Res₁ + λ_n. And |bracket| ≤ |Sf| + |Res₁ + λ_n| — CIRCULAR for bounding Sf. The NON-circular bound is:
**|Sf| ≤ |S_∞+1+Res₁| + |λ_n+Res₁|** — hmm still circular-ish: S_∞+1+Res₁ = bracket.
Ugh, OK. Let me look at it from D-037's ACTUAL bound (4.1) once more: B(n) = 2N(T) + [I_III piece] + [40M₀] + [horizontals] + [I_I] + 1. The 2N(T) bounds |λ_n(T)| (bridge). The sides pieces bound |sides|. +1 = |triv|. So D-037's implicit identity MUST be:
**|Sf| ≤ |λ_n(T)| + |sides| + |triv| + |tail|**, i.e. **Sf = −λ_n(T) ± sides ± triv ± tail** — matching D-037's line-63 identity: S_f = −Σ_{|γ|≤T}·(−1)... + sides + triv(−2). So the intended exact identity IS:
**Sf(n) = −λ_n(T) + sides_k(T) − triv(n) − tail(T)??** — but then Sf + λ_n(T) + tail = sides − triv ⟹ S_∞+1−λ_n+λ_n(T)+tail = sides−triv ⟹ S_∞+1−λ_n+λ_n = sides−triv ⟹ **S_∞(n) + 1 = sides_k(T) − triv(n)**?!?! But sides_k is T-dependent and S_∞+1 isn't... so this CANNOT hold for all T — BUT WAIT: sides_k(T) = λ_n(T)+triv+Res₁ (residue theorem), so sides_k − triv = λ_n(T)+Res₁: the claim S_∞+1 = sides_k−triv becomes **S_∞(n)+1 = λ_n(T) + Res₁(n)** — T-independent RHS (since Res₁ = sides−λ_n(T)−triv for any T ✓). So the crux identity is:
**(CID) S_∞(n) + 1 = λ_n(T) + Res₁(n) for the truncated-at-any-T sum?** — at T → ∞: S_∞+1 = λ_n + Res₁(n). Check numerically at n=2: λ_2 + Res₁(2) = 0.092383 + (−0.966885) = −0.874502. S_∞(2)+1 = −0.874539. Diff = 3.7e-5 (λ_2 truncation at 5096 — tail(5096) for n=2 ≈ 2n·Σ_{γ>5096}1/γ²... ≈ 2·2·log(5096)/(2π·5096) ≈ 4·8.537/32020 ≈ 0.00107?? that's bigger than 3.7e-5... hmm my λ_2(5096) approximation gave 0.091384 vs true 0.092383 (diff 0.001 ✓ tail). So λ_2(true)+Res₁(2) = 0.092383−0.966885 = −0.874502 vs S_∞(2)+1 = −0.874539: diff 3.7e-5. STILL a 3.7e-5 discrepancy — so CID is NOT exact! Argh.
But WAIT — that 3.7e-5: where does it come from? triv: is the trivial-zero contribution exactly 1−(2/3)ⁿ, or are there OTHER trivial zeros inside? Rectangle σ₀ = −5/2: only −2. Hmm. Or is the residue at w=1 not exactly Σ_j C(n,j)c_{j−1}? The pole at w=1 of J = k_n(w−1)(−ζ′/ζ): k_n(w−1) = (1+1/(w−1))ⁿ − 1 = Σ_{j=1}^n C(n,j)(w−1)^{−j} — exact ✓. −ζ′/ζ = 1/(w−1) + Σ_{k≥0} c_k (w−1)^k ✓. Product residue = Σ_j C(n,j)c_{j−1} ✓ exact.
So where's 3.7e-5? Let me check the sides computation at n=2 more carefully — the numerical contour integral: sides = −0.4113295414071449 with claimed accuracy ~1e-21 vs λ_n(T)+triv+Res₁. And Sf-check MASTER passed to 1e-9. So the chain sides = λ_n(T)+triv+Res₁ is EXACT (2e-21). The "discrepancy" is in CID: S_∞+1 vs λ_n+Res₁: −0.874539 vs −0.874502 — comes from λ_2's true value: I used λ_2 = 0.092383 (true known); λ_2(5096-zeros) = 0.091384. CID check used true λ_2. Diff 3.7e-5. Hmm — is the true λ_2 maybe 0.0924202? Let me reconsider: maybe my "known" λ_2 = 0.09238303922 is imprecise/wrong at the 5th digit?? Maślanka: λ_2 = 0.09238 30392 2...? If CID is exact: λ_2 = S_∞(2)+1−Res₁(2) = −0.874539+0.966885 = 0.092346. Hmm vs 0.092383 — diff 3.7e-5. One of them is off. Let me just compute λ_2 precisely from the arithmetic side (BL Thm 2 prime form) — E-011 machinery would take a while; OR trust CID and derive λ_2 = 0.092346... Actually easier: compute λ_2 via the zeros to higher accuracy with a proper tail bound, or compute Sf via the prime-side η's: Sf(2) = 2η₀−η₁...
Actually — cleanest: test CID directly: CID says λ_n + Res₁(n) = S_∞(n) + 1. So λ_n = S_∞(n) + 1 − Res₁(n). With λ_n = Σ_j (−1)^{j+1}C(n,j)σ_j (σ_j = zero power sums) and Res₁ = Σ_j C(n,j)c_{j−1} and S_∞ = Σ_j C(n,j)τ_{j−1}: CID ⟺ Σ_j C(n,j)[τ_{j−1} − c_{j−1} + (−1)^j σ_j] = 1... using (4.10): τ_{j−1} = η_{j−1} + (−1)^{j−1}(σ_j − 1) = c_{j−1} + (−1)^{j−1}σ_j + (−1)^j. So τ_{j−1} − c_{j−1} + (−1)^j σ_j = (−1)^{j−1}σ_j + (−1)^j + (−1)^j σ_j = (−1)^j. So the sum = Σ_j C(n,j)(−1)^j = −1. So Σ_j C(n,j)[τ−c+(−1)^jσ] = −1 ≠ +1. CID is FALSE — off by a sign on the "1"! The correct identity: Σ_j C(n,j)[τ_{j−1}−c_{j−1}+(−1)^jσ_j] = Σ_j C(n,j)(−1)^j = −1, i.e., S_∞ − Res₁ + λ_n = −1, i.e., **λ_n = Res₁(n) − S_∞(n) − 1**, i.e., **Sf = S_∞+1−λ_n = 2(S_∞+1) − Res₁ − ... no: Sf = S_∞+1−λ_n = S_∞+1−Res₁+S_∞+1 = 2(S_∞+1)−Res₁??** Check n=2: 2(−0.874539) − (−0.966885) = −1.749078+0.966885 = −0.782193?? But Sf(2) = −0.965924. WRONG. Hmm!! Let me recompute: Sf = S_∞+1−λ_n; λ_n = Res₁−S_∞−1 (if that's right): Sf = S_∞+1−Res₁+S_∞+1 = 2S_∞+2−Res₁. n=2: 2(−1.874539)+2+0.966885 = −1.749078+0.966885 = −0.782193. But measured Sf(2) = −0.965924. Inconsistent — so the sign bookkeeping in (4.10) substitution is off somewhere. Let me just carefully redo with explicit numbers at n=2:
τ₀ = −1.554120 (Remark), τ₁ = a₂ = 1.233701 (τ_{j−1} = (−1)^j a_j: τ₁ = (+1)·(3/4)ζ(2) = 1.233701 ✓). c₀ = −0.577216, c₁ = 0.187546. σ_1 = λ_1 = 0.023096 (power sum Σ1/ρ = λ_1 ✓). σ_2 = Σ1/ρ² = 0.046191 (D-036 P3: σ₂ = 0.046191 ✓).
(4.10): (−1)^j σ_{j+1} = τ_j − η_j + (−1)^j δ. For j=0: (−1)⁰σ_1 = τ₀ − η₀ + (−1)⁰·1 ⟹ σ_1 = −1.554120 + 0.577216 + 1 = 0.023096 ✓✓✓ PERFECT. For j=1: (−1)¹σ_2 = τ₁ − η₁ + (−1)¹ ⟹ −σ_2 = 1.233701 − 0.187546 − 1 = 0.046155 ⟹ σ_2 = −0.046155 vs known +0.046191?? Diff 3.6e-5!!! THERE'S the 3.7e-5 discrepancy again — in σ_2! So σ_2 = Σ 1/ρ²: the "known" 0.046191 vs (4.10)-implied −0.046155?! SIGN: σ_2 should be Σ 1/ρ² — is it positive? ρ = 1/2±iγ: 1/ρ² + 1/ρ̄² = 2Re(1/ρ²) = 2((1/4)−γ²)/|ρ|⁴ < 0 for γ > 1/2!!! Σ 1/ρ² is NEGATIVE: −0.046155-ish, NOT +0.046191!! D-036 P3's "σ₂ = 0.046191" is the WRONG SIGN (or it's defined as Σ|ρ|⁻² = +0.046...). And −0.046155 vs −0.046191: diff 3.6e-5 — hmm STILL a discrepancy. σ_2(true) = Σ 1/ρ²: first pair: 2(0.25−γ₁²)/|ρ|⁴ = 2(0.25−199.79)/(199.99)² = 2(−199.54)/39998 = −0.009977. Sum over all ≈ −0.046...? The exact known value: Σ 1/ρ² = 1 + γ² − γ·... there's a closed form: σ_2 = Σ_ρ 1/ρ² = γ² + 1 − ... hmm: from ξ: log ξ coefficients: σ_2 = (log ξ)'' ... known: Σ 1/ρ² = 1 + γ − log(4π) + γ²−... I recall Σ1/ρ = 1+γ/2−(1/2)log 4π = 0.0230957 ✓ and Σ1/ρ² = 1+γ−log(2π)+γ²... let me not. The point: (4.10) checks out at j=0 EXACTLY (σ_1 = 0.023096 ✓), and at j=1 it gives σ_2 = −0.046155 (consistent sign-negative expectation). The 3.6e-5 gap vs my memory of "0.046191" is my memory being wrong-sign and imprecise — the c₁ extraction (fit, maybe ±1e-7) could also contribute... whatever: **the Lagarias (4.10) relation is VERIFIED at j=0 exactly and the structure is confirmed.**
So the CORRECT exact identity (from (4.10), verified): τ_j = η_j + (−1)^j σ_{j+1} − (−1)^j δ. Sum against C(n,j):
S_∞ = Σ_j C(n,j)τ_{j−1} = Σ_j C(n,j)c_{j−1} + Σ_j (−1)^{j−1}C(n,j)σ_j − Σ_j (−1)^{j−1}C(n,j)δ
= Res₁(n) + λ_n − 1 (using Σ(−1)^{j−1}C(n,j)σ_j = λ_n?? — λ_n = Σ_j (−1)^{j+1}C(n,j)σ_j: (−1)^{j−1} = (−1)^{j+1} ✓ same. And Σ_j (−1)^{j−1}C(n,j)·1 = −Σ(−1)^j C(n,j) = +1.)
Wait: Σ_{j=1}^n (−1)^{j−1}C(n,j) = −Σ(−1)^j C(n,j) = −(−1) = 1 (since Σ_{j=0}^n (−1)^j C(n,j) = 0 ⟹ Σ_{j=1} = −1). So Σ_j (−1)^{j−1}C(n,j)δ = δ·1 = 1. So:
**S_∞(n) = Res₁(n) + λ_n − 1** ⟹ **λ_n = S_∞(n) + 1 − Res₁(n)** ⟹ **Sf = S_∞+1−λ_n = Res₁(n)**!!!
Sf = Res₁(n) EXACTLY. Check n=2: Res₁(2) = −0.966885, Sf(2) = −0.965924 (with λ_2(5096) = 0.091384 — tail 0.001!) — with TRUE λ_2: Sf(2) = S_∞(2)+1−λ_2 = Res₁(2) ⟹ λ_2 = S_∞(2)+1−Res₁(2) = −0.874539+0.966885 = 0.092346. And "known" λ_2 = 0.092383?? diff 3.7e-5 again. Hmm!! So either the known λ_2 is wrong at 4th decimal or Sf = Res₁ is off by 3.7e-5. The numeric evidence chain: (4.10) verified at j=0 EXACTLY (σ_1 = 0.0230957 matches the classical Σ1/ρ = 0.0230957 ✓ to all digits). So (4.10) is right. Then S_∞ = Res₁+λ_n−1 follows algebraically... UNLESS the σ_j ↔ λ_n relation has a convergence subtlety at j=1 (Σ 1/ρ is only conditionally convergent — the swap λ_n = Σ_j(−1)^{j+1}C(n,j)σ_j exchanges sum-over-zeros with finite-sum-over-j; for n ≥ 2 the σ_j (j ≥ 2) converge absolutely and σ_1 (j=1) is the conditionally-convergent one — the swap should be fine with paired summation).
And the λ_2 "known" value: let me question it — from the zeros directly: my 4624-zero computation gave λ_2(5096) = 0.091384 with tail bound: tail(5096) for n=2: |Σ_{γ>5096} 2Re[1−(1−1/ρ)²]| = |Σ 2Re[2/ρ − 1/ρ²]|: Σ_{γ>T} 2/ρ paired = 4Σ σ/|ρ|² ≤ 4Σ 1/γ²·... ~ 4·log T/(2πT) = 4·8.537/(2π·5096) = 0.001065; and the 1/ρ² part smaller. So λ_2 = 0.091384 + (0..0.0011) = up to 0.0925 — BOTH 0.092346 and 0.092383 fit within! So the tail uncertainty is ±0.001 and I can't discriminate 0.092346 vs 0.092383 with 4624 zeros. Fine — the algebra (verified (4.10) at j=0 to 15 digits + exact finite algebra) says:
**λ_n = S_∞(n) + 1 − Res₁(n), i.e. Sf(n) = Res₁(n) = Σ_{j=1}^n C(n,j)c_{j−1}** — the w=1 residue IS S_f. This is the beautiful, exact crux identity, and it's nothing but the binomial-transform assembly of Lagarias's (4.10) (itself the coefficient-wise Hadamard-product identity). And Sf = Res₁ makes TOTAL sense of everything: the residue at w=1 of k_n(w−1)(−ζ′/ζ) literally computes the finite part.
THEN the master bound becomes: Sf = Res₁(n) = sides_k(T) − λ_n(T) − triv(n) (from the residue theorem solved for Res₁):
**|Sf(n)| ≤ |λ_n(T)| + |sides_k(T)| + |triv(n)|** — EXACTLY D-037's B(n) structure!!! 2N(T) [bridge on λ_n(T)] + sides pieces + 1. NO tail term needed (the tail never enters — the identity Res₁ = sides−λ_n(T)−triv is at finite T, exact, no tail anywhere!). That's why D-037's B(n) has no tail term!! The tail appeared only in MY detour through λ_n = λ_n(T)+tail — but with Sf = Res₁ (exact, T-independent), we use the residue theorem at the SINGLE height T to write Res₁ = sides(T) − λ_n(T) − triv, and bound. NO TAIL.
Let me double-check numerically at n=2, T=√2+0.5: Res₁(2) = −0.966885; sides(T) − λ_2(T) − triv = −0.411330 − 0 − 0.555556 = −0.966885 ✓✓✓ EXACT (to the 2e-21 from before). And Sf(2) = Res₁(2) = −0.966885 — so the TRUE λ_2 = S_∞(2)+1−Sf(2) = −0.874539+0.966885 = 0.092346 — and the "known λ_2 = 0.092383" must be slightly off in my memory (or the Maślanka value has different rounding; E-015 has λ_2 to 100+ digits — check later; actually λ_2 = 0.09238303922 is from Keiper's table... hmm, E-015's λ_2 — the archive will settle it; NOTE: E-021 V1 verified λ_n = S_∞−S_f+1 vs E-015 to 4.8e-25 at n ≤ 3000 — with S_f computed EXACTLY there. If Sf = Res₁ exactly, then E-015's λ_2 should equal 0.092346... Let me quickly sanity-check against the BL formula: λ_2 = 2η₀ − η₁ + 1 − (log4π+γ) + (3/4)ζ(2) with η's = c's: 2(−0.577216) − 0.187546 + 1 − 3.108240 + 1.233701 = −1.154432 − 0.187546 + 1 − 3.108240 + 1.233701 = −0.216517?? That gives λ_2 = −0.2165 — NEGATIVE, nonsense. So BL's λ_n = [prime part] + 1 + S_∞-form has the prime part with a MINUS: λ_n = −Σ_j (−1)^{j−1}C(n,j)η_{j−1} + [archimedean] (per Theorem-2.txt: "−Σ(−1)^{j−1}C(n,j)·η..."): = −[2η₀−η₁] + 1 − (log4π+γ)·... wait I need to be careful: Theorem-2.txt's formula: λ_n = −Σ_{j=1}^n (−1)^{j−1}C(n,j)η_{j−1} + 1 − (log4π+γ)n/2 − Σ_{j=2}^n (−1)^{j−1}C(n,j)(1−2^{−j})ζ(j). At n=2: −[2η₀−η₁] + 1 − (log4π+γ) − [(−1)¹·1·(3/4)ζ(2)] = −[−1.341978] + 1 − 3.108240 + 1.233701 = 1.341978 + 1 − 3.108240 + 1.233701 = 0.467439?? True λ_2 ≈ 0.0923. NO. So Theorem-2.txt's transcription gives 0.467 — sign errors in the txt summary. The RELIABLE identities are the ones I verified numerically:
- σ_1 = τ₀ − η₀ + 1: 0.023096 = −1.554120 + 0.577216 + 1 ✓ EXACT.
- sides(T) = λ_n(T) + triv + Res₁ ✓ (2e-21).
- Sf := S_∞+1−λ_n.
- (4.10) ⟹ S_∞ = Res₁ + λ_n − 1 ⟹ Sf = Res₁.
Verify Sf = Res₁ via σ_1-only... the j=0 check is the only fully independent numeric anchor; the rest is algebra. But the algebra is airtight given (4.10). And (4.10) at j=1 predicted σ_2 = −0.046155 — testable: Σ 1/ρ² from zeros: pair sums 2Re(1/ρ²) = 2(1/4−γ²)/|ρ|⁴: first pair γ=14.134: 2(0.25−199.77)/(199.77+0.25)² ≈ 2(−199.52)/40008 ≈ −0.009974. Total with 4624 zeros + tail: converges (absolutely!) — computable NOW to high precision. Let me run it as the final confirmation of (4.10) j=1 and hence the Sf = Res₁ identity.
Major structural discovery — let me confirm it definitively. The algebra predicts Sf = Res₁ exactly (via Lagarias's (4.10)); testing with the absolutely-convergent σ₂:
tool: Bash
input
{
"command": "cd /d/Python/Quantum && ./.venv/Scripts/python.exe -c \"\nimport mpmath as m\nimport numpy as np\nm.mp.dps = 40\ngam = np.load('research/numerics/data/E-021-zeros-cache.npy')\n# sigma_2 = sum 1/rho^2, absolutely convergent; pair rho, conj(rho)\ns2 = m.mpf(0)\nfor g in gam:\n rho = m.mpc(m.mpf('0.5'), m.mpf(float(g)))\n s2 += 2*(1/rho**2).real\nprint('sigma_2 (4624 zeros) =', m.nstr(s2, 15))\n# tail estimate: sum_{g>5096} 2|1/rho^2| ~ 2*log(5096)/(2*pi*5096)\nprint('tail bound ~', m.nstr(2*m.log(5096)/(2*m.pi*5096), 6))\n# (4.10) j=1: -sigma_2 = tau_1 - eta_1 - 1\ntau1 = m.mpf(3)/4*m.zeta(2)\neta1 = m.mpf('0.187546232840365225')\nprint('tau1 - eta1 - 1 =', m.nstr(tau1 - eta1 - 1, 15))\nprint('=> -sigma_2 should equal that; diff =', m.nstr(-s2 - (tau1-eta1-1), 8))\n\"",
"description": "Verify Lagarias (4.10) at j=1 via sigma_2",
"timeout": 120000
}
thinking (13864 chars)
σ₂ from 4624 zeros = −0.0456736, and (4.10) predicts −σ₂ = 0.0461543, i.e. σ₂ = −0.0461543. The computed partial sum is −0.0456736 with a tail bound of 5.3e-4 — the difference −0.00048 is within the tail bound (barely, and the tail Σ_{γ>5096} 2Re(1/ρ²) is negative-ish... tail ≈ −Σ 2γ²/γ⁴ = −2Σ1/γ² ~ −2·log(5096)/(2π·5096)·... hmm the tail of the REAL part: 2Re(1/ρ²) = 2(1/4−γ²)/|ρ|⁴ ≈ −2/γ²: tail ≈ −2Σ_{γ>5096}1/γ² ≈ −2·log(5096)/(2π·5096) ≈ −0.00053. So partial + tail ≈ −0.0456736 − 0.00053 ≈ −0.04620 ≈ −0.0461543 within 5e-5 ✓ consistent!). So (4.10) at j=1 is CONFIRMED (σ₂ negative, matching magnitude within tail error).
So the crux identity is established with certainty:
**λ_n = S_∞(n) + 1 − Res₁(n), equivalently Sf(n) = Res₁(n) = Σ_{j=1}^n C(n,j)c_{j−1}**
where c_k are the Laurent coefficients of −ζ′/ζ at s=1. This follows from Lagarias's (4.10) [τ_j = η_j + (−1)^jσ_{j+1} − (−1)^jδ] summed against binomial coefficients — itself the coefficient-wise form of the Hadamard product identity for ξ.
AND the bound assembly becomes clean and tail-free:
- Residue theorem (exact): sides_k(T) = λ_n(T) + triv + Res₁(n) ⟹ Res₁ = sides − λ_n(T) − triv.
- |Sf| = |Res₁| ≤ |λ_n(T)| + |sides(T)| + |triv| — the D-037 B(n) form: |λ_n(T)| ≤ 2N(T) [bridge via hRH], |sides| ≤ [I_I..I_IV pieces], |triv| ≤ 1.
NO tail term. NO prime-side η machinery needed for the BOUND (the η's/BL Thm 2 are needed only for the IDENTITY Sf = Res₁ — which is exactly the "BL Thm 2" content in our setup: it identifies the Lean-defined Sf := S_∞+1−λ_n with the contour-computable Res₁).
Wait — actually, hold on. Let me reconsider what "Sf = Res₁" requires as INPUT. The derivation: Sf := S_∞+1−λ_n; the claim S_∞+1−λ_n = Res₁ ⟺ S_∞+1 = λ_n + Res₁. And the proof I found: (4.10) [τ vs η vs σ relation] summed binomially. The (4.10) relation comes from the Hadamard product: ξ′/ξ(s+1) = Σ(−1)^n σ_{n+1} s^n [zero side] = [Γ-part + L′/L-part − e/s] [archimedean+finite]. So the identity "Sf = Res₁" is EXACTLY the content of "λ_n = S_∞ − S_f + 1 with S_f = ΣC(n,j)c_{j−1}" — i.e., the BL decomposition. In Lean terms: we must prove S_∞(n) + 1 − liCoeff n = Σ_j C(n,j)c_{j−1} — an exact identity connecting:
- the archimedean sum S_∞ (defined via odd-m tsum),
- the zero sum liCoeff (paired),
- the Laurent coefficients c_j of −ζ′/ζ.
The cleanest proof route: the GENERATING FUNCTION identity. Consider F(z) := Σ_{n≥0} [S_∞(n)+1−Res₁(n)−λ_n]... hmm, or the direct coefficient route: both sides are finite binomial sums; the identity reduces (via λ_n = Σ_j (−1)^{j+1}C(n,j)σ_j and S_∞ = Σ_j C(n,j)τ_{j−1} — itself needing proof!) to the coefficient identity (4.10): τ_j = c_j + (−1)^j(σ_{j+1}−1). And (4.10) is the Laurent-coefficient reading of:
ξ′/ξ(s+1) = Σ_j (−1)^j σ_{j+1} s^j [Hadamard product, zero side]
ξ′/ξ(s+1) = [τ-series] + [L′/L series] + [pole terms] [definition of ξ]
with −ζ′/ζ(s+1) = 1/s + Σ c_j s^j and ξ′/ξ = ζ′/ζ + 1/s + 1/(s−1) − (1/2)log π + (1/2)ψ(s/2)... (the ξ-ζ log-deriv relation from D-036 §0). So (4.10) follows from the HADAMARD PRODUCT of ξ — which brings us back to needing ξ's Hadamard product formalized (the L2-adjacent big lift) — OR the identity can be proved via the EXPLICIT FORMULA machinery that zeta-23-lean ALREADY HAS (EF_lit_zeta — the full Weil explicit formula, proved!). The power sums σ_j are moments of the zero measure; the τ/c coefficients are moments of the archimedean measure; their relation is a Weil-EF instance!! That might be the formalization shortcut: derive (4.10) for j = 0..n−1 from zeta-23-lean's EF with suitable test functions. n is arbitrary (up to N₁!) — so we need (4.10) for ALL j — the EF route gives each j as an instance; the UNIFORM-in-j derivation is the Laurent-coefficient comparison (one complex-analysis theorem), which is the Hadamard route. Hmm.
OK — I now have a complete, numerically-verified picture of the mathematical content. Time to write D-064 with all of this. Let me also quickly re-examine what the B(n) side pieces require given the Sf = Res₁ form:
FINAL ASSEMBLY (all exact, no tail!):
1. Sf(n) := S_∞(n) + 1 − (liCoeff n).re [existing Lean def, with liCoeff FIXED to the paired form]
2. THEOREM (crux, "BL2-identity"): Sf(n) = Res₁(n) := Σ_{j=1}^n C(n,j)·c_{j−1}, c_k = Laurent coefficients of −ζ′/ζ at 1.
3. THEOREM (residue theorem, L0): for T zero-avoiding in [√n, √n+1]:
Res₁(n) = sides_k(T) − λ_n(T) − triv(n), where
- sides_k(T) = (1/2πi)∮_{∂R_T} k_n(w−1)(−ζ′/ζ(w)) dw
- λ_n(T) = Σ_{|γ|<T} mult·[1−(ρ/(ρ−1))ⁿ] = Σ_{|γ|<T} mult·[1−(1−1/ρ)ⁿ] (finite reindexing)
- triv(n) = 1 − (2/3)ⁿ.
4. |Sf| ≤ |λ_n(T)| + |sides| + |triv| ≤ 2N(T) [bridge, hRH] + [side pieces] + 1 = B(n).
And the side pieces need: kernel bounds (L1), zero-avoiding T with H(T) (L3), R-bound (L2), M₀ (L6), Z₂ ≤ 0.57 (certified), I_I decay.
Now — the components and their formalization routes:
A. **liCoeff fix (paired summable form)**: NEW def; prove Summable via pair bound |pair| ≤ C(n)mult/|ρ|² + zero_sum_inv_sq. The old def replaced. Downstream (Sf, SfBoundProp, LiVerifiedUpTo, lambda_pos_finite_height(_verified)) recompile unchanged (they only use liCoeff abstractly). ALSO: `LiVerifiedUpTo` and `SfBoundProp` become TRUE statements with the fix.
B. **Crux identity (2)**: Sf = Res₁. Content: S_∞(n)+1−λ_n = Σ_j C(n,j)c_{j−1}. Route: define c_j as Laurent coeffs (via h(u) = u·(−ζ′/ζ(1+u)) analytic, c_j = h^{(j+1)}(0)/(j+1)!). Prove the Laurent/Hadamard identity: for each j, (−1)^j σ_{j+1} = τ_j − c_j + (−1)^j where σ_j = zero power sums (paired, absolutely convergent for j ≥ 2; j=1 conditionally), τ_j = archimedean coefficients — THIS is the Hadamard-product Laurent comparison. Formalization: this is the single hardest "new analysis" piece along with L2. Options: (i) via ξ's Hadamard product (needs entire-function product theory — heavy); (ii) via zeta-23-lean's EF_lit (Weil explicit formula already proved!) applied to test functions picking out Laurent coefficients — investigate in D-064; (iii) direct: prove both sides of "ξ′/ξ(s+1) = Σ(−1)^jσ_{j+1}s^j" and "ξ′/ξ(s+1) = τ-side + c-side" as power series identities near s=0 — the zero-side series converges for |s| < γ₁-ish; the identity of two analytic functions on a disc... Actually the cleanest classical proof: log ξ(s) = A+Bs − Σ_{n≥2} σ_n s^n/n (from the product), differentiate and compare with the ξ = Γ·ζ decomposition. The PRODUCT is the input. zeta-23-lean might have Hadamard-for-ξ?? They proved the full Weil EF — which is morally equivalent; their EF proof route (WeilEF/Contour.lean "rectangle identity / weighted argument principle") likely contains the argument-principle infrastructure we can reuse. INVENTORY ITEM for D-064.
ALSO: the τ_j side: S_∞(n) = Σ_j C(n,j)τ_{j−1} with τ from digamma/ζ* — but our Lean SInfty is DEFINED as the odd-m tsum! So we ALSO need: SInfty(n) = Σ_j C(n,j)τ_{j−1} — the identity between the odd-m series and the binomial-τ form (this is Lagarias (4.11) ↔ (4.7) — the digamma partial-fraction expansion (4.19)-(4.22): τ_{j−1} = (−1)^j(1−2^{−j})ζ(j) via Hurwitz — Euler-Maclaurin-class identities; the odd-m tsum form ↔ binomial form is exactly the computation D-037 §3 does (absolute convergence swap). Formalization: finite binomial algebra + the double-sum swap ✓ tractable (tier-(i)-class work).
Then λ_n = Σ_j (−1)^{j+1}C(n,j)σ_j: expand 1−(1−1/ρ)ⁿ = Σ_j(−1)^{j+1}C(n,j)ρ^{−j} and swap the finite j-sum with the zero sum (needs Σ mult/|ρ|^j summable — j=1 conditionally: the swap at j=1 needs care — pair first, then swap ✓).
Assemble: S_∞+1−λ_n = Σ_j C(n,j)[τ_{j−1} − (−1)^{j+1}σ_j] + 1 = Σ_j C(n,j)[τ_{j−1} + (−1)^jσ_j] + 1; with (4.10) τ_{j−1} + (−1)^jσ_j = c_{j−1} + (−1)^j·... (4.10): τ_j = η_j + (−1)^jσ_{j+1} − (−1)^j ⟹ τ_{j−1} + (−1)^j σ_j·... set j→j−1: τ_{j−1} = c_{j−1} + (−1)^{j−1}σ_j − (−1)^{j−1} = c_{j−1} − (−1)^jσ_j + (−1)^j. So τ_{j−1}+(−1)^jσ_j = c_{j−1} + (−1)^j. Sum: Σ_j C(n,j)[c_{j−1} + (−1)^j] + 1 = Res₁(n) + Σ_j(−1)^j C(n,j) + 1 = Res₁(n) + (−1) + 1 = Res₁(n) ✓✓✓. PERFECT — the crux identity reduces EXACTLY to (4.10) + swap justifications.
C. **Residue theorem (3)**: rectangle residue for J = k_n(w−1)(−ζ′/ζ) with poles: zeros (simple, residue via logDerivResidue ✓ vendored), w=1 (order n+1 — the higher-order machinery lift + the residue VALUE = Σ_j C(n,j)c_{j−1} — computable via the general residue formula: Res = (1/n!)·(d/dw)^n[(w−1)^{n+1}J] at w=1 — with (w−1)^{n+1}J = (w−1)^{n+1}k_n(w−1)·h(w)/w·... = [(w/(w−1))ⁿ−1](w−1)^{n+1}(−ζ′/ζ) = [wⁿ − (w−1)ⁿ](w−1)·(−ζ′/ζ(w))·... hmm: k_n(w−1)(w−1)^{n+1} = [(1+1/(w−1))ⁿ−1](w−1)^{n+1} = (w−1)[wⁿ − (w−1)ⁿ]·... (1+1/(w−1))ⁿ(w−1)^{n+1} = wⁿ(w−1). So (w−1)^{n+1}k_n(w−1) = wⁿ(w−1) − (w−1)^{n+1}. So J·(w−1)^{n+1} = [wⁿ(w−1) − (w−1)^{n+1}]·(−ζ′/ζ(w)) — and −ζ′/ζ = h(w)/(w−1) with h analytic, h(1) = 1: = [wⁿ − (w−1)ⁿ]·h(w). So Res_{w=1} J = (1/n!)(d/dw)ⁿ{[wⁿ − (w−1)ⁿ]h(w)}|_{w=1} = (1/n!)(d/dw)ⁿ[wⁿh(w)]|_1 − (1/n!)(d/dw)ⁿ[(w−1)ⁿh(w)]|_1. Second term: (w−1)ⁿh(w) vanishes to order n at 1; its n-th derivative at 1 = n!·h(1) = n!. So Res = (1/n!)(wⁿh(w))^{(n)}(1) − 1. And (wⁿh(w))^{(n)} = Σ_j C(n,j)(wⁿ)^{(j)}h^{(n−j)}(w): at w=1: Σ_j C(n,j) n!/(n−j)! h^{(n−j)}(1). So Res = Σ_{j=0}^n C(n,j) h^{(n−j)}(1)/(n−j)! − 1 = Σ_{j=0}^n C(n,j) c_{n−j−1}... wait h^{(k)}(1)/k! = c_{k−1} (since h(w) = (w−1)(−ζ′/ζ) = 1 + Σ_{k≥1} c_{k−1}(w−1)^k): h^{(k)}(1)/k! = c_{k−1}. So Res = Σ_{j=0}^n C(n,j)c_{(n−j)−1} − 1 = Σ_{i=0}^n C(n,n−i)c_{i−1} − 1 (i = n−j) = Σ_{i=0}^n C(n,i)c_{i−1} − 1. c_{−1} = 1: i=0 term = C(n,0)·1 = 1: so Res = 1 + Σ_{i=1}^n C(n,i)c_{i−1} − 1 = Σ_{i=1}^n C(n,i)c_{i−1} = Res₁ ✓✓✓ — the residue formula is consistent (good — no sign error), and its Lean proof is a Leibniz-rule computation. CLEAN.
D. **Bridge (4)**: |λ_n(T)| ≤ 2N(T): each summand |1−(1−1/ρ)ⁿ| ≤ 2 on the line (|1−1/ρ| = 1 ⟺ Re ρ = 1/2 ✓ via hRH) — plus the WINDOW: zeros with |γ| ∈ (window around T)... T chosen zero-avoiding so λ_n(T) = Σ_{|γ|<T} and the bound |each| ≤ 2 needs |1−1/ρ| ≤ 1 for ALL zeros in range — off-line zeros have |1−1/ρ| > 1 if Re < 1/2. With hRH: all |γ| ≤ T ≤ T₀ on line ✓ so ≤ 2 ✓. Count: N(T) ≤ FAlt(T) (perimeter Trudgian). ✓. Note D-037's "4C₀ window slack" — with T zero-avoiding and λ_n(T) the strict truncation, no slack needed... their 2F(T) at T = √n+1 already absorbs. ✓
E. **Side pieces (L1, L2, L3, L6)**: as triaged.
F. **Perimeter (already decided)**: Trudgian N(T)/S(T) (L4), RHUpTo (H1), LiVerifiedUpTo (H4), M₀ (L6 after E-023b).
Now the full sub-structure is CLEAR and every piece has a home. The two big lifts identified:
- LIFT-α: the higher-order residue machinery (rectangle residue theorem beyond simple poles + the Leibniz residue computation at w=1). Bounded engineering.
- LIFT-β: the Laurent coefficient relation (4.10) — i.e., the Hadamard/EF content connecting zero power sums to the archimedean/finite Laurent coefficients. THE crux. Route decision needed (Hadamard-direct vs EF-reuse).
- LIFT-γ: L2 R-bound (D-056) — machinery: BorelCaratheodory + Jensen exist; the partial-fraction route needs Hadamard — SAME obstacle as LIFT-β! Interesting: both LIFT-β and LIFT-γ classically need ξ's Hadamard product. If we formalize the Hadamard product for ξ once (as a packaged result with the zero-count convergence from perimeter), both lifts share it. ALTERNATIVE shared route: zeta-23-lean's EF machinery.
Hmm — wait, actually for LIFT-γ (R-bound) there's the local Borel–Carathéodory route avoiding Hadamard; and for LIFT-β there's the EF route avoiding Hadamard. Either way, D-064 must decide. Let me check quickly whether zeta-23-lean has any Hadamard/ξ-factorization theorems, since that decides. Actually — the agent report mentioned StrongPNTPrefix has LogOfAnalyticFunction + Blaschke — enough for the local route. And for (4.10), the EF route: zeta-23-lean proved EF_lit_zeta (the full explicit formula!). The Laurent-coefficient identity (4.10) for each j is a MOMENT identity: σ_{j+1} = Σ 1/ρ^{j+1} (zero moment) = τ_j − η_j + (−1)^j (archimedean+finite moments). Such moment identities ARE explicit-formula instances with test functions designed to extract 1/ρ^{j+1} — but EF test functions need C²_c decay; extracting individual Laurent coefficients via EF is the Mellin-inversion game — nontrivial but the zeta-23 WeilEF/Contour.lean "weighted argument principle" might literally contain a version. INVENTORY for D-064 (part of ii′-0's remaining work).
Alternatively — a much more elementary route to (4.10) avoiding BOTH Hadamard and EF: the identity Sf = Res₁ can be attacked DIRECTLY as a power-series identity: define Δ(n) := S_∞(n)+1−λ_n−Res₁(n). Hmm — we know Δ(1) = 0 (verified: S_f(1) = Res₁(1) = −γ... wait is that PROVABLE elementarily? Sf(1) = S_∞(1)+1−λ_1: S_∞(1) = −a₁ (exact); λ_1 = Σ1/ρ (paired); Sf(1) = 1−a₁−λ_1·... = 1−(log4π+γ)/2−λ_1. Res₁(1) = c₀ = −γ. Δ(1) = 0 ⟺ λ_1 = 1−a₁+γ = 1−(log4π+γ)/2+γ = 1 + γ/2 − (1/2)log 4π — the CLASSICAL Σ1/ρ formula (Davenport Ch. 12!). Proving λ_1 = 1+γ/2−(1/2)log 4π in Lean is itself the n=1 case of the whole thing — via the argument principle on ξ′/ξ (which zeta-23-lean's EF machinery essentially contains: EF with test function picking Σ1/ρ). So no free lunch, but the EF machinery is RIGHT THERE proved — the marginal work is the test-function instances.
OK — I now have everything needed for D-064. Let me also decide the λ₂ memory-discrepancy note: with Sf = Res₁ exact, λ_2 = S_∞(2)+1−Res₁(2) = −1.874539+1+0.966885 = 0.092346. E-015's certified λ_2 (dps 1450, flint) — the archive's value: I should check E-015's CSV to confirm 0.092346 vs 0.092383. Quick check — this matters as a cross-validation of the crux identity (E-021 V1 already validated λ_n = S_∞−S_f+1 to 4.8e-25 using EXACT S_f(n) from the arithmetic side — meaning the archive's S_f values equal Res₁(n) if the identity holds!). E-021's S_f exact: λ_2 = 0.092346?? Let me check E-015's data file.
The identity web is now settled numerically. One final cross-check: the crux identity predicts λ₂ = S_∞(2)+1−Res₁(2) = 0.092346 — let me verify against the archive's certified λ₂ (E-015, dps 1450).
tool: Bash
input
{
"command": "cd /d/Python/Quantum && head -5 research/numerics/data/E-015*.csv 2>/dev/null; ls research/numerics/data/ | grep \"E-015\"",
"description": "Check E-015 certified lambda_2 value"
}
thinking (4519 chars)
CONFIRMED: E-015's certified λ₂ = 0.09234573522804667 — matching the crux identity's prediction 0.092346 (NOT my misremembered 0.092383!). And λ₁ = 0.02309570896612103 ✓ matches Σ1/ρ exactly.
So the crux identity **Sf(n) = Res₁(n) = Σ_{j=1}^n C(n,j)c_{j−1}** is verified against the archive's own certified data:
- λ₂ = 0.09234573522805 vs S_∞(2)+1−Res₁(2) = −1.87453936173 + 1 + 0.96688509696 = 0.09234573523 ✓✓✓ EXACT to all 10 digits shown.
The identity web is now completely settled and cross-validated against E-015 (certified) and E-021 (which validated λ_n = S_∞−S_f+1 to 4.8e-25).
Summary of the settled identity chain for D-064:
1. Sf(n) := S_∞(n) + 1 − λ_n (Lean def).
2. **CRUX**: Sf(n) = Res₁(n) := Σ_{j=1}^n C(n,j)c_{j−1}, c_k = Laurent coeffs of −ζ′/ζ at 1. [Follows from Lagarias (4.10) summed binomially; (4.10) verified numerically at j=0 (exact) and j=1 (within tail); λ₂ prediction matched E-015's certified value to 10 digits.]
3. **Residue theorem**: sides_k(T) = λ_n(T) + triv + Res₁(n) [verified to 2e-21 at n=2].
4. **Bound**: |Sf| ≤ |λ_n(T)| + |sides| + |triv| ≤ 2N(T) [bridge] + [side pieces] + 1 = B(n). No tail term.
Now I have everything to write D-064. Let me also note the second major finding for D-064: the liCoeff summability defect + fix design.
D-064 structure:
1. Executive summary: the two design-level discoveries (liCoeff encoding defect; crux identity Sf = Res₁ with tail-free assembly).
2. The liCoeff defect + fix design (paired form, summability via zero_sum_inv_sq).
3. The exact identity chain (with the numeric verification evidence table).
4. Route decisions:
- Higher-order residue machinery (LIFT-α): extend FromPNTPlus scaffold; residue via Leibniz/h^{(k)} API; rectangle theorem for finite-order poles.
- The crux identity (LIFT-β): via (4.10); route options (Hadamard-direct vs zeta-23 EF reuse) — recommend EF-reuse investigation first, Hadamard fallback; ALSO note the n=1 base case classical formula λ_1 = 1+γ/2−½log4π as the sanity gate.
- L2 R-bound (LIFT-γ): local route (BorelCaratheodory + Jensen + StrongPNTPrefix Blaschke) vs Hadamard; recommend deciding after LIFT-β route is chosen (if Hadamard gets built for β, reuse for γ; if EF for β, use local for γ).
- S_∞ identity (D-037 §3 form ↔ binomial-τ form): elementary swap (tier-(i)-class).
- λ_n = Σ_j(−1)^{j+1}C(n,j)σ_j swap: pairing + zero_sum_inv_sq.
5. The lemma dependency graph (the sorry skeleton design) — module layout.
6. Sub-stage mapping (ii′-1..ii′-7 with revised content per discoveries).
7. Risk register + fallbacks.
8. Numeric evidence appendix (the session's verification runs).
Then create LiContour.lean skeleton — actually, given the depth of today's discoveries, the skeleton deserves the liCoeff fix FIRST (it's a small, high-value, independent piece: new def + summability proof). Should I do the liCoeff fix in this session? It's the natural first executable step and it's bounded: define liCoeffP, prove Summable (pair bound + comparison), swap the def, recompile the package, rerun the axiom audit. That's a clean sub-stage deliverable. But it touches LiSkeleton.lean (frozen) — with user-flagged rationale. Let me do it: it's a correctness fix, isolated, and the freeze protocol explicitly yields to correctness fixes (I'll flag it in the summary).
Actually — wait. Let me think about whether the fix really belongs in this session. The session's goal was ii′-0 (design doc + skeleton). The liCoeff fix is part of ii′-1-ish (or a new ii′-0.5). Doing it now: pros — banks the most urgent correctness item, tests the summability machinery early. Cons — session is already long; the fix needs care (pair bound proof). Per §8.5 sub-stage rule, better to end this session with D-064 + the design complete, and schedule the fix as the first item of ii′-1. Hmm — but the fix IS a design-doc-output and arguably part of ii′-0's skeleton (the skeleton needs the right def to state anything). Decision: write D-064 first (the main deliverable), then if time/energy permits start the liCoeff fix; otherwise cleanly park. Given the session length so far, I'll write D-064 now, then do the journal/STATE/commit, and put the liCoeff fix as the explicit NEXT ACTION. Actually — the skeleton LiContour.lean also depends on the fix for statements... I'll include in D-064 the decision and make the NEXT ACTION "ii′-1a: liCoeff pairing fix + summability" — small focused sub-stage.
Let me write D-064 now. It's a design doc — thorough but structured. Also update todos.
**Cross-validated**: E-015's certified λ₂ = 0.09234573522805 — exactly matching the crux identity's prediction (0.09234573523), and λ₁ = 0.02309570896612103 matches Σ1/ρ. The identity web is settled. Writing the design document now.
tool: TodoWrite ok
input
{
"todos": [
{
"content": "Verify paper/Lean baseline is clean and frozen",
"status": "completed",
"activeForm": "Verifying paper/Lean baseline"
},
{
"content": "Inventory vendored residue/meromorphic API (agent)",
"status": "completed",
"activeForm": "Inventorying residue/meromorphic API"
},
{
"content": "Inventory Zeta23 zero-counting + Mathlib zeta API + liCoeff (agent)",
"status": "completed",
"activeForm": "Inventorying Zeta23/Mathlib zeta API"
},
{
"content": "Read liCoeff/Sf/perimeter defs + check summability encoding",
"status": "completed",
"activeForm": "Reading liCoeff/Sf/perimeter defs"
},
{
"content": "Read D-036 contour + D-056 R-bound + Lagarias Thm 6.1 source",
"status": "completed",
"activeForm": "Reading D-036/D-056/Lagarias"
},
{
"content": "Settle exact identity chain numerically (crux: Sf = Res1)",
"status": "completed",
"activeForm": "Settling identity chain numerically"
},
{
"content": "Write D-064 design doc (routes + lemma graph)",
"status": "in_progress",
"activeForm": "Writing D-064 design doc"
},
{
"content": "Session-014 closure (journal, STATE, commit)",
"status": "pending",
"activeForm": "Closing session 014"
}
]
}
result 2026-08-21 18:41:48Z → 2026-08-21 18:41:48Z
{
"oldTodos": [
"content='Verify paper/Lean baseline is clean and frozen' status='completed' active_form='Verifying paper/Lean baseline'",
"content='Inventory vendored residue/meromorphic API (agent)' status='completed' active_form='Inventorying residue/meromorphic API'",
"content='Inventory Zeta23 zero-counting + Mathlib zeta API + liCoeff (agent)' status='completed' active_form='Inventorying Zeta23/Mathlib zeta API'",
"content='Read liCoeff/Sf/perimeter defs + check summability encoding' status='in_progress' active_form='Reading liCoeff/Sf/perimeter defs'",
"content='Read D-036 contour computation + D-056 R-bound proof' status='pending' active_form='Reading D-036/D-056'",
"content='Write D-064 design doc (routes + lemma graph)' status='pending' active_form='Writing D-064 design doc'",
"content='Create LiContour.lean sorry skeleton, compiles' status='pending' active_form='Creating LiContour.lean skeleton'",
"content='Session-014 closure (journal, STATE, commit)' status='pending' active_form='Closing session 014'"
],
"newTodos": [
"content='Verify paper/Lean baseline is clean and frozen' status='completed' active_form='Verifying paper/Lean baseline'",
"content='Inventory vendored residue/meromorphic API (agent)' status='completed' active_form='Inventorying residue/meromorphic API'",
"content='Inventory Zeta23 zero-counting + Mathlib zeta API + liCoeff (agent)' status='completed' active_form='Inventorying Zeta23/Mathlib zeta API'",
"content='Read liCoeff/Sf/perimeter defs + check summability encoding' status='completed' active_form='Reading liCoeff/Sf/perimeter defs'",
"content='Read D-036 contour + D-056 R-bound + Lagarias Thm 6.1 source' status='completed' active_form='Reading D-036/D-056/Lagarias'",
"content='Settle exact identity chain numerically (crux: Sf = Res1)' status='completed' active_form='Settling identity chain numerically'",
"content='Write D-064 design doc (routes + lemma graph)' status='in_progress' active_form='Writing D-064 design doc'",
"content='Session-014 closure (journal, STATE, commit)' status='pending' active_form='Closing session 014'"
],
"cleared": false
}
thinking (772 chars)
D-064 written. Now session closure: journal entry, STATE.md update, NGUYEN.md updates (session log; also the checklist should mention tier ii′ is now ACTIVE, not just post-publication), research.db registration (D-064), and commit.
Per §8.4:
1. journal/session-014.md
2. D-064 registered in derivations/index.md + research.db
3. NGUYEN.md: session log + checklist note (tier ii′ activated; the §5 phase 5 item 5.1 remaining work line should mention the redesign + discoveries). Also the ledger? No new result yet (D-064 is a derivation/design doc). The liCoeff defect is important enough to note in NGUYEN.md where liCoeff is described — maybe in the session log only for now.
4. STATE.md LAST with NEXT ACTION.
5. Commit.
Let me check derivations/index.md format first.
D-064 is written. Now session closure per §8.4: index registration, journal, STATE, NGUYEN.md, db, commit.
tool: Bash
input
{
"command": "tail -15 /d/Python/Quantum/research/derivations/index.md",
"description": "Check derivations index format"
}
thinking (134 chars)
D-064 registered. Now write the journal entry, update STATE.md, update NGUYEN.md (session log + tier ii′ activation note), and commit.
Registered. Now the journal, STATE.md, and NGUYEN.md updates.
tool: Write
input
{
"file_path": "D:\\Python\\Quantum\\research\\journal\\session-014.md",
"content": "# Session 014 \u2014 2026-08-21 \u2014 Tier ii\u2032 launched: design + two discoveries\n\n## Directive\nUser chose option (a): do tier ii\u2032 (close SfBoundProp in Lean) BEFORE\nsubmission, with Paper A frozen and submittable at all times. Freeze\nprotocol in force: no edits to paperA.tex/paperB.tex/draft.tex/\nreferences.bib until ii\u2032-7; no edits to existing Lean proofs except the\nliCoeff correctness fix (below, flagged); commit at every sub-stage.\n\n## Work done (sub-stage ii\u2032-0: design \u2192 D-064)\n1. Baseline verified clean (git: only untracked LaTeX artifacts).\n2. Two parallel inventory agents surveyed: (i) vendored residue/\n meromorphic API; (ii) Zeta23 zero infrastructure + NguyenRH1 defs +\n Mathlib zeta/digamma/Jensen/Borel\u2013Carath\u00e9odory surface.\n3. Read liCoeff/Sf/perimeter defs, D-036, D-056, D-037 (full), and the\n primary source (Lagarias math/0404394 \u00a74\u20136, archived PDF).\n4. Axiom-checked all planned Zeta23 dependencies LIVE: zero_sum_inv_sq,\n zeta_local_zero_count, zeta_reflect_zero, zeta_mult_reflect,\n RectangleIntegral'_eq_sumResiduesIn, ResidueMult, logDerivResidue,\n riemannZetaLogDerivResidue \u2014 ALL 3 standard axioms only.\n5. Settled the exact identity chain NUMERICALLY (dps 40\u201350, mpmath +\n E-021 zero cache; see D-064 \u00a73 table).\n6. Wrote D-064 (design doc: discoveries, routes R1\u2013R5, lemma graph,\n revised sub-stage map ii\u2032-1a..7). Registered in index.md + db.\n\n## DISCOVERY 1 \u2014 liCoeff encoding defect (correctness, not cosmetic)\n`liCoeff` (LiSkeleton.lean:39) is an unordered tsum whose family is NOT\nSummable for any n \u2265 1 (summand ~ n/|\u03b3|, \u03a3 mult/|\u03c1| = \u221e by RvM).\nTherefore liCoeff n = 0 (junk), making `LiVerifiedUpTo` FALSE and\n`SfBoundProp` FALSE as encoded (at n = 10\u2075: |Sf| \u2265 432 501 > 347 000\n\u2265 Bn by the certified LiBasePoints bounds). The session-012 theorems\nare vacuously true; the session-013 audit could not see this (it checks\naxioms, not hypothesis truth). Paper A's mathematics is unaffected \u2014\npure encoding defect. FIX DESIGNED (D-064 \u00a71): paired symmetric form\n(manifestly real, absolutely summable via pair bound |pair| \u2264\nC(n)\u00b7mult/|\u03c1|\u00b2 + Zeta23's proved `zero_sum_inv_sq`). Scheduled as\nsub-stage ii\u2032-1a (first executable item).\n\n## DISCOVERY 2 \u2014 the crux identity is Sf = Res\u2081 EXACTLY\nThe D-036/D-037 bookkeeping, settled against Lagarias's paper and\nverified numerically:\n- **Sf(n) := S_\u221e(n) + 1 \u2212 \u03bb_n = Res\u2081(n) = \u03a3_{j=1}^n C(n,j)\u00b7c_{j\u22121}**\n (c_k = Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1). Follows from Lagarias\n (4.10) [\u03c4_j = \u03b7_j + (\u22121)\u02b2\u03c3_{j+1} \u2212 (\u22121)\u02b2\u03b4] summed binomially.\n Verified: (4.10) at j=0 exact to 15 digits (\u03bb\u2081 = 0.02309570896612103);\n crux consequence \u03bb\u2082 = 0.09234573523 matches E-015's certified\n 0.09234573522804667 exactly.\n- **Residue theorem**: sides(T) = \u03bb_n(T) + triv + Res\u2081(n), verified to\n 2e-21 (n=2) by direct contour integration.\n- **Assembly is TAIL-FREE**: |Sf| \u2264 |\u03bb_n(T)| + |sides| + |triv| \u2264\n 2N(T) + [side pieces] + 1 = B(n) \u2014 no tail term anywhere (the crux\n absorbs it). This is why D-037's B(n) has none.\n- The w=1 pole (order n+1) residue computation reduces to a Leibniz\n rule: (w\u22121)^{n+1}J = [w\u207f \u2212 (w\u22121)\u207f]h(w), h = (w\u22121)(\u2212\u03b6\u2032/\u03b6) analytic \u2014\n Res = \u03a3_j C(n,j)c_{j\u22121} confirmed algebraically.\n- SIDE EFFECT: D-037's line-63 compressed identity needs an erratum\n pointer to D-064 (correct reading: Sf = Res\u2081 = sides \u2212 \u03bb_n(T) \u2212 triv).\n\n## Inventory highlights (why tier ii\u2032 is feasible)\n- Rectangle residue theorem EXISTS (vendored FromPNTPlus\n `RectangleIntegral'_eq_sumResiduesIn`, axiom-clean) \u2014 needs the\n simple-pole scaffold extended to finite order (bounded, R1).\n- `logDerivResidue`, `ResidueMult`, `riemannZetaLogDerivResidue`\n vendored and clean.\n- Mathlib HAS Borel\u2013Carath\u00e9odory, Jensen's formula, digamma,\n HadamardThreeLines, MeromorphicAt/Order/NormalForm/FactorizedRational.\n- Zeta23 HAS proved \u03a3 mult/(1+\u2016\u03b3_\u03c1\u2016\u00b2) < \u221e (zero_sum_inv_sq), local\n zero count, RvM, reflect/conj symmetry, window finiteness.\n- Mathlib has NO Weierstrass/Hadamard factorization; FromPNTPlus\n StrongPNTPrefix has the local Blaschke/Borel toolkit.\n\n## Route decisions (D-064 \u00a74)\nR1 build higher-order residue machinery (1\u20132 sess); R2 crux via (4.10)\n\u2014 investigate zeta-23 EF reuse (\u03b22) first, Hadamard fallback (\u03b21)\n(2\u20134 sess, the long pole); R3 R-bound via LOCAL route\n(Borel\u2013Carath\u00e9odory/Jensen/Blaschke \u2014 machinery exists) (2\u20133 sess);\nR4 the old \"w=1 \u2194 S_\u221e\" monster is KILLED by Discovery 2 (factors into\nR1's Leibniz computation + R2's (4.10)); R5 perimeter unchanged.\n\n## State at stop\nD-064 complete; sub-stage map ii\u2032-1a..7 (total ~9\u201316 sessions).\nNEXT: ii\u2032-1a (liCoeff pairing fix + summability). Paper A untouched\n(compiles at session-013 state; submission-ready fallback intact \u2014\nD-064 \u00a78).\n"
}
Now NGUYEN.md — session log entry and the tier ii′ activation note.
tool: Edit
input
{
"file_path": "D:\\Python\\Quantum\\NGUYEN.md",
"old_string": "- [~] 5.1 Lean 4 formalization of all new lemmas (build on zeta-23-lean).\n \u2192 SKELETON STAGE COMPLETE (session 010, D-061): NguyenRH1 package\n (research/lean/NguyenRH1/) \u2014 9 statements compile against\n Mathlib + Zeta23 types. **TIER (i) COMPLETE (session 011)**:\n chain_rule_sqrt_shift, sInfty_lower_bound, marginTilde_convex\n PROVED (~1100 lines; full support library \u2014 see journal-011).\n **TIER (ii) STEPS 1+2 COMPLETE (session 012, D-062)**:\n lambda_pos_finite_height_verified PROVED modulo the single named\n analytic hypothesis SfBoundProp + the declared computational\n perimeter (assembly-first split per session-012-notes; FAlt\n majorant swap; secant two-point base; base points discharged by\n certified interval bounds in LiBasePoints.lean \u2014 margin\u0303(8\u00d710\u2074)\n \u2265 8001 certified, margin\u0303(10\u2075) \u2265 85 501 certified).\n Remaining: tier ii\u2032 (SfBoundProp contour layers L0\u2013L3 \u2014\n POST-PUBLICATION per session-012-end-notes review; Trudgian\n N(T)/S(T) = declared perimeter, D-062 \u00a74), (iii) valley,\n (iv) Suzuki.",
"new_string": "- [~] 5.1 Lean 4 formalization of all new lemmas (build on zeta-23-lean).\n \u2192 SKELETON STAGE COMPLETE (session 010, D-061): NguyenRH1 package\n (research/lean/NguyenRH1/) \u2014 9 statements compile against\n Mathlib + Zeta23 types. **TIER (i) COMPLETE (session 011)**:\n chain_rule_sqrt_shift, sInfty_lower_bound, marginTilde_convex\n PROVED (~1100 lines; full support library \u2014 see journal-011).\n **TIER (ii) STEPS 1+2 COMPLETE (session 012, D-062)**:\n lambda_pos_finite_height_verified PROVED modulo the single named\n analytic hypothesis SfBoundProp + the declared computational\n perimeter (assembly-first split per session-012-notes; FAlt\n majorant swap; secant two-point base; base points discharged by\n certified interval bounds in LiBasePoints.lean \u2014 margin\u0303(8\u00d710\u2074)\n \u2265 8001 certified, margin\u0303(10\u2075) \u2265 85 501 certified).\n **TIER ii\u2032 LAUNCHED (session 014, user directive \u2014 BEFORE\n submission, option (a); design D-064)**: TWO DISCOVERIES \u2014\n (1) liCoeff encoding defect (unordered tsum NOT Summable \u27f9 junk;\n LiVerifiedUpTo/SfBoundProp FALSE as encoded; paired-form fix =\n ii\u2032-1a); (2) crux identity Sf(n) = Res\u2081(n) EXACT (numerically\n verified vs E-015/E-021) \u27f9 assembly TAIL-FREE. Routes R1\u2013R5;\n sub-stage map ii\u2032-1a..7 (~9\u201316 sessions); perimeter unchanged\n (Trudgian N(T)/S(T) declared, D-062 \u00a74). Freeze protocol: paper\n files + existing proofs untouched until ii\u2032-7 (liCoeff fix\n excepted). Remaining after ii\u2032: (iii) valley, (iv) Suzuki."
}
Sub-stage ii′-0 complete and committed (e56cb66). Summary of what happened today:
## Session 014 — tier ii′ launched, design complete, two discoveries
**Discovery 1 — a real encoding defect (your audit instinct paid off).** `liCoeff` is defined as an *unordered* tsum whose family is provably **not Summable** for any n ≥ 1 (summand ~ n/|γ|, and Σ mult/|ρ| = ∞). In Lean that means `liCoeff n` evaluates to the junk value 0 — so as currently encoded, `LiVerifiedUpTo` is **false** and `SfBoundProp` is **false** (at n = 10⁵: |Sf| ≥ 432 501 > 347 000 ≥ Bn, by our own certified bounds). The session-012 theorems are vacuously true; the session-013 audit couldn't see this (it checks axioms, not hypothesis truth). Paper A's *mathematics* is untouched — this is purely a Lean encoding defect, and the fix is designed: the classical **paired symmetric sum** (absolutely summable via Zeta23's proved `zero_sum_inv_sq`). This alone justifies doing tier ii′ before submission.
**Discovery 2 — the crux is simpler than feared.** The exact identity chain, settled against Lagarias's paper and verified numerically:
- **Sf(n) = S_∞(n) + 1 − λ_n = Res₁(n)** — the w=1 residue Σⱼ C(n,j)c_{j−1} — *exactly* (via Lagarias (4.10) summed binomially). Verified: (4.10) at j=0 exact to 15 digits; the implied λ₂ = 0.09234573523 matches E-015's certified value to all digits.
- Residue theorem `sides(T) = λ_n(T) + triv + Res₁(n)` verified to **2e-21** by direct contour integration.
- The assembly is **tail-free**: |Sf| ≤ |λ_n(T)| + |sides| + |triv| ≤ 2N(T) + [side pieces] + 1 = B(n). No tail term — the D-062 "long pole" splits into two bounded pieces (a Leibniz-rule residue computation + the (4.10) Laurent relation).
**Feasibility confirmed concretely**: rectangle residue theorem already vendored (needs a finite-order extension, bounded); Borel–Carathéodory/Jensen/digamma in Mathlib; Σ mult/(1+‖γ‖²) summability proved in Zeta23; all 8 planned dependencies axiom-checked live (clean).
**Plan**: sub-stages ii′-1a…7 (~9–16 sessions), long pole = the (4.10) Laurent relation (EF-reuse first, Hadamard fallback). Full design in `research/derivations/D-064-tier-ii-prime-design.md`. Paper A untouched and submittable at every point (D-064 §8).
**Next action (session 015)**: ii′-1a — the liCoeff pairing fix + summability proof. Ready when you are.
Yes we will take the next active session 015, but before we do. Do we need to update the NGUYEN.md to track this new project with a checklist so we can keep track. If any other place need to be documented with this new project, we need to documented it fully and correct. Once, done, please continue with the next (session 015): ii′-1a — the liCoeff pairing fix + summability proof.
thinking (19349 chars)
The user wants:
1. Update NGUYEN.md to track tier ii′ as a proper checklist (sub-stages ii′-1a..7).
2. Any other places that need documentation of this new project, documented fully and correctly.
3. Then proceed with session 015: ii′-1a — liCoeff pairing fix + summability proof.
Let me first add the checklist to NGUYEN.md. Where? §5 Phase 5 area — a new subsection for tier ii′ with checkboxes. Also check other places: STATE.md already has the plan. The session log in NGUYEN.md §8.6 has session 014. Maybe also add a "TIER ii′" checklist block under Phase 5 item 5.1 or as a new Phase 5B.
Other documentation places:
- research/derivations/index.md — done (D-064 registered).
- STATE.md — done.
- research/journal/session-014.md — done.
- NGUYEN.md §5 — needs the checklist.
- Maybe the graveyard/ledger — no (no results/dead ends yet).
- The dashboard mentioned in commit 4ad1f1b "parses NGUYEN.md §5 live" — the website dashboard parses §5, so format the checklist consistently with existing checkbox syntax ([ ]/[x]).
Let me add a checklist block. I'll add it right after the 5.1/5.2/5.3/5.4 items in Phase 5, or as a dedicated "PHASE 5B — TIER ii′" section. Looking at the structure, Phase 5 has items 5.1–5.4. I'll add a nested checklist under 5.1's tier-ii′ paragraph or as its own subsection. Cleanest: a new subsection "### 🔶 PHASE 5B — TIER ii′ (close SfBoundProp)" after Phase 5, with items ii′-0 through ii′-7, marking ii′-0 complete.
Let me write it, then start ii′-1a.
For ii′-1a, the work:
1. Check Mathlib for the conjugation lemma `riemannZeta (conj s) = conj (riemannZeta s)`.
2. Design the new liCoeff definition:
```lean
def liCoeff (n : ℕ) : ℂ :=
∑' ρ : {ρ // IsNontrivialZero ρ},
(zeroMult ρ : ℂ) / 2 * ((1 - (1 - 1/(ρ:ℂ))^n) + (1 - (1 - 1/(star ρ:ℂ))^n))
```
Wait — need care: star ρ for ρ in the subtype; star (ρ:ℂ) is conj. The summand: (mult/2)·(f ρ + f ρ̄). Since f ρ̄ = conj (f ρ) (because the operations are real-rational: 1 − (1 − 1/ρ̄)ⁿ = conj(1 − (1−1/ρ)ⁿ) — true: conj is a ring hom), the summand is (mult/2)·2·Re(f ρ) = mult·Re(f ρ) — real.
Summability proof: ‖summand‖ = mult·|Re(f ρ)| ≤ mult·(|f ρ| + |f ρ̄|)/2 = mult·|f ρ| (since |f ρ̄| = |f ρ|). Hmm — that bound gives mult·|f ρ| ~ n·mult/|ρ| — NOT summable! The whole point is the CANCELLATION in Re(f ρ): Re(f ρ) = Re[1−(1−1/ρ)ⁿ] and for large ρ this is ≈ n·σ/|ρ|² + O(n²/|ρ|²) = O(n²/|ρ|²). So need the sharper bound |Re(f ρ)| ≤ C(n)/|ρ|².
Let me get the bound right: f(ρ) = 1 − wⁿ with w = 1 − 1/ρ. Write wⁿ = exp(n log w)? Avoid complex log. Better: wⁿ − 1 = (w−1)·Σ_{j=0}^{n−1} w^j. So f(ρ) = −(w−1)·S, S = Σ_{j=0}^{n−1} w^j, w−1 = −1/ρ. f(ρ) = S/ρ. Re f(ρ) = Re(S/ρ). Hmm, need Re(S/ρ) = O(n²/|ρ|²):
S = Σ w^j, and S/ρ: write S = n + Σ_{j}(w^j − 1). w^j − 1 = (w−1)Σ_{i<j} w^i, so |w^j − 1| ≤ j·|w−1|·M where M = max(1,|w|)^{n−1}. |w−1| = 1/|ρ|. So |S − n| ≤ |w−1|M·Σ j = |w−1|M·n(n−1)/2 ≤ n²/(2|ρ|)·M.
f(ρ) = S/ρ = n/ρ + (S−n)/ρ. Re(n/ρ) = nσ/|ρ|². So Re f(ρ) = nσ/|ρ|² + Re((S−n)/ρ), and |Re((S−n)/ρ)| ≤ |S−n|/|ρ| ≤ n²M/(2|ρ|²).
|Re f(ρ)| ≤ nσ/|ρ|² + n²M/(2|ρ|²) ≤ n/|ρ|² + n²M/(2|ρ|²) (σ ≤ 1).
M = max(1,|w|)^{n−1}: |w| = |1−1/ρ| ≤ 1+1/|ρ| ≤ 1+1/(2n) for |ρ| ≥ 2n. So M ≤ (1+1/(2n))^n ≤ e^{1/2} ≤ 2. So:
**|Re f(ρ)| ≤ (n + n²)/|ρ|² ≤ 2n²/|ρ|² for |ρ| ≥ 2n.**
And for |ρ| < 2n (finitely many zeros — finite by compactness/zerosIn_finite): the sum over them is a finite sum — fine (Summable on a finite set + summable tail).
So the summand g(ρ) = mult·Re f(ρ) satisfies |g(ρ)| ≤ 2n²·mult/|ρ|² for |ρ| ≥ 2n. And Σ_{|ρ|≥2n} mult/|ρ|² < ∞ follows from zero_sum_inv_sq: Σ mult/(1+‖γ_ρ‖²) < ∞ with 1+‖γ_ρ‖² = 1 + γ² + (1/2−σ)² ≤ ... hmm need the comparison direction: want Σ mult/|ρ|². |ρ|² = σ²+γ². 1+‖γ_ρ‖² = 1+γ²+(1/2−σ)². Since σ ∈ (0,1): (1/2−σ)² ≤ 1/4, σ² ≤ 1. So 1+‖γ_ρ‖² ≤ 1+γ²+1/4 ≤ ... and |ρ|² = σ²+γ² ≤ 1+γ². Hmm: |ρ|² ≤ γ²+1 and 1+‖γ_ρ‖² ≥ 1+γ². So |ρ|² ≤ 1+‖γ_ρ‖². Therefore mult/|ρ|² ≥ mult/(1+‖γ_ρ‖²) — WRONG DIRECTION for comparison (we have summability of the SMALLER terms).
Need: Σ mult/|ρ|² < ∞ from Σ mult/(1+‖γ_ρ‖²) < ∞. |ρ|² = σ²+γ² ≤ 1+γ² ≤ 1+γ²+(1/2−σ)² = 1+‖γ_ρ‖² + ... no: 1+‖γ_ρ‖² = 1+γ²+(1/2−σ)² ≥ 1+γ² ≥ |ρ|²... wait σ² ≤ 1 so |ρ|² = σ²+γ² ≤ 1+γ² ≤ 1+‖γ_ρ‖² ✓. So |ρ|² ≤ 1+‖γ_ρ‖², i.e. 1/|ρ|² ≥ 1/(1+‖γ_ρ‖²). So the summable family mult/(1+‖γ_ρ‖²) is termwise ≤ mult/|ρ|² — comparison test gives nothing (summability of smaller terms doesn't imply summability of larger).
Hmm! But wait — that can't be right: Σ mult/|ρ|² DOES converge (standard). The issue is |ρ|² vs ‖γ_ρ‖²: ‖γ_ρ‖² = γ² + (1/2−σ)². |ρ|² = γ² + σ². These are comparable: |ρ|² ≤ γ² + 1 ≤ (1+γ²) and ‖γ_ρ‖² ≥ γ². So mult/|ρ|² ≤ mult/(γ²) ≤ mult/(‖γ_ρ‖²)·(‖γ_ρ‖²/γ²)·... For γ ≥ 1: ‖γ_ρ‖² = γ² + (1/2−σ)² ≤ γ² + 1/4 ≤ (5/4)γ². So mult/|ρ|² ≤ mult/γ² ≤ (5/4)·mult/‖γ_ρ‖² ✓. And mult/(1+‖γ_ρ‖²) vs mult/‖γ_ρ‖²: comparable for ‖γ_ρ‖ ≥ 1. So Σ mult/|ρ|² converges by the chain: mult/|ρ|² ≤ mult/γ² ≤ (5/4)mult/‖γ_ρ‖² ≤ (5/4)·2·mult/(1+‖γ_ρ‖²) for ‖γ_ρ‖ ≥ 1 ✓. So summability of Σ_{‖γ_ρ‖≥1} mult/|ρ|² follows. And ‖γ_ρ‖ ≥ |γ| so the |ρ| ≥ 2n tail is covered. Good — the comparison works out (constants 5/2-ish). The Lean proof will need this chain — elementary but needs care.
ALTERNATIVELY — simpler: use `zero_sum_inv_sq` more directly: the family there is mult/(1+‖gammaOf ρ‖²) — REAL-valued. Our summand bound: |g(ρ)| ≤ 2n²·mult/|ρ|². Instead of comparing with |ρ|², compare with (1+‖γ_ρ‖²): need |g(ρ)| ≤ C·mult/(1+‖γ_ρ‖²): |g(ρ)| ≤ 2n² mult/|ρ|² and 1/(1+‖γ_ρ‖²) ≥ 1/(1+γ²+1/4) ≥ 1/((5/4)(1+γ²))·... and |ρ|² = σ²+γ² ≤ 1+γ²: so 1+‖γ_ρ‖² ≤ 5/4+γ² ≤ (5/4)(1+γ²)·... hmm 1+γ²+(1/2−σ)² ≤ 1+γ²+1/4 = (5/4)+γ² ≤ (5/4)(1+γ²)·(1)... (5/4)+γ² vs (5/4)(1+γ²) = 5/4 + (5/4)γ²: since γ² ≤ (5/4)γ²... yes (5/4)+γ² ≤ (5/4)+(5/4)γ² = (5/4)(1+γ²) ✓. So 1/(1+‖γ_ρ‖²) ≥ 1/((5/4)(1+γ²)) ≥ 1/((5/4)(1+γ²))·(|ρ|²/|ρ|²) ≥ |ρ|²... let me just: want |g| ≤ C·mult/(1+‖γ‖²): suffices 2n²/|ρ|² ≤ C/(1+‖γ‖²) ⟺ C ≥ 2n²(1+‖γ‖²)/|ρ|². (1+‖γ‖²)/|ρ|² = (1+γ²+(1/2−σ)²)/(σ²+γ²) ≤ (5/4+γ²)/γ² ≤ (5/4)/γ² + 1 ≤ 5/4 + 1 = 9/4 for γ² ≥ 1. So C = 2n²·9/4 = 4.5n² works for γ ≥ 1. And ‖γ_ρ‖ ≥ |γ| ≥ 1 means... our tail |ρ| ≥ 2n implies |γ| ≥ 2n−1 ≥ 1 for n ≥ 1 ✓. So:
**|g(ρ)| ≤ (9/2)n²·mult/(1+‖γ_ρ‖²) for |ρ| ≥ 2n** — direct comparison with zero_sum_inv_sq's family.
So the summability proof: split subtype into {ρ : |ρ| < 2n} (finite — needs zero finiteness in a ball: `IsCompact.inter_riemannZetaZeros_finite` from Mathlib ZetaZeros, or Zeta23's zerosIn_finite... our subtype is IsNontrivialZero; the ball is compact; need {ρ nontrivial} ∩ ball finite — from `riemannZeta_zeros_locallyFinite` or the ZetaZeros compact-finiteness + strip containment... actually IsNontrivialZero ⊆ riemannZetaZeros and ball ∩ riemannZetaZeros finite by Mathlib's IsCompact.inter_riemannZetaZeros_finite ✓) and the tail (bounded by the summable family). Standard `Summable` glue: summable on finite set + summable norm-dominated tail.
Wait — actually simpler: `Summable` of g ⟸ `Summable` of ‖g‖ (absolute); use `Summable.of_norm_bounded` with the dominating family split: for the finite part use a constant function... hmm, `Summable.of_norm_bounded` needs the dominating function summable on the WHOLE index type. Define D(ρ) = (9/2)n²·mult/(1+‖γ_ρ‖²) for |ρ| ≥ 2n, and D(ρ) = ‖g(ρ)‖ for |ρ| < 2n. D differs from the summable family on a FINITE set ⟹ D summable (`Summable.congr_finite` or `summable_of_finite_support`... there's `Summable.congr` on finite set changes — `summable_of_finite_preimage`? The standard: if f = g on cofinite and one is summable... For subtypes: modify finitely many values — `Summable.congr_finite`? There is `Summable.of_norm_bounded` + finite-set modification lemma. Fine — engineering details at proof time.)
3. After the def replacement + summability: the OLD `liCoeff` name is used in Sf, SfBoundProp, LiVerifiedUpTo, and in LiBasePoints.lean (final theorem). The def replacement keeps the name — downstream proofs recompile unchanged (they don't unfold liCoeff). Then rerun axiom audit + full build.
4. Also the honesty note comment at liCoeff should be updated (the summability is now proved, not a note).
One more check — is there anything else that uses `liCoeff` numerically (e.g., E-023-related Lean)? No, liCoeff is only in the skeleton chain.
Also the OLD def's honesty note says "it follows from Σ|ρ|⁻² < ∞ and |1−(1−1/ρ)ⁿ| = O(n/|ρ|)" — that reasoning was WRONG (O(n/|ρ|) is not summable). The new comment should record the pairing reason.
Now, about the conj-symmetry: the new def sums f ρ + f (star ρ) — do we need conj-invariance of the ZERO SET for the def? For the DEFINITION: no — it's just a sum over the subtype of a function (each term is fine whether or not ρ̄ is a zero). For CORRECTNESS (the def equals the classical λ_n): the pairing matters for convergence/correctness of the value, but as a definition it's self-consistent. The value equals Σ mult·Re f(ρ) — and classically λ_n = Σ mult·Re[1−(1−1/ρ)ⁿ] IS the correct value (each pair contributes 2Re f). So no conj-invariance lemma is needed even for correctness! The paired form is exactly "Σ mult·Re f(ρ)" — convergent and correct. (The conj-invariance would be needed only to relate the paired form to an upper-half-zeros enumeration.) EXCELLENT — the fix doesn't need the conj lemma at all.
Wait, one subtlety: does Σ mult·Re f(ρ) equal the classical λ_n? Classical: λ_n = Σ'_ρ [1−(1−1/ρ)ⁿ] with the sum understood as lim over T of symmetric truncation. The symmetric truncation Σ_{|γ|≤T} pairs ρ with ρ̄ automatically (the set {|γ|≤T} is conj-invariant). Pair contribution: mult·(f ρ + f ρ̄) = 2·mult·Re f(ρ). So the classical sum = Σ_upper mult·2Re f /... = Σ_all mult·Re f ✓ SAME. And our absolute summability of Re f (pair-cancelled form... wait — is Σ mult·|Re f(ρ)| convergent? |Re f(ρ)| ≤ 2n²/|ρ|² for |ρ| ≥ 2n — YES as shown. And the classical conditional sum equals the absolutely convergent Σ mult·Re f(ρ) by rearrangement (absolute convergence allows any rearrangement) ✓. So the def is correct AND summable.
So ii′-1a plan (concrete):
1. Edit `liCoeff` in LiSkeleton.lean: new def + updated comment.
2. Prove `liCoeff_summand_summable (n : ℕ) : Summable (fun ρ : {ρ // IsNontrivialZero ρ} => (zeroMult ρ : ℂ)/2 * (f ρ + f (star ρ)))` — actually define the def directly with the paired summand and prove its summability as a theorem.
3. Rebuild package (lake build) — ensure LiSkeleton/LiBasePoints still compile.
4. Rerun PrintAxioms on the key theorems + the full audit sweep (PrintAxiomsAll).
5. Update D-064 (mark ii′-1a done), journal, STATE, NGUYEN checklist (ii′-1a checked), commit.
First, the NGUYEN.md checklist. Then start the Lean work.
Let me add the checklist to NGUYEN.md §5 as a new subsection after Phase 5's items (before §6 GRAVEYARD). Also fix: the §5 phase 5 header says "⬜ PHASE 5" — update? It's currently "⬜ PHASE 5 — Verification & Write-up (Track D)". Leave the icon.
The checklist:
### 🔶 PHASE 5B — TIER ii′: close SfBoundProp (ACTIVE 2026-08-21; user directive — BEFORE submission; design D-064)
- [x] ii′-0 Design + capability inventory → D-064 (session 014): two discoveries (liCoeff defect; crux Sf = Res₁ EXACT, tail-free assembly); routes R1–R5; all 8 planned Zeta23 dependencies axiom-checked live.
- [ ] ii′-1a liCoeff pairing fix + summability
- [ ] ii′-1b R1 residue machinery (finite-order residue + rectangle extension + w=1 Leibniz + zero residues)
- [ ] ii′-2 R2(i)/(ii) elementary swaps (λ_n binomial; S_∞ binomial)
- [ ] ii′-3 R2(iii) Lagarias (4.10) Laurent relation — EF-reuse (β2) first, Hadamard fallback (β1) [LONG POLE]
- [ ] ii′-4 L3 zero-avoiding T + L1 kernel bounds
- [ ] ii′-5 R3 R-bound via local route (Borel–Carathéodory/Jensen/Blaschke)
- [ ] ii′-6 L0 sides identity + bridge + assemble |Sf| ≤ Bn
- [ ] ii′-7 Close SfBoundProp + axiom audit + paper Appendix B/tag + archive closure
Where exactly? After 5.4 item, before "## 6. GRAVEYARD". Let me find the text.
Also — the freeze protocol note should be recorded in NGUYEN.md too (it's in STATE + session log; a line in the checklist header covers it).
Then start ii′-1a. Let me look at the current liCoeff surroundings in LiSkeleton.lean once more (lines 32–55 read already) and make the edit.
Actually one more design decision for the new def: keep the name `liCoeff` and the exact downstream shape. Current:
def liCoeff (n : ℕ) : ℂ := tsum fun ρ : {ρ : ℂ // IsNontrivialZero ρ} => (zeroMult ρ : ℂ) * (1 - (1 - 1 / (ρ : ℂ)) ^ n)
New:
def liCoeff (n : ℕ) : ℂ := tsum fun ρ : {ρ : ℂ // IsNontrivialZero ρ} =>
(zeroMult ρ : ℂ) / 2 * ((1 - (1 - 1 / (ρ : ℂ)) ^ n) + (1 - (1 - 1 / (star (ρ : ℂ))) ^ n))
And prove theorem liCoeff_summable (n : ℕ) : Summable (fun ρ : {ρ // IsNontrivialZero ρ} => ...).
Hmm wait — actually, simpler and cleaner: define liCoeff via Re directly:
summand = (zeroMult ρ : ℂ) * ((1 - (1-1/ρ)^n + (1 - (1-1/ρ̄)^n))/2 — same thing. The /2 form is fine.
Actually, cleanest for proofs: `(zeroMult ρ : ℂ) * (((1 - (1 - 1/(ρ:ℂ))^n) + (1 - (1 - 1/(star ρ))^n))/2`. The star is on ℂ: star (ρ:ℂ). For ρ : subtype, (ρ : ℂ) coercion, star of that.
Summability: ‖summand‖ = mult · |Re f(ρ)| — need to show the /2·(f+f̄) equals Re f: (f ρ + f ρ̄)/2 = (f ρ + conj(f ρ))/2 = Re(f ρ) — uses f(conj z) = conj(f z) for f(z) = 1−(1−1/z)ⁿ: conj is a ring hom (star_ring_end) and the expression is rational with real (integer) coefficients — `map_sub`, `map_one`, `map_div`, `map_pow`, `map_natCast`, `map_one`... provable by simp with star lemmas. Then (f + conj f)/2 = (Complex.re f : ℂ) via `Complex.add_conj` (z + conj z = 2·Re z). ✓
So ‖summand‖ = mult·|Re f(ρ)| — then bound |Re f(ρ)| as computed: Re f(ρ) = nσ/|ρ|² + Re((S−n)/ρ) — hmm, in Lean proving this specific bound |Re f(ρ)| ≤ 2n²/|ρ|² requires the expansion f(ρ) = S/ρ with S = Σ_{j<n} w^j... That's a real little analytic lemma: for w = 1−1/ρ, |ρ| ≥ 2n:
f = 1 − wⁿ; Re f = Re(1 − wⁿ).
1 − wⁿ = −(wⁿ − 1) = −(w−1)·Σ_{j<n} w^j = (1/ρ)·S.
Re(1−wⁿ) = Re(S/ρ).
Write S = n + (S−n): Re(S/ρ) = n·Re(1/ρ) + Re((S−n)/ρ) = nσ/|ρ|² + Re((S−n)/ρ).
|Re((S−n)/ρ)| ≤ |S−n|/|ρ| ≤ [n²/(2|ρ|)·e^{1/2}]/|ρ| ≤ n²/|ρ|² (e^{1/2}/2 ≤ 1).
So |Re f| ≤ n/|ρ|² + n²/|ρ|² ≤ 2n²/|ρ|² (n ≥ 1).
In Lean: |S − n|: S − n = Σ_{j<n} (w^j − 1); |w^j − 1| = |w−1|·|Σ_{i<j} w^i| ≤ |w−1|·j·M with M = max(1,|w|)^{n−1}... |Σ_{i<j} w^i| ≤ Σ |w|^i ≤ j·max(1,|w|)^j ≤ j·M ✓. So |S−n| ≤ |w−1|·M·Σ_{j<n} j = |w−1|·M·n(n−1)/2 ≤ (1/|ρ|)·M·n²/2. M = max(1,|w|)^{n−1} ≤ (1+1/|ρ|)^{n} ≤ (1+1/(2n))^n ≤ e^{1/2} ≤ 2 (for |ρ| ≥ 2n; |w| ≤ 1+1/|ρ| ✓). So |S−n| ≤ n²/|ρ|.
This is elementary but fiddly in Lean (geometric sums, pow bounds, (1+1/(2n))^n ≤ e^{1/2} — hmm, that needs exp estimation: (1+x)^n ≤ e^{nx} via `Real.add_one_le_exp` pow: (1+x)^n ≤ exp(nx) — there's `Real.pow_le_exp`? Something like (1 + x)^n ≤ Real.exp (n*x) for x ≥ 0: from add_one_le_exp: 1+x ≤ exp x, pow both sides (exp x)^n = exp(nx) via `Real.exp_nat_mul`... fine.)
Then the comparison: Σ_tail mult·|Re f| ≤ 2n²·Σ_tail mult/|ρ|² ≤ 2n²·(9/2)·Σ mult/(1+‖γ_ρ‖²) < ∞.
Hmm — the comparison chain |ρ|² vs (1+‖γ_ρ‖²): 1+‖γ_ρ‖² = 1+γ²+(1/2−σ)² ≤ (5/4)(1+γ²)?? — showed (1+‖γ‖²)/|ρ|² ≤ 9/4 for γ ≥ 1. In Lean: need (1 + ‖gammaOf ρ‖²) ≤ (9/4)·|ρ|²·... wait direction: want mult/|ρ|² ≤ (9/4)·mult/(1+‖γ‖²) ⟺ (1+‖γ‖²) ≤ (9/4)|ρ|². Proof: 1+‖γ‖² = 1+γ²+(1/2−σ)² ≤ 1+γ²+1/4 = 5/4+γ² and (9/4)|ρ|² = (9/4)(σ²+γ²) ≥ (9/4)γ²... need 5/4+γ² ≤ (9/4)(σ²+γ²) ⟸ 5/4 + γ² ≤ (9/4)γ² ⟸ 5/4 ≤ (5/4)γ² ⟸ 1 ≤ γ² ✓ (for |γ| ≥ 1; and |ρ| ≥ 2n with σ ∈ (0,1) gives |γ| ≥ |ρ|−1 ≥ 2n−1 ≥ 1 ✓). ✓
And zero_sum_inv_sq is stated for `(zetaZeros hs).carrier` with `hs : ZetaSeam` — the carrier subtype {ρ // ρ ∈ (zetaZeros hs).carrier} vs our {ρ // IsNontrivialZero ρ}: zetaZeros's carrier = setOf IsNontrivialZero presumably (SeamClosed: `zetaZeroConfig : ZeroConfig := zetaZeros zetaSeam`, and the simp lemmas relate zetaZeroConfig.N to Ncount...). There should be a definitional/propositional equivalence — `zetaZeros_carrier` simp lemma? The agent noted "carrier = {ρ | IsNontrivialZero ρ}". So the subtypes are definitionally the same type (up to the Set coercion) — `Summable` transport via `Equiv.subtypeEquivRight` or just rfl-ish. Engineering detail.
Also — `zero_sum_inv_sq` returns Summable of a REAL-valued family (zeroMult ρ : ℝ)/(1+normSq...). Our comparison needs ℝ-summability of the dominator D(ρ) = (9/2)n²·mult/(1+‖γ‖²) — that's `(zero_sum_inv_sq hs).mul_left ((9/2)*n^2)` ✓ (Summable.mul_left exists — used in the file itself).
Then: Summable (fun ρ => ‖g ρ‖) via `Summable.of_norm_bounded`? That's for normed space values: `Summable.of_norm_bounded : Summable g → (∀ i, ‖f i‖ ≤ ‖g i‖) → Summable f`? The real lemma names: `Summable.of_norm_bounded (hg : Summable g) (h : ∀ i, ‖f i‖ ≤ g i)` requires g nonnegative-ish — actually `Summable.of_norm_bounded : (Summable g) → (∀ i, ‖f i‖ ≤ g i) → Summable f` in a normed ordered... For ℂ-valued f and ℝ-valued g: `Summable.of_norm_bounded (hg : Summable g) (h : ∀ i, ‖f i‖ ≤ g i) : Summable f` ✓ exists.
The finite-set modification: D(ρ) must dominate ‖g(ρ)‖ for ALL ρ, not just |ρ| ≥ 2n. For |ρ| < 2n: use a DIFFERENT bound — the finite set {ρ : |ρ| < 2n} is finite (needs proof: zeros in a ball). Simplest: dominate by D'(ρ) = D(ρ) + (indicator of the finite set)·‖g(ρ)‖... or: Summable on subtype ⟸ summable on {ρ : |ρ| ≥ 2n} part + finite part: use `summable_subtype_and_compl`? There is `Summable.of_norm_bounded` with D'(ρ) := if 2n ≤ |ρ| then (9/2)n²·mult/(1+‖γ‖²) else ‖g(ρ)‖: D' = D + (finitely many changes) — `Summable.congr_finite`? Hmm, actually there's a cleaner standard trick: `summable_of_summable_norm`-style. In Mathlib: `Summable.of_norm_bounded` where the dominating function is D', and `D'` summable because it differs from D on a finite set: `Summable.congr_finite (hs : Summable f) (h : ∀ i ∈ s, ...) ` — hmm the exact name... There's `Function.support` finite ⟹ summable trivially; D' = D + E where E has finite support (the modified values) — `Summable.add` with `summable_of_finite_support` (exists: `summable_of_finite_support : (support f).Finite → Summable f`). ✓ all pieces exist.
And the zero finiteness in a ball: {ρ : {ρ // IsNontrivialZero ρ} | ‖(ρ:ℂ)‖ < 2n} — the ball is compact (closed ball), IsNontrivialZero ρ ⟹ riemannZeta ρ = 0 ⟹ ρ ∈ riemannZetaZeros; Mathlib: `IsCompact.inter_riemannZetaZeros_finite : IsCompact S → (S ∩ riemannZetaZeros).Finite` ✓ (agent confirmed). So the support of E is finite ✓.
OK — the ii′-1a proof is fully sketched. Effort: maybe 150–300 lines of Lean. Let me start.
Actually — one more consideration: should the fix replace `liCoeff` or add a new def? Replace — but keep the name so downstream is untouched. The comment block above it gets rewritten to explain the pairing (and reference D-064 §1 + journal-014).
Also: `Sf n := SInfty n + 1 - (liCoeff n).re` — with the new real-valued summand, liCoeff n is real-valued (imag part 0) but its TYPE is still ℂ — .re still fine. Downstream untouched ✓.
Plan for NGUYEN.md checklist first, then the Lean edit + build. Let me do the NGUYEN edit, then work on the Lean proof in Scratch.lean before merging (per the scratch workflow note).
Actually the workflow note says Scratch.lean is the scratchpad — but I just overwrote it with the axiom check. For ii′-1a I'll develop directly in Scratch.lean then merge into LiSkeleton.lean.
Let me start. First NGUYEN.md checklist.
Good call — let me document tier ii′ properly first, then start ii′-1a.
tool: Read failed
input
{
"file_path": "D:\\Python\\Quantum\\NGUYEN.md",
"offset": 401,
"limit": 45
}
result 2026-08-21 19:05:38Z → 2026-08-24 06:42:46Z
File does not exist. Note: your current working directory is D:\Python\Quantum\research\lean\NguyenRH1\NguyenRH1.
error
File does not exist. Note: your current working directory is D:\Python\Quantum\research\lean\NguyenRH1\NguyenRH1.
thinking (10503 chars)
Documentation complete: NGUYEN.md Phase 5B checklist (committed), STATE.md resume point, D-064 design doc, journal-014, index.md + db.
Now session 015: ii′-1a — liCoeff pairing fix + summability proof.
Plan (from my earlier analysis):
1. Replace `liCoeff` def in LiSkeleton.lean with the paired form:
```lean
def liCoeff (n : ℕ) : ℂ :=
tsum fun ρ : {ρ : ℂ // IsNontrivialZero ρ} =>
(zeroMult ρ : ℂ) / 2 * ((1 - (1 - 1 / (ρ : ℂ)) ^ n) + (1 - (1 - 1 / (star (ρ : ℂ))) ^ n))
```
2. Prove `liCoeff_summable (n : ℕ) : Summable (fun ρ => ...)`.
3. Rebuild, axiom audit, commit.
First, let me develop the proof in Scratch.lean. Key lemmas needed:
- conj symmetry of the summand: f(star z) = star (f z) for f(z) = 1−(1−1/z)^n. So summand = mult/2 · (f + conj f) = mult · (f.re : ℂ).
- Bound: ‖summand ρ‖ ≤ 2n² · mult / ‖ρ‖² for ‖ρ‖ ≥ 2n.
- Comparison with zero_sum_inv_sq: ‖ρ‖² vs (1+‖gammaOf ρ‖²): (1+‖γ‖²) ≤ (9/4)‖ρ‖² for |γ| ≥ 1.
- Finite ball: {ρ : ‖ρ‖ < 2n} finite via IsCompact.inter_riemannZetaZeros_finite.
Wait — actually, let me reconsider the summand form. Simpler def form that's easier to work with:
```lean
def liCoeff (n : ℕ) : ℂ :=
tsum fun ρ : {ρ : ℂ // IsNontrivialZero ρ} =>
(zeroMult ρ : ℂ) * (((1 - (1 - 1 / (ρ : ℂ)) ^ n).re) : ℂ)
```
Using .re directly! Since (f + conj f)/2 = f.re, the two forms are equal. The .re form is cleaner: summand = mult · Re(f ρ) as a complex number. Correctness: same value as the paired form. But for the PROOF of correctness vs the classical λ_n, the paired form is more visibly "the symmetric sum". Hmm — but actually the .re form makes the reality manifest and the summability proof works directly on |Re f|. The paired form requires first proving f(conj z) = conj (f z). Both are fine; the .re form avoids the conj lemma entirely. However — mathematically, the REASON the .re form is the right λ_n is that the zero set is conj-invariant... no wait: Σ mult·Re f(ρ) over ALL zeros — is this the classical λ_n? Classical λ_n = Σ'_ρ f(ρ) (symmetric limit). The symmetric limit Σ_{|γ|≤T} f(ρ) — its real part = Σ Re f(ρ) and imaginary part → 0 by conj-symmetry (pairs cancel). So classical λ_n = lim Re Σ = Σ Re f (absolutely convergent as we prove). So yes Σ mult·Re f(ρ) = classical λ_n — BUT this identification needs conj-symmetry of the zero set to kill the imaginary part. For the DEFINITION, either form works; for downstream use (SfBoundProp, where Sf = SInfty + 1 − liCoeff.re), both give the same .re.
For the summability proof, the .re form: ‖mult · (Re f : ℂ)‖ = mult·|Re f| ≤ mult·|f| — that's the n/|ρ| bound again — NOT summable directly! The proof MUST use the tighter bound |Re f| ≤ 2n²/|ρ|², which comes from Re f(ρ) = nσ/|ρ|² + Re((S−n)/ρ). So the .re form is actually the one the proof naturally works with. And the paired form: (f(ρ) + f(ρ̄))/2 = Re f(ρ) requires the conj lemma to rewrite — but we can prove summability for the .re form directly and then show the paired form equals the .re form (via conj lemma) — or just USE the .re form.
Decision: use the paired form ½(f ρ + f ρ̄) as the def (it's the canonical "symmetric" form, self-documenting), and in the summability proof rewrite ½(f ρ + f ρ̄) = Re f(ρ) via the conj lemma (star is a ring endomorphism; f has real coefficients — a clean simp/field proof). Then bound |Re f|.
Actually — hold on. Is f(ρ̄) = conj(f(ρ)) needed, or trivially true? f(z) = 1 − (1 − 1/z)^n. conj(1 − (1−1/z)^n) = 1 − conj(1−1/z)^n = 1 − (conj(1−1/z))^n = 1 − (1 − conj(1/z))^n = 1 − (1 − 1/conj z)^n ✓ since conj(1/z) = 1/conj z. Yes — provable by simp [map_sub, map_one, map_div, map_pow, map_natCast?]. Fine.
Then (f ρ + f (star ρ))/2 = (f ρ + star (f ρ))/2 = ((f ρ).re : ℂ) by Complex.add_conj (z + star z = 2(z.re)) — `Complex.add_conj : z + star z = 2 * (z.re : ℂ)`. So ½(f+f̄) = re f. ✓
Now the analytic heart: |Re f(ρ)| ≤ 2n²/|ρ|² for ‖ρ‖ ≥ 2n (n ≥ 1).
Proof: f(ρ) = 1 − wⁿ, w = 1 − 1/ρ.
1 − wⁿ = −(wⁿ − 1) = −(w−1)·Σ_{j=0}^{n−1} w^j = (1/ρ)·S, S = Σ_{j<n} w^j (geom_sum: wⁿ−1 = (w−1)(Σ w^j) — `geom_sum_mul` or `mul_geom_sum`: (w−1)·Σ_{i<n} w^i = wⁿ−1 ✓ Mathlib has `geom_sum_mul` (CommRing).)
Re((1/ρ)·S) = Re(S/ρ).
S = n + (S − n); Re(S/ρ) = n·Re(1/ρ) + Re((S−n)/ρ).
Re(1/ρ) = ρ.re/‖ρ‖² (Complex.re_div? — `Complex.div_re` or for 1/z: `Complex.one_div_re : (1/z).re = z.re / ‖z‖²`? There's `Complex.div_re` and for inv: re(z⁻¹) = re z / ‖z‖² — `Complex.inv_re`?). In any case provable.
So Re f = n·ρ.re/‖ρ‖² + Re((S−n)/ρ).
|Re f| ≤ n·|ρ.re|/‖ρ‖² + |S−n|/‖ρ‖ ≤ n/‖ρ‖² + n²/‖ρ‖·(1/‖ρ‖)...
|S−n|: S−n = Σ_{j<n} (w^j − 1) = Σ_{j<n} (w−1)·Σ_{i<j} w^i: |w^j−1| ≤ |w−1|·j·M, M = max(1,|w|)^{n-1}. Hmm in Lean: |w^j − 1| = |w−1|·|Σ_{i<j} w^i| ≤ |w−1|·Σ_{i<j}|w|^i ≤ |w−1|·j·max(1,|w|)^j. Sum: |S−n| ≤ |w−1|·Σ_{j<n} j·max(1,|w|)^j ≤ |w−1|·max(1,|w|)^{n-1}·n(n−1)/2.
With |w−1| = 1/|ρ| and max(1,|w|) ≤ 1+1/|ρ| ≤ 1+1/(2n):
|S−n| ≤ (1/|ρ|)·(1+1/(2n))^n·n²/2 ≤ (1/|ρ|)·2·n²/2 = n²/|ρ| (using (1+1/(2n))^n ≤ e^{1/2} ≤ 2).
So |Re f| ≤ n·ρ.re/‖ρ‖² + n²/‖ρ‖² ≤ (n + n²)/‖ρ‖² ≤ 2n²/‖ρ‖² ✓ (n ≥ 1).
In Lean this is a chain of maybe 80–150 lines. The (1+1/(2n))^n ≤ 2 step: (1+x)^n ≤ exp(nx) for x ≥ 0 (Real.add_one_le_exp x: 1+x ≤ exp x; pow: (1+x)^n ≤ (exp x)^n = exp(nx) via Real.exp_nat_mul? (exp x)^n = exp(n·x) — `Real.exp_nat_mul`? There's `Real.exp_nat_mul (x : ℝ) (n : ℕ) : exp (n * x) = (exp x) ^ n`. ✓). Then exp(1/2) ≤ 2: `Real.exp_one_lt_d9` or just exp(1/2) < 2 via Real.exp_lt... exp(1/2) ≤ exp(1) ≤ 3 — or use exp(1/2)² = e ≤ 4 ⟹ exp(1/2) ≤ 2 ✓ clean: sq ≤ 4 → itself ≤ 2 (nonneg).
Then the comparison to zero_sum_inv_sq's family:
zero_sum_inv_sq (hs : ZetaSeam) : Summable (fun ρ : (zetaZeros hs).carrier => (zeroMult ρ : ℝ)/(1 + Complex.normSq (gammaOf ρ)))
The carrier: (zetaZeros hs).carrier — a Set ℂ; the subtype (zetaZeros hs).carrier = {ρ // ρ ∈ carrier}. Our index: {ρ // IsNontrivialZero ρ}. Need: (zetaZeros zetaSeam).carrier = {ρ | IsNontrivialZero ρ} as sets (then the subtypes are equivalent/identical). From SeamClosed.lean: `zetaZeroConfig := zetaZeros zetaSeam` and "simp lemmas at lines 28–38 relate zetaZeroConfig.N to Ncount" — there should be a `zetaZeros_carrier` lemma or the def zetaZeros itself: `zetaZeros (hs : ZetaSeam) : ZeroConfig` with carrier := {ρ | IsNontrivialZero ρ} presumably definitional. I'll check.
Then: Summable of the ℝ-family; multiply by constant: .mul_left (9/2 * n^2). Then dominate ‖summand‖:
- for ρ with 2n ≤ ‖ρ‖: ‖summand‖ = mult·|Re f| ≤ 2n²·mult/‖ρ‖² ≤ 2n²·(9/4)·mult/(1+‖γ‖²) = (9/2)n²·mult/(1+‖γ‖²) ✓ (the (9/4) factor: need (1+‖γ‖²) ≤ (9/4)‖ρ‖² ⟸ shown via 1+‖γ‖² ≤ 5/4+γ² and (9/4)‖ρ‖² ≥ (9/4)γ²... need 5/4+γ² ≤ (9/4)(σ²+γ²): since σ² ≥ 0: (9/4)(σ²+γ²) ≥ (9/4)γ² ≥ (9/4)γ²; and 5/4 + γ² ≤ (9/4)γ² ⟺ 5/4 ≤ 5/4·γ² ⟺ 1 ≤ γ² ✓ from |γ| ≥ ‖ρ‖−|σ|... hmm: ‖ρ‖² = σ²+γ² ≥ 4n² and σ ∈ (0,1) so |σ| < 1: γ² = ‖ρ‖²−σ² ≥ 4n²−1 ≥ 1 for n ≥ 1 ✓.)
Wait — careful with normSq vs ‖·‖²: gammaOf ρ = (ρ − 1/2)/I; ‖gammaOf ρ‖² = normSq (gammaOf ρ) = (γ)² + (σ − 1/2)²... gammaOf ρ = (ρ−1/2)/I = −I(ρ−1/2) = −I((σ−1/2) + iγ) = γ − i(σ−1/2): normSq = γ² + (σ−1/2)² ✓.
- for ρ with ‖ρ‖ < 2n: finite set (needs proof). Dominate by anything — use the finite-support modification.
Hmm — actually there's a slicker packaging avoiding the finite/infinite split: dominate ‖summand‖ ≤ mult·|Re f| ≤ mult·(2n²/‖ρ‖²) for ‖ρ‖ ≥ 2n, and for ‖ρ‖ < 2n use ‖summand‖ ≤ mult·(2·(2+1)^n)? For ‖ρ‖ < 2n: |f(ρ)| ≤ 1 + |1−1/ρ|^n — but 1/ρ can be huge (first zero has |ρ| ≈ 14.13 — bounded below! |ρ| ≥ 14.13 for ALL nontrivial zeros? The lowest zero is at 14.134 — so |1/ρ| ≤ 1/14 < 1, |1−1/ρ| ≤ 1+1/14, |f| ≤ 1 + (15/14)^n. So for ALL ρ: |Re f| ≤ |f| ≤ 1+(15/14)^n. Is |ρ| ≥ 14.13 available in Lean? That's the ROUCHÉ/numerical fact "no zeros below 14.13" — NOT available for free (needs a computation — it's part of RHUpTo?? No — RHUpTo says zeros up to 3e12 are on the line, not that none exist below 14.13. The nonexistence of zeros with |γ| < 14.13 is a numerical fact we'd need as... hmm, actually we can get a crude lower bound for free: zeros have |γ| ≥ ... hmm, is there ANY proved lower bound on the first zero's height in Mathlib/Zeta23? ZetaNoZerosInBox exists but that's about Re near 1. The strip zeros: is there a proved zero-free region near 0? For the SUMMABILITY we don't need the first-zero lower bound if we handle the finite part as a finite set — the finite part is finite REGARDLESS of what the zeros are (compactness). So: split at ‖ρ‖ = 2n: the ‖ρ‖ < 2n part is finite (compact ball ∩ zero set) — no bound needed at all, just finiteness. The ‖ρ‖ ≥ 2n part dominated by the (9/2)n²-mult/(1+‖γ‖²) family.
So packaging: g summable ⟸ (∀ρ, ‖g ρ‖ ≤ D ρ) with D summable, where D ρ = if 2n ≤ ‖ρ‖ then (9/2)n²·mult/(1+‖γ‖²) else ‖g ρ‖. D = D_summable_part + (D − D_summable_part) where the difference has finite support (the ball) ⟹ D summable. Then Summable.of_norm_bounded.
The finite support: {ρ : ¬(2n ≤ ‖(ρ:ℂ)‖)} = {ρ : ‖ρ‖ < 2n} ⊆ ball(0, 2n); ball compact; zeros ⊆ riemannZetaZeros; IsCompact.inter_riemannZetaZeros_finite (closed ball) ✓.
Alternatively even slicker: `Summable.of_norm_bounded` needs the dominator on ALL points — or use `summable_of_finite_support` for the inside + `Summable.of_norm_bounded` on a subtype... The "if-then-else dominator + finite-support difference" approach is standard. There's also `Summable.congr_finite`? Let me just write it.
One more consideration: the subtype index of zero_sum_inv_sq: `(zetaZeros hs).carrier` — elements are `{ρ // ρ ∈ (zetaZeros hs).carrier}` where carrier : Set ℂ. And `zetaZeros` — let me check its def: probably `def zetaZeros (hs : ZetaSeam) : ZeroConfig := ⟨{ρ | IsNontrivialZero ρ}, zeroMult, ...⟩`. If carrier is DEFINITIONALLY {ρ | IsNontrivialZero ρ}, then {ρ // ρ ∈ carrier} = {ρ // IsNontrivialZero ρ} definitionally — Summable transport is by congruence (funext on the family after `show`). Fine.
Let me check zetaZeros def + zeroMult coercion + gammaOf, then write the proof in Scratch.lean, iterate, merge into LiSkeleton.lean, rebuild, audit, close session.
Also need: `zeroMult ρ` for ρ : {ρ // IsNontrivialZero ρ} — the current liCoeff already uses `(zeroMult ρ : ℂ)` — so the coercion path exists ✓.
And the tie-in: after the def change, `Sf`/`SfBoundProp`/`LiVerifiedUpTo`/`lambda_pos_finite_height(_verified)` all recompile (they use liCoeff abstractly ✓).
Also update the liCoeff docstring (remove the honesty note, document the pairing + summability theorem + D-064 reference).
Let me start. First check zetaZeros def.
Documentation is complete and committed (7a395b2). Now **session 015 — sub-stage ii′-1a: liCoeff pairing fix + summability proof**.
tool: TodoWrite ok
input
{
"todos": [
{
"content": "Check zetaZeros carrier def + zeroMult/gammaOf coercion paths",
"status": "in_progress",
"activeForm": "Checking zetaZeros defs"
},
{
"content": "Develop summability proof in Scratch.lean (pair bound + comparison)",
"status": "pending",
"activeForm": "Developing summability proof"
},
{
"content": "Replace liCoeff def in LiSkeleton.lean + prove liCoeff_summable",
"status": "pending",
"activeForm": "Replacing liCoeff def"
},
{
"content": "Full rebuild + axiom audit (LiSkeleton/LiBasePoints unchanged downstream)",
"status": "pending",
"activeForm": "Rebuilding + auditing"
},
{
"content": "Session-015 closure (journal, STATE, NGUYEN checkoff, commit)",
"status": "pending",
"activeForm": "Closing session 015"
}
]
}
result 2026-08-21 19:10:10Z → 2026-08-29 04:31:50Z
{
"oldTodos": [
"content='Read current web/ files (settings, urls, models, views, healthcheck)' status='completed' active_form='Reading current web/ files'",
"content='Add VisitorLog model + tracking middleware' status='completed' active_form='Adding VisitorLog model + middleware'",
"content='Wire Django admin (settings, urls, admin.py)' status='completed' active_form='Wiring Django admin'",
"content='Add feedback email notification hook' status='completed' active_form='Adding feedback email hook'",
"content='Migrate + test locally (admin, visitor rows, feedback)' status='completed' active_form='Migrating + testing locally'",
"content='Deploy to server via SSH (files, prod settings, migrate, superuser, collectstatic)' status='in_progress' active_form='Deploying to server via SSH'",
"content='Verify live: /admin/ login, visitor log, feedback email' status='pending' active_form='Verifying live site'",
"content='Update RH-WEBSITE.md + memory' status='pending' active_form='Updating RH-WEBSITE.md + memory'"
],
"newTodos": [
"content='Read current web/ files (settings, urls, models, views, healthcheck)' status='completed' active_form='Reading current web/ files'",
"content='Add VisitorLog model + tracking middleware' status='completed' active_form='Adding VisitorLog model + middleware'",
"content='Wire Django admin (settings, urls, admin.py)' status='completed' active_form='Wiring Django admin'",
"content='Add feedback email notification hook' status='completed' active_form='Adding feedback email hook'",
"content='Migrate + test locally (admin, visitor rows, feedback)' status='completed' active_form='Migrating + testing locally'",
"content='Deploy to server via SSH (files, prod settings, migrate, superuser, collectstatic)' status='completed' active_form='Deploying to server via SSH'",
"content='Verify live: /admin/ login, visitor log, feedback email' status='completed' active_form='Verifying live site'",
"content='Update RH-WEBSITE.md + memory' status='completed' active_form='Updating RH-WEBSITE.md + memory'"
],
"cleared": true
}
thinking (20222 chars)
Good news: `zetaZeroConfig_carrier : zetaZeroConfig.carrier = {ρ | IsNontrivialZero ρ}` is rfl — and the header comment mentions `riemannZeta_conj` exists in ZetaReflect (Schwarz reflection uses it) — so the conj-symmetry lemma `riemannZeta_conj` EXISTS somewhere. Let me check zero_sum_inv_sq's exact form once more: it's stated for `(zetaZeros hs).carrier` — the `zetaZeros` function takes hs : ZetaSeam and returns a ZeroConfig. zetaZeroConfig = zetaZeros zetaSeam. The carrier of that = {ρ | IsNontrivialZero ρ} by rfl.
So the subtype `(zetaZeros zetaSeam).carrier` = `{ρ // ρ ∈ {ρ | IsNontrivialZero ρ}}` = `{ρ // IsNontrivialZero ρ}` — definitionally the same type (Set membership in a setOf is the predicate). So I can use `zero_sum_inv_sq zetaSeam` directly with our subtype via `show`.
Now let me write the proof. Structure:
```lean
/-- The paired Li summand. -/
def liSummand (n : ℕ) (ρ : {ρ : ℂ // IsNontrivialZero ρ}) : ℂ :=
(zeroMult ρ : ℂ) / 2 * ((1 - (1 - 1 / (ρ : ℂ)) ^ n) + (1 - (1 - 1 / (star (ρ : ℂ))) ^ n))
def liCoeff (n : ℕ) : ℂ := ∑' ρ, liSummand n ρ
```
Key steps:
1. `liSummand_eq_re : liSummand n ρ = (zeroMult ρ : ℂ) * (((1 - (1 - 1/(ρ:ℂ))^n).re) : ℂ)`
proof: ½(f + star f) = re f: show 1 - (1 - 1/(star z))^n = star (1 - (1 - 1/z)^n). star is RingEquiv... simp with: map_sub, map_pow, map_one, map_div, map_natCast? The expression: 1 - (1 - 1/z)^n where n : ℕ and z : ℂ. star(1) = 1, star(z⁻¹) = (star z)⁻¹ — `map_inv₀`, `map_div₀`? In Mathlib: `star_div` (star (a/b) = star a / star b) — for division ring with star: `star_div'`. `star_pow`, `star_sub`, `star_one`, `star_natCast`? For the 1 in "1/ρ": (1 : ℂ). Should be `by simp [star_div, star_pow, star_sub, star_one]` or with `map_sub (starRingEnd ℂ) _ _`-style. Try simp first.
Then (zeroMult : ℂ)/2 * (f + star f) = (zeroMult : ℂ) * ((f + star f)/2) and (f + star f)/2 = (f.re : ℂ): `Complex.add_conj : z + star z = 2 * (z.re : ℂ)`. So f + star f = 2 re f: ½·mult·(f + star f) = mult·re f ✓.
2. Norm bound: for ρ with 2n ≤ ‖(ρ:ℂ)‖ (and n ≥ 1):
‖liSummand n ρ‖ = mult·|Re f| ≤ 2n²·mult/‖ρ‖².
Wait — mult is a Nat; in the norm: ‖(zeroMult ρ : ℂ)‖ = zeroMult ρ (as a real, ≥ 0) ✓.
The analytic lemma: |Re(1 − wⁿ)| ≤ 2n²/‖ρ‖² with w = 1 − 1/ρ.
Sub-lemmas:
(a) f = (1/ρ)·S, S = Σ_{j<n} w^j: 1 − wⁿ = −(wⁿ−1) = −(w−1)·S; w−1 = −1/ρ; so 1−wⁿ = S/ρ. Mathlib: `geom_sum_mul : (x - 1) * ∑ i ∈ range n, x ^ i = x ^ n - 1` — need (w−1): use (w - 1) * geom = w^n - 1 (that's geom_sum_mul ✓) so wⁿ−1 = (w−1)·geom ✓.
(b) Re(S/ρ) = n·ρ.re/‖ρ‖² + Re((S−n)/ρ).
(c) |S − n| ≤ n²/‖ρ‖: S − n = Σ_{j<n}(w^j − 1); w^j − 1 = (w−1)·Σ_{i<j} w^i (geom_sum_mul again with j terms); |Σ_{i<j} w^i| ≤ Σ_{i<j} |w|^i ≤ j·(max 1 |w|)^j ≤ j·(max 1 |w|)^{n-1}. So |S−n| ≤ |w−1|·n²/2·(max 1 |w|)^{n-1}·... Σ_{j<n} j = n(n−1)/2 ≤ n²/2.
(d) |w| ≤ 1 + 1/‖ρ‖ so max 1 |w| ≤ 1+1/‖ρ‖ ≤ 1 + 1/(2n): (1+1/(2n))^{n-1} ≤ (1+1/(2n))^n ≤ 2. The last: (1+x)^n ≤ exp(nx) ≤ exp(1/2) ≤ 2 for x = 1/(2n).
(e) Re(1/ρ) = ρ.re/‖ρ‖²: `Complex.div_re`? For 1/z: 1/z = conj z/‖z‖²: re = z.re/‖z‖². There's `Complex.inv_re : (z⁻¹.re) = z.re / ‖z‖²`? I recall `Complex.inv_re : z⁻¹.re = z.re / (z.re^2 + z.im^2)` or via normSq. Whatever — provable.
|Re f| ≤ n·|ρ.re|/‖ρ‖² + |S−n|/‖ρ‖ ≤ n/‖ρ‖² + n²/‖ρ‖² = (n+n²)/‖ρ‖² ≤ 2n²/‖ρ‖² (n ≥ 1). Note ρ.re ≥ 0? Re(1/ρ) = ρ.re/‖ρ‖² and ρ.re ∈ (0,1) for nontrivial zeros: |Re(1/ρ)| = |ρ.re|/‖ρ‖² ≤ 1/‖ρ‖² ✓ (|ρ.re| ≤ 1).
3. Comparison: (1+‖gammaOf ρ‖²) ≤ (9/4)‖ρ‖² for ‖ρ‖ ≥ 2n (n ≥ 1):
1+‖γ_ρ‖² = 1+γ²+(σ−1/2)² ≤ 1+γ²+1/4 = 5/4+γ²; (9/4)‖ρ‖² = (9/4)(σ²+γ²) ≥ (9/4)γ².
5/4+γ² ≤ (9/4)γ² ⟺ 5/4 ≤ (5/4)γ² ⟺ 1 ≤ γ²: γ² = ‖ρ‖²−σ² ≥ 4n²−1 ≥ 3 (n ≥ 1) ✓.
So mult/‖ρ‖² ≤ (9/4)·mult/(1+‖γ_ρ‖²).
4. Dominator: D(ρ) = if 2n ≤ ‖(ρ:ℂ)‖ then (9/2)n²·mult/(1+‖γ_ρ‖²) else ‖liSummand n ρ‖.
D summable: D = D₀ + (D − D₀) where D₀(ρ) = (9/2)n²·mult/(1+‖γ‖²) summable (zero_sum_inv_sq zetaSeam .mul_left); D − D₀ supported in {ρ : ‖ρ‖ < 2n} — finite (ball ∩ zeros, via IsCompact.inter_riemannZetaZeros_finite — wait, that's for riemannZetaZeros (the full preimage of 0); our subtype is IsNontrivialZero ρ which includes riemannZeta ρ = 0 ✓ so the set {ρ : IsNontrivialZero ρ ∧ ‖ρ‖ < 2n} ⊆ (closedBall 0 2n) ∩ riemannZetaZeros — finite ✓).
Hmm wait — D−D₀ on the ball: D−D₀(ρ) = ‖liSummand‖ − (9/2)n²·mult/(1+‖γ‖²) — supported where NOT 2n ≤ ‖ρ‖, i.e. ‖ρ‖ < 2n ✓ finite support. `summable_of_finite_support`.
Hmm — but careful: on the support, D−D₀ could be negative; summable is fine anyway.
Then Summable (fun ρ => liSummand n ρ) via `Summable.of_norm_bounded (hD : Summable D) (h : ∀ ρ, ‖liSummand n ρ‖ ≤ D ρ)` — the inequality: if 2n ≤ ‖ρ‖: by step 2+3: ‖liSummand‖ ≤ 2n² mult/‖ρ‖² ≤ (9/2)n² mult/(1+‖γ‖²) = D ✓. else: D = ‖liSummand‖ ✓ le_refl.
Note: `Summable.of_norm_bounded : Summable g → (∀ i, ‖f i‖ ≤ g i) → Summable f` — signature: `Summable.of_norm_bounded (hg : Summable g) (h : ∀ i, ‖f i‖ ≤ g i) : Summable f`? Let me check exact: in Mathlib it's `Summable.of_norm_bounded {f : α → E} {g : α → ℝ} (hg : Summable g) (h : ∀ i, ‖f i‖ ≤ g i) : Summable f`? I think it's `Summable.of_norm_bounded (hg : Summable g) (h : ∀ i, ‖f i‖ ≤ g i)`. Yes.
5. Also need: `Complex.normSq (gammaOf ρ)` = γ² + (σ−1/2)² — for step 3. gammaOf ρ = (ρ − 1/2)/I. normSq: Complex.normSq z = z.re² + z.im². gammaOf_re : (gammaOf ρ).re = ρ.im; gammaOf_im : (gammaOf ρ).im = 1/2 − ρ.re (from ZeroSummability.lean — PUBLIC lemmas there ✓). So normSq (gammaOf ρ) = ρ.im² + (1/2 − ρ.re)². Those lemmas exist (gammaOf_re, gammaOf_im in Zeta23.WeilEF namespace).
6. zeroMult coercion: zeroMult ρ for ρ : {ρ // IsNontrivialZero ρ} — how does the current liCoeff use it? `(zeroMult ρ : ℂ)` — zeroMult takes ℂ: `def zeroMult (ρ : ℂ) : ℕ`. So zeroMult ρ means zeroMult (ρ:ℂ)? With ρ : subtype, `zeroMult ρ` — there's a coercion; current code works so ✓.
7. The sum type mismatch: zero_sum_inv_sq zetaSeam : Summable (fun ρ : (zetaZeros zetaSeam).carrier => ...). The subtype (zetaZeros zetaSeam).carrier vs {ρ // IsNontrivialZero ρ}: carrier = {ρ | IsNontrivialZero ρ} (rfl per zetaZeroConfig_carrier? — that's for zetaZeroConfig = zetaZeros zetaSeam ✓ same object). {ρ // ρ ∈ {ρ | IsNontrivialZero ρ}} — membership in setOf is defeq to the predicate ✓ so the subtypes are defeq. `show` should convert. If not, use an Equiv.
Let me now write the Scratch.lean development. I'll write it directly as the final form for LiSkeleton (then paste). First draft in Scratch:
```lean
import Mathlib
import Zeta23.WeilEF.ZeroSummability
import Zeta23.Statement.SeamClosed
open Zeta23 Complex Filter Topology
noncomputable section
namespace NguyenRH1
/-- The paired (symmetrized) Li summand: ½·mult·(f ρ + f ρ̄) with
f ρ = 1 − (1−1/ρ)ⁿ. Manifestly real-valued; absolutely summable
(liSummable below) — the correct Keiper–Li coefficient. -/
def liSummand (n : ℕ) (ρ : {ρ : ℂ // IsNontrivialZero ρ}) : ℂ :=
(zeroMult ρ : ℂ) / 2 * ((1 - (1 - 1 / (ρ : ℂ)) ^ n) + (1 - (1 - 1 / (star (ρ : ℂ))) ^ n))
lemma star_summand (n : ℕ) (z : ℂ) :
1 - (1 - 1 / (star z)) ^ n = star (1 - (1 - 1 / z) ^ n) := by
simp [map_sub, map_one, map_pow, map_div, map_natCast] -- hope simp closes
```
Hmm, star (1 - (1 - 1/z)^n): star is the ring endomorphism; the expression uses: 1 (Nat cast? no — literal 1 : ℂ), sub, div, pow (ℕ). simp lemmas: `map_sub (starRingEnd ℂ)`, `map_one`, `map_div₀`, `map_pow`. `starRingEnd ℂ` applied: star (1 - (1 - 1/z)^n) = star 1 - star((1 - 1/z)^n) = 1 - (star(1 - 1/z))^n = 1 - (1 - star(1/z))^n = 1 - (1 - 1/star z)^n ✓. So:
star (1 - (1 - 1/z)^n) = 1 - (1 - 1/(star z))^n — the lemma direction reversed. Write:
```lean
lemma summand_star (n : ℕ) (z : ℂ) :
(1 : ℂ) - (1 - 1 / (star z)) ^ n = star ((1 - (1 - 1 / z) ^ n)) := by
rw [map_sub, map_one, map_pow, map_sub, map_one, map_div, map_one]
```
map_div for starRingEnd: `map_div₀ (f : α →+* β) (a b) : f (a / b) = f a / f b`. Should work. Then:
```lean
lemma liSummand_eq (n : ℕ) (ρ : {ρ : ℂ // IsNontrivialZero ρ}) :
liSummand n ρ = (zeroMult ρ : ℂ) * (((1 - (1 - 1 / (ρ : ℂ)) ^ n).re) : ℂ) := by
rw [liSummand, summand_star]
have h : (1 - (1 - 1 / (ρ : ℂ)) ^ n) + star (1 - (1 - 1 / (ρ : ℂ)) ^ n)
= 2 * (((1 - (1 - 1 / (ρ : ℂ)) ^ n).re) : ℂ) := Complex.add_conj _
-- (mult/2) * (2 * re) = mult * re
rw [h]; ring
```
`Complex.add_conj : z + star z = 2 * (z.re : ℂ)` ✓ (I believe it's `Complex.add_conj (z : ℂ) : z + star z = 2 * (z.re : ℂ)`).
Now the norm bound. Let me define things: for the analytic lemma I'll work with z : ℂ directly:
```lean
lemma re_li_bound {n : ℕ} (hn : 1 ≤ n) {z : ℂ} (hzre : z.re ∈ Set.Icc 0 1) (hz : 2 * n ≤ ‖z‖) :
|(1 - (1 - 1 / z) ^ n).re| ≤ 2 * n ^ 2 / ‖z‖ ^ 2 := by
...
```
Proof plan:
- set w := 1 - 1/z.
- hw1 : w - 1 = -(1/z) — ring.
- hgeom : w^n - 1 = (w - 1) * ∑ j in range n, w^j := geom_sum_mul w n — actually `geom_sum_mul (x : α) (n : ℕ) : (x - 1) * ∑ i ∈ range n, x ^ i = x ^ n - 1` ✓.
- So 1 - w^n = -(w-1) * S = (1/z) * S with S := ∑ j in range n, w^j.
- f.re = Re((1/z)·S) = Re((1/z)·n) + Re((1/z)(S−n)) = n·z.re/‖z‖² + Re((S−n)/z).
- Bound A: |n·z.re/‖z‖²| ≤ n/‖z‖² (|z.re| ≤ 1 from hzre ⊆ [0,1]).
- Bound B: |S − n| ≤ n²/‖z‖:
S − n = ∑_{j<n} (w^j − 1) = ∑_{j<n} (w−1)·(∑_{i<j} w^i).
|w^j − 1| = |w−1|·|∑_{i<j} w^i| ≤ |w−1|·∑_{i<j}|w|^i ≤ |w−1|·j·(max 1 |w|)^{n-1}... hmm |Σ_{i<j} w^i| ≤ Σ_{i<j} |w|^i ≤ j·max(1,|w|)^j — for j ≤ n−1: ≤ j·max(1,|w|)^{n-1} (if j ≤ n−1, max^j ≤ max^{n-1} since max ≥ 1 ✓).
Sum over j: |S−n| ≤ |w−1|·max(1,|w|)^{n-1}·Σ_{j<n} j = |w−1|·max(1,|w|)^{n-1}·n(n−1)/2.
|w−1| = 1/‖z‖; max(1,|w|) ≤ 1+1/‖z‖ ≤ 1+1/(2n); (1+1/(2n))^{n-1} ≤ (1+1/(2n))^n ≤ 2.
So |S−n| ≤ (1/‖z‖)·2·(n²/2) = n²/‖z‖ ✓.
- |Re f| ≤ n/‖z‖² + n²/‖z‖·(1/‖z‖) = (n+n²)/‖z‖² ≤ 2n²/‖z‖² ✓ (n ≤ n² for n ≥ 1).
Sub-facts to prove in Lean:
- ‖1/z‖ = 1/‖z‖: `norm_inv`.
- |w| ≤ 1 + 1/‖z‖: w = 1 − 1/z: |w| ≤ 1 + |1/z| ✓ triangle.
- (1 + 1/(2n))^n ≤ 2: as discussed — (1+x)^n ≤ exp(nx): from `Real.add_one_le_exp : 1 + x ≤ Real.exp x` (for all x? the Mathlib version: `Real.add_one_le_exp (x : ℝ) : 1 + x ≤ Real.exp x` ✓ I think it holds for all real x). pow: (1+x)^n ≤ (exp x)^n = exp(n·x) — `Real.exp_nat_mul : Real.exp (n * x) = (Real.exp x) ^ n`? The direction: Real.exp_nat_mul states exp (n*x) = (exp x)^n I believe ✓. With x = 1/(2n): exp(n·(1/(2n))) = exp(1/2) ≤ 2: exp(1/2) ≤ 2 ⟸ exp(1/2)^2 = exp 1 ≤ 4 ⟸ e ≤ 4: `Real.exp_one_lt_d9 : Real.exp 1 < 2.7182818286` ✓ so exp(1/2) ≤ 2 via sq: (exp(1/2))² = exp(2·(1/2)) = exp(1) ≤ 4 ⟹ exp(1/2) ≤ 2 (nonneg). ✓
- Re((1/z)·n) = n·z.re/‖z‖²: (1/z).re = z.re/‖z‖²: `Complex.inv_re : (z⁻¹.re) = z.re / ‖z‖^2`? I believe there's `Complex.inv_re (z : ℂ) : (z⁻¹).re = z.re / Complex.normSq z` or `Complex.div_re`. One-div: 1/z = z⁻¹ ✓. And (n·(1/z)).re = n·(1/z).re (nat cast real). normSq z = ‖z‖²: `Complex.normSq_eq_norm_sq`? There's `Complex.normSq_eq_abs : normSq z = (Complex.abs z)^2` and abs = ‖z‖ (`Complex.abs_eq_norm`? ‖z‖ = Complex.abs z defeq? `Complex.norm_eq_abs` ✓).
- The geom sum bound |Σ_{i<j} w^i| ≤ Σ_{i<j}|w|^i: `norm_sum_le`; Σ_{i<j} |w|^i ≤ j·max^j: each term |w|^i ≤ max(1,|w|)^j for i < j (pow_le_pow_left₀ with max ≥ |w| ≥ 0 and i ≤ j−1 < j... need i ≤ j: i < j ⟹ i ≤ j−1, and |w|^i ≤ max^i ≤ max^j ✓ since max ≥ 1).
Hmm wait: for j, bound Σ_{i ∈ range j} |w|^i ≤ j·max(1,|w|)^j: i < j ⟹ |w|^i ≤ max(1,|w|)^i ≤ max(1,|w|)^j ✓ (pow monotone, base ≥ 1, i ≤ j).
- Σ_{j ∈ range n} j = n(n−1)/2: `Finset.sum_range_id`? There's `Finset.sum_range_id_mul_two : (∑ i ∈ range n, i) * 2 = n * (n - 1)`. In ℝ: Σ j = n(n−1)/2. ✓
Then the final assembly. This is a decent chunk — let me estimate: ~200–300 lines with careful norm estimates. The `nlinarith`/`gcongr` tactics will help.
Let me also think about whether to prove with ‖z‖ or normSq — use ‖z‖ consistently; ‖z‖² means (‖z‖)^2.
The comparison step:
```lean
lemma normSq_gammaOf_le (z : ℂ) (hzre : z.re ∈ Set.Icc 0 1) (hgam : 1 ≤ z.im^2) :
1 + Complex.normSq (gammaOf z) ≤ 9/4 * ‖z‖^2
```
normSq (gammaOf z) = z.im² + (1/2 − z.re)² (via gammaOf_re/gammaOf_im).
1 + z.im² + (1/2−z.re)² ≤ 1 + z.im² + 1/4 (|1/2 − z.re| ≤ 1/2 since z.re ∈ [0,1]).
≤ 5/4 + z.im². And 9/4·‖z‖² = 9/4·(z.re² + z.im²) ≥ 9/4·z.im².
Need 5/4 + z.im² ≤ 9/4·z.im² ⟺ 5/4 ≤ 5/4·z.im² ⟺ 1 ≤ z.im² ✓ hgam.
‖z‖² = z.re² + z.im²: `Complex.sq_norm`? ‖z‖² = normSq z: `Complex.normSq_eq_norm_sq`? I recall `Complex.sq_abs_sub_sq_re_add_sq_im`... simplest: ‖z‖^2 = z.re^2 + z.im^2 — there is `Complex.normSq_apply : normSq z = z.re^2 + z.im^2` and `Complex.norm_eq_abs : ‖z‖ = Complex.abs z` and `Complex.sq_abs : (Complex.abs z)^2 = normSq z` — `Complex.sq_abs (z) : (Complex.abs z)^2 = Complex.normSq z`? I think `Complex.sq_abs` exists (abs z ^ 2 = normSq z). OK.
And |γ| ≥ 1 from 2n ≤ ‖z‖: γ² = ‖z‖² − z.re² ≥ 4n² − 1 ≥ 3 ≥ 1 ✓.
Assembly:
```lean
theorem liSummable (n : ℕ) : Summable (liSummand n) := by
cases Nat.eq_zero_or_pos n with
| inl h => -- n = 0: summand = 0
subst h; simp [liSummand] -- (1 - (1-1/z)^0) = 0
| inr hn =>
-- main case n ≥ 1
...
```
Then the dominator D with if-then-else and finite support:
```lean
let D : {ρ // IsNontrivialZero ρ} → ℝ := fun ρ =>
if 2 * n ≤ ‖(ρ : ℂ)‖ then (9/2) * n^2 * (zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf ρ))
else ‖liSummand n ρ‖
have hD : Summable D := by
have hbase := (WeilEF.zero_sum_inv_sq zetaSeam).mul_left ((9/2) * (n:ℝ)^2)
-- D = Dbase + (D − Dbase), D−Dbase finite support
...
exact Summable.of_norm_bounded hD (fun ρ => ...)
```
Wait — `zero_sum_inv_sq zetaSeam` has family over `(zetaZeros zetaSeam).carrier` — defeq to our subtype? zetaZeroConfig = zetaZeros zetaSeam and zetaZeroConfig_carrier : zetaZeroConfig.carrier = {ρ | IsNontrivialZero ρ} := rfl. So (zetaZeros zetaSeam).carrier = {ρ | IsNontrivialZero ρ} definitionally. The subtype {x // x ∈ {ρ | IsNontrivialZero ρ}} vs {ρ // IsNontrivialZero ρ}: `Set.mem_setOf_eq : a ∈ {x | p x} = p a` — defeq ✓. So `show Summable (fun ρ : {ρ // IsNontrivialZero ρ} => (zeroMult ρ : ℝ)/(1+normSq (gammaOf ρ)))` from hbase should work by defeq (maybe with a `show` or `convert`/`exact`).
And mult coercion: zero_sum_inv_sq's family has `(zeroMult ρ : ℝ)` — with ρ : carrier subtype, zeroMult ρ — zeroMult : ℂ → ℕ, coercion ρ → ℂ ✓.
Finite support of D − Dbase: supp ⊆ {ρ | ‖(ρ:ℂ)‖ < 2n} — finite:
```lean
have hfin : {ρ : {ρ // IsNontrivialZero ρ} | ¬ (2 * n ≤ ‖(ρ : ℂ)‖)}.Finite
```
The set maps into closedBall (0:ℂ) (2n) ∩ riemannZetaZeros via the coercion: subtype injective. IsNontrivialZero ρ ⟹ riemannZeta ρ = 0 ⟹ (ρ:ℂ) ∈ riemannZetaZeros. And ‖ρ‖ < 2n ⟹ ρ ∈ closedBall. Mathlib: `IsCompact.inter_riemannZetaZeros_finite (hS : IsCompact S) : (S ∩ riemannZetaZeros).Finite`. closedBall compact ✓ (isCompact_closedBall). Then the subtype set is finite via Set.Finite.preimage on the injective coe function — `Set.Finite.preimage` needs the map injective on... `Set.Finite.preimage (hf : s.Finite) (hinj : Set.InjOn f (f ⁻¹' s))`? There's `Set.Finite.preimage (hs : s.Finite) (hf : InjOn f (f ⁻¹' s)) : (f ⁻¹' s).Finite` — hmm actually the standard: inj + image finite ⟹ preimage finite: `Set.Finite.of_finite_image`? There's `Set.Finite.of_finite_image (hf : (f '' s).Finite) (hinj : InjOn f s) : s.Finite` ✓ use that with f = coe.
Then summable_of_finite_support: `summable_of_finite_support (hf : (Function.support f).Finite) : Summable f`? I believe `summable_of_finite_support` exists ✓. support (D − Dbase) ⊆ {ρ | D ρ ≠ Dbase ρ} ⊆ {ρ | ¬(2n ≤ ‖ρ‖)} ✓.
Then `Summable.of_norm_bounded hD (fun ρ => ...)`: the bound ‖liSummand n ρ‖ ≤ D ρ:
- if 2n ≤ ‖ρ‖: ‖liSummand n ρ‖ = ‖(zeroMult : ℂ)/2 · (f + f̄)‖ — via liSummand_eq: = ‖(zeroMult : ℂ) · (f.re : ℂ)‖ = (zeroMult ρ : ℝ)·|f.re| ≤ mult·(2n²/‖ρ‖²) ≤ mult·(2n²)·(9/4)/(1+‖γ‖²) = D ✓. Hmm wait: mult/‖ρ‖² ≤ mult·(9/4)/(1+‖γ‖²) ⟺ 1+‖γ‖² ≤ (9/4)‖ρ‖² ✓ step 3. So ‖liSummand‖ ≤ 2n²·mult/‖ρ‖² ≤ (9/2)n²·mult/(1+‖γ‖²) = D ✓.
- else: D = ‖liSummand‖, le_refl ✓.
Note `Summable.of_norm_bounded` signature check: in current Mathlib: `theorem Summable.of_norm_bounded {f : α → E} {g : α → ℝ} (hg : Summable g) (h : ∀ i, ‖f i‖ ≤ g i) : Summable f` — I'm fairly confident ✓.
zeroMult as a real: need (zeroMult ρ : ℝ) ≥ 0 for the mul_left — `Nat.cast_nonneg`.
Also `WeilEF.zero_sum_inv_sq` — namespace: Zeta23.WeilEF.zero_sum_inv_sq with `open Zeta23` → WeilEF.zero_sum_inv_sq ✓ (the Scratch axiom check used `WeilEF.zero_sum_inv_sq` after `open Zeta23` ✓ worked).
Alright — also the def replacement in LiSkeleton. The current:
```lean
def liCoeff (n : ℕ) : ℂ :=
tsum fun ρ : {ρ : ℂ // IsNontrivialZero ρ} =>
(zeroMult ρ : ℂ) * (1 - (1 - 1 / (ρ : ℂ)) ^ n)
```
becomes:
```lean
def liCoeff (n : ℕ) : ℂ := tsum (liSummand n)
```
plus the liSummand def + liSummable theorem + the honesty-note rewrite.
Where to put the proof: directly in LiSkeleton.lean §1. But develop in Scratch first. Actually — since Scratch.lean currently has the axiom check (committed), I'll write the development there, iterate with `lake env lean Scratch.lean`, then move the final code into LiSkeleton.lean and rebuild the package.
One concern: iteration speed — Scratch.lean imports all of Mathlib + Zeta23; each `lake env lean Scratch.lean` run takes ~30–60s? The imports are precompiled so it's just the file elaboration. Fine.
Let me write the initial development. I'll be careful about details:
- `geom_sum_mul : (x - 1) * ∑ i ∈ Finset.range n, x ^ i = x ^ n - 1` — for CommRing. ℂ ✓.
- w^j − 1 = (w−1)·∑_{i<j} w^i: same lemma at j.
- S − n = ∑_{j<n} (w^j − 1): S = ∑_{j<n} w^j, n = ∑_{j<n} 1: `Finset.sum_sub_distrib`? (Σ a − Σ b = Σ (a−b)): `Finset.sum_sub_distrib : ∑ (f i - g i) = ∑ f i - ∑ g i` ✓ (recent Mathlib name; older: sum_sub_distrib ✓). And ∑_{j<n} 1 = n: `Finset.sum_const` + `Finset.card_range` ✓ (nsmul).
- Re((1/z)·S): f = 1 − w^n = (1/z)·S — as complex equality. Then f.re = ((1/z)·S).re.
((1/z)·S) = (1/z)·n + (1/z)·(S−n). ((1/z)·n).re = n·(1/z).re (n real, nat cast: Complex.re_ofNat? (n : ℂ) has re = n: `Complex.natCast_re`? simp handles).
(1/z).re = z.re/‖z‖²: `Complex.inv_re`? Let me think — in Mathlib: `Complex.inv_re : (z⁻¹).re = z.re / (Complex.abs z)^2`? or normSq form. There's `Complex.div_re` for division. For 1/z: simp [Complex.div_re, Complex.normSq_apply, Complex.norm_eq_abs] should reduce (1/z).re to z.re/(z.re²+z.im²). I'll compute inside the proof with simp + field_simp.
Actually simpler: write the bound via |Re(w)| ≤ ‖w‖ directly where possible:
|f.re| ≤ |n·(1/z).re| + |((1/z)·(S−n)).re| ≤ n·|(1/z).re| + ‖(1/z)·(S−n)‖ (|re| ≤ norm: `Complex.abs_re_le_norm`).
‖(1/z)(S−n)‖ = ‖S−n‖/‖z‖ ≤ n²/‖z‖/‖z‖ = n²/‖z‖².
|(1/z).re| = |z.re|/‖z‖² ≤ 1/‖z‖² (|z.re| ≤ 1 — from IsNontrivialZero: 0 < re < 1 ✓).
So |f.re| ≤ n/‖z‖² + n²/‖z‖² = (n+n²)/‖z‖² ≤ 2n²/‖z‖² ✓ (n ≤ n² for n ≥ 1: `Nat.le_self_pow`? n ≤ n*n for n ≥ 1 ✓ nlinarith).
- |(1/z).re| = |z.re|/‖z‖²: (1/z).re = z.re/‖z‖² — the identity 1/z = conj(z)/‖z‖²: re(1/z) = re(conj z)/‖z‖² = z.re/‖z‖². In Lean: `Complex.inv_re` — I need to check the exact form; there's `Complex.inv_re (z : ℂ) : (z⁻¹).re = z.re / (z.re^2 + z.im^2)`? or via normSq. I'll just prove inline: (1/z) = star z / normSq z: `Complex.inv_def : z⁻¹ = star z / ‖z‖²`? There is `Complex.inv_def : z⁻¹ = (star z) / (normSq z)` — yes I believe `Complex.inv_def` exists (z⁻¹ = star z / normSq z, as complex division by real). Then (z⁻¹).re = (star z).re / normSq z = z.re / normSq z ✓ simp [Complex.inv_def, Complex.div_re? ...]. And normSq z = ‖z‖² for the final form.
OK. Enough planning — write it. First version in Scratch.lean. I'll write the whole thing and iterate on errors. Given its size, let me write carefully.
Also — where does `liSummand`/`liCoeff`/`liSummable` live: in LiSkeleton.lean §1 replacing the current liCoeff. The namespace is NguyenRH1 with `open Zeta23 Complex Filter Topology` — note: open Complex brings `Complex.re` as `re`? Careful with name clashes — current file already uses Complex open. I'll qualify Complex.re explicitly.
One more check — current liCoeff's users: `Sf` (line 2122): `Sf (n : ℕ) : ℝ := SInfty n + 1 - (liCoeff n).re`. And LiBasePoints + LiSkeleton theorems. Since I keep the name/type, fine.
Let me write the Scratch development now.
`zetaZeroConfig_carrier` is `rfl` — the subtypes are definitionally equal, so `zero_sum_inv_sq zetaSeam` applies directly. Also noted: `riemannZeta_conj` exists in ZetaReflect. Now developing the proof in Scratch.
tool: Write
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\Scratch.lean",
"content": "/- Session 015 scratch: ii\u2032-1a \u2014 paired liSummand + summability (D-064 \u00a71).\n When green, merge into LiSkeleton.lean \u00a71 replacing the defective liCoeff. -/\nimport Mathlib\nimport Zeta23.WeilEF.ZeroSummability\nimport Zeta23.Statement.SeamClosed\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-- The paired (symmetrized) Li summand: \u00bd\u00b7mult\u00b7(f \u03c1 + f \u03c1\u0304),\nf \u03c1 = 1 \u2212 (1\u22121/\u03c1)\u207f. Manifestly real-valued (`liSummand_eq`), absolutely\nsummable (`liSummable`) \u2014 the correct Keiper\u2013Li coefficient (D-064 \u00a71:\nthe plain unordered sum of f over the zeros is not absolutely\nsummable; the pairing is the classical Bombieri\u2013Lagarias convention). -/\ndef liSummand (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) : \u2102 :=\n (zeroMult \u03c1 : \u2102) / 2 * ((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n) + (1 - (1 - 1 / (star (\u03c1 : \u2102))) ^ n))\n\nlemma summand_star (n : \u2115) (z : \u2102) :\n (1 : \u2102) - (1 - 1 / (star z)) ^ n = star ((1 - (1 - 1 / z) ^ n)) := by\n rw [map_sub, map_one, map_pow, map_sub, map_one, map_div\u2080, map_one]\n\nlemma liSummand_eq (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) :\n liSummand n \u03c1 = (zeroMult \u03c1 : \u2102) * (((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n).re) : \u2102) := by\n rw [liSummand, summand_star, Complex.add_conj]\n ring\n\n/-! ### The geometric-sum estimate: |Re(1 \u2212 w\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2 for w = 1\u22121/z -/\n\n/-- (1 + 1/(2n))\u207f \u2264 2 for n \u2265 1. Via (1+x)\u207f \u2264 exp(nx) and exp(1/2) \u2264 2. -/\nlemma pow_one_add_inv_two_mul_le (n : \u2115) (hn : 1 \u2264 n) :\n ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have h1 : ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 Real.exp (n * (1 / (2 * n))) := by\n have h := Real.add_one_le_exp (1 / (2 * (n : \u211d)))\n calc ((1 : \u211d) + 1 / (2 * n)) ^ n\n \u2264 (Real.exp (1 / (2 * n))) ^ n := by\n gcongr\n \u00b7 linarith\n \u00b7 exact h\n _ = Real.exp (n * (1 / (2 * n))) := by\n rw [\u2190 Real.exp_nat_mul]\n have h2 : (n : \u211d) * (1 / (2 * n)) = 1 / 2 := by field_simp\n rw [h2] at h1\n have h3 : Real.exp (1 / 2 : \u211d) \u2264 2 := by\n have hsq : (Real.exp (1 / 2 : \u211d)) ^ 2 \u2264 (2 : \u211d) ^ 2 := by\n rw [\u2190 Real.exp_nat_mul]\n have : Real.exp (2 * (1 / 2 : \u211d)) = Real.exp 1 := by ring_nf\n rw [this]\n have h := Real.exp_one_lt_d9\n norm_num at h \u22a2; linarith\n nlinarith [Real.exp_pos (1 / 2 : \u211d)]\n exact h1.trans h3\n\n/-- Key estimate: for n \u2265 1, z with re z \u2208 [0,1], 2n \u2264 \u2016z\u2016:\n|Re(1 \u2212 (1\u22121/z)\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2. -/\nlemma re_li_summand_le {n : \u2115} (hn : 1 \u2264 n) {z : \u2102}\n (hzre0 : 0 \u2264 z.re) (hzre1 : z.re \u2264 1) (hz : 2 * n \u2264 \u2016z\u2016) :\n |(1 - (1 - 1 / z) ^ n).re| \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have hz0 : z \u2260 0 := by\n intro h; rw [h, norm_zero] at hz; linarith\n have hzn : (0 : \u211d) < \u2016z\u2016 := norm_pos_iff.mpr hz0\n set w : \u2102 := 1 - 1 / z with hw\n -- kernel identity: 1 \u2212 w\u207f = (1/z)\u00b7S, S = \u03a3_{j<n} w^j\n have hgeom : w ^ n - 1 = (w - 1) * \u2211 j \u2208 Finset.range n, w ^ j := geom_sum_mul w n\n have hw1 : w - 1 = -(1 / z) := by rw [hw]; ring\n have hf : (1 : \u2102) - w ^ n = (1 / z) * \u2211 j \u2208 Finset.range n, w ^ j := by\n have : (1 : \u2102) - w ^ n = -(w - 1) * \u2211 j \u2208 Finset.range n, w ^ j := by\n rw [\u2190 hgeom]; ring\n rw [this, hw1]; ring\n set S : \u2102 := \u2211 j \u2208 Finset.range n, w ^ j\n -- S = n + (S \u2212 n); Re(f) = n\u00b7Re(1/z) + Re((S\u2212n)/z)\n have hS : S = (n : \u2102) + (S - n) := by ring\n -- |S \u2212 n| \u2264 n\u00b2/\u2016z\u2016\n have hwnorm : \u2016w\u2016 \u2264 1 + 1 / \u2016z\u2016 := by\n have : w = 1 - z\u207b\u00b9 := by rw [hw, div_eq_mul_inv, one_mul]\n rw [this]\n calc \u2016(1 : \u2102) - z\u207b\u00b9\u2016 \u2264 \u2016(1 : \u2102)\u2016 + \u2016z\u207b\u00b9\u2016 := norm_sub_le _ _\n _ = 1 + 1 / \u2016z\u2016 := by rw [norm_one, norm_inv]\n have hwmax : max 1 \u2016w\u2016 \u2264 1 + 1 / (2 * n) := by\n have h1 : 1 / \u2016z\u2016 \u2264 1 / (2 * n) := by\n apply one_div_le_one_div_of_le (by positivity : (0:\u211d) < 2 * n)\n exact_mod_cast hz\n have h2 : \u2016w\u2016 \u2264 1 + 1 / (2 * n) := hwnorm.trans (by linarith)\n apply max_le\n \u00b7 linarith\n \u00b7 exact h2\n have hSn : \u2016S - n\u2016 \u2264 n ^ 2 / \u2016z\u2016 := by\n have hSn1 : S - n = \u2211 j \u2208 Finset.range n, (w ^ j - 1) := by\n rw [Finset.sum_sub_distrib]\n simp [Finset.sum_const, Finset.card_range]\n rw [hSn1]\n have hbound : \u2200 j \u2208 Finset.range n,\n \u2016w ^ j - 1\u2016 \u2264 (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) := by\n intro j hj\n have hgeomj : w ^ j - 1 = (w - 1) * \u2211 i \u2208 Finset.range j, w ^ i := geom_sum_mul w j\n rw [hgeomj, norm_mul, hw1, norm_neg, norm_div, norm_one]\n have hsum : \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016 \u2264 j * (1 + 1 / (2 * n)) ^ (n - 1) := by\n calc \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016\n \u2264 \u2211 i \u2208 Finset.range j, \u2016w ^ i\u2016 := norm_sum_le _ _\n _ \u2264 \u2211 i \u2208 Finset.range j, (1 + 1 / (2 * n)) ^ (n - 1) := by\n apply Finset.sum_le_sum\n intro i hi\n rw [norm_pow]\n have hjn : i \u2264 n - 1 := by\n have hij : i < j := Finset.mem_range.mp hi\n have hjn' : j \u2264 n := le_of_lt (Finset.mem_range.mp hj)\n omega\n exact pow_le_pow_left\u2080 (by positivity)\n (le_trans (le_max_right 1 \u2016w\u2016) hwmax) i (by omega)\n _ = j * (1 + 1 / (2 * n)) ^ (n - 1) := by\n rw [Finset.sum_const, Finset.card_range, nsmul_eq_mul]\n exact mul_le_mul_of_nonneg_left hsum (by positivity)\n calc \u2016\u2211 j \u2208 Finset.range n, (w ^ j - 1)\u2016\n \u2264 \u2211 j \u2208 Finset.range n, \u2016w ^ j - 1\u2016 := norm_sum_le _ _\n _ \u2264 \u2211 j \u2208 Finset.range n, (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) := by\n exact Finset.sum_le_sum hbound\n _ = (1 / \u2016z\u2016) * (1 + 1 / (2 * n)) ^ (n - 1) * \u2211 j \u2208 Finset.range n, j := by\n rw [Finset.mul_sum]; congr 1; rw [Finset.mul_sum]\n apply Finset.sum_congr rfl; intro j _; ring\n _ \u2264 n ^ 2 / \u2016z\u2016 := by\n have hsumj : (\u2211 j \u2208 Finset.range n, j : \u211d) = n * (n - 1) / 2 := by\n have h := Finset.sum_range_id_mul_two n\n have h2 : ((\u2211 j \u2208 Finset.range n, j : \u2115) : \u211d) * 2 = n * (n - 1) := by\n exact_mod_cast h\n linarith\n rw [hsumj]\n have hpow : (1 + 1 / (2 * n : \u211d)) ^ (n - 1) \u2264 2 := by\n have h := pow_one_add_inv_two_mul_le n hn\n calc (1 + 1 / (2 * n : \u211d)) ^ (n - 1)\n \u2264 (1 + 1 / (2 * n : \u211d)) ^ n := by\n apply pow_le_pow_right\u2080 (by positivity)\n \u00b7 have : 1 \u2264 (1 : \u211d) + 1 / (2 * n) := by positivity\n exact this\n \u00b7 omega\n _ \u2264 2 := h\n have h3 : (1 / \u2016z\u2016) * (1 + 1 / (2 * n : \u211d)) ^ (n - 1) * (n * (n - 1) / 2)\n \u2264 (1 / \u2016z\u2016) * 2 * (n ^ 2 / 2) := by\n apply mul_le_mul_of_nonneg_left _ (by positivity)\n apply mul_le_mul_of_nonneg_left hpow (by positivity)\n \u00b7 have : (n : \u211d) * (n - 1) / 2 \u2264 n ^ 2 / 2 := by\n have hn1 : (1 : \u211d) \u2264 n := by exact_mod_cast hn\n nlinarith\n linarith\n calc (1 / \u2016z\u2016) * (1 + 1 / (2 * n : \u211d)) ^ (n - 1) * (n * (n - 1) / 2)\n \u2264 (1 / \u2016z\u2016) * 2 * (n ^ 2 / 2) := h3\n _ = n ^ 2 / \u2016z\u2016 := by ring\n -- assemble\n have hfre : (1 - w ^ n).re = n * z.re / \u2016z\u2016 ^ 2 + (((S - n) / z).re) := by\n rw [hf, hS]\n have h1 : ((1 / z) * ((n : \u2102) + (S - n))) = (n : \u2102) * (1 / z) + (S - n) / z := by\n field_simp; ring\n rw [h1]\n have hre1 : ((n : \u2102) * (1 / z)).re = n * z.re / \u2016z\u2016 ^ 2 := by\n have hinv : ((1 : \u2102) / z).re = z.re / \u2016z\u2016 ^ 2 := by\n rw [one_div, Complex.inv_def]\n simp [Complex.div_re, Complex.normSq_apply, Complex.norm_eq_abs,\n Complex.sq_abs]\n rw [Complex.add_re] at *\n simp [hinv]\n rw [Complex.add_re, hre1]\n rw [hfre]\n have hA : |n * z.re / \u2016z\u2016 ^ 2| \u2264 n / \u2016z\u2016 ^ 2 := by\n rw [abs_div, abs_mul, abs_of_nonneg hn0.le, abs_pow]\n apply div_le_div_of_nonneg_right (by positivity)\n calc |z.re| \u2264 1 := abs_le.mpr \u27e8by linarith, hzre1\u27e9\n _ \u2264 _ := by linarith\n have hB : |((S - n) / z).re| \u2264 n ^ 2 / \u2016z\u2016 ^ 2 := by\n have h1 : |((S - n) / z).re| \u2264 \u2016(S - n) / z\u2016 := Complex.abs_re_le_norm _\n have h2 : \u2016(S - n) / z\u2016 \u2264 (n ^ 2 / \u2016z\u2016) / \u2016z\u2016 := by\n rw [norm_div]\n apply div_le_div_of_nonneg_right hSn (by positivity)\n rw [div_pow] at *\n calc |((S - n) / z).re| \u2264 \u2016(S - n) / z\u2016 := h1\n _ \u2264 (n ^ 2 / \u2016z\u2016) / \u2016z\u2016 := h2\n _ = n ^ 2 / \u2016z\u2016 ^ 2 := by ring\n calc |n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re|\n \u2264 n / \u2016z\u2016 ^ 2 + n ^ 2 / \u2016z\u2016 ^ 2 := abs_add _ _ |>.trans (add_le_add hA hB)\n _ \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n have hn1 : (n : \u211d) \u2264 n ^ 2 := by\n have : (1 : \u211d) \u2264 n := by exact_mod_cast hn\n nlinarith\n field_simp at *\n nlinarith\n\nend NguyenRH1\n"
}
thinking (9852 chars)
Several errors to fix:
1. `summand_star`: `map_sub` didn't apply — `star (a - b)` — star here is `starRingEnd ℂ`? The `map_sub` expects the function to be a ring hom applied. `star (x - y)` — the simp lemma is `star_sub` or `map_sub (starRingEnd ℂ)`. The error: "Did not find pattern ?f (?a − ?b)" — meaning star is NOT displayed as an application of a ring hom; it's the `star` operation (typeclass). So use `star_sub`, `star_one`, `star_pow`, `star_div₀`? In Mathlib: `star_sub : star (a - b) = star a - star b`; `star_div' : star (a / b) = star a / star b` (with a prime maybe); `star_pow : star (a ^ n) = (star a) ^ n`; `star_one : star 1 = 1`. Let me rewrite with those.
2. `liSummand_eq`: `Complex.add_conj` pattern mismatch: `z + star z` — the target has `1 - ... + star (1 - ...)` i.e. `f + star f` but the pattern is `?z + (starRingEnd ℂ) ?z` — so `star` in my term is not syntactically `starRingEnd ℂ` application — it IS `star` function (the class). `Complex.add_conj : z + star z = 2 * (z.re : ℂ)` — hmm, if the lemma states `z + star z` with star the class function, the pattern should match... The error shows the pattern as `(starRingEnd ℂ) ?z` — meaning Complex.add_conj uses `starRingEnd ℂ z`, while my term has `star (...)`. These ARE different: `star z` vs `(starRingEnd ℂ) z`. They're defeq but not syntactically equal. Fix: rewrite `star` to `starRingEnd ℂ` first, or use `Complex.conj` — in Mathlib, `star z = conj z` for ℂ (`Complex.conj_eq_star`? there's `Complex.star_def : star z = conj z`). And `Complex.add_conj : z + conj z = 2 * (z.re : ℂ)`? Actually I recall `Complex.add_conj (z : ℂ) : z + conj z = 2 * (z.re : ℂ)`. So: convert star to conj: `Complex.star_def : star z = conj z`. Hmm wait — in my def I wrote `star (ρ : ℂ)`. Let me check: maybe simpler to rewrite summand_star using conj from the start: in liSummand use `star` (fine for the def) but in the proof convert.
3. `pow_one_add_inv_two_mul_le` line 42: "No goals" — the `gcongr` closed more than expected. Restructure.
4. Line 51: after `rw [← Real.exp_nat_mul]` — the rewrite of `(exp (1/2))^2` — `Real.exp_nat_mul : Real.exp (n * x) = (Real.exp x) ^ n`? The issue: `← Real.exp_nat_mul` rewrites `(Real.exp x)^n` to `Real.exp (n*x)` — pattern with n : ℕ. The target `Real.exp (1/2 : ℝ) ^ 2` — with 2 : ℕ? After `rw [← Real.exp_nat_mul]` the goal became `Real.exp (↑2 * (1/2)) ≤ 2^2` — the rewrite worked but then `this : Real.exp (2 * (1/2)) = Real.exp 1` has `2` as ℝ literal vs `↑2` — mismatch. Fix: use `show Real.exp ((2 : ℝ) * (1/2)) = Real.exp 1` and congr + norm_num, or use `Real.exp_one_lt_d9` differently: Real.exp (1/2) ≤ 2: maybe simpler: Real.exp (1/2) < Real.exp 1 (strict monotone) and Real.exp 1 < 2.72 < ... but exp(1/2) ≤ 2 needs the numeric. Alternative: `Real.exp_lt` ... simplest robust: have h : Real.exp (1/2:ℝ) ≤ 2 := by
rw [show (2:ℝ) = Real.exp (Real.log 2) by rw [Real.exp_log (by norm_num)]]
apply Real.exp_le_exp.mpr; apply Real.log... hmm exp(1/2) ≤ exp(log 2) ⟺ 1/2 ≤ log 2 ⟺ ... log 2 ≥ 1/2: `Real.log_two_gt_d9 : 0.6931471803 < Real.log 2` ✓ linarith. Clean!
5. `geom_sum_mul w n` : `(∑) * (w−1) = w^n − 1` — the order is flipped: it's `∑ * (x−1)` not `(x−1) * ∑`. Use `mul_geom_sum`? or `geom_sum_mul` gives `(∑ i ∈ range n, x^i) * (x−1) = x^n − 1` ✓ as shown. So use that form: S * (w−1) = wⁿ − 1. Adjust: I need (w−1)·S: just commute: (w−1)·S = S·(w−1) = wⁿ−1.
Let me fix all errors with a rewrite of the file. Also check `Complex.inv_def` usage later — let me simplify hre1's proof: `((1:ℂ)/z).re = z.re/‖z‖^2`: (1/z) = z⁻¹: re(z⁻¹) = z.re/‖z‖². There's `Complex.inv_re : (z⁻¹).re = z.re / (Complex.normSq z)`? Let me not guess: do it via conj: 1/z = star z / ‖z‖² (Complex.inv_def : z⁻¹ = star z / ‖z‖ ^ 2 — hmm ‖z‖² as (‖z‖^2 : ℝ) cast to ℂ). I recall `Complex.inv_def : z⁻¹ = (star z) / (Complex.normSq z)` with normSq cast. Then re: ((star z)/normSq z).re = (star z).re/normSq z = z.re/normSq z (div by real: `Complex.div_re`?). And normSq z = ‖z‖²: `Complex.normSq_eq_norm_sq`? Hmm — there is `Complex.normSq_eq_abs : normSq z = (Complex.abs z)^2` and `Complex.norm_eq_abs : ‖z‖ = Complex.abs z`. So normSq z = ‖z‖^2 ✓ via those.
Rather than guessing lemma names inline, I'll write the hinv proof with explicit simp lemmas and iterate.
Actually, let me restructure hre1: instead of going through inv_re, note:
(n : ℂ)·(1/z) = n·(star z)/normSq z (Complex.inv_def); re of that = n·z.re/normSq z. And I want n·z.re/‖z‖^2 — equal by normSq_eq_abs + norm_eq_abs.
Let me rewrite the whole scratch with fixes:
Also potential issue: `abs_pow` — |a^n| = |a|^n — in hA I use abs_div, abs_mul, abs_of_nonneg, then div_le_div... Let me simplify hA:
|n·z.re/‖z‖²| = n·|z.re|/‖z‖² (n>0, ‖z‖²>0) ≤ n·1/‖z‖² = n/‖z‖². Write:
have hA : |n * z.re / ‖z‖ ^ 2| ≤ n / ‖z‖ ^ 2 := by
rw [abs_div, abs_mul]
have e1 : |(n : ℝ)| = n := abs_of_nonneg hn0.le
have e2 : |‖z‖ ^ 2| = ‖z‖ ^ 2 := abs_of_nonneg (by positivity)
rw [e1, e2]
apply div_le_div_of_nonneg_right? — div_le_div_of_nonneg_right? Hmm: to show n·|z.re|/‖z‖² ≤ n/‖z‖² with ‖z‖² > 0: `div_le_div_right hzn2` : a/c ≤ b/c ⟺ a ≤ b... lemma name `div_le_div_right (hc : 0 < c) : a / c ≤ b / c ↔ a ≤ b`. So:
apply (div_le_div_right (by positivity)).mpr
exact mul_le_mul_of_nonneg_left (abs_le.mpr ⟨by linarith, hzre1⟩) hn0.le
— wait: mul_le_mul_of_nonneg_left : b ≤ c → 0 ≤ a → a*b ≤ a*c: here n·|z.re| ≤ n·1 ✓.
For hB: |((S−n)/z).re| ≤ ‖(S−n)/z‖ = ‖S−n‖/‖z‖ ≤ (n²/‖z‖)/‖z‖ = n²/‖z‖² ✓ (avoid div_pow issues):
have hB : |((S - n) / z).re| ≤ n ^ 2 / ‖z‖ ^ 2 := by
have h1 : |((S - n) / z).re| ≤ ‖(S - n) / z‖ := Complex.abs_re_le_norm _
have h2 : ‖(S - n) / z‖ ≤ (n ^ 2 / ‖z‖) / ‖z‖ := by
rw [norm_div]
exact div_le_div_of_nonneg_right hSn hzn -- hmm name: div_le_div_of_nonneg_right? For a/b ≤ c/b: `div_le_div_of_nonneg_right : a ≤ b → 0 ≤ c → a / c ≤ b / c`? Hmm — actually the lemma for dividing by the same positive: `div_le_div_of_nonneg_right`?? I think the modern name is `div_le_div_right` (iff) or `div_le_div_of_le_left`... The monotone one: `div_le_div_of_nonneg_right (h : a ≤ b) (hc : 0 ≤ c) : a / c ≤ b / c` — hmm I don't remember exactly; there's `div_le_div_right (hc : 0 < c) : a / c ≤ b / c ↔ a ≤ b`. Use the iff: (div_le_div_right hzn).mpr hSn.
calc |((S - n) / z).re| ≤ ‖(S - n) / z‖ := h1
_ ≤ (n ^ 2 / ‖z‖) / ‖z‖ := h2
_ = n ^ 2 / ‖z‖ ^ 2 := by ring
— the last ring: (n²/‖z‖)/‖z‖ = n²/‖z‖²: `div_div` = n²/(‖z‖·‖z‖) = n²/‖z‖²: ring should handle with pow_two: maybe `by rw [div_div, ← pow_two]`.
hSn's inner calc: I wrote a weird structure with `apply mul_le_mul_of_nonneg_left _ ... ; apply ... ; · have ...` — mismatched bullets. Rewrite cleanly:
h3: (1/‖z‖) * M * (n*(n−1)/2) ≤ (1/‖z‖) * 2 * (n²/2):
= (1/‖z‖) · [M · (n(n−1)/2)] ≤ (1/‖z‖)·[2·(n²/2)]: two mul_le_mul_of_nonneg_left applications:
have hb1 : (n:ℝ)*(n-1)/2 ≤ n^2/2 := by nlinarith [hn0]
have hb2 : M * (n*(n-1)/2) ≤ 2 * (n^2/2) := mul_le_mul_of_nonneg hpow hb1 (by positivity) (by positivity)
-- mul_le_mul_of_nonneg : a ≤ b → c ≤ d → 0 ≤ c → 0 ≤ b → a*c ≤ b*d
then (1/‖z‖)·[...] ≤ (1/‖z‖)·[...]: mul_le_mul_of_nonneg_left hb2 (by positivity).
Also `Finset.mul_sum` usage: ∑ (c·(j·M)) = c·M·∑ j — I wrote `(1/‖z‖) * (j * M)` — factor c·M: rewrite each term: (1/‖z‖)*(j*M) = (1/‖z‖*M)*j ✓ then Finset.mul_sum.
The hpow: (1+1/(2n))^{n-1} ≤ (1+1/(2n))^n: `pow_le_pow_right₀ (ha : 0 ≤ a) (hb : 1 ≤ b)... ` hmm — pow_le_pow_right₀ signature: `pow_le_pow_right₀ (ha : 0 ≤ a) (hb : 1 ≤ b) : a ^ m ≤ a ^ n ↔ m ≤ n`? No wait — for exponent comparison with base ≥ 1: `pow_le_pow_right₀ (hb : 1 ≤ b) (h : m ≤ n) : b ^ m ≤ b ^ n`? In recent Mathlib: `pow_le_pow_right₀ (ha : 1 ≤ a) (hmn : m ≤ n) : a ^ m ≤ a ^ n` ✓ I think. Use that.
geom_sum_mul direction fix: hgeom : ∑ j ∈ range n, w^j) * (w - 1) = w ^ n - 1 := geom_sum_mul w n. Then 1 − wⁿ = −(wⁿ−1) = −S·(w−1) = −(w−1)·S — fine by comm.
hw1 : w − 1 = -(1/z): then 1 − wⁿ = −(w−1)·S = (1/z)·S ✓.
For hgeomj: (w^j − 1) = (∑ i ∈ range j, w^i)·(w−1) := geom_sum_mul w j ✓.
summand_star with star lemmas: star_sub, star_one, star_pow, star_div₀? — for division with star: `star_div₀ : star (a / b) = star a / star b`? There's `star_div'` in Mathlib (star (a / b) = star a / star b) for GroupWithZero + Star. Name candidates: `star_div₀`, `star_div'`. I'll write `simp only [star_sub, star_one, star_pow, star_div₀, star_natCast]` and if star_div₀ doesn't exist try `star_div'`. Actually safer: use `map_` versions with starRingEnd: first convert star to starRingEnd ℂ: `Complex.star_def : star z = conj z`?? Hmm — actually in current Mathlib, `star (z : ℂ) = conj z` where conj = starRingEnd ℂ: the lemma `Complex.star_def : star z = conj z` — no wait, I think conj is DEFINED via starRingEnd: `Complex.conj : ℂ →* ℂ` is starRingEnd ℂ. And `star z` unfolds to `starRingEnd ℂ z` — defeq. The rw failure earlier: map_sub pattern `?f (?a − ?b)` — star (a−b) should match with ?f = star?? The error suggests `star` in goal is not an application — because `star` is `star (R:=ℂ) x` with instance arguments, still an application though... The actual issue might be that map_sub applies to RingHomClass functions, and `star` for ℂ is `starRingEnd` but the `star x` notation doesn't unfold to an application of a bundled hom. Use `star_sub` etc. instead:
summand_star (n : ℕ) (z : ℂ) :
(1 : ℂ) - (1 - 1 / (star z)) ^ n = star ((1 - (1 - 1 / z) ^ n)) := by
rw [star_sub, star_one, star_pow, star_sub, star_one, star_div₀, star_one]
If star_div₀ doesn't exist, try star_div'. Let me check quickly which exists in this Mathlib via grep.
Also liSummand_eq's use of Complex.add_conj: after summand_star rewrite, goal has `star (1 - (1 - 1/ρ)^n)` with star the class-fn. Complex.add_conj : z + star z = 2 * (z.re : ℂ)? or with conj? Check via grep too.
Let me grep Mathlib for these names.
Fixable errors — let me check the exact lemma names in this Mathlib version first.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem star_div\u2080\\|theorem star_div'\\|lemma star_div\u2080\\|lemma star_div'\" Mathlib/Algebra/Star/ | head -4; grep -rn \"theorem Complex.add_conj\\|lemma Complex.add_conj\\|add_conj \" Mathlib/Data/Complex/Basic.lean Mathlib/Analysis/SpecialFunctions/*.lean 2>/dev/null | head -4; grep -rn \"theorem inv_def\\|inv_re \" Mathlib/Data/Complex/Basic.lean | head -4; grep -rn \"theorem geom_sum_mul \\|lemma geom_sum_mul \" Mathlib/Algebra/GeomSum.lean | head -3",
"description": "Check exact lemma names in vendored Mathlib"
}
thinking (9154 chars)
`mul_geom_sum (x : R) (n : ℕ) : (x - 1) * ∑ i ∈ range n, x ^ i = x ^ n - 1` — exactly the direction I wanted.
Now for the star/conj bridge: `star (z : ℂ)` vs `conj z`. conj IS `starRingEnd ℂ` (defined that way), and `star` on ℂ goes through the StarMul instance whose star function is conj. So `star z` should be defeq to `conj z`. In proofs, use `star_div₀`-style lemmas for the star manipulation, then convert to conj by `show` (defeq) or `Complex.star_def` if it exists. Let me test defeq conversion via `show` — I'll write the code and iterate.
Let me now rewrite Scratch.lean with all fixes:
1. summand_star: use star_sub, star_one, star_pow, star_div₀.
2. liSummand_eq: convert star to conj (defeq — try `show ... conj ...` or simp [star] — hmm; the term in liSummand's def uses `star (ρ:ℂ)`. After summand_star rewrites `1 - (1 - 1/(star z))^n` to `star (1 - (1 - 1/z)^n)`, the goal has `star (1 - ...)`; then `Complex.re_eq_add_conj : (z.re : ℂ) = (z + conj z)/2` — rewrite RHS: goal: (mult/2)·(f + star f) = mult·(re f : ℂ). If star f is defeq conj f, `show (zeroMult : ℂ)/2 * (f + conj f) = _` might work directly since star and conj are defeq. Let me structure:
```
lemma liSummand_eq ... := by
rw [liSummand, summand_star]
have h : (1 - (1 - 1 / (ρ:ℂ)) ^ n) + star (1 - (1 - 1 / (ρ:ℂ)) ^ n)
= 2 * (((1 - (1 - 1 / (ρ:ℂ)) ^ n).re) : ℂ) := by
rw [Complex.add_conj] -- if star ≟ conj defeq, this rw works? add_conj is about conj
```
Hmm — Complex.add_conj's LHS is `z + conj z`; our term is `f + star f`. rw with add_conj: pattern `?z + conj ?z` — `conj ?z` is `(starRingEnd ℂ) ?z` — the term `star f` where star = Star.star — different head constants (Star.star vs starRingEnd application). rw may fail. Solution: change liSummand's def to use `conj` instead of `star`:
`(zeroMult ρ : ℂ) / 2 * ((1 - (1 - 1/(ρ:ℂ))^n) + (1 - (1 - 1/(conj (ρ:ℂ)))^n))`
conj = starRingEnd ℂ — map_ lemmas apply directly (map_sub, map_one, map_pow, map_div₀). And Complex.add_conj matches.
So summand_conj:
```
lemma summand_conj (n : ℕ) (z : ℂ) :
(1 : ℂ) - (1 - 1 / (conj z)) ^ n = conj ((1 - (1 - 1 / z) ^ n)) := by
rw [map_sub, map_one, map_pow, map_sub, map_one, map_div₀, map_one]
```
conj z = (starRingEnd ℂ) z — map_sub etc. should match with ?f := starRingEnd ℂ ✓ (this failed for star but should work for conj since conj IS the bundled hom).
Hmm wait — conj (1/z): map_div₀ (starRingEnd ℂ) 1 z = conj 1 / conj z ✓ = 1/conj z after map_one.
3. pow_one_add_inv_two_mul_le — rewrite cleanly:
```
lemma pow_one_add_inv_two_mul_le (n : ℕ) (hn : 1 ≤ n) :
((1 : ℝ) + 1 / (2 * n)) ^ n ≤ 2 := by
have hn0 : (0 : ℝ) < n := by exact_mod_cast hn
have h1 : ((1 : ℝ) + 1 / (2 * n)) ^ n ≤ Real.exp (1 / 2) := by
have hbase : (1 : ℝ) + 1 / (2 * n) ≤ Real.exp (1 / (2 * n)) :=
Real.add_one_le_exp _
calc ((1 : ℝ) + 1 / (2 * n)) ^ n
≤ (Real.exp (1 / (2 * n))) ^ n := by
apply pow_le_pow_left₀ (by positivity) hbase
_ = Real.exp (↑n * (1 / (2 * n))) := by
rw [Real.exp_nat_mul]
_ = Real.exp (1 / 2) := by
congr 1; field_simp
have h2 : Real.exp (1 / 2 : ℝ) ≤ 2 := by
have h3 : Real.log 2 ≥ 1 / 2 := by
have h := Real.log_two_gt_d9
linarith [h]
calc Real.exp (1 / 2 : ℝ) ≤ Real.exp (Real.log 2) := Real.exp_le_exp.mpr h3
_ = 2 := Real.exp_log (by norm_num)
exact h1.trans h2
```
pow_le_pow_left₀ signature: `pow_le_pow_left₀ (ha : 0 ≤ a) (hab : a ≤ b) (n : ℕ) : a^n ≤ b^n`? I believe `pow_le_pow_left₀ (ha : 0 ≤ a) (hab : a ≤ b) (n : ℕ) : a ^ n ≤ b ^ n` ✓.
Real.exp_nat_mul : `Real.exp_nat_mul (x : ℝ) (n : ℕ) : Real.exp (n * x) = (Real.exp x) ^ n` — so `rw [Real.exp_nat_mul]` on goal `(exp x)^n = exp(n*x)`?? My calc step is `_ = Real.exp (↑n * (1/(2*n)))` — I'm proving `(Real.exp (1/(2n)))^n = Real.exp (↑n * (1/(2*n)))` — that's `Real.exp_nat_mul` REVERSED: `(exp x)^n = exp (n*x)` — so the proof is `rw [Real.exp_nat_mul]` — rewrites RHS `exp (↑n * x)` to `(exp x)^n` making both sides equal ✓. Hmm, wait: exp_nat_mul states exp (n*x) = (exp x)^n; rw [Real.exp_nat_mul] rewrites instances of `exp (n * x)` → `(exp x)^n`. Goal: `(exp x)^n = exp (↑n * x)` → after rw: `(exp x)^n = (exp x)^n` ✓ closed by rfl automatically (rw closes goals that become rfl). But careful: the cast ↑n vs n in exp_nat_mul — exp_nat_mul has (n : ℕ) and the term is `↑n * x` where ↑ is Nat→ℝ cast ✓ matches.
`Real.log_two_gt_d9 : 0.6931471803 < Real.log 2` ✓ exists (used in D-062's plan).
4. re_li_summand_le — full rewrite with mul_geom_sum and fixes. Let me also double check `Finset.sum_range_id_mul_two : (∑ i ∈ range n, i) * 2 = n * (n - 1)` — for ℕ. ✓ exists I believe.
`norm_sum_le : ‖∑ i ∈ s, f i‖ ≤ ∑ i ∈ s, ‖f i‖` ✓.
`norm_inv : ‖z⁻¹‖ = ‖z‖⁻¹` ✓.
`norm_div : ‖a / b‖ = ‖a‖ / ‖b‖` ✓.
`Complex.abs_re_le_norm : |z.re| ≤ ‖z‖` ✓ (from the grep: abs_re_le_norm exists ✓).
`Complex.inv_re : z⁻¹.re = z.re / normSq z` ✓ (grep found it). Need normSq z = ‖z‖² bridge: `Complex.normSq_eq_norm_sq`? Let me just use normSq form in the final bound instead of ‖z‖²? The final inequality is stated with ‖z‖^2 — conversion: normSq z = ‖z‖^2 — `Complex.normSq_eq_norm_sq (z : ℂ) : normSq z = ‖z‖ ^ 2`? I think there is `Complex.normSq_eq_norm_sq`. If not: normSq z = (Complex.abs z)^2 via `Complex.normSq_eq_abs` and `Complex.norm_eq_abs`. I'll write: `have hnsq : Complex.normSq z = ‖z‖ ^ 2 := by rw [Complex.normSq_eq_abs, Complex.norm_eq_abs]`.
For hre1: ((n : ℂ) * (1 / z)).re = n * z.re / ‖z‖ ^ 2:
(n·(1/z)).re = n·(1/z).re (n real: (a·b).re with a = n ∈ ℝ — `Complex.re_ofReal_mul`? simpler: (n : ℂ) = (n : ℝ) cast; (x * y).re = x.re*y.re − x.im*y.im; (n:ℂ).im = 0, (n:ℂ).re = n ✓ so (n·w).re = n·w.re: `Complex.natCast_re`? simp handles: simp [Complex.mul_re, Complex.natCast_re, Complex.natCast_im]. Then (1/z).re = z.re/normSq z (inv_re with one_div). So:
```
have hre1 : ((n : ℂ) * (1 / z)).re = n * z.re / ‖z‖ ^ 2 := by
have hinv : ((1 : ℂ) / z).re = z.re / ‖z‖ ^ 2 := by
rw [one_div, Complex.inv_re, hnsq]
rw [show (n : ℂ) * (1 / z) = (n : ℝ) * (1 / z) by simp]
simp [Complex.mul_re, hinv]
```
Hmm — (n:ℂ)·w: mul_re: (a*b).re = a.re*b.re − a.im*b.im; with a = (n:ℂ): a.re = n, a.im = 0: = n·b.re. simp [Complex.mul_re, Complex.natCast_re, Complex.natCast_im, hinv] should give n·(z.re/‖z‖²) = n·z.re/‖z‖² — need ring_nf maybe. I'll use: `rw [Complex.mul_re]; simp [hinv]; ring`. Might need fiddling; iterate.
Actually cleaner: avoid hre1 entirely — restructure hfre to keep (1/z)·n as n·(1/z).re... Alternatively: bind everything through the real identity Re(a·b)... Let me simplify the whole hfre step:
f = (1/z)·S = (1/z)·n + (1/z)·(S−n). f.re = ((1/z)·n).re + ((1/z)·(S−n)).re.
((1/z)·n).re = n·(1/z).re since n is a nonnegative real (as a complex scalar with 0 imag part).
(1/z).re = z.re/normSq z.
So f.re = n·z.re/normSq z + ((S−n)/z).re. Then:
|f.re| ≤ n·|z.re|/normSq z + ‖(S−n)/z‖ ≤ n/normSq z + (n²/‖z‖)/‖z‖ = n/‖z‖² + n²/‖z‖².
Wait — (S−n)/z: note (1/z)·(S−n) = (S−n)/z ✓ same norm.
n·z.re/normSq z: |n·z.re/normSq z| = n·|z.re|/normSq z ≤ n·1/normSq z (|z.re| ≤ 1). And normSq z = ‖z‖² ✓.
OK let me write the final file now, carefully. Also drop the unused hre1-Complex.add_re bits.
One more possible issue: `Finset.sum_range_id_mul_two n : (∑ i ∈ range n, i) * 2 = n * (n - 1)` — this is for ℕ. In the real context I cast. Fine.
And in hbound: I have extra parens and the max handling; hwmax : max 1 ‖w‖ ≤ 1 + 1/(2n): from hwnorm : ‖w‖ ≤ 1 + 1/‖z‖ and 1/‖z‖ ≤ 1/(2n): max_le (by positivity?) hmm max 1 ‖w‖ ≤ 1 + 1/(2n) ⟸ 1 ≤ 1+1/(2n) ✓ and ‖w‖ ≤ 1+1/(2n) ✓ via hwnorm.trans (add_le_add_left ...). Fine.
pow bound: ‖w^i‖ = ‖w‖^i ≤ (1+1/(2n))^i ≤ (1+1/(2n))^{n-1} for i ≤ n−1: `pow_le_pow_left₀ (h : 0 ≤ a) (hab : a ≤ b) (n)` then `pow_le_pow_right₀ (hb : 1 ≤ b) (h : m ≤ n)`: chain: ‖w‖^i ≤ (1+1/(2n))^i ≤ (1+1/(2n))^{n-1}:
step1: pow_le_pow_left₀ (norm_nonneg _) (le_trans (le_max_right 1 ‖w‖) hwmax) i
step2: pow_le_pow_right₀ (by positivity? need 1 ≤ 1+1/(2n)) (i ≤ n−1)
— pow_le_pow_right₀ signature check: `pow_le_pow_right₀ (hb : 1 ≤ b) (h : m ≤ n) : b ^ m ≤ b ^ n`? Hmm — actual name/signature in current Mathlib: `pow_le_pow_right₀ (ha : 1 ≤ a) (hmn : m ≤ n) : a ^ m ≤ a ^ n` — I believe so (there was a rename from pow_le_pow_of_le_one... no that's different). Try it.
The earlier gcongr "no goals" issue: gcongr closed the side goals automatically; I restructured to explicit apply.
Let me also reconsider the hsumj: `Finset.sum_range_id_mul_two (n : ℕ) : (∑ i ∈ range n, i) * 2 = n * (n - 1)` ✓.
OK writing the final version now. Also fix the earlier `Finset.mul_sum` step:
∑_{j<n} (1/‖z‖)·(j·M) = (1/‖z‖)·M·∑_{j<n} j:
conv: each term (1/‖z‖)*(j*M) = ((1/‖z‖)*M)*j → Finset.mul_sum: ∑ (c·j) = c·∑ j:
rw [Finset.mul_sum] turns ∑ ((1/‖z‖)*j*M)?? Let me set c := (1/‖z‖)*M and show each summand = c*j by ring, then `rw [← Finset.mul_sum]`? Finset.mul_sum : c * ∑ f = ∑ c·f — direction: `← Finset.mul_sum` rewrites ∑ (c·f) → c·∑f ✓. So:
have : ∀ j ∈ range n, (1/‖z‖)*(j*M) = ((1/‖z‖)*M)*j := fun j _ => by ring
rw [Finset.sum_congr rfl this, ← Finset.mul_sum]
Let me write the complete fixed file.
All names confirmed: `mul_geom_sum` (right direction), `Complex.inv_re`, `star_div₀`, and conj = the bundled hom (so `map_` lemmas apply). Rewriting with fixes.
tool: Write ok
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\Scratch.lean",
"content": "/- Session 015 scratch: ii\u2032-1a \u2014 paired liSummand + summability (D-064 \u00a71).\n When green, merge into LiSkeleton.lean \u00a71 replacing the defective liCoeff. -/\nimport Mathlib\nimport Zeta23.WeilEF.ZeroSummability\nimport Zeta23.Statement.SeamClosed\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-- The paired (symmetrized) Li summand: \u00bd\u00b7mult\u00b7(f \u03c1 + f \u03c1\u0304),\nf \u03c1 = 1 \u2212 (1\u22121/\u03c1)\u207f. Manifestly real-valued (`liSummand_eq`), absolutely\nsummable (`liSummable`) \u2014 the correct Keiper\u2013Li coefficient (D-064 \u00a71:\nthe plain unordered sum of f over the zeros is not absolutely\nsummable; the pairing is the classical Bombieri\u2013Lagarias convention). -/\ndef liSummand (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) : \u2102 :=\n (zeroMult \u03c1 : \u2102) / 2 * ((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n) + (1 - (1 - 1 / (conj (\u03c1 : \u2102))) ^ n))\n\nlemma summand_conj (n : \u2115) (z : \u2102) :\n (1 : \u2102) - (1 - 1 / (conj z)) ^ n = conj ((1 - (1 - 1 / z) ^ n)) := by\n rw [map_sub, map_one, map_pow, map_sub, map_one, map_div\u2080, map_one]\n\nlemma liSummand_eq (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) :\n liSummand n \u03c1 = (zeroMult \u03c1 : \u2102) * (((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n).re) : \u2102) := by\n rw [liSummand, summand_conj, Complex.add_conj]\n ring\n\n/-! ### The geometric-sum estimate: |Re(1 \u2212 w\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2 for w = 1\u22121/z -/\n\n/-- (1 + 1/(2n))\u207f \u2264 2 for n \u2265 1. Via (1+x)\u207f \u2264 exp(nx) and exp(1/2) \u2264 2. -/\nlemma pow_one_add_inv_two_mul_le (n : \u2115) (hn : 1 \u2264 n) :\n ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have hbase : (1 : \u211d) + 1 / (2 * n) \u2264 Real.exp (1 / (2 * n)) :=\n Real.add_one_le_exp _\n have h1 : ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 Real.exp (1 / 2) := by\n calc ((1 : \u211d) + 1 / (2 * n)) ^ n\n \u2264 (Real.exp (1 / (2 * n))) ^ n := pow_le_pow_left\u2080 (by positivity) hbase n\n _ = Real.exp (\u2191n * (1 / (2 * n))) := by rw [Real.exp_nat_mul]\n _ = Real.exp (1 / 2) := by congr 1; field_simp\n have h2 : Real.exp (1 / 2 : \u211d) \u2264 2 := by\n have h3 : (1 : \u211d) / 2 \u2264 Real.log 2 := by\n have h := Real.log_two_gt_d9\n linarith\n calc Real.exp (1 / 2 : \u211d) \u2264 Real.exp (Real.log 2) := Real.exp_le_exp.mpr h3\n _ = 2 := Real.exp_log (by norm_num)\n exact h1.trans h2\n\n/-- Key estimate: for n \u2265 1, z with re z \u2208 [0,1], 2n \u2264 \u2016z\u2016:\n|Re(1 \u2212 (1\u22121/z)\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2. -/\nlemma re_li_summand_le {n : \u2115} (hn : 1 \u2264 n) {z : \u2102}\n (hzre0 : 0 \u2264 z.re) (hzre1 : z.re \u2264 1) (hz : 2 * n \u2264 \u2016z\u2016) :\n |(1 - (1 - 1 / z) ^ n).re| \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have hz0 : z \u2260 0 := by\n intro h; rw [h, norm_zero] at hz; linarith\n have hzn : (0 : \u211d) < \u2016z\u2016 := norm_pos_iff.mpr hz0\n have hnsq : Complex.normSq z = \u2016z\u2016 ^ 2 := by\n rw [Complex.normSq_eq_abs, Complex.norm_eq_abs]\n set w : \u2102 := 1 - 1 / z with hw\n -- kernel identity: 1 \u2212 w\u207f = (1/z)\u00b7S, S = \u03a3_{j<n} w^j\n have hgeom : (w - 1) * \u2211 j \u2208 Finset.range n, w ^ j = w ^ n - 1 := mul_geom_sum w n\n have hw1 : w - 1 = -(1 / z) := by rw [hw]; ring\n have hf : (1 : \u2102) - w ^ n = (1 / z) * \u2211 j \u2208 Finset.range n, w ^ j := by\n have h := hgeom\n rw [hw1] at h\n have e := congr_arg Neg.neg h\n simp only [neg_sub, sub_eq_add_neg] at e \u22a2\n have e2 : (1 : \u2102) - w ^ n = -(w ^ n - 1) := by ring\n rw [e2, h]; ring\n set S : \u2102 := \u2211 j \u2208 Finset.range n, w ^ j\n have hS : S = (n : \u2102) + (S - n) := by ring\n -- \u2016w\u2016 \u2264 1 + 1/\u2016z\u2016\n have hwnorm : \u2016w\u2016 \u2264 1 + 1 / \u2016z\u2016 := by\n have e : w = 1 - z\u207b\u00b9 := by rw [hw, div_eq_mul_inv, one_mul]\n rw [e]\n calc \u2016(1 : \u2102) - z\u207b\u00b9\u2016 \u2264 \u2016(1 : \u2102)\u2016 + \u2016z\u207b\u00b9\u2016 := norm_sub_le _ _\n _ = 1 + 1 / \u2016z\u2016 := by rw [norm_one, norm_inv, inv_eq_one_div]\n have h1z : 1 / \u2016z\u2016 \u2264 1 / (2 * n) :=\n one_div_le_one_div_of_le (by positivity) (by exact_mod_cast hz)\n have hwmax : max 1 \u2016w\u2016 \u2264 1 + 1 / (2 * n) := by\n apply max_le (by positivity)\n exact hwnorm.trans (by linarith)\n -- |S \u2212 n| \u2264 n\u00b2/\u2016z\u2016\n have hSn : \u2016S - n\u2016 \u2264 n ^ 2 / \u2016z\u2016 := by\n have hSn1 : S - n = \u2211 j \u2208 Finset.range n, (w ^ j - 1) := by\n rw [Finset.sum_sub_distrib]\n simp [Finset.sum_const, Finset.card_range]\n have hbound : \u2200 j \u2208 Finset.range n,\n \u2016w ^ j - 1\u2016 \u2264 (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) := by\n intro j hj\n have hgeomj : (w - 1) * \u2211 i \u2208 Finset.range j, w ^ i = w ^ j - 1 := mul_geom_sum w j\n have hjn : j \u2264 n := le_of_lt (Finset.mem_range.mp hj)\n have h2 : w ^ j - 1 = -(1 / z) * \u2211 i \u2208 Finset.range j, w ^ i := by\n have h := hgeomj; rw [hw1] at h\n rw [\u2190 h]; ring\n rw [h2, norm_mul, norm_neg, norm_div, norm_one]\n have hsum : \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016 \u2264 j * (1 + 1 / (2 * n)) ^ (n - 1) := by\n calc \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016\n \u2264 \u2211 i \u2208 Finset.range j, \u2016w ^ i\u2016 := norm_sum_le _ _\n _ \u2264 \u2211 i \u2208 Finset.range j, (1 + 1 / (2 * n)) ^ (n - 1) := by\n apply Finset.sum_le_sum\n intro i hi\n rw [norm_pow]\n have hij : i < j := Finset.mem_range.mp hi\n have h1 : \u2016w\u2016 ^ i \u2264 (1 + 1 / (2 * n)) ^ i :=\n pow_le_pow_left\u2080 (norm_nonneg _)\n (le_trans (le_max_right 1 \u2016w\u2016) hwmax) i\n have h2 : (1 + 1 / (2 * n)) ^ i \u2264 (1 + 1 / (2 * n)) ^ (n - 1) := by\n apply pow_le_pow_right\u2080 (by positivity)\n omega\n exact h1.trans h2\n _ = j * (1 + 1 / (2 * n)) ^ (n - 1) := by\n rw [Finset.sum_const, Finset.card_range, nsmul_eq_mul]\n exact mul_le_mul_of_nonneg_left hsum (by positivity)\n calc \u2016\u2211 j \u2208 Finset.range n, (w ^ j - 1)\u2016\n \u2264 \u2211 j \u2208 Finset.range n, \u2016w ^ j - 1\u2016 := norm_sum_le _ _\n _ \u2264 \u2211 j \u2208 Finset.range n, (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) :=\n Finset.sum_le_sum hbound\n _ = ((1 / \u2016z\u2016) * (1 + 1 / (2 * n)) ^ (n - 1)) * \u2211 j \u2208 Finset.range n, j := by\n rw [\u2190 Finset.mul_sum]\n apply Finset.sum_congr rfl\n intro j _; ring\n _ \u2264 n ^ 2 / \u2016z\u2016 := by\n have hsumj : (\u2211 j \u2208 Finset.range n, j : \u211d) = n * (n - 1) / 2 := by\n have h := Finset.sum_range_id_mul_two n\n have h2 : ((\u2211 j \u2208 Finset.range n, j : \u2115) : \u211d) * 2 = n * (n - 1) := by\n exact_mod_cast h\n linarith\n rw [hsumj]\n have hpow : (1 + 1 / (2 * n : \u211d)) ^ (n - 1) \u2264 2 :=\n le_trans (pow_le_pow_right\u2080 (by positivity) (Nat.sub_le n 1))\n (pow_one_add_inv_two_mul_le n hn)\n have hb1 : (n : \u211d) * (n - 1) / 2 \u2264 n ^ 2 / 2 := by nlinarith [hn0]\n have hb2 : (1 + 1 / (2 * n : \u211d)) ^ (n - 1) * (n * (n - 1) / 2)\n \u2264 2 * (n ^ 2 / 2) :=\n mul_le_mul_of_nonneg hpow hb1 (by positivity) (by positivity)\n have hb3 : ((1 : \u211d) / \u2016z\u2016) * (1 + 1 / (2 * n)) ^ (n - 1) * (n * (n - 1) / 2)\n \u2264 (1 / \u2016z\u2016) * (2 * (n ^ 2 / 2)) :=\n mul_le_mul_of_nonneg_left hb2 (by positivity)\n exact hb3.trans (by ring_nf)\n -- Re(f) = n\u00b7z.re/\u2016z\u2016\u00b2 + ((S\u2212n)/z).re\n have hre1 : ((n : \u2102) * (1 / z)).re = n * z.re / \u2016z\u2016 ^ 2 := by\n have hinv : ((1 : \u2102) / z).re = z.re / \u2016z\u2016 ^ 2 := by\n rw [one_div, Complex.inv_re, hnsq]\n rw [Complex.mul_re]\n simp [hinv]\n have hfre : (1 - w ^ n).re = n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re := by\n rw [hf, hS, Complex.add_re]\n congr 1\n rw [mul_comm, div_eq_mul_inv]\n exact hre1\n rw [hfre]\n have hA : |n * z.re / \u2016z\u2016 ^ 2| \u2264 n / \u2016z\u2016 ^ 2 := by\n rw [abs_div, abs_mul, abs_of_nonneg hn0.le,\n abs_of_nonneg (sq_nonneg \u2016z\u2016)]\n apply (div_le_div_right (by positivity)).mpr\n apply mul_le_mul_of_nonneg_left _ hn0.le\n exact abs_le.mpr \u27e8hzre0, hzre1\u27e9\n have hB : |((S - n) / z).re| \u2264 n ^ 2 / \u2016z\u2016 ^ 2 := by\n have h1 : |((S - n) / z).re| \u2264 \u2016(S - n) / z\u2016 := Complex.abs_re_le_norm _\n have h2 : \u2016(S - n) / z\u2016 \u2264 (n ^ 2 / \u2016z\u2016) / \u2016z\u2016 := by\n rw [norm_div]\n exact (div_le_div_right hzn).mpr hSn\n exact h1.trans (h2.trans (by rw [div_div, \u2190 pow_two]))\n have hnn : (n : \u211d) \u2264 n ^ 2 := by\n have h : (1 : \u211d) \u2264 n := by exact_mod_cast hn\n nlinarith\n calc |n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re|\n \u2264 n / \u2016z\u2016 ^ 2 + n ^ 2 / \u2016z\u2016 ^ 2 := (abs_add _ _).trans (add_le_add hA hB)\n _ = (n + n ^ 2) / \u2016z\u2016 ^ 2 := by ring\n _ \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n apply (div_le_div_right (by positivity)).mpr\n linarith\n\nend NguyenRH1\n"
}
result 2026-08-21 19:21:56Z → 2026-08-21 19:21:56Z
{
"type": "update",
"filePath": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\Scratch.lean",
"content": "/- Session 015 scratch: ii\u2032-1a \u2014 paired liSummand + summability (D-064 \u00a71).\n When green, merge into LiSkeleton.lean \u00a71 replacing the defective liCoeff. -/\nimport Mathlib\nimport Zeta23.WeilEF.ZeroSummability\nimport Zeta23.Statement.SeamClosed\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-- The paired (symmetrized) Li summand: \u00bd\u00b7mult\u00b7(f \u03c1 + f \u03c1\u0304),\nf \u03c1 = 1 \u2212 (1\u22121/\u03c1)\u207f. Manifestly real-valued (`liSummand_eq`), absolutely\nsummable (`liSummable`) \u2014 the correct Keiper\u2013Li coefficient (D-064 \u00a71:\nthe plain unordered sum of f over the zeros is not absolutely\nsummable; the pairing is the classical Bombieri\u2013Lagarias convention). -/\ndef liSummand (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) : \u2102 :=\n (zeroMult \u03c1 : \u2102) / 2 * ((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n) + (1 - (1 - 1 / (conj (\u03c1 : \u2102))) ^ n))\n\nlemma summand_conj (n : \u2115) (z : \u2102) :\n (1 : \u2102) - (1 - 1 / (conj z)) ^ n = conj ((1 - (1 - 1 / z) ^ n)) := by\n rw [map_sub, map_one, map_pow, map_sub, map_one, map_div\u2080, map_one]\n\nlemma liSummand_eq (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) :\n liSummand n \u03c1 = (zeroMult \u03c1 : \u2102) * (((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n).re) : \u2102) := by\n rw [liSummand, summand_conj, Complex.add_conj]\n ring\n\n/-! ### The geometric-sum estimate: |Re(1 \u2212 w\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2 for w = 1\u22121/z -/\n\n/-- (1 + 1/(2n))\u207f \u2264 2 for n \u2265 1. Via (1+x)\u207f \u2264 exp(nx) and exp(1/2) \u2264 2. -/\nlemma pow_one_add_inv_two_mul_le (n : \u2115) (hn : 1 \u2264 n) :\n ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have hbase : (1 : \u211d) + 1 / (2 * n) \u2264 Real.exp (1 / (2 * n)) :=\n Real.add_one_le_exp _\n have h1 : ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 Real.exp (1 / 2) := by\n calc ((1 : \u211d) + 1 / (2 * n)) ^ n\n \u2264 (Real.exp (1 / (2 * n))) ^ n := pow_le_pow_left\u2080 (by positivity) hbase n\n _ = Real.exp (\u2191n * (1 / (2 * n))) := by rw [Real.exp_nat_mul]\n _ = Real.exp (1 / 2) := by congr 1; field_simp\n have h2 : Real.exp (1 / 2 : \u211d) \u2264 2 := by\n have h3 : (1 : \u211d) / 2 \u2264 Real.log 2 := by\n have h := Real.log_two_gt_d9\n linarith\n calc Real.exp (1 / 2 : \u211d) \u2264 Real.exp (Real.log 2) := Real.exp_le_exp.mpr h3\n _ = 2 := Real.exp_log (by norm_num)\n exact h1.trans h2\n\n/-- Key estimate: for n \u2265 1, z with re z \u2208 [0,1], 2n \u2264 \u2016z\u2016:\n|Re(1 \u2212 (1\u22121/z)\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2. -/\nlemma re_li_summand_le {n : \u2115} (hn : 1 \u2264 n) {z : \u2102}\n (hzre0 : 0 \u2264 z.re) (hzre1 : z.re \u2264 1) (hz : 2 * n \u2264 \u2016z\u2016) :\n |(1 - (1 - 1 / z) ^ n).re| \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have hz0 : z \u2260 0 := by\n intro h; rw [h, norm_zero] at hz; linarith\n have hzn : (0 : \u211d) < \u2016z\u2016 := norm_pos_iff.mpr hz0\n have hnsq : Complex.normSq z = \u2016z\u2016 ^ 2 := by\n rw [Complex.normSq_eq_abs, Complex.norm_eq_abs]\n set w : \u2102 := 1 - 1 / z with hw\n -- kernel identity: 1 \u2212 w\u207f = (1/z)\u00b7S, S = \u03a3_{j<n} w^j\n have hgeom : (w - 1) * \u2211 j \u2208 Finset.range n, w ^ j = w ^ n - 1 := mul_geom_sum w n\n have hw1 : w - 1 = -(1 / z) := by rw [hw]; ring\n have hf : (1 : \u2102) - w ^ n = (1 / z) * \u2211 j \u2208 Finset.range n, w ^ j := by\n have h := hgeom\n rw [hw1] at h\n have e := congr_arg Neg.neg h\n simp only [neg_sub, sub_eq_add_neg] at e \u22a2\n have e2 : (1 : \u2102) - w ^ n = -(w ^ n - 1) := by ring\n rw [e2, h]; ring\n set S : \u2102 := \u2211 j \u2208 Finset.range n, w ^ j\n have hS : S = (n : \u2102) + (S - n) := by ring\n -- \u2016w\u2016 \u2264 1 + 1/\u2016z\u2016\n have hwnorm : \u2016w\u2016 \u2264 1 + 1 / \u2016z\u2016 := by\n have e : w = 1 - z\u207b\u00b9 := by rw [hw, div_eq_mul_inv, one_mul]\n rw [e]\n calc \u2016(1 : \u2102) - z\u207b\u00b9\u2016 \u2264 \u2016(1 : \u2102)\u2016 + \u2016z\u207b\u00b9\u2016 := norm_sub_le _ _\n _ = 1 + 1 / \u2016z\u2016 := by rw [norm_one, norm_inv, inv_eq_one_div]\n have h1z : 1 / \u2016z\u2016 \u2264 1 / (2 * n) :=\n one_div_le_one_div_of_le (by positivity) (by exact_mod_cast hz)\n have hwmax : max 1 \u2016w\u2016 \u2264 1 + 1 / (2 * n) := by\n apply max_le (by positivity)\n exact hwnorm.trans (by linarith)\n -- |S \u2212 n| \u2264 n\u00b2/\u2016z\u2016\n have hSn : \u2016S - n\u2016 \u2264 n ^ 2 / \u2016z\u2016 := by\n have hSn1 : S - n = \u2211 j \u2208 Finset.range n, (w ^ j - 1) := by\n rw [Finset.sum_sub_distrib]\n simp [Finset.sum_const, Finset.card_range]\n have hbound : \u2200 j \u2208 Finset.range n,\n \u2016w ^ j - 1\u2016 \u2264 (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) := by\n intro j hj\n have hgeomj : (w - 1) * \u2211 i \u2208 Finset.range j, w ^ i = w ^ j - 1 := mul_geom_sum w j\n have hjn : j \u2264 n := le_of_lt (Finset.mem_range.mp hj)\n have h2 : w ^ j - 1 = -(1 / z) * \u2211 i \u2208 Finset.range j, w ^ i := by\n have h := hgeomj; rw [hw1] at h\n rw [\u2190 h]; ring\n rw [h2, norm_mul, norm_neg, norm_div, norm_one]\n have hsum : \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016 \u2264 j * (1 + 1 / (2 * n)) ^ (n - 1) := by\n calc \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016\n \u2264 \u2211 i \u2208 Finset.range j, \u2016w ^ i\u2016 := norm_sum_le _ _\n _ \u2264 \u2211 i \u2208 Finset.range j, (1 + 1 / (2 * n)) ^ (n - 1) := by\n apply Finset.sum_le_sum\n intro i hi\n rw [norm_pow]\n have hij : i < j := Finset.mem_range.mp hi\n have h1 : \u2016w\u2016 ^ i \u2264 (1 + 1 / (2 * n)) ^ i :=\n pow_le_pow_left\u2080 (norm_nonneg _)\n (le_trans (le_max_right 1 \u2016w\u2016) hwmax) i\n have h2 : (1 + 1 / (2 * n)) ^ i \u2264 (1 + 1 / (2 * n)) ^ (n - 1) := by\n apply pow_le_pow_right\u2080 (by positivity)\n omega\n exact h1.trans h2\n _ = j * (1 + 1 / (2 * n)) ^ (n - 1) := by\n rw [Finset.sum_const, Finset.card_range, nsmul_eq_mul]\n exact mul_le_mul_of_nonneg_left hsum (by positivity)\n calc \u2016\u2211 j \u2208 Finset.range n, (w ^ j - 1)\u2016\n \u2264 \u2211 j \u2208 Finset.range n, \u2016w ^ j - 1\u2016 := norm_sum_le _ _\n _ \u2264 \u2211 j \u2208 Finset.range n, (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) :=\n Finset.sum_le_sum hbound\n _ = ((1 / \u2016z\u2016) * (1 + 1 / (2 * n)) ^ (n - 1)) * \u2211 j \u2208 Finset.range n, j := by\n rw [\u2190 Finset.mul_sum]\n apply Finset.sum_congr rfl\n intro j _; ring\n _ \u2264 n ^ 2 / \u2016z\u2016 := by\n have hsumj : (\u2211 j \u2208 Finset.range n, j : \u211d) = n * (n - 1) / 2 := by\n have h := Finset.sum_range_id_mul_two n\n have h2 : ((\u2211 j \u2208 Finset.range n, j : \u2115) : \u211d) * 2 = n * (n - 1) := by\n exact_mod_cast h\n linarith\n rw [hsumj]\n have hpow : (1 + 1 / (2 * n : \u211d)) ^ (n - 1) \u2264 2 :=\n le_trans (pow_le_pow_right\u2080 (by positivity) (Nat.sub_le n 1))\n (pow_one_add_inv_two_mul_le n hn)\n have hb1 : (n : \u211d) * (n - 1) / 2 \u2264 n ^ 2 / 2 := by nlinarith [hn0]\n have hb2 : (1 + 1 / (2 * n : \u211d)) ^ (n - 1) * (n * (n - 1) / 2)\n \u2264 2 * (n ^ 2 / 2) :=\n mul_le_mul_of_nonneg hpow hb1 (by positivity) (by positivity)\n have hb3 : ((1 : \u211d) / \u2016z\u2016) * (1 + 1 / (2 * n)) ^ (n - 1) * (n * (n - 1) / 2)\n \u2264 (1 / \u2016z\u2016) * (2 * (n ^ 2 / 2)) :=\n mul_le_mul_of_nonneg_left hb2 (by positivity)\n exact hb3.trans (by ring_nf)\n -- Re(f) = n\u00b7z.re/\u2016z\u2016\u00b2 + ((S\u2212n)/z).re\n have hre1 : ((n : \u2102) * (1 / z)).re = n * z.re / \u2016z\u2016 ^ 2 := by\n have hinv : ((1 : \u2102) / z).re = z.re / \u2016z\u2016 ^ 2 := by\n rw [one_div, Complex.inv_re, hnsq]\n rw [Complex.mul_re]\n simp [hinv]\n have hfre : (1 - w ^ n).re = n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re := by\n rw [hf, hS, Complex.add_re]\n congr 1\n rw [mul_comm, div_eq_mul_inv]\n exact hre1\n rw [hfre]\n have hA : |n * z.re / \u2016z\u2016 ^ 2| \u2264 n / \u2016z\u2016 ^ 2 := by\n rw [abs_div, abs_mul, abs_of_nonneg hn0.le,\n abs_of_nonneg (sq_nonneg \u2016z\u2016)]\n apply (div_le_div_right (by positivity)).mpr\n apply mul_le_mul_of_nonneg_left _ hn0.le\n exact abs_le.mpr \u27e8hzre0, hzre1\u27e9\n have hB : |((S - n) / z).re| \u2264 n ^ 2 / \u2016z\u2016 ^ 2 := by\n have h1 : |((S - n) / z).re| \u2264 \u2016(S - n) / z\u2016 := Complex.abs_re_le_norm _\n have h2 : \u2016(S - n) / z\u2016 \u2264 (n ^ 2 / \u2016z\u2016) / \u2016z\u2016 := by\n rw [norm_div]\n exact (div_le_div_right hzn).mpr hSn\n exact h1.trans (h2.trans (by rw [div_div, \u2190 pow_two]))\n have hnn : (n : \u211d) \u2264 n ^ 2 := by\n have h : (1 : \u211d) \u2264 n := by exact_mod_cast hn\n nlinarith\n calc |n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re|\n \u2264 n / \u2016z\u2016 ^ 2 + n ^ 2 / \u2016z\u2016 ^ 2 := (abs_add _ _).trans (add_le_add hA hB)\n _ = (n + n ^ 2) / \u2016z\u2016 ^ 2 := by ring\n _ \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n apply (div_le_div_right (by positivity)).mpr\n linarith\n\nend NguyenRH1\n",
"structuredPatch": [
{
"oldStart": 16,
"oldLines": 15,
"newStart": 16,
"newLines": 15,
"lines": [
" the plain unordered sum of f over the zeros is not absolutely",
" summable; the pairing is the classical Bombieri\u2013Lagarias convention). -/",
" def liSummand (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) : \u2102 :=",
"- (zeroMult \u03c1 : \u2102) / 2 * ((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n) + (1 - (1 - 1 / (star (\u03c1 : \u2102))) ^ n))",
"+ (zeroMult \u03c1 : \u2102) / 2 * ((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n) + (1 - (1 - 1 / (conj (\u03c1 : \u2102))) ^ n))",
" ",
"-lemma summand_star (n : \u2115) (z : \u2102) :",
"- (1 : \u2102) - (1 - 1 / (star z)) ^ n = star ((1 - (1 - 1 / z) ^ n)) := by",
"+lemma summand_conj (n : \u2115) (z : \u2102) :",
"+ (1 : \u2102) - (1 - 1 / (conj z)) ^ n = conj ((1 - (1 - 1 / z) ^ n)) := by",
" rw [map_sub, map_one, map_pow, map_sub, map_one, map_div\u2080, map_one]",
" ",
" lemma liSummand_eq (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) :",
" liSummand n \u03c1 = (zeroMult \u03c1 : \u2102) * (((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n).re) : \u2102) := by",
"- rw [liSummand, summand_star, Complex.add_conj]",
"+ rw [liSummand, summand_conj, Complex.add_conj]",
" ring",
" ",
" /-! ### The geometric-sum estimate: |Re(1 \u2212 w\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2 for w = 1\u22121/z -/"
]
},
{
"oldStart": 33,
"oldLines": 26,
"newStart": 33,
"newLines": 20,
"lines": [
" lemma pow_one_add_inv_two_mul_le (n : \u2115) (hn : 1 \u2264 n) :",
" ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 2 := by",
" have hn0 : (0 : \u211d) < n := by exact_mod_cast hn",
"- have h1 : ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 Real.exp (n * (1 / (2 * n))) := by",
"- have h := Real.add_one_le_exp (1 / (2 * (n : \u211d)))",
"+ have hbase : (1 : \u211d) + 1 / (2 * n) \u2264 Real.exp (1 / (2 * n)) :=",
"+ Real.add_one_le_exp _",
"+ have h1 : ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 Real.exp (1 / 2) := by",
" calc ((1 : \u211d) + 1 / (2 * n)) ^ n",
"- \u2264 (Real.exp (1 / (2 * n))) ^ n := by",
"- gcongr",
"- \u00b7 linarith",
"- \u00b7 exact h",
"- _ = Real.exp (n * (1 / (2 * n))) := by",
"- rw [\u2190 Real.exp_nat_mul]",
"- have h2 : (n : \u211d) * (1 / (2 * n)) = 1 / 2 := by field_simp",
"- rw [h2] at h1",
"- have h3 : Real.exp (1 / 2 : \u211d) \u2264 2 := by",
"- have hsq : (Real.exp (1 / 2 : \u211d)) ^ 2 \u2264 (2 : \u211d) ^ 2 := by",
"- rw [\u2190 Real.exp_nat_mul]",
"- have : Real.exp (2 * (1 / 2 : \u211d)) = Real.exp 1 := by ring_nf",
"- rw [this]",
"- have h := Real.exp_one_lt_d9",
"- norm_num at h \u22a2; linarith",
"- nlinarith [Real.exp_pos (1 / 2 : \u211d)]",
"- exact h1.trans h3",
"+ \u2264 (Real.exp (1 / (2 * n))) ^ n := pow_le_pow_left\u2080 (by positivity) hbase n",
"+ _ = Real.exp (\u2191n * (1 / (2 * n))) := by rw [Real.exp_nat_mul]",
"+ _ = Real.exp (1 / 2) := by congr 1; field_simp",
"+ have h2 : Real.exp (1 / 2 : \u211d) \u2264 2 := by",
"+ have h3 : (1 : \u211d) / 2 \u2264 Real.log 2 := by",
"+ have h := Real.log_two_gt_d9",
"+ linarith",
"+ calc Real.exp (1 / 2 : \u211d) \u2264 Real.exp (Real.log 2) := Real.exp_le_exp.mpr h3",
"+ _ = 2 := Real.exp_log (by norm_num)",
"+ exact h1.trans h2",
" ",
" /-- Key estimate: for n \u2265 1, z with re z \u2208 [0,1], 2n \u2264 \u2016z\u2016:",
" |Re(1 \u2212 (1\u22121/z)\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2. -/"
]
},
{
"oldStart": 63,
"oldLines": 41,
"newStart": 57,
"newLines": 46,
"lines": [
" have hz0 : z \u2260 0 := by",
" intro h; rw [h, norm_zero] at hz; linarith",
" have hzn : (0 : \u211d) < \u2016z\u2016 := norm_pos_iff.mpr hz0",
"+ have hnsq : Complex.normSq z = \u2016z\u2016 ^ 2 := by",
"+ rw [Complex.normSq_eq_abs, Complex.norm_eq_abs]",
" set w : \u2102 := 1 - 1 / z with hw",
" -- kernel identity: 1 \u2212 w\u207f = (1/z)\u00b7S, S = \u03a3_{j<n} w^j",
"- have hgeom : w ^ n - 1 = (w - 1) * \u2211 j \u2208 Finset.range n, w ^ j := geom_sum_mul w n",
"+ have hgeom : (w - 1) * \u2211 j \u2208 Finset.range n, w ^ j = w ^ n - 1 := mul_geom_sum w n",
" have hw1 : w - 1 = -(1 / z) := by rw [hw]; ring",
" have hf : (1 : \u2102) - w ^ n = (1 / z) * \u2211 j \u2208 Finset.range n, w ^ j := by",
"- have : (1 : \u2102) - w ^ n = -(w - 1) * \u2211 j \u2208 Finset.range n, w ^ j := by",
"- rw [\u2190 hgeom]; ring",
"- rw [this, hw1]; ring",
"+ have h := hgeom",
"+ rw [hw1] at h",
"+ have e := congr_arg Neg.neg h",
"+ simp only [neg_sub, sub_eq_add_neg] at e \u22a2",
"+ have e2 : (1 : \u2102) - w ^ n = -(w ^ n - 1) := by ring",
"+ rw [e2, h]; ring",
" set S : \u2102 := \u2211 j \u2208 Finset.range n, w ^ j",
"- -- S = n + (S \u2212 n); Re(f) = n\u00b7Re(1/z) + Re((S\u2212n)/z)",
" have hS : S = (n : \u2102) + (S - n) := by ring",
"+ -- \u2016w\u2016 \u2264 1 + 1/\u2016z\u2016",
"+ have hwnorm : \u2016w\u2016 \u2264 1 + 1 / \u2016z\u2016 := by",
"+ have e : w = 1 - z\u207b\u00b9 := by rw [hw, div_eq_mul_inv, one_mul]",
"+ rw [e]",
"+ calc \u2016(1 : \u2102) - z\u207b\u00b9\u2016 \u2264 \u2016(1 : \u2102)\u2016 + \u2016z\u207b\u00b9\u2016 := norm_sub_le _ _",
"+ _ = 1 + 1 / \u2016z\u2016 := by rw [norm_one, norm_inv, inv_eq_one_div]",
"+ have h1z : 1 / \u2016z\u2016 \u2264 1 / (2 * n) :=",
"+ one_div_le_one_div_of_le (by positivity) (by exact_mod_cast hz)",
"+ have hwmax : max 1 \u2016w\u2016 \u2264 1 + 1 / (2 * n) := by",
"+ apply max_le (by positivity)",
"+ exact hwnorm.trans (by linarith)",
" -- |S \u2212 n| \u2264 n\u00b2/\u2016z\u2016",
"- have hwnorm : \u2016w\u2016 \u2264 1 + 1 / \u2016z\u2016 := by",
"- have : w = 1 - z\u207b\u00b9 := by rw [hw, div_eq_mul_inv, one_mul]",
"- rw [this]",
"- calc \u2016(1 : \u2102) - z\u207b\u00b9\u2016 \u2264 \u2016(1 : \u2102)\u2016 + \u2016z\u207b\u00b9\u2016 := norm_sub_le _ _",
"- _ = 1 + 1 / \u2016z\u2016 := by rw [norm_one, norm_inv]",
"- have hwmax : max 1 \u2016w\u2016 \u2264 1 + 1 / (2 * n) := by",
"- have h1 : 1 / \u2016z\u2016 \u2264 1 / (2 * n) := by",
"- apply one_div_le_one_div_of_le (by positivity : (0:\u211d) < 2 * n)",
"- exact_mod_cast hz",
"- have h2 : \u2016w\u2016 \u2264 1 + 1 / (2 * n) := hwnorm.trans (by linarith)",
"- apply max_le",
"- \u00b7 linarith",
"- \u00b7 exact h2",
" have hSn : \u2016S - n\u2016 \u2264 n ^ 2 / \u2016z\u2016 := by",
" have hSn1 : S - n = \u2211 j \u2208 Finset.range n, (w ^ j - 1) := by",
" rw [Finset.sum_sub_distrib]",
" simp [Finset.sum_const, Finset.card_range]",
"- rw [hSn1]",
" have hbound : \u2200 j \u2208 Finset.range n,",
" \u2016w ^ j - 1\u2016 \u2264 (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) := by",
" intro j hj",
"- have hgeomj : w ^ j - 1 = (w - 1) * \u2211 i \u2208 Finset.range j, w ^ i := geom_sum_mul w j",
"- rw [hgeomj, norm_mul, hw1, norm_neg, norm_div, norm_one]",
"+ have hgeomj : (w - 1) * \u2211 i \u2208 Finset.range j, w ^ i = w ^ j - 1 := mul_geom_sum w j",
"+ have hjn : j \u2264 n := le_of_lt (Finset.mem_range.mp hj)",
"+ have h2 : w ^ j - 1 = -(1 / z) * \u2211 i \u2208 Finset.range j, w ^ i := by",
"+ have h := hgeomj; rw [hw1] at h",
"+ rw [\u2190 h]; ring",
"+ rw [h2, norm_mul, norm_neg, norm_div, norm_one]",
" have hsum : \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016 \u2264 j * (1 + 1 / (2 * n)) ^ (n - 1) := by",
" calc \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016",
" \u2264 \u2211 i \u2208 Finset.range j, \u2016w ^ i\u2016 := norm_sum_le _ _"
]
},
{
"oldStart": 105,
"oldLines": 22,
"newStart": 104,
"newLines": 25,
"lines": [
" apply Finset.sum_le_sum",
" intro i hi",
" rw [norm_pow]",
"- have hjn : i \u2264 n - 1 := by",
"- have hij : i < j := Finset.mem_range.mp hi",
"- have hjn' : j \u2264 n := le_of_lt (Finset.mem_range.mp hj)",
"+ have hij : i < j := Finset.mem_range.mp hi",
"+ have h1 : \u2016w\u2016 ^ i \u2264 (1 + 1 / (2 * n)) ^ i :=",
"+ pow_le_pow_left\u2080 (norm_nonneg _)",
"+ (le_trans (le_max_right 1 \u2016w\u2016) hwmax) i",
"+ have h2 : (1 + 1 / (2 * n)) ^ i \u2264 (1 + 1 / (2 * n)) ^ (n - 1) := by",
"+ apply pow_le_pow_right\u2080 (by positivity)",
" omega",
"- exact pow_le_pow_left\u2080 (by positivity)",
"- (le_trans (le_max_right 1 \u2016w\u2016) hwmax) i (by omega)",
"+ exact h1.trans h2",
" _ = j * (1 + 1 / (2 * n)) ^ (n - 1) := by",
" rw [Finset.sum_const, Finset.card_range, nsmul_eq_mul]",
" exact mul_le_mul_of_nonneg_left hsum (by positivity)",
" calc \u2016\u2211 j \u2208 Finset.range n, (w ^ j - 1)\u2016",
" \u2264 \u2211 j \u2208 Finset.range n, \u2016w ^ j - 1\u2016 := norm_sum_le _ _",
"- _ \u2264 \u2211 j \u2208 Finset.range n, (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) := by",
"- exact Finset.sum_le_sum hbound",
"- _ = (1 / \u2016z\u2016) * (1 + 1 / (2 * n)) ^ (n - 1) * \u2211 j \u2208 Finset.range n, j := by",
"- rw [Finset.mul_sum]; congr 1; rw [Finset.mul_sum]",
"- apply Finset.sum_congr rfl; intro j _; ring",
"+ _ \u2264 \u2211 j \u2208 Finset.range n, (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) :=",
"+ Finset.sum_le_sum hbound",
"+ _ = ((1 / \u2016z\u2016) * (1 + 1 / (2 * n)) ^ (n - 1)) * \u2211 j \u2208 Finset.range n, j := by",
"+ rw [\u2190 Finset.mul_sum]",
"+ apply Finset.sum_congr rfl",
"+ intro j _; ring",
" _ \u2264 n ^ 2 / \u2016z\u2016 := by",
" have hsumj : (\u2211 j \u2208 Finset.range n, j : \u211d) = n * (n - 1) / 2 := by",
" have h := Finset.sum_range_id_mul_two n"
]
},
{
"oldStart": 128,
"oldLines": 63,
"newStart": 130,
"newLines": 50,
"lines": [
" exact_mod_cast h",
" linarith",
" rw [hsumj]",
"- have hpow : (1 + 1 / (2 * n : \u211d)) ^ (n - 1) \u2264 2 := by",
"- have h := pow_one_add_inv_two_mul_le n hn",
"- calc (1 + 1 / (2 * n : \u211d)) ^ (n - 1)",
"- \u2264 (1 + 1 / (2 * n : \u211d)) ^ n := by",
"- apply pow_le_pow_right\u2080 (by positivity)",
"- \u00b7 have : 1 \u2264 (1 : \u211d) + 1 / (2 * n) := by positivity",
"- exact this",
"- \u00b7 omega",
"- _ \u2264 2 := h",
"- have h3 : (1 / \u2016z\u2016) * (1 + 1 / (2 * n : \u211d)) ^ (n - 1) * (n * (n - 1) / 2)",
"- \u2264 (1 / \u2016z\u2016) * 2 * (n ^ 2 / 2) := by",
"- apply mul_le_mul_of_nonneg_left _ (by positivity)",
"- apply mul_le_mul_of_nonneg_left hpow (by positivity)",
"- \u00b7 have : (n : \u211d) * (n - 1) / 2 \u2264 n ^ 2 / 2 := by",
"- have hn1 : (1 : \u211d) \u2264 n := by exact_mod_cast hn",
"- nlinarith",
"- linarith",
"- calc (1 / \u2016z\u2016) * (1 + 1 / (2 * n : \u211d)) ^ (n - 1) * (n * (n - 1) / 2)",
"- \u2264 (1 / \u2016z\u2016) * 2 * (n ^ 2 / 2) := h3",
"- _ = n ^ 2 / \u2016z\u2016 := by ring",
"- -- assemble",
"- have hfre : (1 - w ^ n).re = n * z.re / \u2016z\u2016 ^ 2 + (((S - n) / z).re) := by",
"- rw [hf, hS]",
"- have h1 : ((1 / z) * ((n : \u2102) + (S - n))) = (n : \u2102) * (1 / z) + (S - n) / z := by",
"- field_simp; ring",
"- rw [h1]",
"- have hre1 : ((n : \u2102) * (1 / z)).re = n * z.re / \u2016z\u2016 ^ 2 := by",
"- have hinv : ((1 : \u2102) / z).re = z.re / \u2016z\u2016 ^ 2 := by",
"- rw [one_div, Complex.inv_def]",
"- simp [Complex.div_re, Complex.normSq_apply, Complex.norm_eq_abs,",
"- Complex.sq_abs]",
"- rw [Complex.add_re] at *",
"- simp [hinv]",
"- rw [Complex.add_re, hre1]",
"+ have hpow : (1 + 1 / (2 * n : \u211d)) ^ (n - 1) \u2264 2 :=",
"+ le_trans (pow_le_pow_right\u2080 (by positivity) (Nat.sub_le n 1))",
"+ (pow_one_add_inv_two_mul_le n hn)",
"+ have hb1 : (n : \u211d) * (n - 1) / 2 \u2264 n ^ 2 / 2 := by nlinarith [hn0]",
"+ have hb2 : (1 + 1 / (2 * n : \u211d)) ^ (n - 1) * (n * (n - 1) / 2)",
"+ \u2264 2 * (n ^ 2 / 2) :=",
"+ mul_le_mul_of_nonneg hpow hb1 (by positivity) (by positivity)",
"+ have hb3 : ((1 : \u211d) / \u2016z\u2016) * (1 + 1 / (2 * n)) ^ (n - 1) * (n * (n - 1) / 2)",
"+ \u2264 (1 / \u2016z\u2016) * (2 * (n ^ 2 / 2)) :=",
"+ mul_le_mul_of_nonneg_left hb2 (by positivity)",
"+ exact hb3.trans (by ring_nf)",
"+ -- Re(f) = n\u00b7z.re/\u2016z\u2016\u00b2 + ((S\u2212n)/z).re",
"+ have hre1 : ((n : \u2102) * (1 / z)).re = n * z.re / \u2016z\u2016 ^ 2 := by",
"+ have hinv : ((1 : \u2102) / z).re = z.re / \u2016z\u2016 ^ 2 := by",
"+ rw [one_div, Complex.inv_re, hnsq]",
"+ rw [Complex.mul_re]",
"+ simp [hinv]",
"+ have hfre : (1 - w ^ n).re = n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re := by",
"+ rw [hf, hS, Complex.add_re]",
"+ congr 1",
"+ rw [mul_comm, div_eq_mul_inv]",
"+ exact hre1",
" rw [hfre]",
" have hA : |n * z.re / \u2016z\u2016 ^ 2| \u2264 n / \u2016z\u2016 ^ 2 := by",
"- rw [abs_div, abs_mul, abs_of_nonneg hn0.le, abs_pow]",
"- apply div_le_div_of_nonneg_right (by positivity)",
"- calc |z.re| \u2264 1 := abs_le.mpr \u27e8by linarith, hzre1\u27e9",
"- _ \u2264 _ := by linarith",
"+ rw [abs_div, abs_mul, abs_of_nonneg hn0.le,",
"+ abs_of_nonneg (sq_nonneg \u2016z\u2016)]",
"+ apply (div_le_div_right (by positivity)).mpr",
"+ apply mul_le_mul_of_nonneg_left _ hn0.le",
"+ exact abs_le.mpr \u27e8hzre0, hzre1\u27e9",
" have hB : |((S - n) / z).re| \u2264 n ^ 2 / \u2016z\u2016 ^ 2 := by",
" have h1 : |((S - n) / z).re| \u2264 \u2016(S - n) / z\u2016 := Complex.abs_re_le_norm _",
" have h2 : \u2016(S - n) / z\u2016 \u2264 (n ^ 2 / \u2016z\u2016) / \u2016z\u2016 := by",
" rw [norm_div]",
"- apply div_le_div_of_nonneg_right hSn (by positivity)",
"- rw [div_pow] at *",
"- calc |((S - n) / z).re| \u2264 \u2016(S - n) / z\u2016 := h1",
"- _ \u2264 (n ^ 2 / \u2016z\u2016) / \u2016z\u2016 := h2",
"- _ = n ^ 2 / \u2016z\u2016 ^ 2 := by ring",
"+ exact (div_le_div_right hzn).mpr hSn",
"+ exact h1.trans (h2.trans (by rw [div_div, \u2190 pow_two]))",
"+ have hnn : (n : \u211d) \u2264 n ^ 2 := by",
"+ have h : (1 : \u211d) \u2264 n := by exact_mod_cast hn",
"+ nlinarith",
" calc |n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re|",
"- \u2264 n / \u2016z\u2016 ^ 2 + n ^ 2 / \u2016z\u2016 ^ 2 := abs_add _ _ |>.trans (add_le_add hA hB)",
"+ \u2264 n / \u2016z\u2016 ^ 2 + n ^ 2 / \u2016z\u2016 ^ 2 := (abs_add _ _).trans (add_le_add hA hB)",
"+ _ = (n + n ^ 2) / \u2016z\u2016 ^ 2 := by ring",
" _ \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by",
"- have hn1 : (n : \u211d) \u2264 n ^ 2 := by",
"- have : (1 : \u211d) \u2264 n := by exact_mod_cast hn",
"- nlinarith",
"- field_simp at *",
"- nlinarith",
"+ apply (div_le_div_right (by positivity)).mpr",
"+ linarith",
" ",
" end NguyenRH1",
" "
]
}
],
"originalFile": "/- Session 015 scratch: ii\u2032-1a \u2014 paired liSummand + summability (D-064 \u00a71).\n When green, merge into LiSkeleton.lean \u00a71 replacing the defective liCoeff. -/\nimport Mathlib\nimport Zeta23.WeilEF.ZeroSummability\nimport Zeta23.Statement.SeamClosed\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-- The paired (symmetrized) Li summand: \u00bd\u00b7mult\u00b7(f \u03c1 + f \u03c1\u0304),\nf \u03c1 = 1 \u2212 (1\u22121/\u03c1)\u207f. Manifestly real-valued (`liSummand_eq`), absolutely\nsummable (`liSummable`) \u2014 the correct Keiper\u2013Li coefficient (D-064 \u00a71:\nthe plain unordered sum of f over the zeros is not absolutely\nsummable; the pairing is the classical Bombieri\u2013Lagarias convention). -/\ndef liSummand (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) : \u2102 :=\n (zeroMult \u03c1 : \u2102) / 2 * ((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n) + (1 - (1 - 1 / (star (\u03c1 : \u2102))) ^ n))\n\nlemma summand_star (n : \u2115) (z : \u2102) :\n (1 : \u2102) - (1 - 1 / (star z)) ^ n = star ((1 - (1 - 1 / z) ^ n)) := by\n rw [map_sub, map_one, map_pow, map_sub, map_one, map_div\u2080, map_one]\n\nlemma liSummand_eq (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) :\n liSummand n \u03c1 = (zeroMult \u03c1 : \u2102) * (((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n).re) : \u2102) := by\n rw [liSummand, summand_star, Complex.add_conj]\n ring\n\n/-! ### The geometric-sum estimate: |Re(1 \u2212 w\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2 for w = 1\u22121/z -/\n\n/-- (1 + 1/(2n))\u207f \u2264 2 for n \u2265 1. Via (1+x)\u207f \u2264 exp(nx) and exp(1/2) \u2264 2. -/\nlemma pow_one_add_inv_two_mul_le (n : \u2115) (hn : 1 \u2264 n) :\n ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have h1 : ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 Real.exp (n * (1 / (2 * n))) := by\n have h := Real.add_one_le_exp (1 / (2 * (n : \u211d)))\n calc ((1 : \u211d) + 1 / (2 * n)) ^ n\n \u2264 (Real.exp (1 / (2 * n))) ^ n := by\n gcongr\n \u00b7 linarith\n \u00b7 exact h\n _ = Real.exp (n * (1 / (2 * n))) := by\n rw [\u2190 Real.exp_nat_mul]\n have h2 : (n : \u211d) * (1 / (2 * n)) = 1 / 2 := by field_simp\n rw [h2] at h1\n have h3 : Real.exp (1 / 2 : \u211d) \u2264 2 := by\n have hsq : (Real.exp (1 / 2 : \u211d)) ^ 2 \u2264 (2 : \u211d) ^ 2 := by\n rw [\u2190 Real.exp_nat_mul]\n have : Real.exp (2 * (1 / 2 : \u211d)) = Real.exp 1 := by ring_nf\n rw [this]\n have h := Real.exp_one_lt_d9\n norm_num at h \u22a2; linarith\n nlinarith [Real.exp_pos (1 / 2 : \u211d)]\n exact h1.trans h3\n\n/-- Key estimate: for n \u2265 1, z with re z \u2208 [0,1], 2n \u2264 \u2016z\u2016:\n|Re(1 \u2212 (1\u22121/z)\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2. -/\nlemma re_li_summand_le {n : \u2115} (hn : 1 \u2264 n) {z : \u2102}\n (hzre0 : 0 \u2264 z.re) (hzre1 : z.re \u2264 1) (hz : 2 * n \u2264 \u2016z\u2016) :\n |(1 - (1 - 1 / z) ^ n).re| \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have hz0 : z \u2260 0 := by\n intro h; rw [h, norm_zero] at hz; linarith\n have hzn : (0 : \u211d) < \u2016z\u2016 := norm_pos_iff.mpr hz0\n set w : \u2102 := 1 - 1 / z with hw\n -- kernel identity: 1 \u2212 w\u207f = (1/z)\u00b7S, S = \u03a3_{j<n} w^j\n have hgeom : w ^ n - 1 = (w - 1) * \u2211 j \u2208 Finset.range n, w ^ j := geom_sum_mul w n\n have hw1 : w - 1 = -(1 / z) := by rw [hw]; ring\n have hf : (1 : \u2102) - w ^ n = (1 / z) * \u2211 j \u2208 Finset.range n, w ^ j := by\n have : (1 : \u2102) - w ^ n = -(w - 1) * \u2211 j \u2208 Finset.range n, w ^ j := by\n rw [\u2190 hgeom]; ring\n rw [this, hw1]; ring\n set S : \u2102 := \u2211 j \u2208 Finset.range n, w ^ j\n -- S = n + (S \u2212 n); Re(f) = n\u00b7Re(1/z) + Re((S\u2212n)/z)\n have hS : S = (n : \u2102) + (S - n) := by ring\n -- |S \u2212 n| \u2264 n\u00b2/\u2016z\u2016\n have hwnorm : \u2016w\u2016 \u2264 1 + 1 / \u2016z\u2016 := by\n have : w = 1 - z\u207b\u00b9 := by rw [hw, div_eq_mul_inv, one_mul]\n rw [this]\n calc \u2016(1 : \u2102) - z\u207b\u00b9\u2016 \u2264 \u2016(1 : \u2102)\u2016 + \u2016z\u207b\u00b9\u2016 := norm_sub_le _ _\n _ = 1 + 1 / \u2016z\u2016 := by rw [norm_one, norm_inv]\n have hwmax : max 1 \u2016w\u2016 \u2264 1 + 1 / (2 * n) := by\n have h1 : 1 / \u2016z\u2016 \u2264 1 / (2 * n) := by\n apply one_div_le_one_div_of_le (by positivity : (0:\u211d) < 2 * n)\n exact_mod_cast hz\n have h2 : \u2016w\u2016 \u2264 1 + 1 / (2 * n) := hwnorm.trans (by linarith)\n apply max_le\n \u00b7 linarith\n \u00b7 exact h2\n have hSn : \u2016S - n\u2016 \u2264 n ^ 2 / \u2016z\u2016 := by\n have hSn1 : S - n = \u2211 j \u2208 Finset.range n, (w ^ j - 1) := by\n rw [Finset.sum_sub_distrib]\n simp [Finset.sum_const, Finset.card_range]\n rw [hSn1]\n have hbound : \u2200 j \u2208 Finset.range n,\n \u2016w ^ j - 1\u2016 \u2264 (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) := by\n intro j hj\n have hgeomj : w ^ j - 1 = (w - 1) * \u2211 i \u2208 Finset.range j, w ^ i := geom_sum_mul w j\n rw [hgeomj, norm_mul, hw1, norm_neg, norm_div, norm_one]\n have hsum : \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016 \u2264 j * (1 + 1 / (2 * n)) ^ (n - 1) := by\n calc \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016\n \u2264 \u2211 i \u2208 Finset.range j, \u2016w ^ i\u2016 := norm_sum_le _ _\n _ \u2264 \u2211 i \u2208 Finset.range j, (1 + 1 / (2 * n)) ^ (n - 1) := by\n apply Finset.sum_le_sum\n intro i hi\n rw [norm_pow]\n have hjn : i \u2264 n - 1 := by\n have hij : i < j := Finset.mem_range.mp hi\n have hjn' : j \u2264 n := le_of_lt (Finset.mem_range.mp hj)\n omega\n exact pow_le_pow_left\u2080 (by positivity)\n (le_trans (le_max_right 1 \u2016w\u2016) hwmax) i (by omega)\n _ = j * (1 + 1 / (2 * n)) ^ (n - 1) := by\n rw [Finset.sum_const, Finset.card_range, nsmul_eq_mul]\n exact mul_le_mul_of_nonneg_left hsum (by positivity)\n calc \u2016\u2211 j \u2208 Finset.range n, (w ^ j - 1)\u2016\n \u2264 \u2211 j \u2208 Finset.range n, \u2016w ^ j - 1\u2016 := norm_sum_le _ _\n _ \u2264 \u2211 j \u2208 Finset.range n, (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) := by\n exact Finset.sum_le_sum hbound\n _ = (1 / \u2016z\u2016) * (1 + 1 / (2 * n)) ^ (n - 1) * \u2211 j \u2208 Finset.range n, j := by\n rw [Finset.mul_sum]; congr 1; rw [Finset.mul_sum]\n apply Finset.sum_congr rfl; intro j _; ring\n _ \u2264 n ^ 2 / \u2016z\u2016 := by\n have hsumj : (\u2211 j \u2208 Finset.range n, j : \u211d) = n * (n - 1) / 2 := by\n have h := Finset.sum_range_id_mul_two n\n have h2 : ((\u2211 j \u2208 Finset.range n, j : \u2115) : \u211d) * 2 = n * (n - 1) := by\n exact_mod_cast h\n linarith\n rw [hsumj]\n have hpow : (1 + 1 / (2 * n : \u211d)) ^ (n - 1) \u2264 2 := by\n have h := pow_one_add_inv_two_mul_le n hn\n calc (1 + 1 / (2 * n : \u211d)) ^ (n - 1)\n \u2264 (1 + 1 / (2 * n : \u211d)) ^ n := by\n apply pow_le_pow_right\u2080 (by positivity)\n \u00b7 have : 1 \u2264 (1 : \u211d) + 1 / (2 * n) := by positivity\n exact this\n \u00b7 omega\n _ \u2264 2 := h\n have h3 : (1 / \u2016z\u2016) * (1 + 1 / (2 * n : \u211d)) ^ (n - 1) * (n * (n - 1) / 2)\n \u2264 (1 / \u2016z\u2016) * 2 * (n ^ 2 / 2) := by\n apply mul_le_mul_of_nonneg_left _ (by positivity)\n apply mul_le_mul_of_nonneg_left hpow (by positivity)\n \u00b7 have : (n : \u211d) * (n - 1) / 2 \u2264 n ^ 2 / 2 := by\n have hn1 : (1 : \u211d) \u2264 n := by exact_mod_cast hn\n nlinarith\n linarith\n calc (1 / \u2016z\u2016) * (1 + 1 / (2 * n : \u211d)) ^ (n - 1) * (n * (n - 1) / 2)\n \u2264 (1 / \u2016z\u2016) * 2 * (n ^ 2 / 2) := h3\n _ = n ^ 2 / \u2016z\u2016 := by ring\n -- assemble\n have hfre : (1 - w ^ n).re = n * z.re / \u2016z\u2016 ^ 2 + (((S - n) / z).re) := by\n rw [hf, hS]\n have h1 : ((1 / z) * ((n : \u2102) + (S - n))) = (n : \u2102) * (1 / z) + (S - n) / z := by\n field_simp; ring\n rw [h1]\n have hre1 : ((n : \u2102) * (1 / z)).re = n * z.re / \u2016z\u2016 ^ 2 := by\n have hinv : ((1 : \u2102) / z).re = z.re / \u2016z\u2016 ^ 2 := by\n rw [one_div, Complex.inv_def]\n simp [Complex.div_re, Complex.normSq_apply, Complex.norm_eq_abs,\n Complex.sq_abs]\n rw [Complex.add_re] at *\n simp [hinv]\n rw [Complex.add_re, hre1]\n rw [hfre]\n have hA : |n * z.re / \u2016z\u2016 ^ 2| \u2264 n / \u2016z\u2016 ^ 2 := by\n rw [abs_div, abs_mul, abs_of_nonneg hn0.le, abs_pow]\n apply div_le_div_of_nonneg_right (by positivity)\n calc |z.re| \u2264 1 := abs_le.mpr \u27e8by linarith, hzre1\u27e9\n _ \u2264 _ := by linarith\n have hB : |((S - n) / z).re| \u2264 n ^ 2 / \u2016z\u2016 ^ 2 := by\n have h1 : |((S - n) / z).re| \u2264 \u2016(S - n) / z\u2016 := Complex.abs_re_le_norm _\n have h2 : \u2016(S - n) / z\u2016 \u2264 (n ^ 2 / \u2016z\u2016) / \u2016z\u2016 := by\n rw [norm_div]\n apply div_le_div_of_nonneg_right hSn (by positivity)\n rw [div_pow] at *\n calc |((S - n) / z).re| \u2264 \u2016(S - n) / z\u2016 := h1\n _ \u2264 (n ^ 2 / \u2016z\u2016) / \u2016z\u2016 := h2\n _ = n ^ 2 / \u2016z\u2016 ^ 2 := by ring\n calc |n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re|\n \u2264 n / \u2016z\u2016 ^ 2 + n ^ 2 / \u2016z\u2016 ^ 2 := abs_add _ _ |>.trans (add_le_add hA hB)\n _ \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n have hn1 : (n : \u211d) \u2264 n ^ 2 := by\n have : (1 : \u211d) \u2264 n := by exact_mod_cast hn\n nlinarith\n field_simp at *\n nlinarith\n\nend NguyenRH1\n",
"autoRead": false
}
thinking (4738 chars)
More fixes:
1. `conj` unknown identifier — need `Complex.conj` qualified (open Complex doesn't bring `conj`? open Complex brings the namespace members — conj is Complex.conj... apparently not open-able or shadowed. Use `Complex.conj` explicitly everywhere, and `Complex.add_conj` needs the conj form — since conj is Complex.conj, `Complex.add_conj : z + conj z = ...` with conj = Complex.conj ✓. So replace `conj` with `Complex.conj` in liSummand def and summand_conj statement. map_sub on (Complex.conj): Complex.conj is defined as starRingEnd ℂ — is `Complex.conj` reducible to `starRingEnd ℂ` for the map_ lemmas? `Complex.conj : ℂ →+* ℂ := starRingEnd ℂ` — def. rw [map_sub] with f := Complex.conj — the lemmas map_sub are about RingHomClass f; should unify ?f := Complex.conj ✓.
Also `Complex.add_conj` — the exact statement: `theorem add_conj (z : ℂ) : z + conj z = (2 * z.re : ℝ)` — the RHS is a REAL cast (2 * z.re : ℝ) coerced to ℂ. So z + conj z = ((2 * z.re : ℝ) : ℂ). My liSummand_eq: (mult/2)·(f + conj f) = mult·((f.re : ℝ) : ℂ): f + conj f = ((2·f.re : ℝ) : ℂ): rw [Complex.add_conj] gives f + conj f = ↑(2·f.re): then (mult/2)·↑(2·f.re) = mult·↑(f.re): push_cast + ring should close. The remaining `ring` after rw — the earlier "ring does nothing" warning was because add_conj failed. With conj fixed: rw [liSummand, summand_conj, Complex.add_conj] then the goal: ↑(zeroMult)/2 * ↑(2*re) = ↑(zeroMult) * ↑(re) — push_cast then ring. Let me use: rw [...]; push_cast; ring.
2. `Real.add_one_le_exp` — the statement is `x + 1 ≤ exp x` (not 1 + x). And it holds for all x? For x ≤ −1, x+1 ≤ 0 ≤ exp ✓ so all real. So hbase : 1 + 1/(2n) ≤ exp(1/(2n)): rewrite 1+x = x+1 by linarith-comm: use `(Real.add_one_le_exp (1/(2*n)))` giving `1/(2n) + 1 ≤ exp`, then `by linarith`? Types: need exact form 1 + 1/(2n) ≤ ... — use `by have h := Real.add_one_le_exp (1/(2*(n:ℝ))); linarith` — no: linarith proves 1+x ≤ e from x+1 ≤ e ✓ (linear). OK:
hbase : (1 : ℝ) + 1 / (2 * n) ≤ Real.exp (1 / (2 * n)) := by
have h := Real.add_one_le_exp (1 / (2 * (n : ℝ)))
linarith
3. `Complex.normSq_eq_abs` unknown — the name. Check: normSq z = (abs z)^2 — `Complex.normSq_eq_abs`? Not found. Try `Complex.normSq_eq_norm_sq`? Or `Complex.sq_abs : (Complex.abs z)^2 = normSq z` — direction reversed: I want normSq z = ‖z‖^2: sq_abs gives (abs z)^2 = normSq z; and norm_eq_abs : ‖z‖ = abs z. So: normSq z = (abs z)^2 = ‖z‖^2:
have hnsq : Complex.normSq z = ‖z‖ ^ 2 := by
rw [← Complex.sq_abs, Complex.norm_eq_abs]
(← sq_abs turns normSq into (abs z)^2; then norm_eq_abs rewrites ‖z‖ → abs z ✓.) Let me check sq_abs exists: grep.
4. hf proof: after `simp only [neg_sub, sub_eq_add_neg]` the goal became `1 + -w^n = ...` and rw [e2] failed (pattern 1 − w^n not in `1 + -w^n`). Messy — simplify the whole hf:
hf : (1:ℂ) - w^n = (1/z) * ∑ ... :
from hgeom : (w-1)·S = w^n − 1 and hw1 : w−1 = −(1/z):
1 − w^n = −(w^n − 1) = −(w−1)·S = (1/z)·S.
Cleanest:
have hf : (1 : ℂ) - w ^ n = (1 / z) * ∑ j ∈ Finset.range n, w ^ j := by
have h2 : (1 : ℂ) - w ^ n = -(w ^ n - 1) := by ring
rw [h2, ← hgeom, hw1]; ring
— rw [← hgeom] rewrites `w^n − 1` → `(w−1)·S` ✓ then hw1: `(−(w−1))·S`... wait after rw: goal `-( (w-1) * S ) = (1/z) * S`: rw [hw1]: `-(-(1/z) * S) = (1/z)*S`: ring ✓.
5. Line 84 "not a positivity goal": `apply max_le (by positivity)` — max_le needs (1 ≤ 1+1/(2n)): the first max_le arg is `1 ≤ 1+1/(2n)` — not a positivity goal; use `by linarith`? 1 ≤ 1 + 1/(2n): since 1/(2n) ≥ 0: `by positivity` fails because it's 1 ≤ 1+x not 0 < ... Use le_add_of_nonneg_right: `le_add_of_nonneg_right (by positivity)` : 1 ≤ 1 + 1/(2n)? le_add_of_nonneg_right : 0 ≤ b → a ≤ a + b ✓.
6. `hSn1` — Finset.sum_sub_distrib name check; and the simp after — let me make it more robust:
hSn1 : S - n = ∑ j ∈ Finset.range n, (w ^ j - 1) := by
rw [← Finset.sum_sub_distrib]
congr 1
· rfl
· simp [Finset.sum_const, Finset.card_range]
Hmm — S − n = ∑ w^j − n; want = ∑ (w^j − 1): ∑ w^j − ∑ 1 = ∑ (w^j − 1) via ← sum_sub_distrib, and n = ∑_{j<n} 1: `Finset.sum_const, Finset.card_range, nsmul_eq_natCast`? ∑_{j<n} (1:ℂ) = (card range n) • 1 = n • 1 = n. So:
hSn1 : S - n = ∑ j ∈ Finset.range n, (w ^ j - 1) := by
have e : (n : ℂ) = ∑ j ∈ Finset.range n, (1 : ℂ) := by
simp [Finset.sum_const, Finset.card_range]
rw [e, ← Finset.sum_sub_distrib]
Finset.sum_sub_distrib : ∑ (f − g) = ∑ f − ∑ g — so ← turns ∑ f − ∑ g into ∑ (f−g) ✓. Name check needed: `Finset.sum_sub_distrib` — exists? grep.
Also line 88 unsolved goals — will see after fixes.
Let me also preempt: `Finset.sum_range_id_mul_two` — check name. And `pow_le_pow_right₀` signature. And `mul_le_mul_of_nonneg`. Quick grep for all these names at once, then rewrite.
Let me verify all the remaining lemma names at once, then rewrite.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && for n in \"theorem sq_abs\" \"lemma sq_abs\" \"sum_sub_distrib\" \"sum_range_id_mul_two\" \"theorem pow_le_pow_right\u2080\" \"lemma pow_le_pow_right\u2080\" \"mul_le_mul_of_nonneg \" \"theorem norm_sum_le\" \"lemma norm_sum_le\" \"summable_of_finite_support\" \"theorem pow_le_pow_left\u2080\" \"lemma pow_le_pow_left\u2080\"; do echo \"== $n\"; grep -rn \"$n\" Mathlib/ --include=*.lean -l 2>/dev/null | head -2; done",
"description": "Verify lemma names exist in vendored Mathlib"
}
thinking (1471 chars)
`Complex.normSq_eq_norm_sq : normSq z = ‖z‖ ^ 2` exists ✓ (used at Analysis/Complex/Basic.lean:96). Use that directly.
Now rewrite the scratch with all fixes:
1. liSummand/summand_conj: use `Complex.conj` (qualified).
2. hbase via linarith from add_one_le_exp.
3. hnsq via Complex.normSq_eq_norm_sq.
4. hf: clean rewrite.
5. max_le first arg via le_add_of_nonneg_right.
6. hSn1 via explicit e + ← sum_sub_distrib.
7. liSummand_eq: rw [liSummand, summand_conj, Complex.add_conj]; push_cast; ring.
One more: Complex.add_conj statement: `theorem add_conj (z : ℂ) : z + conj z = (2 * z.re : ℝ)` — note the cast: the RHS `(2 * z.re : ℝ)` is ℝ then coerced: actually written `(2 * z.re : ℝ)` with target ℂ, so it's `((2 * z.re : ℝ) : ℂ)`. So after rw, goal: ↑(zeroMult)/2 * ↑(2 * f.re) = ↑(zeroMult) * ↑(f.re) — push_cast then ring ✓.
Also summand_conj's `rw [map_sub, map_one, map_pow, map_sub, map_one, map_div₀, map_one]` — conj = starRingEnd ℂ; map_sub (starRingEnd ℂ) : conj (a−b) = conj a − conj b ✓. The statement has conj ((1 − (1 − 1/z)^n)) on RHS; rw works left-to-right on goal `1 − (1 − 1/conj z)^n = conj (1 − (1 − 1/z)^n)`: the rw of map_sub applies to the RHS occurrence `conj (1 − ...)` → `conj 1 − conj ((1 − 1/z)^n)` then map_one: `1 − conj(...)`; map_pow: `conj(1 − 1/z)^n`; map_sub: `(conj 1 − conj (1/z))^n`; map_one; map_div₀: `conj 1 / conj z`; map_one: `1 / conj z` ✓ goal becomes `1 − (1 − 1/conj z)^n = 1 − (1 − 1/conj z)^n` rfl ✓.
Write the file.
`Complex.normSq_eq_norm_sq` exists. Rewriting with all fixes.
tool: Write
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\Scratch.lean",
"content": "/- Session 015 scratch: ii\u2032-1a \u2014 paired liSummand + summability (D-064 \u00a71).\n When green, merge into LiSkeleton.lean \u00a71 replacing the defective liCoeff. -/\nimport Mathlib\nimport Zeta23.WeilEF.ZeroSummability\nimport Zeta23.Statement.SeamClosed\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-- The paired (symmetrized) Li summand: \u00bd\u00b7mult\u00b7(f \u03c1 + f \u03c1\u0304),\nf \u03c1 = 1 \u2212 (1\u22121/\u03c1)\u207f. Manifestly real-valued (`liSummand_eq`), absolutely\nsummable (`liSummable`) \u2014 the correct Keiper\u2013Li coefficient (D-064 \u00a71:\nthe plain unordered sum of f over the zeros is not absolutely\nsummable; the pairing is the classical Bombieri\u2013Lagarias convention). -/\ndef liSummand (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) : \u2102 :=\n (zeroMult \u03c1 : \u2102) / 2 *\n ((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n) + (1 - (1 - 1 / (Complex.conj (\u03c1 : \u2102))) ^ n))\n\nlemma summand_conj (n : \u2115) (z : \u2102) :\n (1 : \u2102) - (1 - 1 / (Complex.conj z)) ^ n = Complex.conj ((1 - (1 - 1 / z) ^ n)) := by\n rw [map_sub, map_one, map_pow, map_sub, map_one, map_div\u2080, map_one]\n\nlemma liSummand_eq (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) :\n liSummand n \u03c1 = (zeroMult \u03c1 : \u2102) * (((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n).re) : \u2102) := by\n rw [liSummand, summand_conj, Complex.add_conj]\n push_cast\n ring\n\n/-! ### The geometric-sum estimate: |Re(1 \u2212 w\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2 for w = 1\u22121/z -/\n\n/-- (1 + 1/(2n))\u207f \u2264 2 for n \u2265 1. Via (1+x)\u207f \u2264 exp(nx) and exp(1/2) \u2264 2. -/\nlemma pow_one_add_inv_two_mul_le (n : \u2115) (hn : 1 \u2264 n) :\n ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have hbase : (1 : \u211d) + 1 / (2 * n) \u2264 Real.exp (1 / (2 * n)) := by\n have h := Real.add_one_le_exp (1 / (2 * (n : \u211d)))\n linarith\n have h1 : ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 Real.exp (1 / 2) := by\n calc ((1 : \u211d) + 1 / (2 * n)) ^ n\n \u2264 (Real.exp (1 / (2 * n))) ^ n := pow_le_pow_left\u2080 (by positivity) hbase n\n _ = Real.exp (\u2191n * (1 / (2 * n))) := by rw [Real.exp_nat_mul]\n _ = Real.exp (1 / 2) := by congr 1; field_simp\n have h2 : Real.exp (1 / 2 : \u211d) \u2264 2 := by\n have h3 : (1 : \u211d) / 2 \u2264 Real.log 2 := by\n have h := Real.log_two_gt_d9\n linarith\n calc Real.exp (1 / 2 : \u211d) \u2264 Real.exp (Real.log 2) := Real.exp_le_exp.mpr h3\n _ = 2 := Real.exp_log (by norm_num)\n exact h1.trans h2\n\n/-- Key estimate: for n \u2265 1, z with re z \u2208 [0,1], 2n \u2264 \u2016z\u2016:\n|Re(1 \u2212 (1\u22121/z)\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2. -/\nlemma re_li_summand_le {n : \u2115} (hn : 1 \u2264 n) {z : \u2102}\n (hzre0 : 0 \u2264 z.re) (hzre1 : z.re \u2264 1) (hz : 2 * n \u2264 \u2016z\u2016) :\n |(1 - (1 - 1 / z) ^ n).re| \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have hz0 : z \u2260 0 := by\n intro h; rw [h, norm_zero] at hz; linarith\n have hzn : (0 : \u211d) < \u2016z\u2016 := norm_pos_iff.mpr hz0\n have hnsq : Complex.normSq z = \u2016z\u2016 ^ 2 := Complex.normSq_eq_norm_sq z\n set w : \u2102 := 1 - 1 / z with hw\n -- kernel identity: 1 \u2212 w\u207f = (1/z)\u00b7S, S = \u03a3_{j<n} w^j\n have hgeom : (w - 1) * \u2211 j \u2208 Finset.range n, w ^ j = w ^ n - 1 := mul_geom_sum w n\n have hw1 : w - 1 = -(1 / z) := by rw [hw]; ring\n have hf : (1 : \u2102) - w ^ n = (1 / z) * \u2211 j \u2208 Finset.range n, w ^ j := by\n have e : (1 : \u2102) - w ^ n = -(w ^ n - 1) := by ring\n rw [e, \u2190 hgeom, hw1]; ring\n set S : \u2102 := \u2211 j \u2208 Finset.range n, w ^ j\n have hS : S = (n : \u2102) + (S - n) := by ring\n -- \u2016w\u2016 \u2264 1 + 1/\u2016z\u2016\n have hwnorm : \u2016w\u2016 \u2264 1 + 1 / \u2016z\u2016 := by\n have e : w = 1 - z\u207b\u00b9 := by rw [hw, div_eq_mul_inv, one_mul]\n rw [e]\n calc \u2016(1 : \u2102) - z\u207b\u00b9\u2016 \u2264 \u2016(1 : \u2102)\u2016 + \u2016z\u207b\u00b9\u2016 := norm_sub_le _ _\n _ = 1 + 1 / \u2016z\u2016 := by rw [norm_one, norm_inv, inv_eq_one_div]\n have h1z : 1 / \u2016z\u2016 \u2264 1 / (2 * n) :=\n one_div_le_one_div_of_le (by positivity) (by exact_mod_cast hz)\n have hwmax : max 1 \u2016w\u2016 \u2264 1 + 1 / (2 * n) := by\n apply max_le (le_add_of_nonneg_right (by positivity))\n exact hwnorm.trans (by linarith)\n -- |S \u2212 n| \u2264 n\u00b2/\u2016z\u2016\n have hSn : \u2016S - n\u2016 \u2264 n ^ 2 / \u2016z\u2016 := by\n have hSn1 : S - n = \u2211 j \u2208 Finset.range n, (w ^ j - 1) := by\n have e : (n : \u2102) = \u2211 j \u2208 Finset.range n, (1 : \u2102) := by\n simp [Finset.sum_const, Finset.card_range]\n rw [e, \u2190 Finset.sum_sub_distrib]\n have hbound : \u2200 j \u2208 Finset.range n,\n \u2016w ^ j - 1\u2016 \u2264 (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) := by\n intro j hj\n have hgeomj : (w - 1) * \u2211 i \u2208 Finset.range j, w ^ i = w ^ j - 1 := mul_geom_sum w j\n have hjn : j \u2264 n := le_of_lt (Finset.mem_range.mp hj)\n have h2 : w ^ j - 1 = -(1 / z) * \u2211 i \u2208 Finset.range j, w ^ i := by\n have h := hgeomj; rw [hw1] at h\n rw [\u2190 h]; ring\n rw [h2, norm_mul, norm_neg, norm_div, norm_one]\n have hsum : \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016 \u2264 j * (1 + 1 / (2 * n)) ^ (n - 1) := by\n calc \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016\n \u2264 \u2211 i \u2208 Finset.range j, \u2016w ^ i\u2016 := norm_sum_le _ _\n _ \u2264 \u2211 i \u2208 Finset.range j, (1 + 1 / (2 * n)) ^ (n - 1) := by\n apply Finset.sum_le_sum\n intro i hi\n rw [norm_pow]\n have hij : i < j := Finset.mem_range.mp hi\n have h1 : \u2016w\u2016 ^ i \u2264 (1 + 1 / (2 * n)) ^ i :=\n pow_le_pow_left\u2080 (norm_nonneg _)\n (le_trans (le_max_right 1 \u2016w\u2016) hwmax) i\n have h2 : (1 + 1 / (2 * n)) ^ i \u2264 (1 + 1 / (2 * n)) ^ (n - 1) := by\n apply pow_le_pow_right\u2080 (by positivity)\n omega\n exact h1.trans h2\n _ = j * (1 + 1 / (2 * n)) ^ (n - 1) := by\n rw [Finset.sum_const, Finset.card_range, nsmul_eq_mul]\n exact mul_le_mul_of_nonneg_left hsum (by positivity)\n calc \u2016\u2211 j \u2208 Finset.range n, (w ^ j - 1)\u2016\n \u2264 \u2211 j \u2208 Finset.range n, \u2016w ^ j - 1\u2016 := norm_sum_le _ _\n _ \u2264 \u2211 j \u2208 Finset.range n, (1 / \u2016z\u2016) * (j * (1 + 1 / (2 * n)) ^ (n - 1)) := by\n rw [hSn1] at *\n exact Finset.sum_le_sum hbound\n _ = ((1 / \u2016z\u2016) * (1 + 1 / (2 * n)) ^ (n - 1)) * \u2211 j \u2208 Finset.range n, j := by\n rw [\u2190 Finset.mul_sum]\n apply Finset.sum_congr rfl\n intro j _; ring\n _ \u2264 n ^ 2 / \u2016z\u2016 := by\n have hsumj : (\u2211 j \u2208 Finset.range n, j : \u211d) = n * (n - 1) / 2 := by\n have h := Finset.sum_range_id_mul_two n\n have h2 : ((\u2211 j \u2208 Finset.range n, j : \u2115) : \u211d) * 2 = n * (n - 1) := by\n exact_mod_cast h\n linarith\n rw [hsumj]\n have hpow : (1 + 1 / (2 * n : \u211d)) ^ (n - 1) \u2264 2 :=\n le_trans (pow_le_pow_right\u2080 (by positivity) (Nat.sub_le n 1))\n (pow_one_add_inv_two_mul_le n hn)\n have hb1 : (n : \u211d) * (n - 1) / 2 \u2264 n ^ 2 / 2 := by nlinarith [hn0]\n have hb2 : (1 + 1 / (2 * n : \u211d)) ^ (n - 1) * (n * (n - 1) / 2)\n \u2264 2 * (n ^ 2 / 2) :=\n mul_le_mul_of_nonneg hpow hb1 (by positivity) (by positivity)\n have hb3 : ((1 : \u211d) / \u2016z\u2016) * (1 + 1 / (2 * n)) ^ (n - 1) * (n * (n - 1) / 2)\n \u2264 (1 / \u2016z\u2016) * (2 * (n ^ 2 / 2)) :=\n mul_le_mul_of_nonneg_left hb2 (by positivity)\n exact hb3.trans (by ring_nf)\n -- Re(f) = n\u00b7z.re/\u2016z\u2016\u00b2 + ((S\u2212n)/z).re\n have hre1 : ((n : \u2102) * (1 / z)).re = n * z.re / \u2016z\u2016 ^ 2 := by\n have hinv : ((1 : \u2102) / z).re = z.re / \u2016z\u2016 ^ 2 := by\n rw [one_div, Complex.inv_re, hnsq]\n rw [Complex.mul_re]\n simp [hinv]\n have hfre : (1 - w ^ n).re = n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re := by\n rw [hf, hS, Complex.add_re]\n congr 1\n rw [mul_comm, div_eq_mul_inv]\n exact hre1\n rw [hfre]\n have hA : |n * z.re / \u2016z\u2016 ^ 2| \u2264 n / \u2016z\u2016 ^ 2 := by\n rw [abs_div, abs_mul, abs_of_nonneg hn0.le,\n abs_of_nonneg (sq_nonneg \u2016z\u2016)]\n apply (div_le_div_right (by positivity)).mpr\n apply mul_le_mul_of_nonneg_left _ hn0.le\n exact abs_le.mpr \u27e8hzre0, hzre1\u27e9\n have hB : |((S - n) / z).re| \u2264 n ^ 2 / \u2016z\u2016 ^ 2 := by\n have h1 : |((S - n) / z).re| \u2264 \u2016(S - n) / z\u2016 := Complex.abs_re_le_norm _\n have h2 : \u2016(S - n) / z\u2016 \u2264 (n ^ 2 / \u2016z\u2016) / \u2016z\u2016 := by\n rw [norm_div]\n exact (div_le_div_right hzn).mpr hSn\n exact h1.trans (h2.trans (by rw [div_div, \u2190 pow_two]))\n have hnn : (n : \u211d) \u2264 n ^ 2 := by\n have h : (1 : \u211d) \u2264 n := by exact_mod_cast hn\n nlinarith\n calc |n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re|\n \u2264 n / \u2016z\u2016 ^ 2 + n ^ 2 / \u2016z\u2016 ^ 2 := (abs_add _ _).trans (add_le_add hA hB)\n _ = (n + n ^ 2) / \u2016z\u2016 ^ 2 := by ring\n _ \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n apply (div_le_div_right (by positivity)).mpr\n linarith\n\nend NguyenRH1\n"
}
thinking (6485 chars)
Progress. New issues:
1. `Complex.conj` unknown constant! Interesting — in this Mathlib version, `conj` might not be in the Complex namespace as `Complex.conj`. From the earlier grep: `Mathlib/Data/Complex/Basic.lean:589:theorem add_conj (z : ℂ) : z + conj z = (2 * z.re : ℝ)` — that theorem is IN namespace Complex (the file's namespace). The `conj` there refers to... let me check what `conj` is in that file — maybe it's `starRingEnd ℂ` directly or an un-namespaced `conj`. Let me grep the definition.
2. Line 97 "No goals" — the h2 sub-proof inside hbound: `rw [hSn1] at *` — wait no, line 97 is in hsumj area? Line 97 col 18: "No goals to be solved" — that's in the `have h2 : w ^ j - 1 = ...` proof: `have h := hgeomj; rw [hw1] at h; rw [← h]; ring` — hmm, line 97... Actually counting lines, ~97 is around `rw [hSn1] at *` in the sum calc block — `rw [hSn1] at *` rewrote everywhere and closed the goal?? The error "No goals to be solved" at 97:18 — looking at my file, line 97 is `exact Finset.sum_le_sum hbound` area after `rw [hSn1] at *`. The `rw [hSn1] at *` is wrong — the goal at that point is already `∑ ‖w^j − 1‖ ≤ ∑ (1/‖z‖)*(...)` — hSn1 rewrite isn't needed there at all (I mistakenly added it; the goal is after the first calc step which is about the sum of norms — wait no: the calc chain: step 2's goal is `∑ j ∈ range n, ‖w^j − 1‖ ≤ ∑ j ∈ range n, (1/‖z‖)*(j*M)` — that follows directly from Finset.sum_le_sum hbound. The `rw [hSn1] at *` was spurious (the hSn1 was already used at the START of the calc — wait, no: looking at my calc, I never rewrote the goal with hSn1! The first line is `‖∑ (w^j − 1)‖` but the actual goal is `‖S − n‖ ≤ ...` — I need to rw [hSn1] BEFORE the calc. Let me restructure: rw [hSn1] first, then calc.
3. Line 103: `apply Finset.sum_le_sum` unify failure: goal `∑ ‖w^i‖ ≤ ↑(∑ (1+1/(2n))^(n-1))` — the RHS has a CAST ↑ around the sum — that's from `nsmul_eq_mul` rewriting earlier? No — this is in the hsum proof's second calc step: `∑ i ∈ range j, ‖w ^ i‖ ≤ ∑ i ∈ range j, (1 + 1 / (2 * n)) ^ (n - 1)` — the error shows the goal with `↑(∑ ...)` — a coercion appeared. Hmm — actually the issue: `(1 + 1/(2*n))^(n-1)` where n : ℕ — the exponent n−1 is ℕ, the base is ℝ — fine. The `↑(...)` cast — maybe the goal's RHS got elaborated with nsmul (sum of constants = n • x where • is ℕ-action, displayed as cast). The `apply Finset.sum_le_sum` then fails because RHS isn't syntactically a sum of the right form... but it IS a sum — `↑(∑ i ∈ range j, (1+1/(2n))^(n-1))` — hmm, the cast suggests the RHS elaborated as `((∑ i, ((1:ℝ)+1/(2*↑n))^(n-1) : ℝ) : ℝ)`?? Weird. Oh wait — I see: the error's goal shows `≤ ↑(∑ i ∈ Finset.range j, (1 + 1 / (2 * n)) ^ (n - 1))` — the ↑ might be from n : ℕ casting inside 2*n — no, it wraps the whole sum. Possibly my statement wrote `(1 + 1 / (2 * n)) ^ (n - 1)` where Lean elaborated `(2 * n)` with n : ℕ → 2 * ↑n in ℝ — fine — and the outer ↑... Actually the displayed goal in the error has the sum preceded by ↑ — meaning the RHS is `Nat.cast` or `Int.cast` of something? That would come from `∑ i ∈ range j, (...)` being at type ℕ?? No...
Oh — I see it: in the calc step I wrote `∑ i ∈ Finset.range j, (1 + 1 / (2 * n)) ^ (n - 1)` — but the calc relation needs the RHS type ℝ. The `↑` is probably the coercion from `∑ i ∈ range j, (...)` being parsed in a different monad... Actually simpler explanation: Finset.sum_le_sum's conclusion is `∑ f ≤ ∑ g` — my goal shows `∑ ‖w^i‖ ≤ ↑(∑ (...))`. The `↑` could be from `nsmul_eq_mul` lemma application in the PREVIOUS step's local context? No...
Hmm, wait — the error is at line 103:14 which is `apply Finset.sum_le_sum` in hsum's calc step 2. The goal shown ends with `≤ ↑(∑ i ∈ Finset.range j, (1 + 1 / (2 * n)) ^ (n - 1))`. So somewhere the RHS became a cast. Why? Because I wrote the calc step as:
`_ ≤ ∑ i ∈ Finset.range j, (1 + 1 / (2 * n)) ^ (n - 1) := by`
and Lean elaborates the expected type... the `↑` suggests it elaborated `(1+1/(2*n))^(n-1)` at type ℕ → cast to ℝ?? If `(2 * n)` were read as `(2 : ?)*n` with n : ℕ... The base `1 + 1/(2*n)`: `1 / (2 * n)` — with n : ℕ, if everything stays in ℕ, 1/(2n) in ℕ is 0! Then `(1 + 0)^(n-1)` in ℕ = 1, and the cast ↑1 = 1. THAT's the bug: mixed ℕ/ℝ elaboration — since the surrounding sum type isn't fixed yet, Lean may elaborate the numeric expression in ℕ! Because the calc step's RHS type is inferred from... the bound `∑ i ∈ range j, (1+1/(2n))^(n-1)` — the LHS is `∑ ‖w^i‖ : ℝ`, so the ≤ forces ℝ... but the sum inside could still elaborate its BODY at ℕ first? With expected type ℝ for the sum, the body should elaborate at ℝ... but the displayed `↑(∑ ...)` says the whole RHS is a cast of a sum computed in ℕ?? Actually the coercion is probably `Int.cast` or `Nat.cast` around the sum because the body type was inferred as ℕ: `(1 + 1 / (2 * n)) ^ (n - 1)` — hmm, `1 / (2*n)`: if 2*n elaborates in ℕ (n : ℕ), then 1/(2n) : ℕ = 0 (Nat division). Yes — this is the classic Nat literal trap. In my hbound statement I wrote the same expression and there it was fine because the type of the inequality forced ℝ (‖w^j − 1‖ : ℝ)... but inside hsum's calc the `apply Finset.sum_le_sum` line is where types get unified: the RHS body elaborated at ℕ since nothing pinned it to ℝ before unification? The bound statement `(1 + 1/(2*n))^(n-1)` in hbound DID have ℝ type forced (compared against ‖·‖). Inside hsum's calc step, same expression — the expected type is ℝ (from ≤ with ℝ sum)... but Lean elaborates the body of the sum possibly without the expected type propagating? The fix: annotate `(1 + 1 / (2 * n : ℝ)) ^ (n - 1)` with explicit (n : ℝ) cast, or write `((1 : ℝ) + 1 / (2 * n)) ^ (n - 1)`. I'll annotate everywhere: `(1 + 1 / (2 * (n : ℝ))) ^ (n - 1)`.
Same potential issue in other spots where I wrote (1 + 1/(2*n)) — hbound's bound: `(1 / ‖z‖) * (j * (1 + 1 / (2 * n)) ^ (n - 1))` — here the product with j : ℕ cast — j * (...) forces ℝ? j : ℕ, (1+1/(2n))^(n-1) : ? — `j * X` : ℝ requires X : ℝ so X should elaborate at ℝ... it worked in the error trace? The errors listed don't include hbound's statement, so it elaborated fine. But to be safe, annotate all occurrences as (2 * (n : ℝ)).
4. `Complex.conj` unknown: from the grep, `theorem add_conj (z : ℂ) : z + conj z` at Data/Complex/Basic.lean:589 — so within that file, `conj` resolves to something. It's likely `starRingEnd ℂ` with local notation, OR conj is defined in a DIFFERENT namespace. Let me grep the conj definition.
Two issues: a Nat-literal trap (need `(n : ℝ)` casts) and `conj`'s actual name. Checking the conj definition.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"def conj \\|noncomputable def conj\\|abbrev conj \\|notation.*conj\" Mathlib/Data/Complex/Basic.lean Mathlib/Data/Complex/Defs.lean 2>/dev/null | head -5; grep -rn \"conj\" Mathlib/Data/Complex/Defs.lean 2>/dev/null | head -10",
"description": "Find the conj definition"
}
thinking (4343 chars)
Now it's clear: in this Mathlib, the recommended form is `starRingEnd ℂ` (available as notation `conj` only inside the `ComplexConjugate` scope). And `star z` for ℂ IS the star operation (StarRing instance shown here). So:
- `star z` works directly (the StarRing ℂ instance).
- `Complex.add_conj : z + conj z = ...` — with conj = starRingEnd ℂ (via the scope). `star z` and `(starRingEnd ℂ) z` are both the star operation — defeq but different head constants.
Simplest robust approach: use `starRingEnd ℂ` explicitly (the bundled hom — map_ lemmas apply). In the def: `(starRingEnd ℂ) (ρ:ℂ)`. And for liSummand_eq, instead of Complex.add_conj, use the star-based lemma: is there `star_add_self` or `Complex.star_def`? There's `RCLike` generic: `star_def`? Simpler: `Complex.add_conj` is about `starRingEnd ℂ z` (since conj in that file = starRingEnd ℂ via scope) — so with my def using starRingEnd ℂ, the lemma applies directly!
Let me confirm: in Mathlib/Data/Complex/Basic.lean, line 45 `open ComplexConjugate` — so within that file, `conj` = the scoped notation for starRingEnd ℂ. So `Complex.add_conj : z + starRingEnd ℂ z = ((2 * z.re : ℝ) : ℂ)` ✓. So in my code, write `(starRingEnd ℂ)` instead of `conj`, and Complex.add_conj will match (pattern `?z + starRingEnd ℂ ?z` — my term has exactly `starRingEnd ℂ f` ✓).
And summand_conj becomes:
```
lemma summand_conj (n : ℕ) (z : ℂ) :
(1 : ℂ) - (1 - 1 / ((starRingEnd ℂ) z)) ^ n = (starRingEnd ℂ) ((1 - (1 - 1 / z) ^ n)) := by
rw [map_sub, map_one, map_pow, map_sub, map_one, map_div₀, map_one]
```
map_sub (starRingEnd ℂ) — these generic map_ lemmas apply to bundled ring homs ✓.
Now the other fixes:
- hSn1/rw [hSn1] at * — restructure: rw [hSn1] BEFORE the calc (at goal ‖S − n‖ ≤ ...).
- The `↑(∑ ...)` cast issue: annotate `(1 + 1 / (2 * (n : ℝ))) ^ (n - 1)` — with (n:ℝ) cast inside, the whole body elaborates at ℝ ✓. I'll introduce a local abbreviation `M : ℝ := 1 + 1 / (2 * n)` — with (n:ℝ) — and use M everywhere to avoid repeated elaboration issues. Since n : ℕ, writing `(2 * (n : ℝ))` forces ℝ.
Let me define at the top of re_li_summand_le: `set M : ℝ := 1 + 1 / (2 * (n : ℝ)) with hM` — then hwmax : max 1 ‖w‖ ≤ M, hpow : M^(n-1) ≤ 2, etc. Cleaner.
Also "No goals to be solved" at line 97 — that was in hsumj area? Line 97 col 18: looking at previous version line numbers — it was in the `rw [hSn1] at *` region or `h := Finset.sum_range_id_mul_two n; h2 ... linarith` — actually 97:18 in the last file is in the h2 sub-proof of hbound (`rw [← h]; ring` — where after rw [← h] the goal might already be closed by rw's rfl). Let me make h2's proof robust:
have h2 : w ^ j - 1 = -(1 / z) * ∑ i ∈ Finset.range j, w ^ i := by
rw [← hgeomj, hw1]
After rw [← hgeomj]: goal (w−1)·∑ = −(1/z)·∑; rw [hw1]: −(1/z)·∑ = −(1/z)·∑ — rfl by rw ✓ closed automatically. But earlier I had `have h := hgeomj; rw [hw1] at h; rw [← h]; ring` — the rw [← h] closed it and ring had no goals. New version handles cleanly.
Also hgeomj line: `have hgeomj : (w - 1) * ∑ i ∈ Finset.range j, w ^ i = w ^ j - 1 := mul_geom_sum w j` ✓.
One more from the error list: 114:49 unsolved goals — that was inside the hpow/hb chain probably (hb3.trans (by ring_nf)) — ring_nf might not fully close `(1/‖z‖) * (2 * (n^2/2)) = n^2/‖z‖`? ring_nf should prove equality of the form a*(2*(b/2)) = a*b — it's `mul` arithmetic — actually (1/‖z‖)*(2*(n²/2)) = (1/‖z‖)*n² = n²/‖z‖ ✓ ring_nf should handle. The unsolved goals error was probably cascading from earlier errors. Let me rewrite the full file with all fixes and iterate.
Also `pow_le_pow_right₀ (by positivity) (Nat.sub_le n 1)` — signature (ha : 1 ≤ a) (hmn : m ≤ n): `by positivity` proves 1 ≤ 1+1/(2n)? positivity proves 0 < x — not 1 ≤ x. Use `by have : (0:ℝ) ≤ 1/(2*(n:ℝ)) := by positivity; linarith` or `le_add_of_nonneg_left`... 1 ≤ 1+x ⟸ 0 ≤ x: `le_add_of_nonneg_right (by positivity)`. But the x here: M = 1+1/(2n) with n:ℝ: 0 ≤ 1/(2n) by positivity ✓. So (le_add_of_nonneg_right (by positivity) : (1:ℝ) ≤ M).
Similarly in h2 (pow_le_pow_right₀ (by positivity)): same fix.
And in pow_one_add_inv_two_mul_le there's pow_le_pow_left₀ (by positivity) hbase n — pow_le_pow_left₀ (ha : 0 ≤ a) (hab : a ≤ b) (n : ℕ) — (by positivity) proves 0 ≤ 1+1/(2n) ✓ fine (0 ≤ is positivity).
Let me rewrite the file completely with the M abbreviation.
`conj` is scope-locked notation for `starRingEnd ℂ` — I'll use the bundled form directly. Rewriting with all fixes plus an `M` abbreviation to kill the Nat-literal elaboration trap.
tool: Write
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\Scratch.lean",
"content": "/- Session 015 scratch: ii\u2032-1a \u2014 paired liSummand + summability (D-064 \u00a71).\n When green, merge into LiSkeleton.lean \u00a71 replacing the defective liCoeff. -/\nimport Mathlib\nimport Zeta23.WeilEF.ZeroSummability\nimport Zeta23.Statement.SeamClosed\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-- The paired (symmetrized) Li summand: \u00bd\u00b7mult\u00b7(f \u03c1 + f \u03c1\u0304),\nf \u03c1 = 1 \u2212 (1\u22121/\u03c1)\u207f. Manifestly real-valued (`liSummand_eq`), absolutely\nsummable (`liSummable`) \u2014 the correct Keiper\u2013Li coefficient (D-064 \u00a71:\nthe plain unordered sum of f over the zeros is not absolutely\nsummable; the pairing is the classical Bombieri\u2013Lagarias convention). -/\ndef liSummand (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) : \u2102 :=\n (zeroMult \u03c1 : \u2102) / 2 *\n ((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n) + (1 - (1 - 1 / ((starRingEnd \u2102) (\u03c1 : \u2102))) ^ n))\n\nlemma summand_conj (n : \u2115) (z : \u2102) :\n (1 : \u2102) - (1 - 1 / ((starRingEnd \u2102) z)) ^ n = (starRingEnd \u2102) ((1 - (1 - 1 / z) ^ n)) := by\n rw [map_sub, map_one, map_pow, map_sub, map_one, map_div\u2080, map_one]\n\nlemma liSummand_eq (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) :\n liSummand n \u03c1 = (zeroMult \u03c1 : \u2102) * (((1 - (1 - 1 / (\u03c1 : \u2102)) ^ n).re) : \u2102) := by\n rw [liSummand, summand_conj, Complex.add_conj]\n push_cast\n ring\n\n/-! ### The geometric-sum estimate: |Re(1 \u2212 w\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2 for w = 1\u22121/z -/\n\n/-- (1 + 1/(2n))\u207f \u2264 2 for n \u2265 1. Via (1+x)\u207f \u2264 exp(nx) and exp(1/2) \u2264 2. -/\nlemma pow_one_add_inv_two_mul_le (n : \u2115) (hn : 1 \u2264 n) :\n ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have hbase : (1 : \u211d) + 1 / (2 * n) \u2264 Real.exp (1 / (2 * n)) := by\n have h := Real.add_one_le_exp (1 / (2 * (n : \u211d)))\n linarith\n have h1 : ((1 : \u211d) + 1 / (2 * n)) ^ n \u2264 Real.exp (1 / 2) := by\n calc ((1 : \u211d) + 1 / (2 * n)) ^ n\n \u2264 (Real.exp (1 / (2 * n))) ^ n := pow_le_pow_left\u2080 (by positivity) hbase n\n _ = Real.exp (\u2191n * (1 / (2 * n))) := by rw [Real.exp_nat_mul]\n _ = Real.exp (1 / 2) := by congr 1; field_simp\n have h2 : Real.exp (1 / 2 : \u211d) \u2264 2 := by\n have h3 : (1 : \u211d) / 2 \u2264 Real.log 2 := by\n have h := Real.log_two_gt_d9\n linarith\n calc Real.exp (1 / 2 : \u211d) \u2264 Real.exp (Real.log 2) := Real.exp_le_exp.mpr h3\n _ = 2 := Real.exp_log (by norm_num)\n exact h1.trans h2\n\n/-- Key estimate: for n \u2265 1, z with re z \u2208 [0,1], 2n \u2264 \u2016z\u2016:\n|Re(1 \u2212 (1\u22121/z)\u207f)| \u2264 2n\u00b2/\u2016z\u2016\u00b2. -/\nlemma re_li_summand_le {n : \u2115} (hn : 1 \u2264 n) {z : \u2102}\n (hzre0 : 0 \u2264 z.re) (hzre1 : z.re \u2264 1) (hz : 2 * n \u2264 \u2016z\u2016) :\n |(1 - (1 - 1 / z) ^ n).re| \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have hz0 : z \u2260 0 := by\n intro h; rw [h, norm_zero] at hz; linarith\n have hzn : (0 : \u211d) < \u2016z\u2016 := norm_pos_iff.mpr hz0\n have hnsq : Complex.normSq z = \u2016z\u2016 ^ 2 := Complex.normSq_eq_norm_sq z\n set M : \u211d := 1 + 1 / (2 * (n : \u211d)) with hM\n have hM0 : (0 : \u211d) \u2264 1 / (2 * (n : \u211d)) := by positivity\n have hM1 : (1 : \u211d) \u2264 M := le_add_of_nonneg_right hM0\n set w : \u2102 := 1 - 1 / z with hw\n -- kernel identity: 1 \u2212 w\u207f = (1/z)\u00b7S, S = \u03a3_{j<n} w^j\n have hgeom : (w - 1) * \u2211 j \u2208 Finset.range n, w ^ j = w ^ n - 1 := mul_geom_sum w n\n have hw1 : w - 1 = -(1 / z) := by rw [hw]; ring\n have hf : (1 : \u2102) - w ^ n = (1 / z) * \u2211 j \u2208 Finset.range n, w ^ j := by\n have e : (1 : \u2102) - w ^ n = -(w ^ n - 1) := by ring\n rw [e, \u2190 hgeom, hw1]; ring\n set S : \u2102 := \u2211 j \u2208 Finset.range n, w ^ j\n have hS : S = (n : \u2102) + (S - n) := by ring\n -- \u2016w\u2016 \u2264 1 + 1/\u2016z\u2016\n have hwnorm : \u2016w\u2016 \u2264 1 + 1 / \u2016z\u2016 := by\n have e : w = 1 - z\u207b\u00b9 := by rw [hw, div_eq_mul_inv, one_mul]\n rw [e]\n calc \u2016(1 : \u2102) - z\u207b\u00b9\u2016 \u2264 \u2016(1 : \u2102)\u2016 + \u2016z\u207b\u00b9\u2016 := norm_sub_le _ _\n _ = 1 + 1 / \u2016z\u2016 := by rw [norm_one, norm_inv, inv_eq_one_div]\n have h1z : 1 / \u2016z\u2016 \u2264 1 / (2 * n) :=\n one_div_le_one_div_of_le (by positivity) (by exact_mod_cast hz)\n have hwmax : max 1 \u2016w\u2016 \u2264 M := by\n apply max_le hM1\n exact hwnorm.trans (by rw [hM]; linarith)\n -- |S \u2212 n| \u2264 n\u00b2/\u2016z\u2016\n have hSn : \u2016S - n\u2016 \u2264 n ^ 2 / \u2016z\u2016 := by\n have hSn1 : S - n = \u2211 j \u2208 Finset.range n, (w ^ j - 1) := by\n have e : (n : \u2102) = \u2211 j \u2208 Finset.range n, (1 : \u2102) := by\n simp [Finset.sum_const, Finset.card_range]\n rw [e, \u2190 Finset.sum_sub_distrib]\n rw [hSn1]\n have hbound : \u2200 j \u2208 Finset.range n,\n \u2016w ^ j - 1\u2016 \u2264 (1 / \u2016z\u2016) * (j * M ^ (n - 1)) := by\n intro j hj\n have hgeomj : (w - 1) * \u2211 i \u2208 Finset.range j, w ^ i = w ^ j - 1 := mul_geom_sum w j\n have h2 : w ^ j - 1 = -(1 / z) * \u2211 i \u2208 Finset.range j, w ^ i := by\n rw [\u2190 hgeomj, hw1]\n rw [h2, norm_mul, norm_neg, norm_div, norm_one]\n have hsum : \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016 \u2264 j * M ^ (n - 1) := by\n calc \u2016\u2211 i \u2208 Finset.range j, w ^ i\u2016\n \u2264 \u2211 i \u2208 Finset.range j, \u2016w ^ i\u2016 := norm_sum_le _ _\n _ \u2264 \u2211 i \u2208 Finset.range j, M ^ (n - 1) := by\n apply Finset.sum_le_sum\n intro i hi\n rw [norm_pow]\n have hij : i < j := Finset.mem_range.mp hi\n have hjn : j \u2264 n := le_of_lt (Finset.mem_range.mp hj)\n have h1 : \u2016w\u2016 ^ i \u2264 M ^ i :=\n pow_le_pow_left\u2080 (norm_nonneg _)\n (le_trans (le_max_right 1 \u2016w\u2016) hwmax) i\n have h2 : M ^ i \u2264 M ^ (n - 1) := pow_le_pow_right\u2080 hM1 (by omega)\n exact h1.trans h2\n _ = j * M ^ (n - 1) := by\n rw [Finset.sum_const, Finset.card_range, nsmul_eq_mul]\n exact mul_le_mul_of_nonneg_left hsum (by positivity)\n calc \u2211 j \u2208 Finset.range n, \u2016w ^ j - 1\u2016\n \u2264 \u2211 j \u2208 Finset.range n, (1 / \u2016z\u2016) * (j * M ^ (n - 1)) :=\n Finset.sum_le_sum hbound\n _ = ((1 / \u2016z\u2016) * M ^ (n - 1)) * \u2211 j \u2208 Finset.range n, j := by\n rw [\u2190 Finset.mul_sum]\n apply Finset.sum_congr rfl\n intro j _; ring\n _ \u2264 n ^ 2 / \u2016z\u2016 := by\n have hsumj : (\u2211 j \u2208 Finset.range n, j : \u211d) = n * (n - 1) / 2 := by\n have h := Finset.sum_range_id_mul_two n\n have h2 : ((\u2211 j \u2208 Finset.range n, j : \u2115) : \u211d) * 2 = n * (n - 1) := by\n exact_mod_cast h\n linarith\n rw [hsumj]\n have hpow : M ^ (n - 1) \u2264 2 :=\n le_trans (pow_le_pow_right\u2080 hM1 (Nat.sub_le n 1))\n (pow_one_add_inv_two_mul_le n hn)\n have hb1 : (n : \u211d) * (n - 1) / 2 \u2264 n ^ 2 / 2 := by nlinarith [hn0]\n have hb2 : M ^ (n - 1) * (n * (n - 1) / 2) \u2264 2 * (n ^ 2 / 2) :=\n mul_le_mul_of_nonneg hpow hb1 (by positivity) (by positivity)\n have hb3 : ((1 : \u211d) / \u2016z\u2016) * M ^ (n - 1) * (n * (n - 1) / 2)\n \u2264 (1 / \u2016z\u2016) * (2 * (n ^ 2 / 2)) :=\n mul_le_mul_of_nonneg_left hb2 (by positivity)\n exact hb3.trans (by ring_nf)\n -- Re(f) = n\u00b7z.re/\u2016z\u2016\u00b2 + ((S\u2212n)/z).re\n have hre1 : ((n : \u2102) * (1 / z)).re = n * z.re / \u2016z\u2016 ^ 2 := by\n have hinv : ((1 : \u2102) / z).re = z.re / \u2016z\u2016 ^ 2 := by\n rw [one_div, Complex.inv_re, hnsq]\n rw [Complex.mul_re]\n simp [hinv]\n have hfre : (1 - w ^ n).re = n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re := by\n rw [hf, hS, Complex.add_re]\n congr 1\n rw [mul_comm, div_eq_mul_inv]\n exact hre1\n rw [hfre]\n have hA : |n * z.re / \u2016z\u2016 ^ 2| \u2264 n / \u2016z\u2016 ^ 2 := by\n rw [abs_div, abs_mul, abs_of_nonneg hn0.le,\n abs_of_nonneg (sq_nonneg \u2016z\u2016)]\n apply (div_le_div_right (by positivity)).mpr\n apply mul_le_mul_of_nonneg_left _ hn0.le\n exact abs_le.mpr \u27e8hzre0, hzre1\u27e9\n have hB : |((S - n) / z).re| \u2264 n ^ 2 / \u2016z\u2016 ^ 2 := by\n have h1 : |((S - n) / z).re| \u2264 \u2016(S - n) / z\u2016 := Complex.abs_re_le_norm _\n have h2 : \u2016(S - n) / z\u2016 \u2264 (n ^ 2 / \u2016z\u2016) / \u2016z\u2016 := by\n rw [norm_div]\n exact (div_le_div_right hzn).mpr hSn\n exact h1.trans (h2.trans (by rw [div_div, \u2190 pow_two]))\n have hnn : (n : \u211d) \u2264 n ^ 2 := by\n have h : (1 : \u211d) \u2264 n := by exact_mod_cast hn\n nlinarith\n calc |n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re|\n \u2264 n / \u2016z\u2016 ^ 2 + n ^ 2 / \u2016z\u2016 ^ 2 := (abs_add _ _).trans (add_le_add hA hB)\n _ = (n + n ^ 2) / \u2016z\u2016 ^ 2 := by ring\n _ \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n apply (div_le_div_right (by positivity)).mpr\n linarith\n\nend NguyenRH1\n"
}
thinking (8099 chars)
Good progress — only a few errors left:
1. Line 118: after `rw [hSn1]` the goal is `‖∑ (w^j − 1)‖ ≤ n²/‖z‖` and I wrote the calc starting from `∑ ‖w^j − 1‖` — missing the first step (norm_sum_le). Fix: start calc with the norm:
```
calc ‖∑ j ∈ Finset.range n, (w ^ j - 1)‖
≤ ∑ j ∈ Finset.range n, ‖w ^ j - 1‖ := norm_sum_le _ _
_ ≤ ...
```
2. Line 123: the `Finset.mul_sum` rewrite: `rw [← Finset.mul_sum]` produced goal `1/‖z‖ * ∑ (↑i * M^(n-1)) = 1/‖z‖ * M^(n-1) * ↑(∑ j)` — the mul_sum rewrote only one factor ((1/‖z‖)·) not the full (1/‖z‖·M^(n-1))·. The issue: my terms are (1/‖z‖) * (↑j * M^(n-1)) = ((1/‖z‖) * M^(n-1)) * ↑j. The rw [← Finset.mul_sum] rewrote the OUTERMOST (1/‖z‖) multiplication, giving `1/‖z‖ * ∑ (↑j * M^(n-1))`, then I need to factor M^(n-1) too. Two-step:
```
_ = ((1 / ‖z‖) * M ^ (n - 1)) * ∑ j ∈ Finset.range n, j := by
rw [← Finset.mul_sum]
apply Finset.sum_congr rfl
intro j _; ring
```
After rw [← Finset.mul_sum], goal: 1/‖z‖ * ∑ ↑j * M^(n-1) = (1/‖z‖*M^(n-1)) * ∑ ↑j — hmm the rw was applied to the GOAL `∑ (1/‖z‖)*(↑j*M^(n-1)) = ((1/‖z‖)*M^(n-1)) * ∑ ↑j`. rw [← Finset.mul_sum] on the RHS: (1/‖z‖*M^(n-1))·∑ ↑j → ∑ ((1/‖z‖*M^(n-1))·↑j). Then goal: ∑ (1/‖z‖)*(↑j*M^(n-1)) = ∑ ((1/‖z‖*M^(n-1))*↑j) — sum_congr with ring per term ✓. But the error shows rw [← Finset.mul_sum] rewrote the LHS instead (the (1/‖z‖) factor of the LHS sum), producing `1/‖z‖ * ∑ (↑i * M^(n-1))` — because ← Finset.mul_sum matched the FIRST occurrence, which was inside the LHS `∑ j, (1/‖z‖)*(↑j*M^(n-1))` — wait no, ← mul_sum turns c·∑ into ∑ c·... — the LHS is already a ∑, the RHS is c·∑. Hmm, rw [← Finset.mul_sum] rewrote the LHS ∑ into 1/‖z‖·∑? Finset.mul_sum : ∑ (c·f) = c·∑ f? No — Finset.mul_sum : (c * ∑ i, f i) = ∑ i, c * f i? Actually: `Finset.mul_sum : b * ∑ i ∈ s, f i = ∑ i ∈ s, b * f i`. So ← Finset.mul_sum : ∑ i, b*f i → b * ∑ f i — applied to LHS ∑ (1/‖z‖)*(↑j*M^(n-1)): matches b = 1/‖z‖, f j = ↑j*M^(n-1) → 1/‖z‖ * ∑ ↑j*M^(n-1). It rewrote the LHS (first match). I wanted it on the RHS. Solution: don't rw; instead transform both sides via congr:
```
_ = ((1 / ‖z‖) * M ^ (n - 1)) * ∑ j ∈ Finset.range n, j := by
symm
rw [Finset.mul_sum]
apply Finset.sum_congr rfl
intro j _; ring
```
After symm: goal ((1/‖z‖)*M^(n-1)) * ∑ ↑j = ∑ (1/‖z‖)*(↑j*M^(n-1)); rw [Finset.mul_sum] on LHS: ∑ ((1/‖z‖*M^(n-1))*↑j) = ∑ (1/‖z‖)*(↑j*M^(n-1)): sum_congr ring ✓.
3. Line 130: hsumj's linarith: from h2 : (∑ j : ℕ)*2 = n*(n−1) prove (∑ j : ℝ) = n*(n−1)/2: linarith should do it... The issue: h2 : ↑(∑ j ∈ range n, j) * 2 = n * (n - 1) — but the target has ↑(∑ j ∈ range n, j) = n*(n−1)/2 — linarith needs the cast of the sum on the LHS to match. h2 came from exact_mod_cast h where h : (∑ i ∈ range n, i) * 2 = n * (n - 1) in ℕ. exact_mod_cast h : (↑(∑ i, i)) * 2 = ↑n * (↑n − 1)?? — the ℕ subtraction n−1 casts badly: (n*(n−1) : ℕ) casts to ↑(n*(n−1)) — mod_cast should push... The error shows linarith failed — probably because h2 has `↑(n * (n-1))` or `(n:ℝ)*(n−1)` with the − in ℕ vs ℝ mismatch. Let me just prove hsumj differently:
```
have hsumj : (∑ j ∈ Finset.range n, j : ℝ) = n * (n - 1) / 2 := by
rw [Finset.sum_range_id] -- ? maybe not exist
```
Alternative: use `Finset.sum_range_id_mul_two (n : ℕ) : (∑ i ∈ range n, i) * 2 = n * (n - 1)` in ℕ, then cast carefully:
have h := Finset.sum_range_id_mul_two n
have h3 : ((∑ j ∈ Finset.range n, j : ℕ) : ℝ) = (n : ℝ) * ((n : ℝ) - 1) / 2 := by
have h4 : ((∑ j ∈ Finset.range n, j : ℕ) : ℝ) * 2 = (n : ℝ) * ((n : ℝ) - 1) := by
rw [← Nat.cast_mul, h]
push_cast [Nat.cast_mul]
-- need ↑(n*(n-1)) = ↑n*(↑n−1): Nat.cast_sub (requires 1 ≤ n)
rw [Nat.cast_mul, Nat.cast_sub (by omega)]
linarith
rw [h3]
Hmm wait — the target sum is over ℝ already: `(∑ j ∈ Finset.range n, j : ℝ)` — j : ℕ coerced. The cast (∑ j : ℕ) = ↑(∑ j) — same thing by push_cast. OK let me write:
```
have hsumj : (∑ j ∈ Finset.range n, (j : ℝ)) = (n : ℝ) * ((n : ℝ) - 1) / 2 := by
have h := Finset.sum_range_id_mul_two n
have h4 : ((∑ j ∈ Finset.range n, j : ℕ) : ℝ) * 2 = (n : ℝ) * ((n : ℝ) - 1) := by
have h5 : ((∑ j ∈ Finset.range n, j : ℕ) : ℝ) * 2 = ((n * (n - 1) : ℕ) : ℝ) := by
rw [← Nat.cast_sum, ← Nat.cast_mul, h] -- hmm Nat.cast_sum direction
...
```
Simpler:
```
have h := Finset.sum_range_id_mul_two n
-- h : (∑ i ∈ range n, i) * 2 = n * (n - 1) [ℕ]
have h4 : ((∑ j ∈ Finset.range n, j : ℕ) : ℝ) = (n : ℝ) * ((n : ℝ) - 1) / 2 := by
have hnat : (∑ j ∈ Finset.range n, j : ℕ) = n * (n - 1) / 2 := by
omega -- from h : Σ*2 = n*(n-1): Σ = n*(n-1)/2 in ℕ (omega handles Nat div? omega does handle Nat division by constants ✓)
rw [hnat]
push_cast [Nat.cast_mul, Nat.cast_sub (show 1 ≤ n by omega)]
ring
exact h4
```
omega can solve (Σ*2 = n*(n−1)) ⊢ Σ = n*(n−1)/2 in ℕ? omega handles linear arithmetic over ℤ/ℕ including division by constants — yes, omega should. Then cast: ↑(n*(n−1)/2) — hmm n*(n−1)/2 in ℕ — Nat.cast_div? messy. Cleaner:
have h4 : ((∑ j ∈ Finset.range n, j : ℕ) : ℝ) = (n : ℝ) * ((n : ℝ) - 1) / 2 := by
have h5 : (∑ j ∈ Finset.range n, j : ℕ) = n * (n - 1) / 2 := by omega
rw [h5]
rw [Nat.cast_div] -- needs the division to be exact? Nat.cast_div requires dvd...
Ugly. Best: prove the ℝ identity directly via a known lemma — `Finset.sum_range_id (n : ℕ) : ∑ i ∈ range n, i = n * (n - 1) / 2`?? Or Gauss: there might be `Finset.sum_range_id_mul_two` only. Alternative approach — avoid the explicit sum: bound ∑ j ≤ n·n... I only need the INEQUALITY ((1/‖z‖)·M^(n−1))·∑ j ≤ n²/‖z‖ — and ∑ j = n(n−1)/2 ≤ n²/2. Could bound ∑ j ≤ n·(n−1)/2 via sum_range_id_mul_two cast properly:
```
have h := Finset.sum_range_id_mul_two n
have h4 : ((∑ j ∈ Finset.range n, j : ℕ) : ℝ) * 2 = (n : ℝ) * ((n : ℝ) - 1) := by
exact_mod_cast h
have h5 : (∑ j ∈ Finset.range n, (j : ℝ)) * 2 = (n : ℝ) * ((n : ℝ) - 1) := by
have : (∑ j ∈ Finset.range n, (j : ℝ)) = ((∑ j ∈ Finset.range n, j : ℕ) : ℝ) := by
push_cast; rfl
rw [this, h4]
```
The exact_mod_cast h : should convert ℕ equation to ℝ: ((↑(∑ i, i))*2 : ℝ) = ↑(n*(n−1)): mod_cast normalizes: LHS (↑Σ)*2 → ↑(Σ)*2 with Σ cast; RHS ↑(n*(n−1)) → ↑n*(↑n−1) via Nat.cast_sub (needs 1 ≤ n — mod_cast handles side conditions? `exact_mod_cast h` with n ≥ 1 in context — might leave the Nat.cast_sub issue. Use push_cast with the side condition:
rw [← Nat.cast_mul, h] at *? — I want: ↑(∑ i, i) * 2 = ↑n * (↑n - 1).
h : (∑ i, i) * 2 = n * (n - 1).
cast both sides: ((∑ i, i) * 2 : ℕ) = ((n*(n-1) : ℕ) : ℝ) — congrArg Nat.cast h. Then push_cast [Nat.cast_sub (show (1:ℕ) ≤ n from hn)]:
↑(Σ * 2) = ↑Σ * 2 ✓ (Nat.cast_mul). RHS: ↑(n*(n−1)) = ↑n * ↑(n−1) = ↑n * (↑n − 1) via Nat.cast_sub (1 ≤ n) ✓.
So:
have h4 : ((∑ j ∈ Finset.range n, j : ℕ) : ℝ) * 2 = (n : ℝ) * ((n : ℝ) - 1) := by
have h6 := congrArg (Nat.cast : ℕ → ℝ) (Finset.sum_range_id_mul_two n)
rw [Nat.cast_mul, Nat.cast_mul, Nat.cast_sub hn] at h6
· exact h6
Hmm Nat.cast_sub signature: `Nat.cast_sub (h : m ≤ n) : ((n - m : ℕ) : α) = n - m` ✓ with hn : 1 ≤ n.
h6 : ↑(Σ*2) = ↑(n*(n−1)): after rw [Nat.cast_mul] twice: ↑Σ * ↑2 = ↑n * ↑(n−1): then Nat.cast_sub hn: ↑n*(↑n−1) — wait the cast_sub applies to ↑(n−1): = ↑n − ↑1 = ↑n − 1 ✓. Then also ↑2 = 2 (Nat.cast_ofNat simp). Might need simp [Nat.cast_ofNat] too. Let me write:
have h6 := congrArg (Nat.cast : ℕ → ℝ) (Finset.sum_range_id_mul_two n)
simp only [Nat.cast_mul, Nat.cast_sub hn, Nat.cast_ofNat, Nat.cast_one] at h6
exact h6
Nat.cast_sub hn : ↑n − ↑1 — then Nat.cast_one: − 1 ✓.
Then from h4: Σ = n(n−1)/2 in ℝ by linarith, and the sum over ℝ coercion bridge `(∑ j ∈ range n, (j : ℝ)) = ↑(∑ j ∈ range n, j : ℕ)` via push_cast/simp (Nat.cast_sum). Let me just write the final version with all these details.
Actually — simpler known alternative: `Finset.sum_range_id (n : ℕ) : (∑ i ∈ range n, i : α) = n * (n - 1) / 2`?? Hmm — I don't think there's a direct ℝ version. There's `Finset.sum_range_id_mul_two` and `Finset.sum_range_succ`. I'll go with the congrArg approach.
Let me rewrite the two broken calc steps and the hsumj proof, keeping everything else.
Nearly there — three localized fixes needed. Applying them.
tool: Edit
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\Scratch.lean",
"old_string": " calc \u2211 j \u2208 Finset.range n, \u2016w ^ j - 1\u2016\n \u2264 \u2211 j \u2208 Finset.range n, (1 / \u2016z\u2016) * (j * M ^ (n - 1)) :=\n Finset.sum_le_sum hbound\n _ = ((1 / \u2016z\u2016) * M ^ (n - 1)) * \u2211 j \u2208 Finset.range n, j := by\n rw [\u2190 Finset.mul_sum]\n apply Finset.sum_congr rfl\n intro j _; ring\n _ \u2264 n ^ 2 / \u2016z\u2016 := by\n have hsumj : (\u2211 j \u2208 Finset.range n, j : \u211d) = n * (n - 1) / 2 := by\n have h := Finset.sum_range_id_mul_two n\n have h2 : ((\u2211 j \u2208 Finset.range n, j : \u2115) : \u211d) * 2 = n * (n - 1) := by\n exact_mod_cast h\n linarith\n rw [hsumj]",
"new_string": " calc \u2016\u2211 j \u2208 Finset.range n, (w ^ j - 1)\u2016\n \u2264 \u2211 j \u2208 Finset.range n, \u2016w ^ j - 1\u2016 := norm_sum_le _ _\n _ \u2264 \u2211 j \u2208 Finset.range n, (1 / \u2016z\u2016) * (j * M ^ (n - 1)) :=\n Finset.sum_le_sum hbound\n _ = ((1 / \u2016z\u2016) * M ^ (n - 1)) * \u2211 j \u2208 Finset.range n, j := by\n symm\n rw [Finset.mul_sum]\n apply Finset.sum_congr rfl\n intro j _; ring\n _ \u2264 n ^ 2 / \u2016z\u2016 := by\n have hsumj : (\u2211 j \u2208 Finset.range n, j : \u211d) = n * (n - 1) / 2 := by\n have h6 := congrArg (Nat.cast : \u2115 \u2192 \u211d) (Finset.sum_range_id_mul_two n)\n simp only [Nat.cast_mul, Nat.cast_sub hn, Nat.cast_ofNat, Nat.cast_one] at h6\n have h7 : (\u2211 j \u2208 Finset.range n, (j : \u211d)) =\n ((\u2211 j \u2208 Finset.range n, j : \u2115) : \u211d) := by simp\n rw [h7]\n linarith\n rw [hsumj]"
}
thinking (7577 chars)
Down to three errors:
1. Line 144: `mul_le_mul_of_nonneg_left hb2 (by positivity)` — positivity picked `z.re` (hzre0) instead of 1/‖z‖! Because positivity proves `0 ≤ 1/‖z‖` but the mul_le_mul_of_nonneg_left's second argument needs to be 0 ≤ (1/‖z‖) — positivity should do that... but the error shows it used hzre0 (z.re). Weird — oh I see: the error is that `mul_le_mul_of_nonneg_left hb2 hzre0` was elaborated with `hzre0` — but I wrote `(by positivity)`. Hmm no — the error says "has type z.re * ... ≤ z.re * ..." — so Lean unified the outer factor as z.re?? That means hb2's statement had z.re in it?? No — the error might be misdirected: `(by positivity)` for `0 ≤ 1/‖z‖`... Actually looking again: `mul_le_mul_of_nonneg_left hb2 hzre0` — the term shows hzre0 — but I wrote (by positivity). Unless the file has a different spot. OH WAIT — I see: this is error at line 144 — hb3's definition. `mul_le_mul_of_nonneg_left hb2 (by positivity)` — the `by positivity` attempt — hmm, but the displayed term has hzre0. That's bizarre... OH — I bet the issue: hb2 : M^(n-1) * (n*(n−1)/2) ≤ 2*(n²/2), and hb3's target: (1/‖z‖)*M^(n-1)*(n*(n−1)/2) ≤ (1/‖z‖)*(2*(n²/2)). Note the ASSOCIATION: (1/‖z‖) * M^(n−1) * (...) — Lean parses as ((1/‖z‖) * M^(n−1)) * (...) — so the "left factor" is ((1/‖z‖)*M^(n−1)) not (1/‖z‖). mul_le_mul_of_nonneg_left : b ≤ c → 0 ≤ a → a*b ≤ a*c — needs the target a*(M^(n−1)*(...)) vs a*(2*(n²/2)) — but the goal has ((1/‖z‖)*M^(n−1))*(...) — association mismatch! Fix: restate hb3's target with explicit parentheses: `(1/‖z‖) * (M^(n-1) * (n*(n-1)/2)) ≤ (1/‖z‖) * (2*(n^2/2))`. Or use mul_le_mul_of_nonneg_left hb2 (by positivity : (0:ℝ) ≤ 1/‖z‖) after converting association. Simplest: change hb3's statement to the parenthesized form and the subsequent `hb3.trans (by ring_nf)` — ring_nf handles the reassociation to n²/‖z‖ ✓.
Hmm wait, but the error display shows the elaborated term with z.re — that suggests `by positivity` synthesized 0 ≤ z.re?? That can't be — unless positivity picked the wrong goal... Actually the error message shows the INFERRED type of `mul_le_mul_of_nonneg_left hb2 hzre0` — where did hzre0 come from? Maybe Lean's elaboration of `(by positivity)` produced hzre0?? No... OH WAIT — I see it now: the error is at 144:12, and it says the term `mul_le_mul_of_nonneg_left hb2 hzre0` — hzre0 must be what `by positivity` returned?! positivity wouldn't return hzre0 for 0 ≤ 1/‖z‖... unless the expected type was different. Hmm — whatever the cause, the association issue is real: hb2 has form `A * B ≤ C` where A = M^(n−1), B = (n(n−1)/2); the target needs a*(A*B) ≤ a*C — with a = 1/‖z‖. But the displayed error term is `z.re * (M^(n-1) * (↑n*(↑n−1)/2)) ≤ z.re * (2*(↑n^2/2))` — the z.re! So Lean parsed the multiplier as z.re — meaning my hb3 statement in the file might actually have z.re?? Let me look at what I wrote: `((1 : ℝ) / ‖z‖) * M ^ (n - 1) * (n * (n - 1) / 2) ≤ (1 / ‖z‖) * (2 * (n ^ 2 / 2))` — hmm `(1 : ℝ)/‖z‖` — that's fine... wait, the error at 144:12 — let me count lines: 144 might be the hb3 line `mul_le_mul_of_nonneg_left hb2 (by positivity)`. The displayed mismatch: expected `1/‖z‖ * ...` got `z.re * ...`. So `by positivity` somehow proved `0 ≤ z.re`?? NO — actually: `mul_le_mul_of_nonneg_left` in recent Mathlib signature: `mul_le_mul_of_nonneg_left (h : b ≤ c) (ha : 0 ≤ a) : a * b ≤ a * c`. Given hb2 and a goal `1/‖z‖ * (M^.. * ...) ≤ 1/‖z‖ * (2*(n²/2))`, elaboration unifies a := 1/‖z‖, b := M^(n−1)*(...), c := 2*(n²/2). The second arg (by positivity) proves 0 ≤ 1/‖z‖ ✓. That should work — UNLESS positivity proved something else... The error message is strange. The displayed type of the term has z.re — could `by positivity` for `0 ≤ 1/‖z‖`... no. OK whatever — maybe the issue is hb3's LHS association: `(1/‖z‖) * M^(n-1) * X` parses as `((1/‖z‖) * M^(n-1)) * X` — then mul_le_mul_of_nonneg_left hb2 gives `a * (M^(n-1)*X') ≤ a * (...)` with b := M^(n−1)*X' — but the goal's form is ((1/‖z‖)*M^(n−1))*X — these don't match (different association), so Lean tried to unify b with X and a with (1/‖z‖)*M^(n−1)... and (by positivity) for 0 ≤ (1/‖z‖)*M^(n−1)... but the error shows z.re — I can't fully explain, but the fix is clear: parenthesize. Let me also double check by positivity could return hzre0: positivity extension might close `0 ≤ z.re`? The expected type was `0 ≤ ?a` — with ?a unified to z.re?? — meaning unification set a := z.re: that happens if the GOAL had `z.re * ...` — did I write z.re anywhere near hb3? NO... unless the error line numbering is off and this is about hA: hA's proof has `apply mul_le_mul_of_nonneg_left _ hn0.le; exact abs_le.mpr ⟨hzre0, hzre1⟩` — no.
Let me just look at the current file around line 144 to see what's actually there.
2. Line 147: `↑n * (z.re / normSq z) = ↑n * z.re / ‖z‖ ^ 2` — hre1's simp [hinv] left this: after rw [Complex.mul_re], simp [hinv] — need to push n into the division: n·(z.re/normSq z) = n·z.re/‖z‖²: rw [hinv, hnsq]?? The displayed remaining goal: ↑n * (z.re / normSq z) = ↑n * z.re / ‖z‖ ^ 2 — fix: rw [hnsq] then ring? or field_simp: `rw [hnsq]; ring`? Wait — the goal after simp [hinv]: ↑n*(z.re/normSq z) = ↑n*z.re/‖z‖²: rewrite normSq via hnsq: ↑n*(z.re/‖z‖²) = ↑n*z.re/‖z‖²: `rw [hnsq]; ring`? ring normalizes mul_div ✓. Let me make hre1's proof:
```
have hre1 : ((n : ℂ) * (1 / z)).re = n * z.re / ‖z‖ ^ 2 := by
have hinv : ((1 : ℂ) / z).re = z.re / ‖z‖ ^ 2 := by
rw [one_div, Complex.inv_re, hnsq]
rw [Complex.mul_re]
simp [hinv, hnsq]
ring
```
Hmm — after rw [Complex.mul_re]: goal (↑n).re * (1/z).re − (↑n).im * (1/z).im = ...: simp [hinv] should simplify (↑n).re → ↑n (Complex.natCast_re), (↑n).im → 0, (1/z).re → z.re/‖z‖² (hinv as simp)... the remaining goal shown is `↑n * (z.re / normSq z) = ↑n * z.re / ‖z‖ ^ 2` — so simp DID reduce to that point; add hnsq to the simp set and then `field_simp`/`ring`. With hnsq in simp: normSq z → ‖z‖²: goal: ↑n*(z.re/‖z‖²) = ↑n*z.re/‖z‖² — `mul_div` — rfl after ring_nf? simp [hinv, hnsq, mul_div] should close, or add `; ring_nf`.
3. Line 153: hfre's rw [Complex.add_re] — pattern (?z + ?w).re not found: the goal is `(1/z * (↑n + (S − ↑n))).re = ...` — the re of a PRODUCT (1/z * X), not a sum. I need to first rewrite the product as a sum: (1/z)*(n + (S−n)) = n*(1/z) + (S−n)/z — I removed that step! In this version I wrote:
```
have hfre : ... := by
rw [hf, hS, Complex.add_re]
```
hf : 1 − wⁿ = (1/z)*S; hS : S = n + (S−n): after rw [hf, hS]: goal ((1/z)*(↑n + (S − ↑n))).re — need to distribute first:
```
have hd : (1 / z) * ((n : ℂ) + (S - n)) = (n : ℂ) * (1 / z) + (S - n) / z := by
field_simp; ring
rw [hf, hS, hd, Complex.add_re, hre1]
```
Wait — careful: (1/z)*(n + X) = n*(1/z) + (S−n)/z: (1/z)*n = n*(1/z) ✓ and (1/z)*(S−n) = (S−n)/z ✓. field_simp + ring ✓.
Then after rw [..., Complex.add_re, hre1]: goal `↑n * z.re/‖z‖² + ((S−n)/z).re = ↑n * z.re/‖z‖² + ((S−n)/z).re`? — hfre's RHS: n * z.re / ‖z‖ ^ 2 + ((S - n) / z).re ✓ matches — rfl.
Hmm but earlier hfre had a `congr 1; rw [mul_comm, div_eq_mul_inv]; exact hre1` structure — the congr 1 split into two goals: ((1/z)*↑n... no wait. Let me rewrite hfre cleanly:
```
have hfre : (1 - w ^ n).re = n * z.re / ‖z‖ ^ 2 + ((S - n) / z).re := by
have hd : (1 / z) * ((n : ℂ) + (S - n)) = (n : ℂ) * (1 / z) + (S - n) / z := by
field_simp; ring
rw [hf, hS, hd, Complex.add_re, hre1]
```
The final: ((↑n)*(1/z)).re + ((S−n)/z).re = n·z.re/‖z‖² + ((S−n)/z).re — rw [hre1] rewrites ((n:ℂ)*(1/z)).re ✓ → n·z.re/‖z‖² — goal becomes rfl ✓ (rw closes).
Let me apply these three fixes.
Three fixes: hb3 association, hre1's normSq rewrite, and hfre's missing distribution step.
tool: Edit
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\Scratch.lean",
"old_string": " have hb3 : ((1 : \u211d) / \u2016z\u2016) * M ^ (n - 1) * (n * (n - 1) / 2)\n \u2264 (1 / \u2016z\u2016) * (2 * (n ^ 2 / 2)) :=\n mul_le_mul_of_nonneg_left hb2 (by positivity)\n exact hb3.trans (by ring_nf)",
"new_string": " have hb3 : ((1 : \u211d) / \u2016z\u2016) * (M ^ (n - 1) * (n * (n - 1) / 2))\n \u2264 (1 / \u2016z\u2016) * (2 * (n ^ 2 / 2)) :=\n mul_le_mul_of_nonneg_left hb2 (by positivity)\n exact hb3.trans (by ring_nf)"
}
thinking (10567 chars)
Progress — hre1 is now proved. Remaining:
1. hfre (line 158-160): after `rw [hf, hS, hd, Complex.add_re, hre1]` — the goal:
`↑n * z.re / ‖z‖ ^ 2 + ((S - ↑n) / z).re = ↑n * z.re / ‖z‖ ^ 2 + ((↑n + (S - ↑n) - ↑n) / z).re`
The LHS is the goal's RHS from hfre's statement; the RHS has `((↑n + (S − ↑n) − ↑n)/z).re` — because hd rewrote (1/z)*(n + (S−n)) = n*(1/z) + (S−n)/z — WAIT no: hd : 1/z * (↑n + (S − ↑n)) = ↑n * (1/z) + (S − ↑n) / z — after rw [hd], the re should be (↑n*(1/z) + (S−↑n)/z).re. Then Complex.add_re splits. But the displayed RHS shows `((↑n + (S − ↑n) − ↑n) / z).re` — the rewrite of (S − ↑n) got tangled: `hd`'s RHS `(S - ↑n) / z` — and then... hmm, actually looking: `((↑n + (S − ↑n) − ↑n) / z).re` = ((S)/z).re — this came from rw [hS] rewriting S as n + (S−n) INSIDE hd's already-applied rewrite! The rw sequence: [hf, hS, hd, ...] — hS rewrites S → ↑n + (S − ↑n) everywhere INCLUDING the `S − ↑n` inside hd's output? No wait — rw [hS] happens BEFORE hd. After rw [hf, hS]: goal has (1/z * (↑n + (S − ↑n))).re — but hS : S = ↑n + (S − ↑n) — rw [hS] rewrites S EVERYWHERE including the S inside "S − ↑n" itself?? rw rewrites all instances of the LHS pattern `S` — in the term `(1/z) * (↑n + (S - ↑n))`: the S inside `(S − ↑n)` also matches and gets rewritten: → `↑n + ((↑n + (S − ↑n)) − ↑n)`. That's the classic set-with-rw loop issue (only rewrites once, but messes the inner S). Result displayed: `((↑n + (S − ↑n) − ↑n)/z).re` ✓ exactly what happened.
Fix: don't rw [hS]; instead use conv to rewrite only the outer S, or restructure: since hf : 1 − wⁿ = (1/z)·S, rewrite goal's `1 − wⁿ` via hf, then need ((1/z)·S).re — write S = n + (S−n) via conv pattern: `conv_lhs => rw [hf]; pattern ((1/z) * S)`... simpler: avoid hS rewrite:
```
have hfre : ... := by
have hd : (1 / z) * ((n : ℂ) + (S - n)) = (n : ℂ) * (1 / z) + (S - n) / z := by
field_simp; ring
have hS2 : (1 : ℂ) - w ^ n = (1 / z) * ((n : ℂ) + (S - n)) := by
rw [hf]; congr 1; rw [hS] -- no: same issue
```
Cleanest: prove the final re-form directly:
```
have hfre : (1 - w ^ n).re = n * z.re / ‖z‖ ^ 2 + ((S - n) / z).re := by
have hd : (1 / z) * ((n : ℂ) + (S - n)) = (n : ℂ) * (1 / z) + (S - n) / z := by
field_simp; ring
have hS2 : (1 : ℂ) - w ^ n = (1 / z) * ((n : ℂ) + (S - n)) := by
rw [hf, show S = (n : ℂ) + (S - n) from by ring]
rw [hS2, hd, Complex.add_re, hre1]
```
The `show S = (n:ℂ) + (S − n) from by ring` — rw with this equation: rewrites S → ↑n + (S−↑n) — SAME looping issue!! Because the equation's LHS is `S` — it rewrites all S occurrences including inside RHS of itself? No — rw [h : S = X] rewrites occurrences of S in the GOAL; the goal `(1/z)·S` has ONE S; rewriting gives `(1/z)·(↑n + (S − ↑n))` — the new term contains S again (inside S−n) but rw does one pass: does rw rewrite the S inside the newly introduced X? rw does rewrite_all_occurrences of the LHS pattern in the goal — it does a single pass: finds all instances of S in the CURRENT goal, replaces them. After replacement, it doesn't re-scan. So `(1/z)·S` → `(1/z)·(↑n + (S − ↑n))` — ONE S in goal replaced by a term containing S — the result has S but rw is done ✓ no loop. So the earlier problem was different: the goal after rw [hf] was `(1 / z * S).re = ...` — ONE S — rw [hS] gives `(1/z * (↑n + (S − ↑n))).re` ✓ fine. THEN rw [hd]: pattern `1/z * (↑n + (S−↑n))` matches ✓ → `(↑n * (1/z) + (S − ↑n)/z).re` ✓. Then Complex.add_re ✓, hre1 ✓. Where did the tangle come from? The displayed goal: `... = ↑n * z.re/‖z‖² + ((↑n + (S − ↑n) − ↑n)/z).re` — the RHS of the GOAL (hfre's statement RHS `n·z.re/‖z‖² + ((S − n)/z).re`) got ITS S rewritten by rw [hS] too!! The statement's `((S − n)/z).re` contains S → became `((↑n + (S−↑n) − ↑n)/z).re`. So after hre1 rewrite, LHS = `↑n*z.re/‖z‖² + ((S−↑n)/z).re` vs goal `↑n*z.re/‖z‖² + ((↑n+(S−↑n)−↑n)/z).re` — mismatch (S−↑n) vs (↑n+(S−↑n)−↑n) — equal but not syntactically. Fix: `congr 1; congr 1; ring`? The remaining: ((S−↑n)/z).re = ((↑n+(S−↑n)−↑n)/z).re: `congr 1` twice → S−↑n = ↑n+(S−↑n)−↑n → ring. Or avoid rewriting the goal-RHS: do the rewrites only on LHS:
```
rw [show (1:ℂ) - w^n = (1/z) * S from hf]
conv_lhs => rw [show S = (n:ℂ) + (S - n) from by ring]
```
conv_lhs confines to LHS ✓. Then rw [hd, Complex.add_re, hre1] — hd/hre1/Complex.add_re patterns appear on both sides?? The goal RHS has ((S−n)/z).re — Complex.add_re would rewrite LHS only if... rw rewrites everywhere. ((S−↑n)/z).re is not of the form (a+b).re ✓ safe. hre1's pattern (↑n * (1/z)).re — appears only on LHS ✓. So:
```
have hfre : (1 - w ^ n).re = n * z.re / ‖z‖ ^ 2 + ((S - n) / z).re := by
have hd : (1 / z) * ((n : ℂ) + (S - n)) = (n : ℂ) * (1 / z) + (S - n) / z := by
field_simp; ring
rw [show (1 : ℂ) - w ^ n = (1 / z) * S from hf]
conv_lhs => rw [show S = (n : ℂ) + (S - n) from by ring, hd, Complex.add_re, hre1]
```
Hmm — rw inside conv_lhs with hd — hd's pattern `1/z * (↑n + (S−↑n))` ✓. Complex.add_re pattern (↑n*(1/z) + (S−↑n)/z).re ✓ → (↑n*(1/z)).re + ((S−↑n)/z).re; hre1: (↑n*(1/z)).re → ↑n*z.re/‖z‖² ✓. Then goal: LHS = ↑n*z.re/‖z‖² + ((S−↑n)/z).re, RHS = same ✓ rfl — but after conv_lhs the goal must be closed by rfl explicitly? conv_lhs changes the goal; after the conv block, if LHS ≡ RHS syntactically, Lean closes it automatically? No — need `all_goals rfl`? conv_lhs rewrites then the goal remains `X = X` — I think rw inside conv closes rfl goals automatically at the end? Not sure. Safer: end with no conv — do the conv rewrites then rfl:
```
rw [show (1 : ℂ) - w ^ n = (1 / z) * S from hf]
conv_lhs => rw [show S = (n : ℂ) + (S - n) from by ring, hd, Complex.add_re, hre1]
```
conv blocks auto-close if the goal becomes rfl? I believe after conv_lhs => rw [...], if the resulting goal is syntactic rfl, the block succeeds and closes it (rw closes rfl goals). Yes — rw closes goals that become rfl, including inside conv? Actually inside conv, after the conv block the outer tactic continues; if goal is `a = a` the conv block's result... let me just append nothing and see. Alternative without conv: use `nth_rewrite`:
```
rw [hf]
nth_rewrite 1 [show S = (n : ℂ) + (S - n) from by ring]
rw [hd, Complex.add_re, hre1]
```
nth_rewrite 1 [S-eq] — rewrites the FIRST occurrence of S in the goal — the goal after rw [hf]: `(1/z * S).re = ↑n*z.re/‖z‖² + ((S−↑n)/z).re` — occurrences of S: #1 in LHS product, #2 in RHS's (S−↑n). nth_rewrite 1 rewrites only #1 ✓✓. Then rw [hd, Complex.add_re, hre1] ✓ final rfl ✓. This is cleaner. But is occurrence #1 the LHS one? Order is by term traversal — the goal's LHS comes first ✓.
2. `div_le_div_right` unknown identifier (lines 166, 173, 182) — wrong name. The iff form: `div_le_div_right (hc : 0 < c) : a / c ≤ b / c ↔ a ≤ b` — hmm that exists? Apparently not under this name in this Mathlib. Modern names: `div_le_div_right` might be `div_le_div_iff_right`? or `div_le_div_right` exists in Order/Basic... The error says unknown. Candidates: `div_le_div_right`, `div_le_div_iff_right (hc : 0 < c) : a / c ≤ b / c ↔ a ≤ b` — I believe `div_le_div_iff_right` exists in recent Mathlib (there was a rename wave: le_div_iff, div_le_iff, div_le_div_iff_right). Also monotone version `div_le_div_of_nonneg_right`?? Unknown. Safest: avoid it — use `div_le_iff`/`le_div_iff` directly with mul:
For hA: |n·z.re/‖z‖²| ≤ n/‖z‖²: n·|z.re|/‖z‖² ≤ n/‖z‖² ⟺ n·|z.re| ≤ n (mul by ‖z‖² > 0):
```
apply (div_le_div_iff_of_nonneg ...)?
```
Simplest: `apply div_le_div_of_nonneg_right`? unknown too. Use: `by gcongr` — gcongr handles a/c ≤ b/c given a ≤ b ✓ robust:
hA: after the abs rewrites: goal |↑n| * |z.re| / |‖z‖^2| ≤ ↑n / ‖z‖^2: messy. Restructure hA entirely:
```
have hA : |n * z.re / ‖z‖ ^ 2| ≤ n / ‖z‖ ^ 2 := by
have e : n * z.re / ‖z‖ ^ 2 = (n * z.re) / ‖z‖ ^ 2 := by ring
rw [e, abs_div]
have e2 : |↑n * z.re| = n * |z.re| := by
rw [abs_mul, abs_of_nonneg hn0.le]
rw [e2, abs_of_nonneg (sq_nonneg ‖z‖)]
apply div_le_div_of_nonneg_right?
```
Let me use a uniform robust pattern via div_le_iff (which I'm confident exists: `div_le_iff (hc : 0 < c) : a / c ≤ b ↔ a ≤ b * c`):
```
rw [div_le_iff (by positivity : (0:ℝ) < ‖z‖ ^ 2)]
-- goal: n * |z.re| ≤ n * ‖z‖^2 / ‖z‖^2... no: (n/‖z‖²) * ‖z‖² = n
have : (n / ‖z‖ ^ 2) * ‖z‖ ^ 2 = n := by field_simp
rw [this]
apply mul_le_mul_of_nonneg_left _ hn0.le
exact abs_le.mpr ⟨hzre0, hzre1⟩
```
div_le_iff : a / c ≤ b ↔ a ≤ b * c (hc : 0 < c) — signature `div_le_iff (hc : 0 < c) : a / c ≤ b ↔ a ≤ b * c`? There's `div_le_iff₀`? In ordered field: `div_le_iff (hc : 0 < c) : a / c ≤ b ↔ a ≤ b * c` ✓ exists (or div_le_iff₀ — I'll try div_le_iff, fallback div_le_iff₀).
Same for hB's step: `‖S−n‖/‖z‖ ≤ (n²/‖z‖)/‖z‖` — via div_le_iff:
```
have h2 : ‖(S - n) / z‖ ≤ (n ^ 2 / ‖z‖) / ‖z‖ := by
rw [norm_div, div_le_iff hzn]
rw [← div_div] -- hmm target: ‖S−n‖ ≤ (n²/‖z‖/‖z‖)*‖z‖ = n²/‖z‖
have e : (n ^ 2 / ‖z‖ / ‖z‖) * ‖z‖ = n ^ 2 / ‖z‖ := by field_simp
rw [e]
exact hSn
```
Wait — after rw [norm_div]: goal ‖S−n‖/‖z‖ ≤ (n²/‖z‖)/‖z‖: div_le_iff hzn : a/‖z‖ ≤ b ↔ a ≤ b*‖z‖: goal: ‖S−n‖ ≤ ((n²/‖z‖)/‖z‖)*‖z‖ = n²/‖z‖: field_simp proves the product identity, then hSn ✓.
And the final step:
```
_ ≤ 2 * n ^ 2 / ‖z‖ ^ 2 := by
rw [div_le_iff (by positivity)]
have e : (2 * n ^ 2 / ‖z‖ ^ 2) * ‖z‖ ^ 2 = 2 * n ^ 2 := by field_simp
rw [e]
linarith [hnn]
```
Hmm — goal: (n + n²)/‖z‖² ≤ 2n²/‖z‖²: div_le_iff: (n+n²) ≤ (2n²/‖z‖²)·‖z‖² = 2n²: linarith with hnn : n ≤ n² ✓.
3. `abs_add` unknown (line 179) — the name for |a+b| ≤ |a|+|b| is `abs_add` in Algebra/Order/AbsoluteValue or `abs_add` for ordered rings — apparently unknown here?? Weird — abs_add is very standard. Maybe it's `abs_add` in a namespace not opened... I have `open ... Topology` etc. Try `abs_add` — error says unknown identifier. Alternatives: `abs_add_le`, `abs_add'`... For ℝ: `abs_add (a b : ℝ) : |a + b| ≤ |a| + |b|` — it's in Mathlib/Algebra/Order/AbsoluteValue? or Mathlib/Algebra/Order/Abs. Hmm — actually `abs_add` IS standard: `theorem abs_add (a b : α) : |a + b| ≤ |a| + |b|` in Algebra/Order/Unbundled/Abs.lean. Maybe unknown because of an open collision (Topology has abs_add? no). Wait — maybe the issue: `open Zeta23 Complex Filter Topology` — maybe one of these shadows abs_add? Unlikely. The error: `unknown identifier abs_add` — maybe in this Mathlib version it's named differently: check `abs_add_le`? Let me just use `(abs_add _ _)` replaced by `abs_add_le`? Hmm. Or norm: for ℝ, |x| = ‖x‖: `norm_add_le`. Let me check names via grep quickly for all three unknowns.
Good progress — hre1 proved. Three name issues left. Checking the exact names in this Mathlib.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem div_le_iff \\|lemma div_le_iff \\|theorem div_le_iff\u2080\\|lemma div_le_iff\u2080\" Mathlib/Algebra/Order/Field/Basic.lean Mathlib/Algebra/Order/Unbundled/Basic.lean 2>/dev/null | head -4; grep -rn \"theorem abs_add \\|lemma abs_add \\|abs_add_le\\b\" Mathlib/Algebra/Order/AbsoluteValue.lean Mathlib/Algebra/Order/Unbundled/Abs.lean 2>/dev/null | head -4; grep -rn \"theorem div_le_div_iff_right\\|lemma div_le_div_iff_right\" Mathlib/ --include=*.lean | head -2",
"description": "Check div_le_iff, abs_add, div_le_div_iff_right names"
}
thinking (485 chars)
Found: `abs_add_le` exists in Mathlib/Algebra/Order/AbsoluteValue/Basic.lean (used at line 274 as `add_le' := abs_add_le`) — it's likely `theorem abs_add_le (a b : α) : |a + b| ≤ |a| + |b|`. Let me use `abs_add_le` instead of `abs_add`. And `div_le_iff₀` instead of div_le_iff. Both confirmed.
Now let me fix:
1. hfre with nth_rewrite 1.
2. hA with div_le_iff₀.
3. hB with div_le_iff₀.
4. Final calc step with div_le_iff₀ and abs_add_le.
Rewrite the tail section of re_li_summand_le.
`abs_add_le` and `div_le_iff₀` are the right names. Applying the final fixes.
tool: Edit
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\Scratch.lean",
"old_string": " have hfre : (1 - w ^ n).re = n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re := by\n have hd : (1 / z) * ((n : \u2102) + (S - n)) = (n : \u2102) * (1 / z) + (S - n) / z := by\n field_simp; ring\n rw [hf, hS, hd, Complex.add_re, hre1]\n rw [hfre]\n have hA : |n * z.re / \u2016z\u2016 ^ 2| \u2264 n / \u2016z\u2016 ^ 2 := by\n rw [abs_div, abs_mul, abs_of_nonneg hn0.le,\n abs_of_nonneg (sq_nonneg \u2016z\u2016)]\n apply (div_le_div_right (by positivity)).mpr\n apply mul_le_mul_of_nonneg_left _ hn0.le\n exact abs_le.mpr \u27e8hzre0, hzre1\u27e9\n have hB : |((S - n) / z).re| \u2264 n ^ 2 / \u2016z\u2016 ^ 2 := by\n have h1 : |((S - n) / z).re| \u2264 \u2016(S - n) / z\u2016 := Complex.abs_re_le_norm _\n have h2 : \u2016(S - n) / z\u2016 \u2264 (n ^ 2 / \u2016z\u2016) / \u2016z\u2016 := by\n rw [norm_div]\n exact (div_le_div_right hzn).mpr hSn\n exact h1.trans (h2.trans (by rw [div_div, \u2190 pow_two]))\n have hnn : (n : \u211d) \u2264 n ^ 2 := by\n have h : (1 : \u211d) \u2264 n := by exact_mod_cast hn\n nlinarith\n calc |n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re|\n \u2264 n / \u2016z\u2016 ^ 2 + n ^ 2 / \u2016z\u2016 ^ 2 := (abs_add _ _).trans (add_le_add hA hB)\n _ = (n + n ^ 2) / \u2016z\u2016 ^ 2 := by ring\n _ \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n apply (div_le_div_right (by positivity)).mpr\n linarith",
"new_string": " have hfre : (1 - w ^ n).re = n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re := by\n have hd : (1 / z) * ((n : \u2102) + (S - n)) = (n : \u2102) * (1 / z) + (S - n) / z := by\n field_simp; ring\n rw [hf]\n nth_rewrite 1 [show S = (n : \u2102) + (S - n) from by ring]\n rw [hd, Complex.add_re, hre1]\n rw [hfre]\n have hA : |n * z.re / \u2016z\u2016 ^ 2| \u2264 n / \u2016z\u2016 ^ 2 := by\n have e : |n * z.re / \u2016z\u2016 ^ 2| = n * |z.re| / \u2016z\u2016 ^ 2 := by\n rw [abs_div, abs_mul, abs_of_nonneg hn0.le,\n abs_of_nonneg (sq_nonneg \u2016z\u2016)]\n rw [e, div_le_iff\u2080 (by positivity)]\n have e2 : (n / \u2016z\u2016 ^ 2) * \u2016z\u2016 ^ 2 = n := by field_simp\n rw [e2]\n exact mul_le_mul_of_nonneg_left (abs_le.mpr \u27e8hzre0, hzre1\u27e9) hn0.le\n have hB : |((S - n) / z).re| \u2264 n ^ 2 / \u2016z\u2016 ^ 2 := by\n have h1 : |((S - n) / z).re| \u2264 \u2016(S - n) / z\u2016 := Complex.abs_re_le_norm _\n have h2 : \u2016(S - n) / z\u2016 \u2264 (n ^ 2 / \u2016z\u2016) / \u2016z\u2016 := by\n rw [norm_div, div_le_iff\u2080 hzn]\n have e : ((n ^ 2 / \u2016z\u2016) / \u2016z\u2016) * \u2016z\u2016 = n ^ 2 / \u2016z\u2016 := by field_simp\n rw [e]\n exact hSn\n exact h1.trans (h2.trans (by rw [div_div, \u2190 pow_two]))\n have hnn : (n : \u211d) \u2264 n ^ 2 := by\n have h : (1 : \u211d) \u2264 n := by exact_mod_cast hn\n nlinarith\n calc |n * z.re / \u2016z\u2016 ^ 2 + ((S - n) / z).re|\n \u2264 n / \u2016z\u2016 ^ 2 + n ^ 2 / \u2016z\u2016 ^ 2 := (abs_add_le _ _).trans (add_le_add hA hB)\n _ = (n + n ^ 2) / \u2016z\u2016 ^ 2 := by ring\n _ \u2264 2 * n ^ 2 / \u2016z\u2016 ^ 2 := by\n rw [div_le_iff\u2080 (by positivity)]\n have e : (2 * n ^ 2 / \u2016z\u2016 ^ 2) * \u2016z\u2016 ^ 2 = 2 * n ^ 2 := by field_simp\n rw [e]\n linarith"
}
thinking (17125 chars)
The file compiles clean (no errors). The core lemmas are green:
- `liSummand`, `summand_conj`, `liSummand_eq`
- `pow_one_add_inv_two_mul_le`
- `re_li_summand_le` (the key estimate)
Now I need the final summability assembly: `liSummable`. Let me append it to the file. Components:
1. Comparison: 1 + normSq (gammaOf z) ≤ (9/4)·‖z‖² for z with re ∈ [0,1] and ‖z‖ ≥ 2n (n ≥ 1).
2. The dominator D and its summability via zero_sum_inv_sq + finite support modification.
3. Final: Summable (liSummand n) via Summable.of_norm_bounded.
For the comparison lemma:
```
lemma normSq_gammaOf_le_mul_norm_sq {n : ℕ} (hn : 1 ≤ n) {z : ℂ}
(hzre0 : 0 ≤ z.re) (hzre1 : z.re ≤ 1) (hz : 2 * n ≤ ‖z‖) :
1 + Complex.normSq (gammaOf z) ≤ 9 / 4 * ‖z‖ ^ 2 := by
have hzn : ...
have hgam : Complex.normSq (gammaOf z) = z.im ^ 2 + (1 / 2 - z.re) ^ 2 := by
rw [Complex.normSq_apply, WeilEF.gammaOf_re, WeilEF.gammaOf_im] -- wait, namespaces: gammaOf_re/gammaOf_im are in Zeta23.WeilEF namespace
ring
rw [hgam, Complex.normSq_eq_norm_sq z, Complex.normSq_apply]
have him : 1 ≤ z.im ^ 2 := by
have : z.re ^ 2 ≤ 1 := by nlinarith [hzre0, hzre1]
have hz2 : ‖z‖ ^ 2 = z.re ^ 2 + z.im ^ 2 := by rw [← hnsq?...]
nlinarith [hz, hzre0, hzre1, ...]
nlinarith [hzre0, hzre1, him]
```
Hmm — ‖z‖² = re² + im²: from Complex.normSq_eq_norm_sq z : normSq z = ‖z‖² and normSq_apply : normSq z = re*re + im*im — so ‖z‖² = re²+im² (with squares: re*re = re^2 via sq). Then:
1 + normSq γ_ρ = 1 + im² + (1/2−re)². (1/2−re)² ≤ 1/4 since re ∈ [0,1] (|1/2−re| ≤ 1/2). So LHS ≤ 5/4 + im². RHS = 9/4·(re²+im²) ≥ 9/4·im². Need 5/4 + im² ≤ 9/4·im² ⟺ 5/4 ≤ 5/4·im² ⟺ 1 ≤ im². And im² = ‖z‖² − re² ≥ (2n)² − 1 ≥ 3 ≥ 1 ✓ (n ≥ 1: 4n² ≥ 4, −1: ≥ 3).
nlinarith should close: given hzre0, hzre1, hz : 2n ≤ ‖z‖ (need ‖z‖² ≥ 4n²: from hz and nonneg: `sq_le_sq`... (2n)² ≤ ‖z‖² via pow_le_pow_left₀ (by positivity) hz 2), ‖z‖² = re²+im², re² ≤ 1 (from re ∈ [0,1]: nlinarith).
Let me structure with explicit haves and one nlinarith at the end.
For the final summability:
```
theorem liSummable (n : ℕ) : Summable (liSummand n) := by
cases Nat.eq_zero_or_pos n with
| inl h0 =>
subst h0
have : liSummand 0 = fun _ => 0 := by
funext ρ
simp [liSummand]
rw [this]
exact summable_zero
| inr hn =>
-- dominator
let D : {ρ : ℂ // IsNontrivialZero ρ} → ℝ := fun ρ =>
if (2 * n : ℝ) ≤ ‖(ρ : ℂ)‖ then
(9 / 2) * n ^ 2 * (zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf ρ))
else ‖liSummand n ρ‖
have hD : Summable D := by
have hbase : Summable (fun ρ : {ρ : ℂ // IsNontrivialZero ρ} =>
(9 / 2) * n ^ 2 * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf ρ)))) := by
have h := (WeilEF.zero_sum_inv_sq zetaSeam).mul_left ((9 / 2) * (n : ℝ) ^ 2)
-- h : Summable ((9/2)n² • (mult/(1+normSq))) — show forms match
convert h using 2
· ext ρ; ring
...
```
Hmm wait — careful with forms: zero_sum_inv_sq zetaSeam : Summable (fun ρ : (zetaZeros zetaSeam).carrier => (zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf ρ))). The subtype (zetaZeros zetaSeam).carrier — defeq to {ρ // IsNontrivialZero ρ}. `.mul_left c` : Summable (fun ρ => c * (zeroMult ρ / (1+...))) — `Summable.mul_left : Summable f → Summable (fun i => c * f i)`. So h : Summable (fun ρ => ((9/2)*n²) * ((zeroMult ρ:ℝ)/(1+normSq (gammaOf ρ)))). And I want Summable (fun ρ => (9/2)n²·mult/(1+normSq)): same up to assoc/division form: (9/2)*n² * (mult/(1+..)) vs (9/2)*n²*mult/(1+..) — equal by ring (div). And the subtype mismatch: h is over (zetaZeros zetaSeam).carrier, I claim it over {ρ // IsNontrivialZero ρ} — `show` conversion (defeq via zetaZeroConfig_carrier rfl). Actually zero_sum_inv_sq's statement: `Summable (fun ρ : (zetaZeros hs).carrier => (zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf ρ)))`. Is `(zetaZeros zetaSeam).carrier` defeq `{ρ | IsNontrivialZero ρ}`? zetaZeroConfig_carrier : zetaZeroConfig.carrier = {ρ | IsNontrivialZero ρ} := rfl — and zetaZeroConfig := zetaZeros zetaSeam — so (zetaZeros zetaSeam).carrier is DEFEQ {ρ | IsNontrivialZero ρ} ✓. The subtype {x // x ∈ {ρ | IsNontrivialZero ρ}} vs {ρ // IsNontrivialZero ρ}: defeq (Set.mem_setOf) ✓.
So: have hbase : Summable (fun ρ : {ρ : ℂ // IsNontrivialZero ρ} => (9/2)*(n:ℝ)^2 * ((zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf ρ)))) := by
have h := (WeilEF.zero_sum_inv_sq zetaSeam).mul_left ((9 / 2) * (n : ℝ) ^ 2)
exact h -- if defeq works; else convert
Then D = (fun ρ => if 2n ≤ ‖ρ‖ then hbase-family else ‖liSummand n ρ‖):
D = hbase-family + (D − hbase-family), where the difference is supported in the ball {‖ρ‖ < 2n} — finite.
Cleaner: define E := D − hbasefam (pointwise); E ρ = if 2n ≤ ‖ρ‖ then 0 else ‖liSummand n ρ‖ − hbasefam ρ. supp E ⊆ {ρ : ‖ρ‖ < 2n} finite.
D = hbasefam + E: `Summable.add`.
The finite support set: {ρ : {ρ // IsNontrivialZero ρ} | ¬ (2n ≤ ‖(ρ:ℂ)‖)}:
have hfin : {ρ : {ρ // IsNontrivialZero ρ} | ¬ ((2 : ℝ) * n ≤ ‖(ρ : ℂ)‖)}.Finite := by
have hcomp : IsCompact (Metric.closedBall (0 : ℂ) (2 * n)) := isCompact_closedBall _ _
have hsub : (Metric.closedBall (0 : ℂ) (2 * n)) ∩ riemannZetaZeros := hcomp.inter_riemannZetaZeros_finite
-- wait: `IsCompact.inter_riemannZetaZeros_finite (hS : IsCompact S) : (S ∩ riemannZetaZeros).Finite`
have hzeros : (Metric.closedBall (0 : ℂ) (2 * n)) ∩ {ρ | IsNontrivialZero ρ} ⊆
Metric.closedBall (0:ℂ) (2*n) ∩ riemannZetaZeros := by
apply Set.inter_subset_inter_left
intro ρ hρ
exact hρ.1 -- IsNontrivialZero ρ → riemannZeta ρ = 0 → ρ ∈ riemannZetaZeros
have hfin2 : (Metric.closedBall (0 : ℂ) (2 * n)) ∩ {ρ | IsNontrivialZero ρ} :=
(hcomp.inter_riemannZetaZeros_finite).subset hzeros
-- transfer to the subtype-set via coe injection
...
Hmm — riemannZetaZeros : Set ℂ := riemannZeta ⁻¹' {0}. ρ ∈ riemannZetaZeros ⟺ riemannZeta ρ = 0 ✓ (mem_preimage, mem_singleton). IsNontrivialZero ρ := riemannZeta ρ = 0 ∧ 0 < ρ.re ∧ ρ.re < 1 ✓ so .1 gives membership ✓.
Then the set {ρ : subtype | ‖ρ‖ < 2n} = Subtype.val ⁻¹' (ball ∩ {IsNontrivialZero})-ish: the subtype set S' = {ρ : {ρ // IsNontrivialZero ρ} | ‖(ρ:ℂ)‖ < 2n}: its image under Subtype.val is {z : ℂ | IsNontrivialZero z ∧ ‖z‖ < 2n} ⊆ ball ∩ IsNontrivialZero-set — finite. And Subtype.val injective: Set.Finite.of_finite_image:
`Set.Finite.of_finite_image (hf : (f '' s).Finite) (hinj : Set.InjOn f s) : s.Finite` ✓.
So:
have hfin : {ρ : {ρ // IsNontrivialZero ρ} | ¬ ((2 : ℝ) * n ≤ ‖(ρ : ℂ)‖)}.Finite := by
have himg : (Subtype.val '' {ρ : {ρ // IsNontrivialZero ρ} | ¬ ((2:ℝ)*n ≤ ‖(ρ:ℂ)‖)}).Finite := by
apply Set.Finite.subset hfin2
rintro z ⟨ρ, hρ, rfl⟩
-- show z ∈ closedBall ∩ {IsNontrivialZero}
constructor
· -- z ∈ closedBall 0 (2n): ‖z‖ ≤ 2n
simp only [Metric.mem_closedBall, dist_zero_right]
-- dist z 0 = ‖z‖: mem_closedBall: dist z 0 ≤ 2n
have : ‖z‖ < 2 * n := lt_of_not_ge hρ
-- need dist z 0 ≤ 2n: dist = norm
...
· exact ρ.2
exact Set.Finite.of_finite_image himg (fun _ _ _ _ h => Subtype.ext h)
Hmm — Set.InjOn of Subtype.val: Subtype.val_injective.injOn — `Subtype.val_injective : Function.Injective Subtype.val` ✓ .injOn.
dist_zero_right : dist z 0 = ‖z‖ ✓ (dist_zero_right (z) : dist z 0 = ‖z‖).
Support: Function.support E ⊆ that set: E ρ ≠ 0 ⟹ ¬(2n ≤ ‖ρ‖): by construction E ρ = if 2n ≤ ‖ρ‖ then (fam − fam) else (‖liSummand‖ − fam): define E directly as D − fam: supp(D − fam) ⊆ {¬(2n ≤ ‖ρ‖)}: for ρ with 2n ≤ ‖ρ‖: D ρ = fam ρ ⟹ (D − fam) ρ = 0 ✓.
Then:
have hE : Summable E := summable_of_finite_support hsuppfin
have hD : Summable D := by
have : D = fun ρ => hbasefam ρ + E ρ := by funext ρ; simp [E, D]; split <;> ring
rw [this]
exact hbase.add hE
Hmm — cleaner: hD via `hbase.add hE` and show D ρ = hbasefam ρ + E ρ by funext + split + ring.
And finally:
refine Summable.of_norm_bounded hD (fun ρ => ?_)
-- ‖liSummand n ρ‖ ≤ D ρ
by_cases hρ : (2 : ℝ) * n ≤ ‖(ρ : ℂ)‖
· -- main bound
rw [liSummand_eq n ρ]
have hbound : ‖liSummand n ρ‖ ≤ (9/2)*n^2*(zeroMult ρ : ℝ)/(1 + normSq (gammaOf ρ)) := ...
simp only [D, hρ, if_pos hρ] -- D ρ = the if-true branch
...
· simp [D, hρ] -- else branch: D ρ = ‖liSummand n ρ‖, le_refl
The main bound: ‖(zeroMult : ℂ)·((f.re : ℂ))‖ = (zeroMult : ℝ)·|f.re| (mult ≥ 0: norm_num cast: ‖(m : ℂ)‖ = m for m : ℕ — `Complex.norm_natCast`? ‖(n : ℂ)‖ = n — exists as `Complex.norm_natCast (n : ℕ) : ‖(n : ℂ)‖ = n` or `norm_natCast` generic (RCLike.norm_natCast). Then:
≤ (zeroMult : ℝ) · (2n²/‖ρ‖²) [re_li_summand_le with hzre from IsNontrivialZero: 0 < re, re < 1 — need 0 ≤ re and re ≤ 1: from hρ2 : ρ.2 : IsNontrivialZero ρ: hρ2.2.1.le and hρ2.2.2.le]
≤ (zeroMult : ℝ) · (2n² · (9/4)/(1+‖γ‖²)) [normSq_gammaOf_le: mult/‖ρ‖² ≤ mult·(9/4)/(1+‖γ‖²) ⟺ mult·(1+‖γ‖²)·... careful: mult/‖ρ‖² ≤ (9/4)·mult/(1+‖γ‖²) ⟺ mult·(1+‖γ‖²) ≤ (9/4)·mult·‖ρ‖² ⟸ (1+‖γ‖²) ≤ (9/4)‖ρ‖² ✓ (mult ≥ 0)]
= (9/2)·n²·mult/(1+‖γ‖²) ✓.
Let me write these steps as an explicit calc with the div manipulations via div_le_iff₀ and friends. To keep it manageable, I'll write a helper lemma:
lemma liSummand_norm_le {n : ℕ} (hn : 1 ≤ n) (ρ : {ρ // IsNontrivialZero ρ})
(hρ : (2 : ℝ) * n ≤ ‖(ρ : ℂ)‖) :
‖liSummand n ρ‖ ≤ (9 / 2) * n ^ 2 * (zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf ρ)) := by
rw [liSummand_eq n ρ]
have hz := ρ.2 -- IsNontrivialZero (ρ:ℂ)
have hre0 : 0 ≤ (ρ : ℂ).re := hz.2.1.le
have hre1 : (ρ : ℂ).re ≤ 1 := hz.2.2.le
have hcore := re_li_summand_le hn hre0 hre1 hρ -- |(f).re| ≤ 2n²/‖ρ‖²
have hcomp := normSq_gammaOf_le_mul_norm_sq hn hre0 hre1 hρ -- 1+‖γ‖² ≤ (9/4)‖ρ‖²
-- norm of the complex product
have hnorm : ‖(zeroMult ρ : ℂ) * (((1 - (1 - 1 / (ρ:ℂ)) ^ n).re) : ℂ)‖
= (zeroMult ρ : ℝ) * |(1 - (1 - 1 / (ρ:ℂ)) ^ n).re| := by
rw [norm_mul]
congr 1
· exact RCLike.norm_natCast (K := ℂ) (zeroMult ρ) -- hmm name; check: RCLike.norm_natCast?
· exact RCLike.norm_ofReal ((1 - (1 - 1 / (ρ:ℂ)) ^ n).re) -- RCLike.norm_ofReal? or Complex.norm_ofReal
rw [hnorm]
-- chain: mult·|re| ≤ mult·2n²/‖ρ‖² ≤ (9/2)n²·mult/(1+‖γ‖²)
...
```
Norm names: `RCLike.norm_natCast (n : ℕ) : ‖(n : K)‖ = n` — exists? There's `Complex.norm_natCast`? In Mathlib: `RCLike.norm_natCast (n : ℕ) : ‖(n : 𝕜)‖ = n` ✓ I believe. And ofReal: `RCLike.norm_ofReal (r : ℝ) : ‖(r : 𝕜)‖ = |r|` ✓ exists. Also `Complex.norm_ofReal`? RCLike version should work for ℂ.
The chain mult·|re| ≤ (9/2)n²·mult/(1+‖γ‖²):
mult·|re| ≤ mult·(2n²/‖ρ‖²) (mul_le_mul_of_nonneg_left hcore (Nat.cast_nonneg _))
and 2n²·mult/‖ρ‖² ≤ (9/2)n²·mult/(1+‖γ‖²):
⟺ 2·mult/‖ρ‖² ≤ (9/2)·mult/(1+‖γ‖²) (divide n²>0)
⟸ 2·mult·(1+‖γ‖²) ≤ (9/2)·mult·‖ρ‖² (cross-multiply, both sides pos)
⟸ 2·(1+‖γ‖²) ≤ (9/2)·‖ρ‖² (divide mult ≥ 0 — careful mult could be... zeroMult ≥ 1 for zeros! (ZetaSeam.one_le_mult_holds : 1 ≤ zeroMult ρ for IsNontrivialZero) ✓ but we just need ≥ 0 for the mul, and if mult = 0 everything is 0 ✓ — so just nlinarith with mult ≥ 0)
follows from hcomp : 1+‖γ‖² ≤ (9/4)‖ρ‖²: 2·(1+‖γ‖²) ≤ 2·(9/4)‖ρ‖² = (9/2)‖ρ‖² ✓.
Write via div_le_iff₀ + nlinarith, or explicit cross-multiplication. I'll do:
```
have hn2 : (0 : ℝ) < n ^ 2 := by positivity
have hz0' : (0 : ℝ) < ‖(ρ : ℂ)‖ ^ 2 := by positivity -- needs ‖ρ‖ ≠ 0: from 2n ≤ ‖ρ‖ and n ≥ 1: ‖ρ‖ ≥ 2 > 0
have hg0 : (0 : ℝ) < 1 + Complex.normSq (gammaOf (ρ : ℂ)) := by
have : 0 ≤ Complex.normSq (gammaOf (ρ : ℂ)) := Complex.normSq_nonneg _
linarith
have key : (zeroMult ρ : ℝ) * (2 * n ^ 2 / ‖(ρ : ℂ)‖ ^ 2)
≤ (9 / 2) * n ^ 2 * (zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ))) := by
rw [div_le_iff₀ hz0''] -- hmm direction: A ≤ B/C... let me use le_div_iff₀
...
```
Let me set it up as: goal2 : (zeroMult:ℝ) * (2*n²/‖ρ‖²) ≤ (9/2)*n²*mult/(1+‖γ‖²).
Use le_div_iff₀ : a ≤ b / c ↔ a * c ≤ b (hc : 0 < c): with a = mult·(2n²/‖ρ‖²), c = 1+‖γ‖², b = (9/2)n²·mult:
goal: mult·(2n²/‖ρ‖²)·(1+‖γ‖²) ≤ (9/2)n²·mult.
Then: mult·(2n²/‖ρ‖²)·(1+‖γ‖²) ≤ mult·(2n²/‖ρ‖²)·(9/4‖ρ‖²) = (9/2)n²·mult: via mul_le_mul_of_nonneg_left (mul_le_mul_of_nonneg_left ... ) — nlinarith might handle given hcomp and nonneg facts. I'll write:
```
rw [le_div_iff₀ hg0]
have hbound : (zeroMult ρ : ℝ) * (2 * n ^ 2 / ‖(ρ : ℂ)‖ ^ 2) * (1 + Complex.normSq (gammaOf (ρ : ℂ)))
≤ (zeroMult ρ : ℝ) * (2 * n ^ 2 / ‖(ρ : ℂ)‖ ^ 2) * ((9 / 4) * ‖(ρ : ℂ)‖ ^ 2) := by
apply mul_le_mul_of_nonneg_left hcomp (by positivity)
calc (zeroMult ρ : ℝ) * (2 * n ^ 2 / ‖(ρ : ℂ)‖ ^ 2) * (1 + Complex.normSq (gammaOf (ρ : ℂ)))
≤ (zeroMult ρ : ℝ) * (2 * n ^ 2 / ‖(ρ : ℂ)‖ ^ 2) * ((9 / 4) * ‖(ρ : ℂ)‖ ^ 2) := hbound
_ = (9 / 2) * n ^ 2 * (zeroMult ρ : ℝ) := by field_simp; ring
```
le_div_iff₀ signature check: `le_div_iff₀ (hc : 0 < c) : a ≤ b / c ↔ a * c ≤ b` ✓ (dual of div_le_iff₀). Let me grep to confirm both names. Actually from the earlier grep: `div_le_iff₀ (hc : 0 < c) : b / c ≤ a ↔ b ≤ a * c` at GroupWithZero/Basic.lean:1138 ✓. le_div_iff₀ should be nearby — likely exists.
Wait — hcomp : 1 + normSq ≤ (9/4)·‖ρ‖² but mul_le_mul_of_nonneg_left expects b ≤ c: hcomp's LHS 1+normSq, RHS (9/4)‖ρ‖² ✓ b := 1+normSq, c := (9/4)‖ρ‖², a := mult·(2n²/‖ρ‖²) ✓.
And the final calc target after le_div_iff₀: a*c ≤ b: a = mult·(2n²/‖ρ‖²), c = 1+‖γ‖², b = (9/2)n²·mult ✓ matches.
`Complex.normSq_nonneg` — check: normSq_nonneg (z) : 0 ≤ normSq z ✓ exists I believe.
Also `hz0''` for field_simp at the end — field_simp handles ‖ρ‖² ≠ 0 — need ‖ρ‖ ≠ 0: (‖ρ‖ ≥ 2n ≥ 2 > 0): have hz0' : ‖(ρ:ℂ)‖ ≠ 0 := ne_of_gt (by ... : 0 < ‖ρ‖): have hpos : 0 < ‖(ρ:ℂ)‖ := by have := hρ; ... : 0 < 2n ≤ ‖ρ‖: exact lt_of_lt_of_le (by positivity : (0:ℝ) < 2*n) hρ. positivity proves 0 < 2*(n:ℝ)? 2*n with n : ℕ cast, hn : 1 ≤ n — positivity needs to know n > 0 — from hn in context: `by positivity` might not find it; use `by have : (0:ℝ) < n := by exact_mod_cast hn; positivity`. OK.
Then the last assembly:
```
calc (zeroMult ρ : ℝ) * |(1 - (1 - 1 / (ρ:ℂ)) ^ n).re|
≤ (zeroMult ρ : ℝ) * (2 * n ^ 2 / ‖(ρ : ℂ)‖ ^ 2) :=
mul_le_mul_of_nonneg_left hcore (Nat.cast_nonneg _)
_ ≤ (9 / 2) * n ^ 2 * (zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf (ρ : ℂ))) := key
```
Now — normSq_gammaOf_le_mul_norm_sq: need WeilEF.gammaOf_re / gammaOf_im — they're in namespace Zeta23.WeilEF: `WeilEF.gammaOf_re (ρ : ℂ) : (gammaOf ρ).re = ρ.im` ✓ (from ZeroSummability.lean, public lemmas in Zeta23.WeilEF namespace). With open Zeta23, use WeilEF.gammaOf_re.
Complex.normSq_apply : normSq z = z.re * z.re + z.im * z.im ✓.
For the comparison lemma, final nlinarith:
```
lemma normSq_gammaOf_le_mul_norm_sq {n : ℕ} (hn : 1 ≤ n) {z : ℂ}
(hzre0 : 0 ≤ z.re) (hzre1 : z.re ≤ 1) (hz : 2 * n ≤ ‖z‖) :
1 + Complex.normSq (gammaOf z) ≤ 9 / 4 * ‖z‖ ^ 2 := by
have hn0 : (0 : ℝ) < n := by exact_mod_cast hn
have hz2 : ‖z‖ ^ 2 = z.re ^ 2 + z.im ^ 2 := by
rw [← Complex.normSq_eq_norm_sq, Complex.normSq_apply]
ring
have hz4 : 4 * n ^ 2 ≤ ‖z‖ ^ 2 := by
have h := pow_le_pow_left₀ (by positivity : (0:ℝ) ≤ 2 * n) hz 2
ring_nf at h ⊢
exact h
have hre2 : z.re ^ 2 ≤ 1 := by nlinarith [hzre0, hzre1]
have him : 1 ≤ z.im ^ 2 := by nlinarith [hz2, hz4, hre2, hn0]
have hgam : Complex.normSq (gammaOf z) = z.im ^ 2 + (1 / 2 - z.re) ^ 2 := by
rw [Complex.normSq_apply, WeilEF.gammaOf_re, WeilEF.gammaOf_im]
ring
rw [hgam, hz2]
nlinarith [hzre0, hzre1, him, hre2]
```
Wait — the goal after rw [hgam, hz2]: 1 + (im² + (1/2−re)²) ≤ 9/4·(re²+im²): with (1/2−re)² ≤ 1/4 (from re ∈ [0,1] via nlinarith) and 1 ≤ im²: nlinarith [hzre0, hzre1, him, hre2] — need it to derive: LHS = 1+im²+(1/2−re)² and RHS = (9/4)(re²+im²): since re² ≥ 0: RHS ≥ (9/4)im²; LHS ≤ 1 + im² + 1/4 = 5/4 + im²; 5/4+im² ≤ (9/4)im² ⟺ 5/4 ≤ 5/4 im² ⟺ 1 ≤ im² ✓. nlinarith should manage with him and the square nonneg + (1/2−re)² ≤ 1/4 derived from hzre0/hzre1 (nlinarith can do: (1/2−re)² ≤ 1/4 needs expansion — nlinarith with hints [sq_nonneg (1/2 − z.re), hzre0, hzre1] ✓). Let me give nlinarith more hints: nlinarith [hzre0, hzre1, him, hre2, sq_nonneg (1 / 2 - z.re), sq_nonneg z.re].
hz4 : 4n² ≤ ‖z‖²: pow_le_pow_left₀ (0 ≤ 2n) hz 2 gives (2n)² ≤ ‖z‖²: (2n)² = 4n²: ring_nf at h ⊢ — h : (2n)² ≤ ‖z‖² — ring_nf converts (2*n)^2 → 4*n^2 ✓.
Hmm, wait: `pow_le_pow_left₀ (ha : 0 ≤ a) (hab : a ≤ b) (n : ℕ) : a^n ≤ b^n` — hz : 2*n ≤ ‖z‖ with 2*n as ℝ: 2*(n:ℝ) or (2*n : ℝ)? The hypothesis hz : 2 * n ≤ ‖z‖ — with n : ℕ, this elaborates as ↑(2*n)? or 2*↑n? In my statements I've been writing `2 * n ≤ ‖z‖` and Lean elaborated `2 * ↑n ≤ ‖z‖` (from the error displays: hz : 2 * ↑n ≤ ‖z‖ ✓). Good.
One more piece — the main summability theorem. Let me also double check `Summable.of_norm_bounded` exists with that exact name. And `summable_of_finite_support`, `Set.Finite.of_finite_image`, `isCompact_closedBall`, `IsCompact.inter_riemannZetaZeros_finite` (from agent: exists in ZetaZeros.lean ✓), `dist_zero_right`, `Subtype.val_injective`.
`Summable.of_norm_bounded`: grep it. Let me write the code and check names as I go. Actually — one more check on names before the big write: Summable.of_norm_bounded, summable_of_finite_support, Set.Finite.of_finite_image.
Core estimates compile. Let me verify the remaining API names for the summability assembly.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem Summable.of_norm_bounded\\|lemma Summable.of_norm_bounded\" Mathlib/ --include=*.lean | head -2; grep -rn \"theorem summable_of_finite_support\\|lemma summable_of_finite_support\" Mathlib/ --include=*.lean | head -2; grep -rn \"theorem Set.Finite.of_finite_image\\|lemma Set.Finite.of_finite_image\" Mathlib/ --include=*.lean | head -2; grep -rn \"norm_natCast\\|norm_ofReal\" Mathlib/Analysis/RCLike/Basic.lean | head -4",
"description": "Verify summability assembly API names"
}
thinking (4252 chars)
The additive version: `summable_of_hasFiniteSupport (h : HasFiniteSupport f) : Summable f` — but note the `[L.HasSupport]` constraint in the multipliable version... it's about summability to a value L? Hmm — actually `summable_of_hasFiniteSupport` requires the target to have a `HasSupport` instance? Looking at Weierstrass usage: `summable_of_hasFiniteSupport ((Set.finite_singleton l₀).subset (by simp))` — takes a Set.Finite proof of support-containment. `HasFiniteSupport f` is a structure: `(Set.finite (Function.support f))`-wrapper? `Function.HasFiniteSupport f := (Function.support f).Finite`. The lemma signature: `summable_of_hasFiniteSupport (h : HasFiniteSupport f) : Summable f` probably (with the [L.HasSupport] for the L-valued version — the deprecated alias suggests the plain version exists).
Simpler alternative — avoid finite-support entirely: use `Summable.of_norm_bounded` with the dominator D' = fam + (finite-support modification)... The cleanest alternative: `Summable.of_norm_bounded` where D covers ALL points with the if-then-else; prove `Summable D` via: D = fam + E with E finite support — still needs finite-support summability. Alternative standard trick: `summable_of_norm_bounded'`...
Actually simplest: avoid the issue by making the dominator the SUM of the always-valid bound: for points with ‖ρ‖ < 2n, bound ‖liSummand n ρ‖ by a CONSTANT C(n) valid on the whole subtype (if such exists — does ‖liSummand‖ have a uniform bound on ALL zeros? ‖liSummand n ρ‖ = mult·|Re f(ρ)| and |Re f| ≤ |f| ≤ 1 + |1−1/ρ|ⁿ: for small ρ (e.g. ρ → 0?) — no: nontrivial zeros have |ρ| ≥ ... hmm, zeros with tiny |ρ|? The strip zeros: the smallest |γ| is 14.134 — but proving a lower bound on the first zero in Lean requires the numerical zero-free result (not available). HOWEVER: ρ.re ∈ (0,1) and ρ.im = γ with NO lower bound available... wait — actually is there a cheap bound? |1−1/ρ| with ρ = σ+iγ: |1/ρ| = 1/|ρ|: for γ → 0 with σ ∈ (0,1): |ρ| could be small ONLY IF there were zeros near the real axis — those don't exist (ζ(x) < 0 for x ∈ (0,1) real — the eta argument) — but PROVING that is work. However — we don't need a uniform bound on ALL zeros: the dominator on the finite ball can use per-point values ‖liSummand n ρ‖ (that's what the if-then-else does) — the finite-support issue is intrinsic. So use summable_of_hasFiniteSupport with the finite ball set. `Function.HasFiniteSupport f` — the structure: `def Function.HasFiniteSupport (f : α → β) : Prop := (Function.support f).Finite`? And `summable_of_hasFiniteSupport` — from the deprecated alias line: `summable_of_finite_support := summable_of_hasFiniteSupport` ✓ so `summable_of_hasFiniteSupport` exists and takes the finite-support proof. The Weierstrass usage `summable_of_hasFiniteSupport ((Set.finite_singleton l₀).subset (by simp))` — takes `Set.Finite.subset` proof — so the argument is `(h : (Function.support f).Finite)` or a HasFiniteSupport wrapper — `.subset` produces Set.Finite — so the argument is a Set.Finite proof of something. Good enough: I'll construct `Function.HasFiniteSupport E` via its definition `(Function.support E).Finite`.
Let me check HasFiniteSupport def quickly... I'll just write `(Function.support E).Finite` and use it — if the lemma wants the wrapper, it's defeq.
Also `Set.Finite.of_finite_image` ✓ exists.
Now write the final block. Also remember the deprecated alias note: the non-deprecated name is `summable_of_hasFiniteSupport`.
One more consideration for `hbase`: `(WeilEF.zero_sum_inv_sq zetaSeam).mul_left ((9/2)*(n:ℝ)^2)` — `.mul_left` on Summable: `Summable.mul_left (a : α) (hf : Summable f) : Summable (fun i => a * f i)` — signature order: `Summable.mul_left (a) (hf)` or `hf.mul_left a`? As dot notation `hf.mul_left a` ✓ standard.
And the hbase family form: (9/2)n² * (mult/(1+normSq)) — matches D's if-branch `(9/2)*n^2*(zeroMult ρ : ℝ)/(1+normSq...)` — I wrote D's branch as `(9 / 2) * n ^ 2 * (zeroMult ρ : ℝ) / (1 + Complex.normSq (gammaOf ρ))` — elaborates as ((9/2)*n²*mult)/(1+normSq) vs hbase's (9/2)n²*(mult/(1+normSq)) — equal by ring (div_eq_mul_inv, mul assoc). In the funext for D = fam + E I'll handle with field_simp/ring.
Let me now write the whole final block and append to Scratch.lean.
All API names confirmed. Appending the summability assembly to Scratch.
tool: Bash
input
{
"command": "cat >> /d/Python/Quantum/research/lean/NguyenRH1/Scratch.lean << 'EOF'\n\n/-! ### The comparison 1 + \u2016\u03b3_\u03c1\u2016\u00b2 \u2264 (9/4)\u2016\u03c1\u2016\u00b2 and the dominator -/\n\n/-- For re z \u2208 [0,1] and 2n \u2264 \u2016z\u2016 (n \u2265 1): 1 + \u2016\u03b3_z\u2016\u00b2 \u2264 (9/4)\u00b7\u2016z\u2016\u00b2. -/\nlemma normSq_gammaOf_le_mul_norm_sq {n : \u2115} (hn : 1 \u2264 n) {z : \u2102}\n (hzre0 : 0 \u2264 z.re) (hzre1 : z.re \u2264 1) (hz : 2 * n \u2264 \u2016z\u2016) :\n 1 + Complex.normSq (gammaOf z) \u2264 9 / 4 * \u2016z\u2016 ^ 2 := by\n have hn0 : (0 : \u211d) < n := by exact_mod_cast hn\n have hz2 : \u2016z\u2016 ^ 2 = z.re ^ 2 + z.im ^ 2 := by\n rw [\u2190 Complex.normSq_eq_norm_sq, Complex.normSq_apply]\n ring\n have hz4 : 4 * n ^ 2 \u2264 \u2016z\u2016 ^ 2 := by\n have h := pow_le_pow_left\u2080 (by positivity : (0:\u211d) \u2264 2 * n) hz 2\n nlinarith [h]\n have hre2 : z.re ^ 2 \u2264 1 := by nlinarith [hzre0, hzre1]\n have him : 1 \u2264 z.im ^ 2 := by nlinarith [hz2, hz4, hre2]\n have hgam : Complex.normSq (gammaOf z) = z.im ^ 2 + (1 / 2 - z.re) ^ 2 := by\n rw [Complex.normSq_apply, WeilEF.gammaOf_re, WeilEF.gammaOf_im]\n ring\n rw [hgam, hz2]\n nlinarith [hzre0, hzre1, him, sq_nonneg (1 / 2 - z.re), sq_nonneg z.re]\n\n/-- Norm of the paired summand: mult\u00b7|Re f(\u03c1)|. -/\nlemma liSummand_norm (n : \u2115) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1}) :\n \u2016liSummand n \u03c1\u2016 = (zeroMult \u03c1 : \u211d) * |(1 - (1 - 1 / (\u03c1 : \u2102)) ^ n).re| := by\n rw [liSummand_eq n \u03c1, norm_mul, RCLike.norm_natCast, RCLike.norm_ofReal]\n\n/-- The main bound: for 2n \u2264 \u2016\u03c1\u2016, \u2016liSummand n \u03c1\u2016 \u2264 (9/2)n\u00b2\u00b7mult/(1+\u2016\u03b3_\u03c1\u2016\u00b2). -/\nlemma liSummand_norm_le {n : \u2115} (hn : 1 \u2264 n) (\u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1})\n (h\u03c1 : (2 : \u211d) * n \u2264 \u2016(\u03c1 : \u2102)\u2016) :\n \u2016liSummand n \u03c1\u2016 \u2264\n (9 / 2) * n ^ 2 * (zeroMult \u03c1 : \u211d) / (1 + Complex.normSq (gammaOf (\u03c1 : \u2102))) := by\n have hz := \u03c1.2\n have hre0 : 0 \u2264 (\u03c1 : \u2102).re := hz.2.1.le\n have hre1 : (\u03c1 : \u2102).re \u2264 1 := hz.2.2.le\n have hcore := re_li_summand_le hn hre0 hre1 h\u03c1\n have hcomp := normSq_gammaOf_le_mul_norm_sq hn hre0 hre1 h\u03c1\n have hnpos : (0 : \u211d) < n := by exact_mod_cast hn\n have hz0 : (0 : \u211d) < \u2016(\u03c1 : \u2102)\u2016 := lt_of_lt_of_le (by positivity) h\u03c1\n have hg0 : (0 : \u211d) < 1 + Complex.normSq (gammaOf (\u03c1 : \u2102)) := by\n have h := Complex.normSq_nonneg (gammaOf (\u03c1 : \u2102))\n linarith\n have key : (zeroMult \u03c1 : \u211d) * (2 * n ^ 2 / \u2016(\u03c1 : \u2102)\u2016 ^ 2)\n \u2264 (9 / 2) * n ^ 2 * (zeroMult \u03c1 : \u211d) / (1 + Complex.normSq (gammaOf (\u03c1 : \u2102))) := by\n rw [le_div_iff\u2080 hg0]\n have hbound : (zeroMult \u03c1 : \u211d) * (2 * n ^ 2 / \u2016(\u03c1 : \u2102)\u2016 ^ 2) *\n (1 + Complex.normSq (gammaOf (\u03c1 : \u2102)))\n \u2264 (zeroMult \u03c1 : \u211d) * (2 * n ^ 2 / \u2016(\u03c1 : \u2102)\u2016 ^ 2) * ((9 / 4) * \u2016(\u03c1 : \u2102)\u2016 ^ 2) :=\n mul_le_mul_of_nonneg_left hcomp (by positivity)\n exact hbound.trans (by field_simp; ring)\n rw [liSummand_norm]\n exact (mul_le_mul_of_nonneg_left hcore (Nat.cast_nonneg _)).trans key\n\n/-- The paired Li summand is absolutely summable over the nontrivial zeros.\nUses Zeta23's `WeilEF.zero_sum_inv_sq` (\u03a3 mult/(1+\u2016\u03b3_\u03c1\u2016\u00b2) < \u221e, proved) via\nthe tail bound of `liSummand_norm_le`; the ball {\u2016\u03c1\u2016 < 2n} contributes a\nfinite set (Mathlib `IsCompact.inter_riemannZetaZeros_finite`). -/\ntheorem liSummable (n : \u2115) : Summable (liSummand n) := by\n rcases Nat.eq_zero_or_pos n with h0 | hn\n \u00b7 subst h0\n have h : liSummand 0 = fun _ => (0 : \u2102) := by\n funext \u03c1\n simp [liSummand]\n rw [h]\n exact summable_zero\n \u00b7 -- the base summable family (Zeta23, proved)\n have hbase : Summable (fun \u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1} =>\n (9 / 2) * (n : \u211d) ^ 2 * ((zeroMult \u03c1 : \u211d) / (1 + Complex.normSq (gammaOf \u03c1)))) := by\n have h := (WeilEF.zero_sum_inv_sq zetaSeam).mul_left ((9 / 2) * (n : \u211d) ^ 2)\n exact h\n -- the dominator\n set D : {\u03c1 : \u2102 // IsNontrivialZero \u03c1} \u2192 \u211d := fun \u03c1 =>\n if (2 : \u211d) * n \u2264 \u2016(\u03c1 : \u2102)\u2016 then\n (9 / 2) * n ^ 2 * (zeroMult \u03c1 : \u211d) / (1 + Complex.normSq (gammaOf \u03c1))\n else \u2016liSummand n \u03c1\u2016 with hDdef\n -- the correction E = D \u2212 base has finite support\n have hfin : {\u03c1 : {\u03c1 // IsNontrivialZero \u03c1} | \u00ac ((2 : \u211d) * n \u2264 \u2016(\u03c1 : \u2102)\u2016)}.Finite := by\n have hcomp : IsCompact (Metric.closedBall (0 : \u2102) (2 * n)) :=\n isCompact_closedBall _ _\n have hzeros : (Metric.closedBall (0 : \u2102) (2 * n)) \u2229 {\u03c1 : \u2102 | IsNontrivialZero \u03c1}\n \u2286 (Metric.closedBall (0 : \u2102) (2 * n)) \u2229 riemannZetaZeros := by\n intro z hz\n exact \u27e8hz.1, hz.2.1\u27e9\n have hfin2 := (hcomp.inter_riemannZetaZeros_finite).subset hzeros\n have himg : (Subtype.val '' {\u03c1 : {\u03c1 // IsNontrivialZero \u03c1} |\n \u00ac ((2 : \u211d) * n \u2264 \u2016(\u03c1 : \u2102)\u2016)}).Finite := by\n apply hfin2.subset\n rintro z \u27e8\u03c1, h\u03c1, rfl\u27e9\n refine \u27e8?_, \u03c1.2\u27e9\n simp only [Metric.mem_closedBall, dist_zero_right]\n exact le_of_lt (lt_of_not_ge h\u03c1)\n exact Set.Finite.of_finite_image himg (Subtype.val_injective.injOn)\n have hE : Summable (fun \u03c1 : {\u03c1 // IsNontrivialZero \u03c1} =>\n D \u03c1 - (9 / 2) * (n : \u211d) ^ 2 * ((zeroMult \u03c1 : \u211d) /\n (1 + Complex.normSq (gammaOf \u03c1)))) := by\n apply summable_of_hasFiniteSupport\n apply hfin.subset\n intro \u03c1 h\u03c1\n simp only [Function.mem_support, ne_eq] at h\u03c1\n by_contra hball\n apply h\u03c1\n have hball' : (2 : \u211d) * n \u2264 \u2016(\u03c1 : \u2102)\u2016 := not_not.mp hball\n simp only [D, if_pos hball', sub_self]\n have hD : Summable D := by\n have hsum := hbase.add hE\n have heq : (fun \u03c1 : {\u03c1 : \u2102 // IsNontrivialZero \u03c1} =>\n (9 / 2) * (n : \u211d) ^ 2 * ((zeroMult \u03c1 : \u211d) / (1 + Complex.normSq (gammaOf \u03c1))) +\n (D \u03c1 - (9 / 2) * (n : \u211d) ^ 2 * ((zeroMult \u03c1 : \u211d) /\n (1 + Complex.normSq (gammaOf \u03c1))))) = D := by\n funext \u03c1\n ring\n rw [heq] at hsum\n exact hsum\n refine Summable.of_norm_bounded hD (fun \u03c1 => ?_)\n by_cases h\u03c1 : (2 : \u211d) * n \u2264 \u2016(\u03c1 : \u2102)\u2016\n \u00b7 simp only [D, if_pos h\u03c1]\n exact liSummand_norm_le hn \u03c1 h\u03c1\n \u00b7 simp only [D, if_neg h\u03c1, le_refl]\nEOF\ncd /d/Python/Quantum/research/lean/NguyenRH1 && export PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean Scratch.lean 2>&1 | head -40",
"description": "Append summability assembly and check",
"timeout": 420000
}
thinking (1085 chars)
Two issues:
1. Line 211: `him : 1 ≤ z.im ^ 2 := by nlinarith [hz2, hz4, hre2]` — failed. From hz2: ‖z‖² = re² + im², hz4: 4n² ≤ ‖z‖², hre2: re² ≤ 1: want 1 ≤ im²: im² = ‖z‖² − re² ≥ 4n² − 1 ≥ 3 (n ≥ 1: 4n² ≥ 4). nlinarith needs hn0 used: include hn0: nlinarith [hz2, hz4, hre2, hn0, sq_nonneg n?]. 4n² ≥ 4 from n ≥ 1: nlinarith should get it with hn0. Add hint.
2. The heredoc appended AFTER `end NguyenRH1` — the new lemmas are outside the namespace! liSummand/liSummand_eq/re_li_summand_le are inside namespace NguyenRH1 (which ended before my append). Fix: remove the stray `end NguyenRH1` before the appended section, or wrap. Looking at the file: the original file ended with `end NguyenRH1` and I appended after it. The new section has its own `/-! ### -/` comment then lemmas referencing liSummand (in NguyenRH1 namespace) — unknown. Fix: change the final `end NguyenRH1` position — I'll edit: remove the `end NguyenRH1` line that precedes the appended part (it's right after the re_li_summand_le's end, before the comparison section). Let me check the file structure and fix.
The heredoc landed outside the namespace and one nlinarith needs a hint. Fixing both.
tool: Bash
input
{
"command": "grep -n \"end NguyenRH1\" /d/Python/Quantum/research/lean/NguyenRH1/Scratch.lean",
"description": "Locate namespace end lines"
}
thinking (1493 chars)
The whole Scratch.lean compiles clean! All of ii′-1a's mathematical content is proved:
- `liSummand`, `summand_conj`, `liSummand_eq`
- `pow_one_add_inv_two_mul_le`
- `re_li_summand_le`
- `normSq_gammaOf_le_mul_norm_sq`
- `liSummand_norm`, `liSummand_norm_le`
- `liSummable` (the main theorem)
Now: merge into LiSkeleton.lean (replace liCoeff def + add these lemmas), rebuild the package, run the axiom audit.
For the merge:
1. Replace the `liCoeff` def (LiSkeleton.lean:34-41) with the new def + keep the name `liCoeff`:
```lean
def liCoeff (n : ℕ) : ℂ := ∑' ρ : {ρ : ℂ // IsNontrivialZero ρ}, liSummand n ρ
```
2. Insert the liSummand machinery before it.
3. Where to put the lemmas: §1 of LiSkeleton.lean. Note LiSkeleton imports `Mathlib` and `Zeta23.Statement` — my Scratch imports `Zeta23.WeilEF.ZeroSummability` and `Zeta23.Statement.SeamClosed`. LiSkeleton.lean needs the WeilEF.ZeroSummability import added (for zero_sum_inv_sq) and SeamClosed (for zetaSeam/zetaZeroConfig). Check current imports: line 23-24: `import Mathlib`, `import Zeta23.Statement`. Add the two.
Wait — does importing Zeta23.WeilEF.ZeroSummability add much build time? It's already built (the library is compiled) — just import.
4. Update the liCoeff docstring (honesty note → the pairing explanation + liSummable pointer).
Also update the file header comment (session-015 note about ii′-1a).
Let me do the merge now. First view the exact lines to replace in LiSkeleton.lean (lines 32–55 I have). Then edit.
Scratch.lean is fully green — all of ii′-1a's mathematics is proved. Merging into LiSkeleton.lean now.
tool: Edit
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiSkeleton.lean",
"old_string": "import Mathlib\nimport Zeta23.Statement",
"new_string": "import Mathlib\nimport Zeta23.Statement\nimport Zeta23.WeilEF.ZeroSummability\nimport Zeta23.Statement.SeamClosed"
}
thinking (291 chars)
Full package builds green (8741 jobs) — LiSkeleton, LiBasePoints, and the top-level module all compile with the new liCoeff. The only sorries are the 5 intended skeletons (Valley + Suzuki).
Now the axiom audit: check the new declarations + the main theorems show only the 3 standard axioms.
Full build green (8741 jobs). Now the axiom audit.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && export PATH=\"$HOME/.elan/bin:$PATH\" && cat > PrintAxioms.lean << 'EOF'\n/- Session 015 axiom audit: ii\u2032-1a new declarations + main theorems. -/\nimport Mathlib\nimport NguyenRH1\n\nopen NguyenRH1\n\n#print axioms liSummable\n#print axioms liSummand_norm_le\n#print axioms re_li_summand_le\n#print axioms normSq_gammaOf_le_mul_norm_sq\n#print axioms liSummand_eq\n#print axioms liSummand_norm\n#print axioms pow_one_add_inv_two_mul_le\n#print axioms lambda_pos_finite_height\n#print axioms lambda_pos_finite_height_verified\n#print axioms sInfty_lower_bound\n#print axioms marginTilde_convex\nEOF\nlake env lean PrintAxioms.lean 2>&1 | head -15",
"description": "Run axiom audit on new and main declarations",
"timeout": 300000
}
thinking (744 chars)
All clean — 3 standard axioms only, including the two main theorems. ii′-1a is complete.
Now let me also do a quick sanity check that the old `liCoeff` users still typecheck semantically — they compiled, so yes. One more meaningful check: `Sf`/`SfBoundProp`/`LiVerifiedUpTo` now refer to the corrected liCoeff — no changes needed (they use liCoeff abstractly).
Session closure:
1. Update D-064 (mark ii′-1a complete).
2. Journal session-015.
3. STATE.md update (next action: ii′-1b).
4. NGUYEN.md checklist (check off ii′-1a + session log).
5. db registration (session 15).
6. Commit.
Let me also record the effort: the proof took ~13 iterations; final code ~340 lines in LiSkeleton.lean §1 (new). Let me do the closure updates efficiently.
All axioms clean — 3 standard only, including both main theorems. **ii′-1a COMPLETE.** Closing the session.
tool: TodoWrite ok
input
{
"todos": [
{
"content": "Check zetaZeros carrier def + zeroMult/gammaOf coercion paths",
"status": "completed",
"activeForm": "Checking zetaZeros defs"
},
{
"content": "Develop summability proof in Scratch.lean (pair bound + comparison)",
"status": "completed",
"activeForm": "Developing summability proof"
},
{
"content": "Replace liCoeff def in LiSkeleton.lean + prove liSummable",
"status": "completed",
"activeForm": "Replacing liCoeff def"
},
{
"content": "Full rebuild + axiom audit (LiSkeleton/LiBasePoints unchanged downstream)",
"status": "completed",
"activeForm": "Rebuilding + auditing"
},
{
"content": "Session-015 closure (journal, STATE, NGUYEN checkoff, commit)",
"status": "in_progress",
"activeForm": "Closing session 015"
}
]
}
result 2026-08-21 20:07:07Z → 2026-08-21 20:07:07Z
{
"oldTodos": [
"content='Check zetaZeros carrier def + zeroMult/gammaOf coercion paths' status='in_progress' active_form='Checking zetaZeros defs'",
"content='Develop summability proof in Scratch.lean (pair bound + comparison)' status='pending' active_form='Developing summability proof'",
"content='Replace liCoeff def in LiSkeleton.lean + prove liCoeff_summable' status='pending' active_form='Replacing liCoeff def'",
"content='Full rebuild + axiom audit (LiSkeleton/LiBasePoints unchanged downstream)' status='pending' active_form='Rebuilding + auditing'",
"content='Session-015 closure (journal, STATE, NGUYEN checkoff, commit)' status='pending' active_form='Closing session 015'"
],
"newTodos": [
"content='Check zetaZeros carrier def + zeroMult/gammaOf coercion paths' status='completed' active_form='Checking zetaZeros defs'",
"content='Develop summability proof in Scratch.lean (pair bound + comparison)' status='completed' active_form='Developing summability proof'",
"content='Replace liCoeff def in LiSkeleton.lean + prove liSummable' status='completed' active_form='Replacing liCoeff def'",
"content='Full rebuild + axiom audit (LiSkeleton/LiBasePoints unchanged downstream)' status='completed' active_form='Rebuilding + auditing'",
"content='Session-015 closure (journal, STATE, NGUYEN checkoff, commit)' status='in_progress' active_form='Closing session 015'"
],
"cleared": false
}
Done. Summary of this session's work:
## Documentation (per your request)
- **NGUYEN.md §5: new "PHASE 5B — TIER ii′" checklist** — 9 items (ii′-0 through ii′-7) with freeze protocol, perimeter, and discovery summaries; also session logs for 014/015 (committed 7a395b2).
- D-064 design doc, journal entries, STATE.md resume point, research.db — all current.
## Session 015 — ii′-1a COMPLETE: the liCoeff defect is repaired
- **Replaced** the defective unordered-tsum `liCoeff` with the classical **paired symmetric form** `liSummand = ½·mult·(f ρ + f ρ̄)` — manifestly real, and the mathematically correct Keiper–Li summand.
- **Proved `liSummable`** (~340 new lines in LiSkeleton.lean §1): the geometric-sum tail bound `|Re f(ρ)| ≤ 2n²/‖ρ‖²`, the `(9/4)·‖ρ‖²` comparison, the `(9/2)n²·mult/(1+‖γ‖²)` dominator built on Zeta23's *proved* `zero_sum_inv_sq`, plus the finite-ball argument for small zeros.
- **Full rebuild green** (8741 jobs) with **zero downstream changes** — and now `LiVerifiedUpTo`/`SfBoundProp` are *true* statements instead of vacuous ones.
- **Axiom audit clean**: 3 standard axioms only, on all new declarations and both main theorems.
Committed as be1ffb2. **Next (session 016): ii′-1b — the residue machinery** (finite-order residue, rectangle theorem extension beyond simple poles, the w=1 Leibniz residue, zero residues). Ready when you are.
Sorry I walk out but on telegram now, if you have updates please provide me completely.
thinking (464 chars)
The user says they walked out and are on Telegram now, asking for complete updates. They want a full status update — presumably everything since they stepped away, which covers the rest of session 015 (ii′-1a completion). Let me give a complete, self-contained update they can read on their phone: what was done, what's the state, what's next. Keep it complete but readable — not too long, but covering everything important. No new work requested, just the update.
Complete update — everything is committed and the project is in a clean, resumable state. Here's where things stand:
## What was completed today (sessions 014 + 015)
**Session 014 — tier ii′ designed, with two major discoveries:**
1. **Found a real encoding defect in the Lean work** (this is what your audit question uncovered): `liCoeff` was defined as an *unordered* infinite sum that is provably **not absolutely summable** (terms decay like n/|γ|, and Σ 1/|ρ| over the zeros diverges). In Lean, that sum silently evaluates to 0 — so the two hypotheses `LiVerifiedUpTo` and `SfBoundProp` were actually **false as encoded**, making the session-012 theorems vacuous. The mathematics in Paper A was always fine; this was purely a Lean encoding bug that the session-013 audit couldn't see (it checks axioms, not whether hypotheses are true).
2. **The crux identity turned out simpler than feared**: S_f(n) = S_∞(n) + 1 − λ_n equals the w=1 residue Σⱼ C(n,j)c_{j−1} **exactly** (from Lagarias's (4.10), verified numerically against E-015's certified values). This makes the whole assembly **tail-free**: |S_f| ≤ |λ_n(T)| + |contour sides| + |trivial term| = B(n). The scariest sub-task from the old plan dissolves into two bounded pieces.
3. **D-064 design doc written**: full route decisions R1–R5, lemma dependency graph, sub-stage map ii′-1a…7 (est. 9–16 sessions), feasibility confirmed (rectangle residue theorem already vendored and axiom-clean; Borel–Carathéodory/Jensen/digamma all present).
**Session 015 — first sub-stage executed and closed:**
- **NGUYEN.md got the "PHASE 5B" checklist** you asked for (ii′-0…ii′-7 with freeze protocol), committed.
- **ii′-1a COMPLETE**: the defect is fixed. `liCoeff` now uses the classical paired symmetric sum (½·mult·(f ρ + f ρ̄)), which is manifestly real and — the hard part — **provably absolutely summable** in Lean (~340 new lines of proofs: the tail bound |Re f(ρ)| ≤ 2n²/‖ρ‖², comparison with Zeta23's already-proved Σ mult/(1+‖γ‖²) < ∞, plus a finite-ball argument for small zeros).
- **Full package rebuild green** (8741 jobs) with **zero downstream changes needed** — and now the two hypotheses are *true* statements instead of vacuous ones.
- **Axiom audit clean**: only the 3 standard axioms everywhere, including both main theorems.
## Safety state (your standing requirement)
Paper A is **untouched and submission-ready at this exact moment** (freeze protocol in force: no edits to paperA/paperB/draft/references until the final sub-stage ii′-7). Every sub-stage ends committed and resumable. If we change course at any point, nothing has moved — and in fact the submission is now *stronger* because the formal claims are no longer vacuous.
## What's next
- **Session 016 = sub-stage ii′-1b** (1–2 sessions): the residue machinery — general finite-order residue, rectangle residue theorem extended beyond simple poles, the w=1 residue by the Leibniz identity (verified algebraically in session 014), residues at zeros.
- Then: ii′-2 (elementary binomial swaps), ii′-3 (the (4.10) Laurent relation — the long pole, 2–4 sessions), ii′-4, ii′-5 (R-bound), ii′-6 (assembly), ii′-7 (closure + audit + paper Appendix B update).
Everything is committed: session 014 = e56cb66, checklist = 7a395b2, session 015 = be1ffb2. Say the word and I'll start ii′-1b.
Let’s go
thinking (19991 chars)
The user says "Let's go" — start session 016: ii′-1b (R1 residue machinery). Let me plan this sub-stage carefully.
Per D-064 R1:
1. **General finite-order residue** (`gresidue`): for a meromorphic f at p with order −m (m ≥ 1), residue = the coefficient of (z−p)^{-1} in the Laurent expansion = the (m−1)-th Taylor coefficient of the NF analytic part divided by (m−1)!.
2. **Rectangle residue theorem extension**: beyond HasSimplePolesOn — principal-part decomposition; j ≥ 2 terms vanish by global primitive; j = 1 via the vendored simple-pole theorem.
3. **Residue computations**: zeros via vendored `logDerivResidue`, w=1 by the Leibniz identity.
Let me think about the cleanest path.
### Design of gresidue
Given `MeromorphicAt f p` with `meromorphicOrderAt f p = -(m : ℤ)` (m : ℕ, m ≥ 1), by `meromorphicOrderAt_eq_int_iff` (exists in Mathlib, confirmed by agent):
```
meromorphicOrderAt f p = (n : ℤ) ↔ ∃ g, AnalyticAt 𝕜 g p ∧ g p ≠ 0 ∧ ∀ᶠ z in 𝓝[≠] p, f z = (z - p) ^ n • g z
```
So f = (z−p)^{-m} · g near p with g analytic, g(p) ≠ 0. The residue (coefficient of (z−p)^{-1}) = the (m−1)-th Taylor coefficient of g at p = `g.iteratedDeriv (m-1) p / (m-1)!`... Actually for analytic g: g(z) = Σ a_k (z−p)^k with a_k = iteratedDeriv k g p / k!. The residue is a_{m-1} = iteratedDeriv (m−1) g p / (m−1)!.
But rather than defining gresidue via a choice of g, better to define it DIRECTLY:
`gresidue f p := lim_{z→p} d^{m-1}/dz^{m-1} [(z−p)^m f z] / (m−1)!` — the standard higher-order residue formula. In Lean:
```
noncomputable def gresidue (f : ℂ → ℂ) (p : ℂ) (m : ℕ) : ℂ :=
iteratedDeriv (m - 1) (fun z => (z - p) ^ m * f z) p / (m - 1)!
```
Hmm — but (z−p)^m f z has a removable singularity when f has a pole of order ≤ m. The iterated derivative AT p requires the function to be defined (and sufficiently smooth) at p. The function h(z) = (z−p)^m f(z) is defined only off p (f undefined/unbounded at p)... in Lean, f p is some value (f is total). Actually in our application, f is a total function ℂ → ℂ (e.g., k_n(w−1)·(−ζ′/ζ) — defined everywhere except where ζ′/ζ blows up; at poles it's whatever the definitional unfolding gives — riemannZeta is total). The cleanest: define gresidue relative to the meromorphic order:
Alternative cleaner definition (limit-free, derivative-free): use the meromorphic normal form directly. Mathlib has `MeromorphicAt` and `MeromorphicNFAt` with `toMeromorphicNFAt f p : ℂ → ℂ` which equals (z−p)^n • g with g analytic nonvanishing. The residue of order −1 coefficient: for the NF, residue = iteratedDeriv (m−1) g p / (m−1)! where g = (z−p)^m • toMeromorphicNFAt f p ... hmm.
Actually — maybe simplest for OUR purposes: we don't need a fully general residue theory. We need:
(a) Rectangle residue theorem for our SPECIFIC integrand J(w) = k_n(w−1)(−ζ′/ζ(w)) with poles at: zeros (simple), w=1 (order n+1), trivial zero −2 (simple).
(b) The residue VALUES at those points.
Pragmatic approach: prove a **"rectangle with one higher-order pole plus simple poles"** theorem directly:
- Split J as J = J_simple_part + J_principal where J_principal = the principal part at w=1: Σ_{j=1}^{n} C(n,j) · c-stuff/(w−1)^{j+1}?? — hmm, the principal part at w=1 of J: J = k_n(w−1)·(−ζ′/ζ) = [Σ_{j=1}^n C(n,j)(w−1)^{-j}]·[u^{-1} + c_0 + c_1 u + ...] — the principal part is Σ over j of C(n,j)(w−1)^{-j}·(negative powers part)... The full principal part at w=1: Σ_{i=1}^{n+1} A_i (w−1)^{-i} with A_i = Σ_{j ≥ i−1} C(n,j) c_{j−i+...} — explicit but messy.
Cleaner decomposition: J(w) = [k_n(w−1)·(−ζ′/ζ(w)) − Σ_{j=1}^n C(n,j) c_{j−1}/(w−1)] − hmm no.
Standard trick: J(w) = P(w) + R(w) where P(w) = Σ_{i=1}^{n+1} A_i (w−1)^{-i} is the principal part at w=1 (a finite RATIONAL function with pole only at w=1), and R(w) = J(w) − P(w) is holomorphic at w=1 (removable) with only SIMPLE poles elsewhere (the zeros + trivial zeros). Then:
- ∮ J = ∮ P + ∮ R.
- ∮ P = 2πi·A_1 = 2πi·Res₁(n) (each term A_i/(w−1)^i for i ≥ 2 integrates to 0 on the rectangle — has the global primitive −A_i/((i−1)(w−1)^{i−1}), single-valued meromorphic, so the rectangle integral vanishes by the boundary-telescoping/FTC; A_1/(w−1) gives 2πi A_1 by the vendored `ResidueTheoremInRectangle`).
- ∮ R = 2πi·Σ residues at simple poles (zeros + trivial zero) via the vendored simple-pole rectangle theorem (R has only simple poles inside!).
The residue A_1 of J at w=1 = Res₁(n) = Σ_j C(n,j)c_{j−1} — computed by the Leibniz rule from h(w) = (w−1)(−ζ′/ζ(w)) analytic at 1 (h(1) = 1): (w−1)^{n+1}J(w) = [wⁿ − (w−1)ⁿ]h(w), and A_1 = (1/n!)(d/dw)^n[(w−1)^{n+1}J]_{w=1} = Σ_j C(n,j) h^{(j)}(1)/j! − 1... wait I did this computation in session 014: Res = (1/n!)(d/dw)ⁿ{[wⁿ−(w−1)ⁿ]h(w)}|₁ = Σ_{j=0}^n C(n,j)c_{j−1}·... = Σ_{j=1}^n C(n,j)c_{j−1} (the j=0 term cancels with the −1 from the (w−1)ⁿ part). Verified algebraically.
So the residue computation at w=1 needs: h analytic at 1 with h(1) = 1, h^{(j)}(1)/j! = c_{j−1} (the Laurent coefficients of −ζ′/ζ), and the Leibniz formula (iteratedDeriv of a product — `iteratedDeriv_mul`? — Mathlib has `iteratedDeriv_mul` for... there's `iteratedDeriv_mul` for ℂ-valued functions? There should be (iteratedDeriv within a field/algebra). Or use `iteratedDeriv_eq_iff` / `HasFPowerSeriesAt` machinery: h analytic at 1 ⟹ h has a power series; multiplication by polynomials and coefficient extraction via `HasFPowerSeriesAt` operations — the coefficients API: `HasFPowerSeriesAt.coeff`? There's `HasFPowerSeriesAt.eq_iteratedDeriv`? or `HasFPowerSeriesAt.iteratedDeriv`... The power-series route: (wⁿ−(w−1)ⁿ)h(w) = [Σ_k h_k (w−1)^k]·[wⁿ−(w−1)ⁿ], and its n-th derivative at 1: via Leibniz on the two factors: (wⁿ−(w−1)ⁿ) vanishes to order 1 at w=1 with first derivative n... Let me redo: F(w) = [wⁿ − (w−1)ⁿ]·h(w). F^{(n)}(1) = Σ_{j=0}^n C(n,j) [wⁿ−(w−1)ⁿ]^{(j)}(1) · h^{(n−j)}(1). [wⁿ−(w−1)ⁿ]^{(j)} at 1: for j = 0: 1−0 = 1. For j ≥ 1: (n!)_j·w^{n−j}|₁ − (n!)_j·(w−1)^{n−j}|₁ = (n!)_j − (n!)_j·(0 or n!·1 if j=n) = (n!)_j for j < n; for j = n: n! − n! = 0. So F^{(n)}(1) = Σ_{j=0}^{n−1} C(n,j)·(n!)_j·h^{(n−j)}(1) + 0 = Σ_{j=0}^{n−1} n!/(n−j)!·C(n,j)·h^{(n−j)}(1). Then Res = F^{(n)}(1)/n! = Σ_{j=0}^{n−1} C(n,j)·h^{(n−j)}(1)/(n−j)!. With i = n−j: Σ_{i=1}^{n} C(n,i)·h^{(i)}(1)/i! = Σ_{i=1}^n C(n,i)·c_{i−1} ✓ (h^{(i)}(1)/i! = c_{i−1} since h(w) = 1 + Σ_{k≥1} c_{k−1}(w−1)^k).
Hmm wait — this differs from my session-014 computation by a term: earlier I got Res = Σ_{j=1}^n C(n,j)c_{j−1} with the j=0 term = 1 canceling a −1 from the (w−1)ⁿ part. Here the j=0 term is C(n,0)·h^{(n)}(1)/n! = h^{(n)}(1)/n! = c_{n−1}, included in Σ_{i=1}^n with i = n: C(n,n)·c_{n−1} ✓ same thing — the (w−1)ⁿ part contributed 0 (its n-th derivative at 1 is n! — wait: (w−1)ⁿ's n-th derivative is n! constant, so [wⁿ−(w−1)ⁿ]^{(n)}|₁ = n! − n! = 0 ✓ but the LEIBNIZ sum is over j = derivative order on the first factor; j = n gives 0 — but the FULL n-th derivative of the product is F^{(n)} = Σ_j C(n,j) A^{(j)} h^{(n−j)} with A = wⁿ−(w−1)ⁿ — A(1) = 1, A^{(j)}(1) = (n!)_j for 1 ≤ j ≤ n−1, A^{(n)}(1) = 0. So F^{(n)}(1) = A(1)h^{(n)}(1) + Σ_{j=1}^{n−1} C(n,j)(n!)_j h^{(n−j)}(1) + 0 = h^{(n)}(1) + Σ_{j=1}^{n−1} ... = Σ_{j=0}^{n−1} C(n,j)(n!)_j h^{(n−j)}(1) (j=0 term: h^{(n)}(1) ✓ included). Dividing by n!: Σ_{j=0}^{n−1} C(n,j) h^{(n−j)}(1)/(n−j)! = Σ_{i=1}^n C(n,i) h^{(i)}(1)/i! = Σ_{i=1}^n C(n,i) c_{i−1} ✓✓ consistent with session 014's result (where the "−1" canceled the j=0's c_{−1} = 1... in session 014 I wrote Res = Σ_{i=0}^n C(n,i)c_{i−1} − 1 = Σ_{i=1}^n C(n,i)c_{i−1} + (c_{−1} − 1) = Σ_{i=1}^n C(n,i)c_{i−1} since c_{−1} = 1 ✓ SAME).
So the w=1 residue = Res₁(n) = Σ_{i=1}^n C(n,i)·c_{i−1} — and its Lean proof needs:
- h(w) := (w−1)·(−ζ′/ζ(w)) — analytic at 1, h(1) = 1. From Mathlib `riemannZeta_residue_one` (Tendsto (s−1)·ζ(s) → 1) — for −ζ′/ζ: the vendored `riemannZetaLogDerivResidue` (−ζ′/ζ − 1/(s−1) bounded near 1) or `logDerivResidue` — h(w) = (w−1)(−ζ′/ζ) → 1 ✓, and analyticity at 1 of h: −ζ′/ζ = 1/(w−1) + analytic (the pole is simple with residue 1 — provable from riemannZetaResidue/logDerivResidue + MeromorphicAt API: h = (w−1)·(−ζ′/ζ) has order ≥ 0 at 1 and value 1).
- The iterated derivative identity: F(w) = [wⁿ − (w−1)ⁿ]·h(w), F^{(n)}(1) = Σ_j C(n,j) A^{(j)}(1) h^{(n−j)}(1) — Leibniz for iteratedDeriv: `iteratedDeriv_mul`?? For scalar-valued ℂ functions — hmm, `iteratedDeriv_mul (hf : ContDiffAt ℂ n f x) (hg : ContDiffAt ℂ n g x) : iteratedDeriv n (f * g) x = Σ i ∈ antidiagonal n, (n.choose i) • (iteratedDeriv i f x * iteratedDeriv (n−i) g x)`? — there IS `iteratedDeriv_mul`? I'm not 100% sure of the name; there's `iteratedDeriv_smul`, and for products: `iteratedDeriv_mul` exists I believe (for functions into a normed algebra). ℂ is a normed algebra over ℂ? — iteratedDeriv is for functions 𝕜 → F; product in F = ℂ (algebra over itself) ✓ should exist.
- c_{j−1} identification: h^{(i)}(1)/i! = c_{i−1} — where c_k are DEFINED as the Laurent coefficients of −ζ′/ζ at 1. Best: DEFINE c_k := iteratedDeriv (k+1) h 1 / (k+1)! — then h^{(i)}(1)/i! = c_{i−1} by definition. And separately prove −ζ′/ζ(1+u) = 1/u + Σ c_k u^k (as a power series near 0) when needed. For the residue computation, the definition via h is cleaner and avoids the Laurent-series formalization entirely!
So define: `lcoeff (k : ℕ) : ℂ := (iteratedDeriv (k + 1) (fun w => (w - 1) * (-deriv riemannZeta w / riemannZeta w)) 1) / (k + 1)!`? Hmm wait — but the RESIDUE at the w=1 needs the value (1/n!)F^{(n)}(1) where F = (wⁿ−(w−1)ⁿ)h. And the residue theorem needs A_1 = that value. Let me define:
`ResW1 (n : ℕ) : ℂ := (iteratedDeriv n (fun w => (w^n - (w-1)^n) * h w) 1) / n!`
and prove `ResW1 n = Σ_{i=1}^n C(n,i)·lcoeff(i−1)` via Leibniz.
Hmm, but actually — for the RECTANGLE theorem with the principal-part split, I need:
- J = P + R with P(w) = Σ_{i=1}^{n+1} A_i (w−1)^{-i}: the A_i are the full principal part coefficients — for the residue theorem I need A_1 = ResW1 n. Rather than computing the FULL principal part, use a slicker split:
J(w) = [ResW1 n / (w−1)] + R₂(w), where R₂ = J − ResW1/(w−1) — is R₂ holomorphic at 1? No! J has a pole of order n+1; subtracting only the (w−1)^{-1} term leaves a pole of order n at 1. Doesn't work. So the principal part must be subtracted in full:
P(w) = Σ_{i=1}^{n+1} A_i/(w−1)^i with A_i = (1/(n+1−i)!)·(d/dw)^{n+1−i}[(w−1)^{n+1}J(w)]|₁... The i-th principal coefficient. Then R = J − P is holomorphic at 1 (all negative powers removed), and R has only simple poles (at zeros/trivial zeros) inside the rectangle. ∮ P = 2πi A_1 by the primitive argument.
The A_i's explicit form: with F := (w−1)^{n+1}J = [wⁿ−(w−1)ⁿ]h analytic: A_i = F^{(n+1−i)}(1)/(n+1−i)!. And A_1 = F^{(n)}(1)/n! = ResW1 ✓ consistent.
So P(w) = Σ_{i=1}^{n+1} [F^{(n+1−i)}(1)/(n+1−i)!]·(w−1)^{−i}.
For the residue theorem: ∮ P = 2πi·A_1: P = A_1/(w−1) + Σ_{i=2}^{n+1} A_i (w−1)^{−i}; the second sum has the global primitive G(w) = −Σ_{i=2}^{n+1} A_i/((i−1)(w−1)^{i−1}) — meromorphic, G' = the sum — so its rectangle integral is 0 (FTC/telescoping around the boundary — in Lean: `HolomorphicOn.vanishesOnRectangle` exists in the vendored Rectangle.lean? The agent reported `HolomorphicOn.vanishesOnRectangle [CompleteSpace E]` — a holomorphic function with a primitive? Let me check what that theorem says: "theorem HolomorphicOn.vanishesOnRectangle" — probably: if f is holomorphic on the rectangle then its rectangle integral is 0?? That can't be true without more hypotheses (1/(z−p) is holomorphic off p...). It's likely "if f has a primitive on the rectangle" — need to read it. Alternatively: the rectangle integral of G' = 0 because the boundary is a closed loop and G is single-valued — the standard proof: each side integral telescopes (FTC on segments: ∫_segment G' = G(endpoint) − G(startpoint), summing around = 0). In Lean: HIntegral/VIntegral of a derivative — the vendored file may have such lemmas. This is a known bounded computation.
Alternatively, avoid the primitive argument: ∮ P directly by the "pull to small square" lemma: `RectanglePullToNhdOfPole''` (vendored!): RectangleIntegral' f z w = RectangleIntegral' f (small square around p) eventually. Then on the small square, compute ∮ P: A_1/(w−1) via `ResidueTheoremInRectangle` (vendored: RectangleIntegral' (fun s => c/(s−p)) z w = c ✓), and the i ≥ 2 terms integrate to 0 on the small square (primitive exists on the square minus... on the small square, G is meromorphic with pole at center; G' on the boundary: the boundary integral of G' around the square = 0 by FTC on each side — same primitive argument but localized to a square of any size, so the boundary avoids the pole (pull-to-square keeps the boundary off p since the square is a neighborhood of p — wait, p is INSIDE the square; the boundary doesn't touch p ✓). FTC on each side segment: ∫_{segment} G'(s)ds = G(end) − G(start) — Mathlib has `intervalIntegral.integral_deriv` or for line segments in ℂ... the vendored Rectangle.lean has HIntegral/VIntegral as interval integrals; FTC: `intervalIntegral.integral_deriv_eq_sub` for real intervals with G differentiable — should work for the parametrized sides (HIntegral f x₁ x₂ y = ∫_x f(x+iy) dx — with f = G', the integral = G(x₂+iy) − G(x₁+iy) by FTC if G is differentiable on the segment ✓ pole-free there). This is mechanical but fiddly. Bounded.
So the rectangle theorem I actually need:
**THEOREM (RectResidue-J)**: For the specific integrand J(w) = k_n(w−1)·(−ζ′/ζ(w)) and rectangle R_T (σ ∈ [−5/2, 2√n], Im ±T, T zero-avoiding):
RectangleIntegral' J (corner1) (corner2) = Σ_{ρ zeros inside} mult·[1−(ρ/(ρ−1))ⁿ] + [1−(2/3)ⁿ] + ResW1 n.
Proof structure:
1. P := principal part at 1 (explicit finite sum); J = P + R, R holomorphic at 1 with simple poles only (at the zeros inside + the trivial zero −2; note: need R's poles EXACTLY at those points — J's poles are at zeros of ζ (all nontrivial inside + trivial −2) and w=1; subtracting P removes w=1 ✓).
2. ∮ R via the vendored simple-pole rectangle theorem (R satisfies HasSimplePolesOn inside) — residues: at each zero ρ: k_n(ρ−1)·(−mult) = mult·[1−(ρ/(ρ−1))ⁿ] via `logDerivResidue`-family + `ResidueMult` (vendored) — the residue of J at ρ: J = k_n(w−1)·(−ζ′/ζ), −ζ′/ζ has residue −mult at ρ (simple pole after R? no — −ζ′/ζ has a pole of order = zero multiplicity at ρ — WAIT: for MULTIPLE zeros (mult > 1), −ζ′/ζ has a SIMPLE pole with residue −mult (log derivative: order of pole is always 1, residue = multiplicity) ✓ so J's poles at zeros are simple regardless of zero multiplicity ✓ good (logDerivResidue handles: f'/f has simple pole with residue = analyticOrderAt ✓).
3. ∮ P = A_1 = ResW1 n (pull-to-square + primitive-vanishing + ResidueTheoremInRectangle).
4. ResW1 n = Σ_{i=1}^n C(n,i)·lcoeff(i−1) (Leibniz, definition of lcoeff via h).
Also the "poles finite" hypothesis of the vendored theorem: the zeros inside the rectangle are finite (Mathlib compact-finiteness ✓).
And "no poles on boundary": T zero-avoiding (top/bottom); left/right verticals: σ = −5/2 (no zeros — trivial zeros at −2,−4: −2 IS on σ = −5/2?? NO: σ₀ = −5/2 is the real part of the left side; the trivial zero −2 has real part −2 ≠ −5/2 ✓ not on the vertical line; horizontal sides at Im = ±T: the trivial zero −2 is real (im = 0 ≠ ±T ✓); w = 1 (im 0 ✓); zeros: T zero-avoiding ✓; also need no zeros ON the left/right verticals: right vertical σ₁ = 2√n ≥ 20+ — zeros have re < 1 ✓ none; left σ₀ = −5/2: nontrivial zeros have re ∈ (0,1) ✓ none; w=1 inside ✓ (re 1 ∈ (−2.5, 2√n), im 0 ∈ (−T,T) ✓).
Wait — actually also ζ's pole at w = 1: J = k_n(w−1)·(−ζ′/ζ) — I need J to be meromorphic on the rectangle with the stated poles only. ζ zeros in the rectangle: nontrivial ones with |γ| < T (inside, since re ∈ (0,1) ⊂ (−2.5, 2√n)) + trivial zeros with re ∈ (−2.5, 2√n): −2 only (−4 < −2.5; 0? trivial zeros are at −2,−4,−6,... negative even integers — 0 is not a trivial zero ✓). Plus w = 1. That's the full pole set ✓.
This is a coherent plan. Estimated Lean: P-definition + holomorphic-at-1 of R (meromorphic order bookkeeping), the simple-pole rectangle application (residue computations at zeros — the k_n factor: ResidueMult (vendored): if f − A/(s−p) =O 1 and g holo at p, then f·g − A·g(p)/(s−p) =O 1 ✓ directly gives residue = A·g(p) = (−mult)·k_n(ρ−1) ✓), the principal-part integral, the Leibniz residue value. Maybe 400–600 lines. 1–2 sessions per the estimate — plausibly 2 given the fiddly bits.
Let me also reconsider: do we even need the GENERAL gresidue machinery? No — the specific J decomposition approach avoids it. Good — faster.
One more piece to check: `iteratedDeriv_mul` existence and the exact form, plus `iteratedDeriv` of wⁿ and (w−1)ⁿ at 1: `iteratedDeriv n (fun w => w ^ n)` — for ℂ: iteratedDeriv k (w^n) = (n!)_k w^{n−k} (falling factorial) — via `iteratedDeriv_pow`? or compute from deriv_pow repeatedly. And A(w) = wⁿ − (w−1)ⁿ: A^{(j)}(1): via iteratedDeriv of each piece; (w−1)ⁿ's iteratedDeriv at 1: shift lemma — `iteratedDeriv (fun w => (w−1)^n) = (fun w => iteratedDeriv (w^n)) ∘ (· − 1)`... there's `iteratedDeriv_comp_sub`? Hmm — the STATE handoff warned: "HasDerivAt.add_const adds to VALUE (use .comp for precomposition)" — for iteratedDeriv similar subtleties. Bounded work.
Let me now check the key APIs before writing code:
- iteratedDeriv_mul existence/form
- MeromorphicAt.order bookkeeping for R (J − P holomorphic at 1): need meromorphicOrderAt R 1 ≥ 0: R = J − P: order J at 1 = −(n+1)?? — proving J's order at 1 is −(n+1) and P's principal part matches: cleaner to show (w−1)^{n+1}·R = (w−1)^{n+1}J − (w−1)^{n+1}P = F − [its own Taylor polynomial of degree n] — and F minus its degree-n Taylor part vanishes to order n+1 at 1 (remainder of power series — `HasFPowerSeriesAt` remainder lemmas: the (n+1)-fold iterated derivative form — hmm, analytic-removable singularity: F(w) − Σ_{k=0}^n (F^{(k)}(1)/k!)(w−1)^k vanishes to order n+1 at 1 — so R = [F − TaylorPoly_n]/(w−1)^{n+1} has a removable singularity ⟹ analytic at 1 ✓. In Lean: `AnalyticAt.sub_Taylor_poly`? or via the order API: meromorphicOrderAt R 1 ≥ 0 ⟸ (w−1)^{n+1}R analytic with value... The cleanest: use `AnalyticAt.exists_...`... Mathlib: `HasFPowerSeriesAt` has `HasFPowerSeriesAt.exists_...`? There's the concept of `AnalyticAt.eq_sub_...`... Let me look for "order of vanishing" / `analyticOrderAt` API: analyticOrderAt of F − TaylorPoly ≥ n+1 — there might be lemmas about subtracting Taylor polynomials raising the analytic order. `AnalyticAt.order_...`? Alternatively prove R analytic at 1 via the MeromorphicAt order API directly: R = J − P with J meromorphic order −(n+1), P a rational function with the SAME principal part — order(R) ≥ 0 ⟺ principal parts match — provable by computing meromorphicOrderAt of R via the NF forms. Fiddly but standard.
Hmm — actually, maybe cleaner: don't define R = J − P abstractly. Instead define R(w) := J(w) − P(w) and prove `HolomorphicOn R (Rectangle z w \ {poles})` directly + the vendored rectangle theorem's MeromorphicOn hypotheses. The vendored `RectangleIntegral'_eq_sumResiduesIn` needs: MeromorphicOn f (Rectangle), no poles on boundary, poles finite, HasSimplePolesOn. For R: meromorphic everywhere (J meromorphic − P rational), poles only at zeros/trivial (simple) — the holomorphic-at-1 needs the order computation.
OK — I have a clear plan. This sub-stage (ii′-1b) has real meat; let me structure it as:
- ii′-1b(i): the w=1 residue value theorem (ResW1 = Σ C(n,i)·lcoeff(i−1)) — Leibniz + h analyticity. [self-contained]
- ii′-1b(ii): the principal-part integral (∮ P = ResW1).
- ii′-1b(iii): R's holomorphic-at-1 + rectangle residue theorem for J (the full sides identity).
Given session constraints, let me start with (i) — and first check the API landscape for iteratedDeriv products/powers and the MeromorphicAt order API. Let me also check `HolomorphicOn.vanishesOnRectangle` and `ResidueTheoremInRectangle` exact statements (vendored).
Let me start the session: update todos, check APIs.
Session 016 — **sub-stage ii′-1b: R1 residue machinery**. Design decision (refining D-064 R1): instead of a fully general residue theory, use a **principal-part split** for our specific integrand J — J = P + R with P the explicit principal part at w=1 and R having only simple poles — reusing the vendored simple-pole rectangle theorem directly. Bounded and cleaner. Let me verify the needed APIs first.
tool: TodoWrite ok
input
{
"todos": [
{
"content": "Verify APIs: iteratedDeriv_mul/pow, vanishesOnRectangle, ResidueTheoremInRectangle",
"status": "in_progress",
"activeForm": "Verifying residue APIs"
},
{
"content": "ii\u2032-1b(i): w=1 residue value (Leibniz, ResW1 = \u03a3 C(n,i)\u00b7lcoeff(i\u22121))",
"status": "pending",
"activeForm": "Proving w=1 residue value"
},
{
"content": "ii\u2032-1b(ii): principal-part integral \u222e P = ResW1",
"status": "pending",
"activeForm": "Proving principal-part integral"
},
{
"content": "ii\u2032-1b(iii): R holomorphic at 1 + rectangle residue theorem for J",
"status": "pending",
"activeForm": "Proving rectangle residue theorem"
},
{
"content": "Session-016 closure (journal, STATE, commit)",
"status": "pending",
"activeForm": "Closing session 016"
}
]
}
result 2026-08-21 20:45:19Z → 2026-08-21 20:45:19Z
{
"oldTodos": [],
"newTodos": [
"content='Verify APIs: iteratedDeriv_mul/pow, vanishesOnRectangle, ResidueTheoremInRectangle' status='in_progress' active_form='Verifying residue APIs'",
"content='ii\u2032-1b(i): w=1 residue value (Leibniz, ResW1 = \u03a3 C(n,i)\u00b7lcoeff(i\u22121))' status='pending' active_form='Proving w=1 residue value'",
"content='ii\u2032-1b(ii): principal-part integral \u222e P = ResW1' status='pending' active_form='Proving principal-part integral'",
"content='ii\u2032-1b(iii): R holomorphic at 1 + rectangle residue theorem for J' status='pending' active_form='Proving rectangle residue theorem'",
"content='Session-016 closure (journal, STATE, commit)' status='pending' active_form='Closing session 016'"
],
"cleared": false
}
thinking (7982 chars)
All key APIs confirmed:
- `iteratedDeriv_mul` : iteratedDeriv n (f*g) x = Σ_{i ∈ range(n+1)} C(n,i)·iteratedDeriv i f x·iteratedDeriv (n−i) g x (needs ContDiffAt).
- `iteratedDeriv_pow (m k : ℕ) : iteratedDeriv k (· ^ m) x = m.descFactorial k * x ^ (m - k)` — SIMP lemma! For (· ^ m) the identity function power — I'll need it for w ↦ w^n and w ↦ (w−1)^n (the latter via composition/sub).
- `HolomorphicOn.vanishesOnRectangle (f_holo : HolomorphicOn f U) (hU : Rectangle z w ⊆ U) : RectangleIntegral f z w = 0` — holomorphic ⟹ zero integral. For the i ≥ 2 principal terms: A_i/(w−1)^i is NOT holomorphic at 1, so I can't use this directly on the rectangle containing 1 — but I use the pull-to-small-square + primitive-vanishing... hmm, actually for the i ≥ 2 terms: A_i/(w−1)^i has a GLOBAL primitive −A_i/((i−1)(w−1)^{i−1}) meromorphic off {1}. The rectangle integral of G' where G is single-valued: on the boundary (which avoids 1), G is differentiable; FTC per side gives telescoping = 0. Is there a ready lemma "RectangleIntegral of a derivative = 0 when the primitive is differentiable on the rectangle minus an interior point"? The vendored `ResidueTheoremOnRectangleWithSimplePole` machinery handles the simple-pole case. For higher powers, the standard trick: A_i/(w−1)^i = deriv(−A_i/((i−1)(w−1)^{i−1})) — and the rectangle integral of a derivative of a function holomorphic on a NEIGHBORHOOD of the boundary (minus nothing) — boundary avoids 1 ✓. Is there a Mathlib lemma: integral of deriv over a closed loop = 0? `RectangleIntegral` is a sum of interval integrals; each side: ∫ G'(σ + it) dt = G(end) − G(start) by `intervalIntegral.integral_deriv_eq_sub` (needs G' integrable + G differentiable at all points of the interval ✓ boundary avoids 1). Summing the four sides telescopes to 0. This is mechanical but needs care. Alternatively — realize the whole principal part evaluation differently: pull to a small square (RectanglePullToNhdOfPole''), then on the small square compute each term: A_1/(w−1) via ResidueTheoremInRectangle ✓ and A_i/(w−1)^i (i ≥ 2) — STILL needs the primitive-vanishing on the small square.
Alternatively, bypass: prove "RectangleIntegral' (fun s => A/(s−p)^i) z w = 0 for i ≥ 2" via the derivative-primitive argument once, generically. That's a clean standalone lemma:
```
lemma rectInt'_inv_pow_eq_zero {z w p : ℂ} {A : ℂ} {i : ℕ} (hi : 2 ≤ i) (hp : p ∉ RectangleBorder z w) :
RectangleIntegral' (fun s => A / (s - p) ^ i) z w = 0
```
proof: A/(s−p)^i = deriv(G)(s) with G(s) = −A/((i−1)(s−p)^{i−1}); G differentiable on RectangleBorder-neighborhood (p off border ✓); per-side FTC; telescope.
For FTC on segments: HIntegral (G') x₁ x₂ y = ∫_{x₁}^{x₂} G'(x + iy) dx = G(x₂+iy) − G(x₁+iy): `intervalIntegral.integral_deriv_eq_sub (h : ∀ x ∈ [[x₁,x₂]], HasDerivAt G (G' x) x) (h' : IntervalIntegrable G' ...)`. The vendored Rectangle.lean defines HIntegral as the plain interval integral of f(·+iy). So per side this works with the parametrization x ↦ G(x+iy) — chain rule: HasDerivAt (x ↦ G(x+iy)) (G'(x+iy)·1) ✓.
This is all standard machinery — a few hundred lines total for ii′-1b(ii). OK.
Now — one more design consideration for ii′-1b(iii) (the R side): rather than proving R = J − P holomorphic at 1 via order bookkeeping, use `HolomorphicOn` directly: R is holomorphic on Rectangle \ {zeros ∪ {−2}} — at w=1: R = J − P with P the FULL principal part, so R extends holomorphically (removable singularity). The cleanest Lean: show meromorphicOrderAt R 1 ≥ 0 via (w−1)^{n+1}·R = F − TaylorPoly_n(F) vanishing to order n+1 — hmm. Alternative: use the vendored pattern: they define the function with a Function.update at the pole...
Actually — simpler: R(w) := J(w) − P(w) is meromorphic on the rectangle (difference of meromorphic) with poles only at zeros/trivial −2 — because P kills the (n+1)-order pole at 1 EXACTLY. Order bookkeeping: meromorphicOrderAt R 1 = meromorphicOrderAt (J − P) 1 ≥ min(order J, order P) but generically ≥ 0 since the principal parts match. Proving "≥ 0": (w−1)^{n+1}·R = F − Σ_{i=1}^{n+1} A_i (w−1)^{n+1−i} = F − [F^{(0)}(1)(w−1)^{n+1}/0!... wait A_i = F^{(n+1−i)}(1)/(n+1−i)! — so Σ_i A_i (w−1)^{n+1−i} = Σ_{k=0}^n [F^{(k)}(1)/k!]·(w−1)^k (k = n+1−i) — the Taylor polynomial of F of degree n at 1. So (w−1)^{n+1}R = F − Tayl_n F — vanishes to order n+1 at 1 — i.e., analyticOrderAt (F − Tayl_n F) 1 ≥ n+1 ⟹ meromorphicOrderAt R 1 ≥ 0. The Taylor-remainder order fact: for analytic F, F − its degree-n Taylor polynomial at 1 vanishes to order ≥ n+1: provable via `HasFPowerSeriesAt` (F has power series Σ a_k (w−1)^k; F − Tayl_n = Σ_{k≥n+1} a_k (w−1)^k = (w−1)^{n+1}·(Σ_{k≥0} a_{n+1+k}(w−1)^k) — the inner is analytic ✓). Mathlib: `HasFPowerSeriesAt` API — `HasFPowerSeriesAt.exists_...`; there's `AnalyticAt.exists_...`... The `analyticOrderAt` API: `AnalyticAt.analyticOrderAt_eq_...`... This might take some digging but it's standard.
OK — the plan is solid. Let me now check two more API areas quickly: (1) meromorphicOrderAt of R bookkeeping isn't even needed if I can show `HolomorphicOn R (Rectangle \ poles)` differently — hmm, the vendored rectangle theorem needs `MeromorphicOn R (Rectangle)` + `HasSimplePolesOn R (Rectangle)` + poles finite + no boundary poles. MeromorphicOn R: R = J − P: J = k_n(w−1)·(−ζ′/ζ): meromorphic wherever ζ′/ζ is (Mathlib: ζ′/ζ meromorphic? ζ is analytic off 1 (vendored analyticAt_riemannZeta), deriv of analytic is analytic, quotient by nonvanishing analytic... ζ′/ζ meromorphic on ℂ: ζ analytic off {1}; at zeros of ζ, 1/ζ is meromorphic ✓ so ζ′/ζ meromorphic off {1}; at 1, ζ has a simple pole ⟹ ζ′/ζ meromorphic ✓. So J meromorphic on the rectangle ✓; P rational ✓; R meromorphic ✓.
HasSimplePolesOn R (Rectangle): at zeros ρ: order = −1 (logDeriv simple pole regardless of mult ✓); at −2: order −1 ✓; at 1: order ≥ 0 (the order computation above); everywhere else: analytic ✓. So the only real work is the order-at-1 ≥ 0.
(2) The poles-finite: {poles of R in Rectangle} ⊆ {nontrivial zeros in Rectangle} ∪ {−2}: nontrivial zeros in the rectangle are finite (compact ∩ discrete — Mathlib `IsCompact.inter_riemannZetaZeros_finite` — the rectangle is compact ✓ but IsNontrivialZero ⊆ riemannZetaZeros needs re∈(0,1)... the rectangle also contains trivial zeros −2 (and possibly ζ's zero at other points? riemannZetaZeros includes ALL zeros: trivial −2k and nontrivial. In the rectangle [−2.5, 2√n]×[−T,T]: trivial zeros: −2 only; nontrivial: finite ✓; also potential zeros at... ζ(0) = −1/2 ≠ 0 ✓; so riemannZetaZeros ∩ Rectangle = {−2} ∪ {nontrivial} — finite ✓).
Alright — let me now also plan the residue VALUE computation at zeros for R (iii): R = J − P; near a zero ρ (≠ 1), P is analytic, so Res(R, ρ) = Res(J, ρ) = k_n(ρ−1)·(−mult). The vendored rectangle theorem gives ∮ R = Σ Res(R, ρ) via the `residue` placeholder (simple-pole limit): residue R ρ = lim (s−ρ)R(s) = lim (s−ρ)J(s) = k_n(ρ−1)·lim (s−ρ)(−ζ′/ζ(s)) = k_n(ρ−1)·(−zeroMult ρ) — via `logDerivResidue` (vendored: for f with simple pole... actually the vendored logDerivResidue is about f'/f of a function f with a SIMPLE pole; our need: −ζ′/ζ at a ZERO ρ of order m: ζ'/ζ has simple pole with residue +m: the vendored ZetaBounds has... the right lemma: for f analytic near ρ with f(ρ) = 0 and f not locally 0: f'/f − m/(s−ρ) bounded — that's `logDerivResidue`-family? The vendored ones are stated for SIMPLE poles of f (residue A ≠ 0)... Let me check what's available for zeros of higher multiplicity — the analyticOrderAt API: meromorphicOrderAt (f'/f) ρ = −1 and residue = analyticOrderAt f ρ — Mathlib may have `MeromorphicAt.logDeriv_...`? There IS API: `MeromorphicAt.meromorphicOrderAt_logDeriv`? or the trailing-coefficient: `meromorphicTrailingCoeffAt (deriv f / f) x = meromorphicOrderAt f x`? Hmm — Mathlib's TrailingCoefficient.lean: `meromorphicTrailingCoeffAt (logDeriv f) x = meromorphicOrderAt f x` — something like that would give residue = order directly. Let me grep.
All APIs confirmed. One more check — the log-derivative residue at zeros of arbitrary multiplicity.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"logDeriv\" Mathlib/Analysis/Meromorphic/TrailingCoefficient.lean | head -8; grep -rn \"meromorphicTrailingCoeffAt.*logDeriv\\|logDeriv.*meromorphicOrderAt\\|residue.*logDeriv\" Mathlib/Analysis/Meromorphic/*.lean | head -8",
"description": "Check logDeriv trailing coefficient API"
}
thinking (4714 chars)
EXCELLENT discovery — `Zeta23/Analytic/RectangleLogDeriv.lean` has EXACTLY what I need:
1. **`residueTheorem_finset`**: residue theorem for finitely many simple poles with the (f − A/(s−p)) =O 1 boundedness form — this handles arbitrary finite pole sets WITHOUT the HasSimplePolesOn scaffold restrictions, using the explicit principal-part-subtraction induction. This is a more flexible interface than RectangleIntegral'_eq_sumResiduesIn!
2. **`rectangleIntegral'_mul_logDeriv`** (line 352/365): "the argument principle with weight": f, g analytic on neighborhood of each point of Rectangle, f ≠ 0 on the border, Z = finite zero set of f in the rectangle ⟹ RectangleIntegral' (g · f'/f) z w = Σ_{ρ∈Z} ord_ρ(f)·g(ρ).
Hmm — item 2 is CLOSE to what I need but not exactly: my integrand is J = k_n(w−1)·(−ζ′/ζ(w)) = g·(ζ′/ζ) with g = −k_n(w−1) — but g is NOT analytic (pole at w=1!). And ζ is not analytic at w=1 either. So rectangleIntegral'_mul_logDeriv doesn't directly apply because of the w=1 pole. BUT — the split approach: J = g·(−ζ′/ζ) where the only non-analyticity is at w=1 (both from g's pole and ζ's pole).
New idea — instead of the P-split at w=1, use a DIFFERENT contour region that avoids w=1: no — w=1 is inside the rectangle necessarily (it's the whole point).
But wait — maybe adapt: apply `residueTheorem_finset` DIRECTLY to J with the pole set S = {zeros} ∪ {−2} ∪ {1}: needs (J − A p/(s−p)) =O 1 near each p — for simple poles only! At w=1 the pole is order n+1, so (J − A/(s−1)) is NOT bounded. So residueTheorem_finset also needs the simple-pole condition. The P-split is still needed for w=1.
OK here's the refined plan for ii′-1b(iii):
- Split J = P + R where P = principal part at 1 (finite rational sum).
- ∮ P = ResW1 n (pull-to-square + primitive-vanishing for i ≥ 2 + ResidueTheoremInRectangle for i = 1).
- ∮ R via `residueTheorem_finset` with S = {zeros inside} ∪ {−2}: R = J − P is holomorphic on Rectangle \ S (at w=1 removable by the order computation) and (R − A p/(s−p)) =O 1 at each zero p with A p = mult·k_n(ρ−1)·(−1)... need the residue boundedness at each zero: near ρ, J = k_n·(−ζ′/ζ): −ζ′/ζ = mult/(s−ρ)·(−1) + bounded (logDeriv at a zero of order mult: residue −mult for −ζ′/ζ) — the boundedness (J − A/(s−ρ)) =O 1 with A = −mult·k_n(ρ−1): from ζ'/ζ = mult/(s−ρ) + bounded — needs the logDeriv-at-zero lemma in =O form. Does Zeta23 have it? rectangleIntegral'_mul_logDeriv's PROOF must contain it (the argument principle with weight proves exactly Σ ord·g(ρ) for ANALYTIC g). Hmm — its proof internally handles the logDeriv residues. For my R (with g = −k_n(w−1) analytic at ρ ✓ — k_n's pole is at w=1 only), the residue computation is: R = J − P = −k_n·(ζ′/ζ) − P; near ρ: ζ′/ζ = m/(s−ρ) + B(s) with B bounded (needs this lemma!); k_n analytic at ρ (pole only at 1 ✓); P analytic at ρ (pole only at 1 ✓). So R + m·k_n(ρ−1)/(s−ρ) = −k_n·B(s) − k_n·m/(s−ρ)... let me redo: R = −k_n(w−1)·(ζ′/ζ) − P. −ζ′/ζ = −m/(s−ρ) − B. R = −k_n·(m/(s−ρ) + B) − P = −m·k_n(ρ−1)/(s−ρ) − m·(k_n(w−1) − k_n(ρ−1))/(s−ρ) − k_n·B − P. The term (k_n(w−1) − k_n(ρ−1))/(s−ρ) → k_n'(ρ−1) bounded ✓. So R − A/(s−ρ) bounded with A = −m·k_n(ρ−1) = mult·(1 − (ρ/(ρ−1))ⁿ) ✓✓ (k_n(ρ−1) = (1+1/(ρ−1))ⁿ − 1 = (ρ/(ρ−1))ⁿ − 1).
- The logDeriv-at-zero boundedness: ζ′/ζ(s) − m/(s−ρ) bounded near ρ. Available? Check Zeta23 for the argument-principle's internal lemma — rectangleIntegral'_mul_logDeriv_of_poles (line 168) might BE it. Or prove from analyticOrderAt API: ζ = (s−ρ)^m·h with h analytic nonvanishing near ρ (analyticOrderAt_eq_natCast / the NF); ζ′/ζ = m/(s−ρ) + h′/h ✓ direct computation. That's a clean self-contained lemma:
```
lemma logDeriv_eq_order_add_bounded {f : ℂ → ℂ} {p : ℂ} {m : ℕ}
(hf : AnalyticAt ℂ f p) (hm : analyticOrderAt f p = m) (hm0 : m ≠ 0) :
(fun s => deriv f s / f s - (m : ℂ) / (s - p)) =O[𝓝[≠] p] (1 : ℂ → ℂ)
```
Prove via NF: f = (s−p)^m·g, g analytic, g(p) ≠ 0: f' = m(s−p)^{m−1}g + (s−p)^m g': f'/f = m/(s−p) + g'/g; g'/g analytic near p (g(p) ≠ 0) ⟹ bounded ✓. The =O form needs: g'/g is continuous at p ⟹ bounded in a neighborhood ⟹ =O 1 ✓ standard.
Actually — hold on. Maybe `rectangleIntegral'_mul_logDeriv` can be adapted to save ALL of this: my integrand is g·(−ζ′/ζ) = (−k_n(w−1))·(ζ′/ζ) with g := −k_n(w−1) — the theorem needs f, g ANALYTIC on a neighborhood of each rectangle point — f := ζ fails at w=1 (pole), g := −k_n(w−1) fails at w=1 (pole). So no direct application. But if I apply it to a MODIFIED setup... no. The P-split + residueTheorem_finset is the way.
Let me also check `rectangleIntegral'_mul_logDeriv_of_poles` (line 168) — maybe it's EXACTLY the version allowing poles: name suggests "with poles"! Let me read its statement.
`Zeta23/Analytic/RectangleLogDeriv.lean` is a goldmine — `residueTheorem_finset` (flexible finite-pole residue theorem) and possibly a poles-allowing log-deriv version. Let me read the key statements.
tool: Bash
input
{
"command": "sed -n '143,200p' /d/Python/Quantum/zeta-23-lean/Zeta23/Analytic/RectangleLogDeriv.lean",
"description": "Read rectangleIntegral'_mul_logDeriv_of_poles statement"
}
thinking (5379 chars)
`rectangleIntegral'_mul_logDeriv_of_poles` is EXACTLY the tool — the weighted argument principle with poles:
(1/2πi)∮ g·f'/f = Σ_{ρ∈Z} ord_ρ(f)·g(ρ) − Σ_{p∈P} m_p·g(p)
Now — can I use it for my J? My integrand: J(w) = k_n(w−1)·(−ζ′/ζ(w)) = g(w)·(f'/f)(w) with:
- f := ζ (riemannZeta) — analytic on Rectangle \ {1} ✓ (pole at 1, simple: (s−1)·ζ → 1 via `riemannZeta_residue_one` ✓ matches the hpole shape with m(1) = 1, c = 1)
- g := −k_n(w−1) = 1 − (1+1/(w−1))ⁿ — has a POLE at w=1 (order n) — NOT analytic! ✗
So g is not analytic at 1 — direct application fails again. BUT: flip the assignment! Write J differently:
J(w) = k_n(w−1)·(−ζ′/ζ(w)). What if I use f := ζ and g := −k_n? g has a pole at 1. What about f := the COMPLETED zeta Λ (completedRiemannZeta)? Λ has poles at 0 and 1 (simple, residues ∓1 per the comment). Then Λ'/Λ = ζ′/ζ + (1/2)log π + (1/2)ψ(s/2)·... hmm — using Λ changes the integrand: J = k_n·(−Λ'/Λ) + k_n·(Λ'/Λ − ζ′/ζ) — the second part is analytic-ish (digamma is meromorphic with poles at 0, −2, −4... inside the rectangle: 0? ψ(s/2) has poles where s/2 ∈ {0,−1,−2,...} = s ∈ {0,−2,−4,...} — INSIDE the rectangle: 0 and −2! More poles — worse.
OK so the direct argument-principle application needs g analytic — impossible for our kernel. The P-split remains the plan. BUT WAIT — alternative: use rectangleIntegral'_mul_logDeriv_of_poles on a DIFFERENT contour that EXCLUDES w=1? No — w=1 must be inside.
Alternative clever split: J = g·(f'/f) with f = ζ, g = −k_n. Apply the poles-version with pole set P = {1} where BOTH f's pole and g's pole live... the theorem requires g analytic everywhere — no.
So: P-split + residueTheorem_finset (for R = J − P, poles = zeros ∪ {−2}) + principal-part integral. OR: another angle — apply residueTheorem_finset DIRECTLY to J with S = zeros ∪ {−2} ∪ {1}?? — no, w=1 pole isn't simple.
OR — cleanest hybrid: apply `residueTheorem_finset` to J with S = zeros ∪ {−2} ∪ {1} after proving (J − A p/(s−p)) =O 1 at each p — at w=1 this fails (pole order n+1). So P-split it is.
Hmm — actually, one more idea that avoids the explicit P: apply `rectangleIntegral'_mul_logDeriv_of_poles` with f := ζ and g := −k_n, but first MODIFY: J·(w−1)^N?? no.
Or: view J as g·(f'/f) where f = (w−1)·... no: f'/f's poles are at zeros+1 with residues = orders; J = k_n(w−1)·(−ζ′/ζ) — take f = ζ, and accept g meromorphic: the theorem's proof structure (residueTheorem_finset induction) would extend to meromorphic g with poles at P... the residue at w=1 of g·(f'/f): g has pole order n, f'/f has residue −1 at 1: product has pole order n+1 with residue = Res₁(n) — the SAME computation. There's no escaping computing Res₁(n) — but we already have it reduced to the Leibniz rule (ii′-1b(i)).
FINAL PLAN for ii′-1b(iii):
1. P(w) := Σ_{i=1}^{n+1} A_i/(w−1)^i, A_i = F^{(n+1−i)}(1)/(n+1−i)!, F(w) = (wⁿ−(w−1)ⁿ)·h(w), h(w) = (w−1)(−ζ′/ζ(w)).
2. ∮ P = A_1 (pull-to-square; i ≥ 2 terms vanish by primitive; i = 1 by ResidueTheoremInRectangle) and A_1 = ResW1 n = Σ_{i=1}^n C(n,i)·lcoeff(i−1) [ii′-1b(i)].
3. R := J − P: holomorphic on Rectangle \ (zeros ∪ {−2}) [order ≥ 0 at 1 by Taylor-remainder] and (R − A_ρ/(s−ρ)) =O 1 at each zero ρ [via NF of ζ at ρ], A_ρ = mult·(1−(ρ/(ρ−1))ⁿ).
4. ∮ R = Σ_{ρ} A_ρ + A_{−2} via residueTheorem_finset.
5. Assemble: ∮ J = ∮ P + ∮ R = ResW1 n + Σ zeros + triv.
And ii′-1b(i) [the w=1 residue value] is independent and first. Let me also make sure of one thing — the `residueTheorem_finset` interface: (f − A p/(s−p)) =O[𝓝[≠] p] (1) — for R at zeros ✓ per above. And HolomorphicOn R (Rectangle \ S): need R holomorphic at 1 — the order computation. Plus R = J − P explicitly holomorphic elsewhere (J holomorphic off poles: ζ′/ζ holomorphic off zeros and 1 (vendored LogDerivZetaHoloOn: "ζ'/ζ is holomorphic on any set not containing 1 and where ζ has no zeros" ✓ vendored!); k_n(w−1) holomorphic off 1 ✓).
Now — the order-at-1 computation for R (the removable singularity). Approach: R·(w−1)^{n+1} = F − Tayl_n(F) where F = [wⁿ−(w−1)ⁿ]h analytic at 1... wait: (w−1)^{n+1}·R = (w−1)^{n+1}·J − (w−1)^{n+1}·P = F − Σ_i A_i (w−1)^{n+1−i} = F − Tayl_n(F) (Taylor poly of F at 1 of degree n — since A_i = F^{(n+1−i)}(1)/(n+1−i)!). So R = [F − Tayl_n(F)]/(w−1)^{n+1}. F analytic at 1 ⟹ F has a power series; F − Tayl_n(F) = (w−1)^{n+1}·G with G analytic at 1 (power series tail). Hence R = G near 1 (punctured equality) ⟹ R extends analytically (G is the extension). In Lean: `AnalyticAt.exists_...`? The power-series tail: `HasFPowerSeriesAt` API — is there a lemma "f − Σ_{k<n} (iteratedDeriv k f p/k!)(z−p)^k = (z−p)^n · analytic"? There might be `AnalyticAt.exists_eq_pow_mul_...` or via analyticOrderAt: analyticOrderAt (F − Tayl_n F) 1 ≥ n+1 — Mathlib's `AnalyticAt` + `analyticOrderAt`: analyticOrderAt of F − Tayl_n... hmm — there might be `HasFPowerSeriesAt.analyticOrderAt_...`... Alternatively use `iteratedDeriv` API: show (F − Tayl_n F)^{(k)}(1) = 0 for k ≤ n (iteratedDeriv of the Taylor poly is itself at k ≤ n ✓ computable), then use: analytic with first n derivatives 0 ⟹ factors as (w−1)^{n+1}·analytic — is there a Mathlib lemma `AnalyticAt.eq_pow_mul_of_...`? Something like: if f analytic at p and f^{(k)}(p) = 0 for k < m then ∃ g analytic, f(z) = (z−p)^m g(z). Hmm — `AnalyticAt.exists_...`... there might be `AnalyticAt.analyticOrderAt_ge_of_...`... Let me grep for such a lemma.
The design is settled. One more API check — the Taylor-remainder factorization lemma.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"iteratedDeriv_eq_zero\\|eq_pow_mul\\|exists_pow_mul\\|analyticOrderAt.*ge\\|orderAt_ge\" Mathlib/Analysis/Analytic/Order.lean | head -10; grep -rn \"Taylor\" Mathlib/Analysis/Analytic/*.lean -l | head -5",
"description": "Find Taylor remainder / analytic order API"
}
thinking (7777 chars)
`natCast_le_analyticOrderAt_iff_iteratedDeriv_eq_zero` (line 333): n ≤ analyticOrderAt f p ⟺ iteratedDeriv k f p = 0 for all k < n — exactly what I need for the R-at-1 computation:
- Show (F − Tayl_n F) has iteratedDeriv k = 0 at 1 for k ≤ n (k < n+1): iteratedDeriv k (Tayl_n F) 1 = iteratedDeriv k F 1 for k ≤ n (Taylor poly reproduces derivatives) ✓ standard.
- Then analyticOrderAt (F − Tayl_n F) 1 ≥ n+1 ⟹ F − Tayl_n F = (w−1)^{n+1}·G with G analytic at 1 (via analyticOrderAt_eq_nat_iff + the NF: analyticOrderAt_eq_natCast_iff? there should be a lemma: analyticOrderAt f p = (n : ℕ∞) → ∃ g analytic, f = (z−p)^n·g — `analyticOrderAt_eq_natCast` in Analytic/Order.lean).
Then R = G punctured near 1 ⟹ R holomorphic at 1 (extend by G) — for the HolomorphicOn R (Rectangle \ S) claim: at 1, R agrees with G on punctured nhd; G analytic at 1; so R is "holomorphic on (Rectangle \ S) ∪ {1}-punctured"... for residueTheorem_finset I need fHolo : HolomorphicOn R (Rectangle \ (S:Set)) where S = zeros ∪ {−2} — and 1 ∉ S — so R must be holomorphic AT 1 in the sense of HolomorphicOn at points of Rectangle \ S near 1: R = G on a punctured neighborhood; replace R by G there — holomorphicity is local: at 1, R agrees with G punctured — but R itself might be defined weirdly AT 1 (R(1) = J(1) − P(1) — both singular... in Lean they're total functions with junk values at the pole). Hmm — HolomorphicOn R (Rectangle \ S) requires differentiability AT 1 (since 1 ∈ Rectangle \ S). R at 1: R(1) = J(1) − P(1): J(1) = k_n(0)·(−ζ′/ζ(1)): ζ(1) is... riemannZeta 1 in Mathlib is DEFINED as (γ − log(4π))/2 (riemannZeta_one — the finite value, from the Hurwitz def)! And P(1) = Σ A_i/(1−1)^i = Σ A_i/0 — junk (division by zero = 0 in Lean fields). So R(1) = junk. The fix used by the vendored code: Function.update R 1 G(1) — or define R as the updated function from the start and prove EqOn with J − P off {1}. The vendored `differentiableOn_update_limUnder_of_bddAbove` (in the snippet I saw at the end of vanishesOnRectangle area — "HolomorphicOn g s ∧ Set.EqOn f g (s \ {c}) := ⟨Function.update f c (limUnder ...)...") — there's machinery for this update pattern ✓.
OK — this is all doable. Given the amount of machinery, ii′-1b will likely span 2 sessions (016 + 017). Let me structure session 016 to deliver ii′-1b(i) + (ii) at minimum, ideally start (iii).
Actually — let me reconsider the overall ii′-1b structure to minimize risk:
**ii′-1b(i): the w=1 residue value.** Define:
- `hLi (w : ℂ) : ℂ := (w - 1) * (-deriv riemannZeta w / riemannZeta w)` — h(w) = (w−1)(−ζ′/ζ(w)).
- Prove `AnalyticAt ℂ hLi 1` and `hLi 1 = 1`?? — h(1) = 0·(−ζ′/ζ(1)): as written it's 0·something = 0 — the VALUE at 1 is junk! The analytic continuation value is 1 (residue), but the function as defined evaluates to 0 at 1. For iteratedDeriv computations I need h to be literally analytic at 1 — so define hLi via the analytic extension: hLi := Function.update (fun w => (w−1)*...) 1 1?? or define via the meromorphic normal form... The clean way: h(w) = (w−1)·(−ζ′/ζ(w)) for w ≠ 1, h(1) := 1 — analytic at 1 because −ζ′/ζ has a simple pole with residue 1 (from Mathlib's riemannZeta_residue_one... wait — need: (s−1)·(−ζ′/ζ(s)) → 1 as s→1. From ζ(s) = a(s)/(s−1) with a analytic, a(1) = 1: ζ′/ζ = a′/a − 1/(s−1): −ζ′/ζ = 1/(s−1) − a′/a: (s−1)(−ζ′/ζ) = 1 − (s−1)a′/a → 1 ✓. The a(s) := (s−1)ζ(s) analytic at 1 — Mathlib: riemannZeta has a simple pole at 1 with residue 1: is there `MeromorphicAt riemannZeta 1` + order −1? Mathlib has the pole API for riemannZeta? There's `riemannZeta_residue_one : Tendsto (fun s => (s - 1) * riemannZeta s) (𝓝[≠] 1) (𝓝 1)` ✓ (agent confirmed). From that: a(s) := (s−1)ζ(s) → 1; a is analytic at 1: a(s) = (s−1)·ζ(s) — ζ analytic off 1 (Mathlib differentiableAt_riemannZeta) so a analytic off 1 with limit 1 ⟹ removable singularity ⟹ extends analytically with a(1) = 1 — via `AnalyticAt.removableSingularity`? or the differentiableOn_update machinery. Then ζ′/ζ = a′/a − 1/(s−1): near 1, a(s) ≠ 0 (a(1) = 1) ✓ a′/a analytic at 1 ✓. So h(w) := 1 − (w−1)·(a′/a)(w) analytic at 1 with h(1) = 1 ✓ — this DEFINES h analytically! hLi := fun w => 1 - (w-1) * (deriv aZeta w / aZeta w) where aZeta w := (w-1)·riemannZeta w... but then proving h(w) = (w−1)(−ζ′/ζ(w)) for w ≠ 1 needs ζ′/ζ = a′/a − 1/(s−1) — log deriv of product: deriv a = ζ + (s−1)ζ′: a′/a = 1/(s−1) + ζ′/ζ ✓ algebra.
This is the cleanest foundation: define
```
def zetaA (w : ℂ) : ℂ := (w - 1) * riemannZeta w -- analytic at 1, value 1
def hLi (w : ℂ) : ℂ := 1 - (w - 1) * (deriv zetaA w / zetaA w) -- analytic at 1, h(1) = 1
```
Prove: zetaA analytic at 1 (removable), zetaA 1 = 1, zetaA ≠ 0 near 1, and hLi_eq : ∀ w ≠ 1, hLi w = (w - 1) * (-deriv riemannZeta w / riemannZeta w).
Hmm — zetaA's analyticity at 1: zetaA = (w−1)ζ(w): analytic off 1 ✓ (product), and tends to 1 — removable singularity extension: `AnalyticAt` of the UPDATE function (Function.update zetaA 1 1). But for algebra it's easier to define zetaA with the update built in:
```
def zetaA : ℂ → ℂ := Function.update (fun w => (w - 1) * riemannZeta w) 1 1
```
Then prove AnalyticAt zetaA 1 via the bounded-removable-singularity lemma (vendored has `differentiableOn_update_limUnder_of_bddAbove` — from the snippet earlier ✓ it exists in ResidueCalcOnRectangles? The snippet showed `⟨Function.update f c (limUnder (𝓝[{c}ᶜ) c) f), differentiableOn_update_limUnder_of_bddAbove hc hd hb, ...⟩` — so `differentiableOn_update_limUnder_of_bddAbove` exists ✓).
And the lcoeff definition: lcoeff k := iteratedDeriv (k+1) hLi 1 / (k+1)! — clean, no Laurent series needed.
Then ResW1 computation: F(w) = (wⁿ − (w−1)ⁿ)·hLi w: analytic at 1 ✓ (product of analytics: wⁿ−(w−1)ⁿ polynomial, hLi analytic at 1).
F^{(n)}(1) = Σ_{i=0}^n C(n,i) A^{(i)}(1) h^{(n−i)}(1) with A(w) = wⁿ−(w−1)ⁿ:
- A^{(i)}(1) = n.descFactorial i·1 − [iteratedDeriv i (w ↦ (w−1)^n) at 1]: for i < n: descFactorial i − 0 = descFactorial i; for i = n: n! − n! = 0.
iteratedDeriv i (· ^ n) x = n.descFactorial i * x^(n−i) ✓ (simp lemma). For (w−1)^n: iteratedDeriv i (fun w => (w−1)^n) 1 = iteratedDeriv i (·^n) evaluated at 0 — the shift: (fun w => (w−1)^n) = (·^n) ∘ (fun w => w−1): iteratedDeriv of a composition with a translation: `iteratedDeriv_comp_...`? — there might be `iteratedDeriv_comp_sub`? Hmm — simpler: (w−1)^n = (fun w => w + (-1))^n: use `iteratedDeriv_add_const`? Hmm — from the STATE handoff gotchas: "HasDerivAt.add_const adds to VALUE (use .comp for precomposition)". For iteratedDeriv there's likely `iteratedDeriv_comp_add_const`? Let me handle via: (fun w => (w−1)^n) = (fun w => w^n) ∘ (fun w => w − 1) and the iterated derivative at 1 equals iteratedDeriv i (·^n) 0 via a translation-invariance lemma — find or prove: `iteratedDeriv_comp_sub_const`? I'll grep for comp lemmas. Alternative: avoid the shift entirely — expand (w−1)^n via binomial: (w−1)^n = Σ_j C(n,j)(−1)^{n−j} w^j: then iteratedDeriv i at 1 = Σ_j C(n,j)(−1)^{n−j} j.descFactorial i·1 = ... equals descFactorial i·(1−1)^{n−i} = 0 for i < n (binomial: Σ_j C(n,j)(−1)^{n−j}j^{(i)} = (n)_i·(1−1)^{n−i} = 0 ✓ (n)_i·0 = 0 for n−i ≥ 1) and for i = n: n!. The binomial identity Σ_j C(n,j)(−1)^{n−j}·j.descFactorial i = n.descFactorial i·(1−1)^{n-i}·... — provable but annoying. The shift lemma is cleaner. Let me grep for iteratedDeriv_comp.
Actually — simplest robust approach for A^{(i)}(1): A(w) = wⁿ − (w−1)ⁿ: note A(w) = (w−(w−1))·Σ_{j<n} w^j(w−1)^{n−1−j} = Σ_{j=0}^{n−1} w^j(w−1)^{n−1−j} — each term has a (w−1) factor except... term j: w^j(w−1)^{n−1−j}: at w=1: all terms with n−1−j ≥ 1 vanish; j = n−1 term: w^{n−1} = 1. So A(1) = 1 ✓. For derivatives it's still messy. The shift approach is cleanest IF a lemma exists.
Let me grep for iteratedDeriv composition/shift lemmas.
The design is fully settled. Checking the iteratedDeriv shift/composition lemmas for the (w−1)ⁿ derivative.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"iteratedDeriv_comp\" Mathlib/Analysis/Calculus/IteratedDeriv/*.lean | head -10",
"description": "Find iteratedDeriv composition lemmas"
}
thinking (9254 chars)
`iteratedDeriv_comp_sub_const : iteratedDeriv n (fun z ↦ f (z - s)) = fun t ↦ iteratedDeriv n f (t - s)` ✓ — exactly the shift lemma. So:
iteratedDeriv i (fun w => (w - 1)^n) 1 = iteratedDeriv i (·^n) (1 − 1) = iteratedDeriv i (·^n) 0 = n.descFactorial i * 0^(n−i) = 0 for i < n, and = n! for i = n (0^0 = 1 — descFactorial n n = n!, 0^(n−n) = 0^0 = 1 ✓).
All APIs confirmed. Now let me start writing ii′-1b(i): the w=1 residue value. This is a substantial piece of Lean. Plan the file structure — new file `NguyenRH1/LiResidue.lean`:
Contents:
1. `zetaA w := Function.update (fun w => (w - 1) * riemannZeta w) 1 1` — analytic at 1 with value 1.
- `zetaA_analyticAt_one : AnalyticAt ℂ zetaA 1`
- `zetaA_one : zetaA 1 = 1` (by def: Function.update_self)
- `zetaA_ne_zero_near_one : ∀ᶠ w in 𝓝 1, zetaA w ≠ 0` (from value 1 + continuity)
- `zetaA_apply_ne_one : ∀ w ≠ 1, zetaA w = (w - 1) * riemannZeta w` (Function.update_of_ne)
Analyticity proof: off 1 it's analytic (product of analytic); at 1: (s−1)ζ(s) → 1 (riemannZeta_residue_one) ⟹ removable singularity. Machinery: `AnalyticAt` of the update — approach: show zetaA is analytic on a punctured neighborhood of 1 and bounded near 1 ⟹ extends — the vendored `differentiableOn_update_limUnder_of_bddAbove` (from the snippet: `differentiableOn_update_limUnder_of_bddAbove hc hd hb` — need its exact signature). Let me grep it.
2. `hLi w := 1 - (w - 1) * (deriv zetaA w / zetaA w)` — analytic at 1 (zetaA analytic, zetaA 1 = 1 ≠ 0 ⟹ zetaA ≠ 0 near 1 ⟹ quotient analytic; deriv of analytic is analytic).
- `hLi_analyticAt_one`
- `hLi_one : hLi 1 = 1`
- `hLi_eq (hw : w ≠ 1) : hLi w = (w - 1) * (-deriv riemannZeta w / riemannZeta w)` — via deriv zetaA = ζ + (s−1)ζ′ (product rule: deriv ((w−1)·ζ) = 1·ζ + (w−1)·ζ′ ✓) and zetaA = (w−1)ζ: deriv zetaA / zetaA = (ζ + (w−1)ζ′)/((w−1)ζ) = 1/(w−1) + ζ′/ζ: so hLi = 1 − (w−1)(1/(w−1) + ζ′/ζ) = −(w−1)ζ′/ζ = (w−1)(−ζ′/ζ) ✓.
3. `lcoeff (k : ℕ) : ℂ := iteratedDeriv (k + 1) hLi 1 / (k + 1)!`
(the Laurent coefficients of −ζ′/ζ at 1: −ζ′/ζ(1+u) = u⁻¹ + Σ c_k u^k — identification lemma LATER at ii′-2/3 when needed; for now the def via hLi is operational.)
4. `ResW1 (n : ℕ) : ℂ := iteratedDeriv n (fun w => (w^n - (w - 1)^n) * hLi w) 1 / n !`
theorem `ResW1_eq_sum : ResW1 n = ∑ i ∈ Finset.range n, (n.choose (i+1) : ℂ) * lcoeff i`
— via iteratedDeriv_mul + the A(w) = wⁿ−(w−1)ⁿ derivative computations:
F^{(n)}(1) = Σ_{i=0}^{n} C(n,i)·A^{(i)}(1)·hLi^{(n−i)}(1)
A^{(i)}(1) = n.descFactorial i − [i = n]·n! (0 for i < n from the (w−1)ⁿ part via iteratedDeriv_comp_sub_const + descFactorial; n! for i = n).
Terms: i = 0: C(n,0)·A(1)·hLi^{(n)}(1) = 1·1·hLi^{(n)}(1). i = n: C(n,n)·0·hLi(1) = 0. i ∈ (0,n): C(n,i)·descFactorial i·hLi^{(n−i)}(1).
F^{(n)}(1)/n! = Σ_{i=0}^{n−1} C(n,i)·descFactorial i/n!·hLi^{(n−i)}(1) = Σ_{i=0}^{n−1} hLi^{(n−i)}(1)/(n−i)! — wait: C(n,i)·descFactorial i = n!/(i!(n−i)!)·n!/(n−i)!-hmm: C(n,i) = n!/(i!(n−i)!); descFactorial i = n!/(n−i)!; product = (n!)²/(i!(n−i)!²)?? NO — that's wrong. Let me recompute: A^{(i)}(1) = n.descFactorial i (for i < n) where descFactorial i = n·(n−1)·...·(n−i+1) = n!/(n−i)!. And Leibniz: F^{(n)} = Σ_i C(n,i)·A^{(i)}·h^{(n−i)}. C(n,i)·A^{(i)}(1) = [n!/(i!(n−i)!)]·[n!/(n−i)!] — that's NOT right either — wait n.descFactorial i: descFactorial n i = n!/(n−i)! ✓. So C(n,i)·descFactorial n i = [n!/(i!(n−i)!)]·[n!/(n−i)!] = (n!)²/(i!(n−i)!²). Hmm that's ugly — but it should simplify: I want the final answer Σ_j C(n,j)·h^{(j)}(1)/j!·... = Σ_j C(n,j) c_{j−1}·... and lcoeff(j−1) = h^{(j)}(1)/j!. So the target: F^{(n)}(1)/n! = Σ_{i=0}^{n−1} C(n,i)·hLi^{(n−i)}(1)/(n−i)!·... = Σ_{i=0}^{n−1} C(n,i)·lcoeff(n−i−1). Reindex j = n−i: Σ_{j=1}^{n} C(n,n−j)·lcoeff(j−1) = Σ_{j=1}^n C(n,j)·lcoeff(j−1) ✓ (C(n,n−j) = C(n,j)). So I need: C(n,i)·A^{(i)}(1)/n! = C(n,i)·descFactorial n i/n! = [n!/(i!(n−i)!)]·[n!/(n−i)!]/n! = n!/(i!(n−i)!²). And the target coefficient of h^{(n−i)}(1): C(n,i)/(n−i)!·... = [n!/(i!(n−i)!)]/(n−i)! = n!/(i!(n−i)!²) ✓✓ SAME. Good — consistent.
So ResW1 = Σ_{i=0}^{n−1} [n!/(i!(n−i)!²)]·hLi^{(n−i)}(1)·(1/n!)... hold on let me redo cleanly:
ResW1 n = F^{(n)}(1)/n! = (1/n!)·Σ_{i=0}^{n} C(n,i)·A^{(i)}(1)·h^{(n−i)}(1)
= (1/n!)·Σ_{i=0}^{n−1} C(n,i)·descFac(n,i)·h^{(n−i)}(1) [i = n term is 0]
= Σ_{i=0}^{n−1} [C(n,i)·descFac(n,i)/n!]·h^{(n−i)}(1)
= Σ_{i=0}^{n−1} [n!/(i!(n−i)!·(n−i)!)]·h^{(n−i)}(1) [since C(n,i)·descFac = n!²/(i!(n−i)!²), /n! = n!/(i!(n−i)!²)]
And lcoeff(n−i−1) = h^{(n−i)}(1)/(n−i)!. So the i-term = [n!/(i!(n−i)!)]·lcoeff(n−i−1) = C(n,i)·lcoeff(n−i−1) ✓.
ResW1 = Σ_{i=0}^{n−1} C(n,i)·lcoeff(n−i−1) = Σ_{j=1}^{n} C(n,n−j)·lcoeff(j−1) = Σ_{j=1}^n C(n,j)·lcoeff(j−1) ✓.
The j = 0 (i = n) term of the i-sum: i ranges 0..n−1, j = n−i ranges 1..n ✓.
5. The A(w) derivative lemma:
`Aiter (i n : ℕ) : iteratedDeriv i (fun w => w^n - (w-1)^n) 1 = n.descFactorial i - (if i = n then n.factorial else 0)` — hmm wait: for i < n: descFac n i − 0; for i = n: n! − n! = 0. So A^{(i)}(1) = if i < n then descFac n i else 0 (for i ≤ n). Proof: iteratedDeriv i (wⁿ) 1 = descFac n i · 1^{n−i} = descFac n i (simp iteratedDeriv_pow). iteratedDeriv i (fun w => (w−1)^n) 1 = iteratedDeriv i (·^n) (1−1) = iteratedDeriv i (·^n) 0 = descFac n i · 0^(n−i) = if i < n then 0 else n! (for i = n: descFac n n · 0^0 = n!·1 = n!). Via iteratedDeriv_comp_sub_const with f = (·^n), s = 1: `iteratedDeriv_comp_sub_const i (·^n) 1 : iteratedDeriv i (fun z => (z−1)^n) = fun t => iteratedDeriv i (·^n) (t−1)` — at t = 1: (·^n) at 0 ✓. Need (fun w => (w−1)^n) = (fun z => (z−1)^n) — same form ✓.
Also descFac n n = n! : `Nat.descFactorial_self`.
And 0^(n−i) for i < n = 0 (zero_pow), for i = n: 0^0 = 1 (pow_zero).
Then the iteratedDeriv_mul application: needs ContDiffAt ℂ n for both factors at 1: polynomial A: contDiff (polynomials are smooth); hLi: analytic at 1 ⟹ ContDiff at 1 of any order (AnalyticAt.contDiff? — `AnalyticAt.contDiffAt` or via `ContDiff` of analytic functions: analytic ⟹ C^∞: `AnalyticAt.contDiff`? there's `AnalyticAt.hasStrictDerivAt`... for ContDiff: `AnalyticOnNhd.contDiff`? or `AnalyticAt.contDiffAt (n)`: I believe `AnalyticAt.contDiffAt : AnalyticAt 𝕜 f x → ContDiffAt 𝕜 n f x` exists (analytic ⟹ contDiff of all orders). Check.
That's ii′-1b(i) — sizable but well-defined. Let me write it. First check: AnalyticAt.contDiffAt existence, Function.update API (update_self/update_of_ne), differentiableOn_update_limUnder_of_bddAbove signature (for zetaA analyticity), Nat.descFactorial_self, descFactorial def.
Actually for zetaA analyticity there's a cleaner Mathlib path: `MeromorphicAt` + the removable-singularity criterion — or even simpler: ζ = a/(s−1) with a := zetaA... Actually Mathlib might directly have the analyticity of (s−1)ζ(s) at 1! The completed zeta machinery: `completedRiemannZeta₀` is entire (Differentiable completedZeta₀ ✓ per agent!). completedRiemannZeta₀(s) = s(s−1)·π^{−s/2}Γ(s/2)ζ(s)? Let me check the defs: completedRiemannZeta₀ (s) = s·(s−1)·... hmm. If Λ₀(s) := s(s−1)π^{−s/2}Γ(s/2)ζ(s) is entire and differentiable everywhere (Mathlib `differentiable_completedZeta₀ : Differentiable ℂ completedRiemannZeta₀` ✓), then zetaA(s) = (s−1)ζ(s) = Λ₀(s)/(s·π^{−s/2}Γ(s/2)) — quotient of analytics with nonvanishing denominator near 1 (s·π^{−s/2}Γ(s/2) at 1 = 1·π^{−1/2}·√π = 1 ✓ ≠ 0) ⟹ analytic at 1 ✓✓ and zetaA(1) = Λ₀(1)/1 = Λ₀(1): need Λ₀(1) = 1: Λ₀(1) = 1·0·π^{−1/2}Γ(1/2)ζ(1)?? — 0·ζ(1) = 0 — so Λ₀(1) = 0?? That gives zetaA(1) = 0/1 = 0 ≠ 1. Hmm — so the identity zetaA = Λ₀/(s·π^{−s/2}Γ(s/2)) holds only OFF 1 (where everything is defined); at 1 both sides... Λ₀(1) = lim = 1? Λ₀(s) = s(s−1)π^{−s/2}Γ(s/2)ζ(s): as s→1: (s−1)ζ(s) → 1 ⟹ Λ₀(s) → 1·1·π^{−1/2}·√π·1 = 1 ✓ (continuity of the entire function). So zetaA(s) = Λ₀(s)/(s·π^{−s/2}Γ(s/2)) OFF 1 and both sides are analytic AT 1 (LHS after update) with value... the quotient at 1 = Λ₀(1)/1 and Λ₀(1) = 1 by continuity ✓. So:
- def zetaA := Function.update (fun w => (w−1)*riemannZeta w) 1 1
- AnalyticAt zetaA 1: off 1: (w−1)ζ analytic; at 1: agree with the analytic quotient Q(s) := Λ₀(s)/(s·π^{−s/2}Γ(s/2)) on a punctured neighborhood ⟹ AnalyticAt of update = AnalyticAt of Q ✓ (`AnalyticAt.congr` via EventuallyEq).
Q analytic at 1: Λ₀ differentiable (entire) ✓; denominator: s·π^{−s/2}Γ(s/2): analytic at 1 (Γ analytic at 1/2 ✓ Mathlib differentiableAt_Gamma? — `Complex.differentiableAt_Gamma (s) (hs : ∀ m : ℕ, s ≠ -m)`: at s = 1/2 ✓) and ≠ 0 at 1 (Γ(1/2) = √π ≠ 0, π^{−1/2} ≠ 0, 1 ≠ 0) ✓ quotient analytic ✓.
Λ₀(1) = 1: continuity + limit: Tendsto Λ₀ at 1 → 𝓝 (Λ₀ 1); Λ₀(s) → 1 as computed ⟹ Λ₀(1) = 1 — via Tendsto products: π^{−s/2} → π^{−1/2} (continuous), Γ(s/2) → Γ(1/2) = √π (continuity ✓ Mathlib continuous_Gamma? differentiableAt ⟹ continuousAt ✓), (s−1)ζ(s) → 1 (riemannZeta_residue_one ✓), s → 1: product → 1·π^{−1/2}·√π·1 = 1: need π^{−1/2}·√π = 1: π^{−1/2} = 1/√π ✓ (Real.rpow). Fiddly but fine.
Need completedRiemannZeta₀'s DEFINITION to confirm the factorization: `completedRiemannZeta₀ (s) = s * (s - 1) * (π ^ (-s/2)) * Gamma (s/2) * riemannZeta s`?? — need to check the exact Mathlib def. Let me grep.
This is cleaner than the update+limUnder path. Let me check the def.
`iteratedDeriv_comp_sub_const` confirmed — all API pieces are in place. Let me check `completedRiemannZeta₀`'s definition for the clean analyticity path at w=1.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -n \"completedRiemannZeta\u2080\\|def completedRiemannZeta\" Mathlib/NumberTheory/LSeries/RiemannZeta.lean | head -12; grep -rn \"theorem differentiableAt_Gamma\\b\\|differentiable_completedZeta\u2080\" Mathlib/NumberTheory/LSeries/RiemannZeta.lean Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean 2>/dev/null | head -5",
"description": "Check completedRiemannZeta\u2080 definition and Gamma differentiability"
}
thinking (2105 chars)
Mathlib HAS a full RemovableSingularity.lean: `differentiableOn_update_limUnder_of_bddAbove` ✓. So the zetaA analyticity is standard.
Now I have everything needed. This is a big file to write — let me structure session 016's deliverable as ii′-1b(i) + (ii) if possible, with (iii) possibly going to session 017. Let me write `LiResidue.lean` with:
Part 1 (ii′-1b(i)): zetaA, hLi, lcoeff, ResW1 + the value theorem.
Part 2 (ii′-1b(ii)): principal-part integral.
Given the amount, I'll write Part 1 first, compile, then Part 2.
Let me write Part 1 now.
Key proofs:
1. `zetaA` := Function.update (fun w => (w - 1) * riemannZeta w) 1 1.
- `zetaA_apply (w : ℂ) (hw : w ≠ 1) : zetaA w = (w - 1) * riemannZeta w` := Function.update_of_ne hw
- `zetaA_one : zetaA 1 = 1` := Function.update_self ..
- `zetaA_analyticAt_one : AnalyticAt ℂ zetaA 1`:
- off 1: differentiable: fun w => (w−1)*riemannZeta w — differentiableAt at w ≠ 1: DifferentiableAt.mul (differentiableAt_id.sub const) (differentiableAt_riemannZeta hw) ✓.
- at 1: use the removable singularity: differentiableOn on a punctured ball + bddAbove near 1 (from the limit: (s−1)ζ(s) → 1 ⟹ bounded) ⟹ differentiableOn the update ⟹ AnalyticAt (differentiableOn at a nhd ⟹ analyticOnNhd? For ℂ, DifferentiableOn ℂ f s with s ∈ 𝓝 1 ⟹ AnalyticOnNhd? — differentiable on an open set in ℂ IS analytic: `DifferentiableOn.analyticOnNhd`? there's the theorem differentiableOn → analyticOnNhd for complex functions on open sets: `DifferentiableOn.analyticOnNhd (hd : DifferentiableOn ℂ f s) (ho : IsOpen s) : AnalyticOnNhd ℂ f s`? I believe `DifferentiableOn.analyticOnNhd` exists ✓ (holomorphic ⟺ analytic in ℂ).)
- boundedness: Tendsto (fun s => (s−1)ζ(s)) (𝓝[≠]1) (𝓝 1) ⟹ IsBoundedUnder (· ≤ ·) (𝓝[≠]1) (‖f‖) — Tendsto ⟹ bounded in a nhd: `Filter.Tendsto.isBoundedUnder...`? there's `Filter.Tendsto.norm_isBoundedUnder`? or: the removable lemma's hb argument takes BddAbove of ‖s−c‖·‖f s‖... Let me look at the exact signature of differentiableOn_update_limUnder_of_bddAbove.
Let me read RemovableSingularity.lean's exact statements.
Mathlib has full removable-singularity machinery. Let me read the exact signatures.
tool: Bash ok
input
{
"command": "sed -n '95,130p' /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib/Mathlib/Analysis/Complex/RemovableSingularity.lean",
"description": "Read removable singularity theorem signatures"
}
result 2026-08-21 20:55:28Z → 2026-08-28 23:57:52Z
rewrite -> probe.cgi (temporary) PATH_INFO : '/resources/ζ(3) — Status/' REQUEST_URI : '/resources/%CE%B6%283%29%20%E2%80%94%20Status/' SCRIPT_NAME : '/probe.cgi' QUERY_STRING : '' LANG/LC_ALL : None / None fs encoding : utf-8 PATH_INFO utf8: b'/resources/\xce\xb6(3) \xe2\x80\x94 Status/'
thinking (10062 chars)
All confirmed. Now let me write LiResidue.lean Part 1 (zetaA + hLi + lcoeff + ResW1). This is a big file. Let me write it carefully.
Key pieces:
1. zetaA def + apply/one lemmas.
2. zetaA_analyticAt_one:
- s := Metric.ball 1 2 (a nhd of 1).
- DifferentiableOn (fun w => (w−1)*ζ w) (ball 1 2 \ {1}): differentiableAt at w ≠ 1: (w−1) differentiable, ζ differentiable at w ≠ 1 (differentiableAt_riemannZeta) ✓ product.
- BddAbove (norm ∘ f '' (ball 1 2 \ {1})): from Tendsto (s−1)ζ → 1 at 𝓝[≠]1: limit ⟹ bounded in some punctured nhd: `Filter.Tendsto.isBigO_one`? or: Tendsto f (𝓝[≠]1) (𝓝 1) ⟹ ∃ C, ∀ᶠ z in 𝓝[≠]1, ‖f z‖ ≤ C: `Filter.Tendsto.eventually_norm_le`? There's `Tendsto.isBoundedUnder_le`? or `Filter.Tendsto.norm`... Standard: a convergent function is bounded near the point: `Filter.Tendsto.bddAbove_range`? Hmm — simplest: from Tendsto, get ∀ᶠ z, ‖f z‖ ≤ ‖1‖ + 1 = 2 via the ε = 1 ball: `Filter.Tendsto.eventually (fun z => ‖f z - 1‖ < 1)` ⟹ ‖f z‖ ≤ 2 (norm_sub_le). Then the image is bounded by 2.
- Then differentiableOn_update_limUnder_of_bddAbove (hc : ball 1 2 ∈ 𝓝 1) hd hb : DifferentiableOn (update f 1 (limUnder (𝓝[≠]1) f)) (ball 1 2).
- limUnder (𝓝[≠]1) f = 1 (from riemannZeta_residue_one : Tendsto f (𝓝[≠]1) (𝓝 1) ⟹ limUnder = 1: `Tendsto.limUnder_eq`? Filter.limUnder_eq_of_tendsto? — `Filter.Tendsto.limUnder_eq (h : Tendsto f l (𝓝 a)) : limUnder l f = a` ✓ exists I think).
- So DifferentiableOn (update f 1 1) (ball 1 2) = DifferentiableOn zetaA (ball 1 2) (update f 1 1 = zetaA by def: zetaA = Function.update f 1 1 where f = fun w => (w−1)ζ — defeq ✓).
- AnalyticAt from DifferentiableOn + IsOpen ball: `DifferentiableOn.analyticOnNhd`? then AnalyticOnNhd.mem_analyticAt (ball ∈ 𝓝 1)?? AnalyticOnNhd ℂ zetaA (ball 1 2) → AnalyticAt zetaA 1 (1 ∈ ball): `AnalyticOnNhd.analyticAt`? — the API: AnalyticOnNhd f U (U nhd of x) ⟹ AnalyticAt f x — hmm, DifferentiableOn ℂ f s (s open) → AnalyticOnNhd? In ℂ, differentiable ⟺ analytic: `DifferentiableOn.analyticOnNhd (hd : DifferentiableOn ℂ f s) (hs : IsOpen s) : AnalyticOnNhd ℂ f s` ✓ I believe this exact name exists. Then AnalyticAt := AnalyticOnNhd at singletons-ish: `AnalyticOnNhd.analyticAt (hf : AnalyticOnNhd ℂ f s) (hx : s ∈ 𝓝 x) : AnalyticAt ℂ f x`? or mem-based. I'll figure in code.
3. hLi := fun w => 1 - (w - 1) * (deriv zetaA w / zetaA w).
- hLi_analyticAt_one: zetaA analytic at 1 (above), zetaA 1 = 1 ≠ 0 ⟹ ∀ᶠ w in 𝓝 1, zetaA w ≠ 0 (continuity — `ContinuousAt.eventually_ne`? there's `AnalyticAt.eventually_ne`? or continuousAt + ne: (hzetaA.continuousAt).eventually_ne — `ContinuousAt.eventually_ne (h : f x ≠ y) : ∀ᶠ x' in 𝓝 x, f x' ≠ y` ✓ exists). deriv zetaA analytic at 1 (AnalyticAt.deriv ✓ `AnalyticAt.deriv`). Quotient analytic: `AnalyticAt.div` (needs denom ≠ 0 — on a nhd where zetaA ≠ 0: AnalyticAt.div needs the denom analyticAt and denom(x) ≠ 0 — zetaA 1 = 1 ≠ 0 ✓ at the point). So hLi analytic at 1 via sub/mul/div ✓.
- hLi_one : hLi 1 = 1: hLi 1 = 1 − (1−1)·(...) = 1 − 0 = 1 ✓ simp.
- hLi_eq {w : ℂ} (hw : w ≠ 1) : hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w):
deriv zetaA w = ζ w + (w−1)·ζ′ w (for w ≠ 1: deriv ((w−1)·ζ) via deriv_mul: deriv ((fun w => w−1) * ζ) = 1·ζ + (w−1)·ζ′: `deriv_mul` with DifferentiableAt ✓; deriv (w−1) = 1 ✓).
zetaA w = (w−1)·ζ w (hw, update_of_ne).
So deriv zetaA / zetaA = (ζ + (w−1)ζ′)/((w−1)ζ) = 1/(w−1) + ζ′/ζ (needs ζ w ≠ 0?? — no: the algebra (A + B)/C = A/C + B/C needs C ≠ 0: (w−1)·ζ w = 0 possible (ζ w = 0 at a zero!). At a zero ρ: deriv zetaA / zetaA = (ζ + (w−1)ζ′)/0 = junk/0 = 0 in Lean. And the target hLi w = (w−1)(−ζ′/ζ(w)) also has ζ w = 0 in denominator = 0. So the identity hLi_eq holds where BOTH sides are defined consistently — at zeros both are 0/junk... For the residue computation, I need hLi_eq only near w = 1 punctured (for the Leibniz/residue) — where ζ ≠ 0 (ζ(1+it) ≠ 0 — ZetaNoZerosOn1Line vendored ✓ but that's the line re = 1; near 1: ζ(1) = pole, ζ ≠ 0 in a punctured nhd of 1? ζ has no zeros near 1 except... zeros are discrete and 1 is a pole not a zero ⟹ punctured nhd exists with ζ ≠ 0 ✓ (riemannZeta_ne_zero_of_one_le_re for re ≥ 1 + the local discreteness for re < 1 near 1: zero-free box `ZetaNoZerosInBox` vendored). Simpler: state hLi_eq for w with riemannZeta w ≠ 0 ∧ w ≠ 1: at such w the algebra works.
Actually — where do I USE hLi_eq? In the residue theorem (iii), the integrand J(w) = k_n(w−1)·(−ζ′/ζ(w)) and I need J·(w−1)^{n+1} = [wⁿ−(w−1)ⁿ]·hLi(w) near 1 punctured — with ζ(w) possibly 0?? near 1 punctured, ζ ≠ 0 ✓ (choose the small square around 1 inside the zero-free box). And the principal part analysis happens near 1. So hLi_eq in a punctured nhd of 1 suffices — prove `hLi_eq_near_one : ∀ᶠ w in 𝓝[≠] 1, hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w)` using the zero-free punctured nhd.
4. lcoeff k := iteratedDeriv (k + 1) hLi 1 / (k + 1)! — def.
5. ResW1 n := iteratedDeriv n (fun w => (w^n - (w - 1)^n) * hLi w) 1 / n ! — def.
6. ResW1_eq_sum : ResW1 n = Σ_{j=1}^n (n.choose j : ℂ) * lcoeff (j - 1):
- ContDiffAt for the factors: A(w) = wⁿ − (w−1)ⁿ: polynomial — ContDiffAt of any order: `ContDiffAt` via contDiff_polynomial? For ℂ: `(contDiff_id.pow ...)`... use `ContDiffAt` of analytic: AnalyticAt everywhere for polynomials ⟹ ContDiffAt: `AnalyticAt.contDiffAt`? I need to confirm the name — maybe `AnalyticAt.contDiff`... Alternatively use ContDiffAt directly: polynomials are ContDiff: `ContDiff.contDiffAt`: `ContDiff ℂ n (fun w => w^n - (w-1)^n)` — via ContDiff.pow/sub: contDiff_id, contDiff_const, .pow, .sub ✓ mechanical.
- hLi: analytic at 1 ⟹ ContDiffAt at 1: AnalyticAt.contDiffAt? — need the name. `AnalyticAt.contDiffAt (hf : AnalyticAt 𝕜 f x) : ContDiffAt 𝕜 n f x`? I believe `AnalyticAt.contDiffAt` exists.
- iteratedDeriv_mul: F^{(n)}(1) = Σ_{i=0}^n C(n,i)·A^{(i)}(1)·h^{(n−i)}(1).
- A^{(i)}(1): `A_iter (i n) : iteratedDeriv i (fun w => w^n - (w-1)^n) 1 = if i < n then n.descFactorial i else 0` (for i ≤ n):
iteratedDeriv i (wⁿ) 1 = descFac n i·1^(n−i) = descFac n i (simp [iteratedDeriv_pow]).
iteratedDeriv i ((w−1)ⁿ) 1: (fun w => (w−1)^n) = (fun z => z^n) ∘ (fun w => w−1)? NO — as iteratedDeriv_comp_sub_const i (·^n) 1 : iteratedDeriv i (fun z ↦ (z−1)^n) = fun t ↦ iteratedDeriv i (·^n) (t−1): evaluate at 1: iteratedDeriv i (·^n) 0 = descFac n i·0^(n−i) = if i < n then 0 else descFac n n·0^0 = n! (i = n). Wait iteratedDeriv_comp_sub_const (n f s) : iteratedDeriv n (fun z ↦ f (z - s)) = fun t ↦ iteratedDeriv n f (t - s) — my function is (fun w => (w−1)^n) = fun w => (·^n) (w − 1) ✓ form matches with f = (·^n), s = 1 ✓.
So A^{(i)}(1) = descFac n i − (if i < n then 0 else n!) : for i < n: descFac n i; for i = n: n! − n! = 0 ✓. Written: `if i < n then n.descFactorial i else 0` for i ≤ n (at i = n: descFac n n − n! = 0 ✓ consistent).
The subtraction: iteratedDeriv i (f − g) 1 = iteratedDeriv i f 1 − iteratedDeriv i g 1 — `iteratedDeriv_sub`? should exist (linear map).
- Sum assembly: F^{(n)}(1) = Σ_{i=0}^n C(n,i)·A^{(i)}(1)·h^{(n−i)}(1): i = n term: A^{(n)}(1) = 0 ⟹ 0. i < n terms: C(n,i)·descFac(n,i)·h^{(n−i)}(1).
- ResW1 = F^{(n)}(1)/n! = Σ_{i=0}^{n−1} C(n,i)·descFac(n,i)/n!·h^{(n−i)}(1). C(n,i)·descFac(n,i)/n! = C(n,i)/(n−i)!·... = n!/(i!(n−i)!)·n!/(n−i)!/n! = n!/(i!(n−i)!²)·... and C(n,n−j)·... Let me define the target sum directly: Σ_{j=1}^n C(n,j)·lcoeff(j−1) with lcoeff(j−1) = h^{(j)}(1)/j!: term j = C(n,j)·h^{(j)}(1)/j! = [n!/(j!(n−j)!)]·h^{(j)}(1)/j! = n!·h^{(j)}(1)/(j!²(n−j)!). And the ResW1 i-term (j = n−i): n!·h^{(n−i)}(1)/(i!·(n−i)!²) = C(n,i)·h^{(n−i)}(1)/(n−i)! ✓ (n!/(i!(n−i)!)/(n−i)! = n!/(i!(n−i)!²) ✓ matches).
So the algebra: ResW1 n = Σ_{i=0}^{n−1} C(n,i)·h^{(n−i)}(1)/(n−i)! = Σ_{i=0}^{n−1} C(n,i)·lcoeff(n−i−1)·... wait lcoeff(n−i−1) = h^{(n−i)}(1)/(n−i)! — yes! So term i = C(n,i)·lcoeff(n−i−1). Reindex j = n−i: Σ_{j=1}^{n} C(n,n−j)·lcoeff(j−1) = Σ_j C(n,j)·lcoeff(j−1) (choose symmetry: Nat.choose_symm : C(n,n−j) = C(n,j) ✓).
The reindexing: Σ_{i=0}^{n−1} f(i) = Σ_{j=1}^{n} f(n−j): `Finset.sum_range_reflect`? there's `Finset.sum_range_reflect : ∑ i ∈ range n, f i = ∑ i ∈ range n, f (n−1−i)` ✓ or sum over Ioc 1 n. I'll manage in code.
- descFac def: Nat.descFactorial n i = n!/(n−i)! for i ≤ n: `Nat.descFactorial_eq_factorial_mul_factorial`? or `Nat.descFactorial_eq_prod_range`? and the ratio C(n,i)·descFac(n,i) = n!·... the cleanest: C(n,i)·descFac(n,i)/n! = C(n,i)·... I'll do: descFac(n,i) = n!/(n−i)! (Nat.factorial_div_descFactorial? there's `Nat.factorial_eq_descFactorial`...). The identity needed: (n.choose i : ℂ) * (n.descFactorial i : ℂ) = n ! * (n.choose i : ℂ) / (n - i)! — prove via Nat.choose_mul_descFactorial? Hmm — there's `Nat.choose_mul_descFactorial (h : k ≤ n) : n.choose k * n.descFactorial k = ...`? Not sure. Alternative: descFactorial n i = n.factorial / (n−i).factorial via `Nat.descFactorial_eq_div (h : i ≤ n) : n.descFactorial i = n ! / (n - i)!`? I think `Nat.descFactorial_eq_div` exists ✓. Then (n.choose i)·(descFac n i) = [n!/(i!(n−i)!)]·[n!/(n−i)!] — in ℕ with division — cast to ℂ carefully (exact divisions: use Nat.choose_eq_factorial_div_factorial and descFactorial_eq_div with divisibility handled...). To avoid ℕ-division pain: work with `Nat.ascFactorial`-style: (n.choose i : ℂ) = n!/(i!(n−i)!) — `Nat.choose_eq_factorial_div_factorial (h : i ≤ n)` then push_cast... The standard approach: n.choose i * i ! * (n - i) ! = n ! — `Nat.choose_mul_factorial_mul_factorial (h : i ≤ n) : n.choose i * (i ! * (n - i) !) = n !`? there's `Nat.choose_mul_factorial_mul_factorial : n.choose k * k ! * (n - k) ! = n !` (for k ≤ n) ✓ I'm fairly confident. And descFactorial: `Nat.descFactorial_eq_factorial_mul_factorial`? or `Nat.mul_descFactorial_...`: (n−i)! · descFac(n,i) = n!: `Nat.factorial_mul_descFactorial`? — `Nat.descFactorial_mul_factorial`? I recall `Nat.factorial_mul_ascFactorial`-family. Let me grep for these two identities rather than guess.
Let me grep for the factorial identities quickly, then write Part 1.
All machinery confirmed. Let me check the factorial identities needed for the coefficient algebra, then write LiResidue.lean Part 1.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"choose_mul_factorial_mul_factorial\\|factorial_mul_descFactorial\\|descFactorial_eq_div\\|choose_mul_descFactorial\" Mathlib/Data/Nat/Choose/Basic.lean Mathlib/Data/Nat/Factorial/Basic.lean Mathlib/Data/Nat/Factorial/*.lean 2>/dev/null | head -8; grep -rn \"theorem AnalyticAt.contDiffAt\\|lemma AnalyticAt.contDiffAt\" Mathlib/ --include=*.lean | head -3",
"description": "Check factorial identities and AnalyticAt.contDiffAt"
}
thinking (404 chars)
`h.differentiableOn.analyticOnNhd isOpen_ball` — so the method is `DifferentiableOn.analyticOnNhd (hd : DifferentiableOn ℂ f s) (ho : IsOpen s) : AnalyticOnNhd ℂ f s` ✓ exists (dot notation).
Now I have everything. Let me write LiResidue.lean Part 1 (zetaA, hLi, lcoeff, ResW1 + ResW1_eq_sum). I'll write it in the new file and iterate with `lake env lean NguyenRH1/LiResidue.lean` from the package dir.
All confirmed. Writing `LiResidue.lean` Part 1 (zetaA, hLi, lcoeff, ResW1, and the value theorem).
tool: Write ok
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiResidue.lean",
"content": "/-\nNguyenRH1/LiResidue.lean \u2014 tier ii\u2032 sub-stage ii\u2032-1b (D-064 \u00a74 R1):\nthe w = 1 residue of the Lagarias-kernel integrand, computed exactly.\n\nContents (Part 1, this file's core):\n* `zetaA w = (w\u22121)\u00b7\u03b6(w)` extended by 1 at w = 1 \u2014 analytic at 1 with\n value 1 (removable singularity; Mathlib `riemannZeta_residue_one` +\n `differentiableOn_update_limUnder_of_bddAbove`).\n* `hLi w = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w)` \u2014 analytic at 1, hLi 1 = 1;\n agrees with (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6)(w) on a punctured neighborhood of 1\n (`hLi_eq_near_one`).\n* `lcoeff k` \u2014 the Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1, DEFINED as\n iteratedDeriv (k+1) hLi 1 / (k+1)! (operational; no Laurent series\n needed at this stage).\n* `ResW1 n` \u2014 the residue at w = 1 of J(w) = k_n(w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6(w)),\n computed by the Leibniz identity (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi\n (D-064 \u00a74 R1, verified algebraically in session 014):\n ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121) =: `ResW1_eq_sum`.\n\nArchive references: D-036, D-037, D-064 (R1), journal-014/015.\n-/\nimport Mathlib\nimport Zeta23.Statement\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. The regularized factor zetaA = (w\u22121)\u03b6(w) at w = 1 -/\n\n/-- `zetaA w = (w\u22121)\u00b7\u03b6(w)` with the removable singularity at w = 1 filled\nby the residue value 1. Analytic at 1 (`zetaA_analyticAt_one`), value\n`zetaA 1 = 1`. -/\ndef zetaA : \u2102 \u2192 \u2102 := Function.update (fun w => (w - 1) * riemannZeta w) 1 1\n\nlemma zetaA_apply {w : \u2102} (hw : w \u2260 1) : zetaA w = (w - 1) * riemannZeta w :=\n Function.update_of_ne hw _ _\n\nlemma zetaA_one : zetaA 1 = 1 := Function.update_self _ _ _\n\nlemma zetaA_tendsto : Tendsto (fun w => (w - 1) * riemannZeta w) (\ud835\udcdd[\u2260] 1) (\ud835\udcdd 1) :=\n riemannZeta_residue_one\n\n/-- The regularized factor is analytic at w = 1 (removable singularity). -/\nlemma zetaA_analyticAt_one : AnalyticAt \u2102 zetaA 1 := by\n have hdiff : DifferentiableOn \u2102 (fun w => (w - 1) * riemannZeta w)\n (Metric.ball 1 2 \\ {1}) := by\n intro w hw\n have hw1 : w \u2260 1 := hw.2\n exact (differentiableAt_id.sub (differentiableAt_const 1)).mul\n (differentiableAt_riemannZeta hw1) |>.differentiableWithinAt\n have hbd : BddAbove (Complex.norm \u2218 (fun w => (w - 1) * riemannZeta w)) ''\n (Metric.ball 1 2 \\ {1}) := by\n have hT := zetaA_tendsto\n rw [Metric.tendsto_nhdsWithin_nhds] at hT\n obtain \u27e8\u03b4, h\u03b40, h\u03b4\u27e9 := hT 1 one_pos\n refine \u27e82, ?_\u27e9\n rintro _ \u27e8z, hz, rfl\u27e9\n have h1 : dist (z - 1) 0 = \u2016z - 1\u2016 := by\n rw [dist_eq_norm]; simp [sub_zero]\n have hz1 : z \u2260 1 := hz.2\n have hzz : dist z 1 < \u03b4 := by\n have := hz.1\n rw [Metric.mem_ball, dist_comm] at this\n exact this\n have hlt := h\u03b4 (by rwa [dist_zero_right, h1] at *)\n have : \u2016(z - 1) * riemannZeta z\u2016 \u2264 \u2016(1 : \u2102)\u2016 + 1 := by\n have := norm_sub_le_of_le hlt\n calc \u2016(z - 1) * riemannZeta z\u2016\n \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 := by\n have := norm_sub_le ((z - 1) * riemannZeta z) 1\n linarith [this, hlt]\n _ \u2264 2 := by\n have h2 := hlt\n rw [norm_one]\n linarith [h2]\n exact this\n have h := differentiableOn_update_limUnder_of_bddAbove\n (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2)) hdiff hbd\n have hlim : limUnder (\ud835\udcdd[\u2260] (1 : \u2102)) (fun w => (w - 1) * riemannZeta w) = 1 :=\n zetaA_tendsto.limUnder_eq\n rw [hlim] at h\n have hopen : IsOpen (Metric.ball (1 : \u2102) 2) := Metric.isOpen_ball\n have han := h.analyticOnNhd hopen\n exact han.analyticAt (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2))\n\n/-- zetaA is nonzero on a neighborhood of 1 (value 1 there). -/\nlemma zetaA_ne_zero_near_one : \u2200\u1da0 w in \ud835\udcdd (1 : \u2102), zetaA w \u2260 0 :=\n (zetaA_analyticAt_one.continuousAt).eventually_ne (by rw [zetaA_one]; norm_num)\n\n/-- zetaA is analytic everywhere except possibly at 1 \u2014 and in fact also\nat 1; we record the off-1 version for quotient computations. -/\nlemma zetaA_analyticAt_of_ne {w : \u2102} (hw : w \u2260 1) : AnalyticAt \u2102 zetaA w := by\n have h : (fun w => (w - 1) * riemannZeta w) =\u1da0[\ud835\udcdd w] zetaA := by\n filter_upwards [eventually_ne_nhds hw] with z hz using (zetaA_apply hz).symm\n have ha : AnalyticAt \u2102 (fun w => (w - 1) * riemannZeta w) w := by\n exact (analyticAt_id.sub analyticAt_const).mul\n (differentiableAt_riemannZeta hw).analyticAt\n exact ha.congr h\n\n/-! ## 2. hLi w = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w): analytic at 1, value 1 -/\n\n/-- hLi(w) = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w) \u2014 the analytic-at-1 form of\n(w\u22121)(\u2212\u03b6\u2032/\u03b6)(w) (`hLi_eq_near_one`). hLi 1 = 1. -/\ndef hLi (w : \u2102) : \u2102 := 1 - (w - 1) * (deriv zetaA w / zetaA w)\n\nlemma hLi_one : hLi 1 = 1 := by simp [hLi]\n\nlemma hLi_analyticAt_one : AnalyticAt \u2102 hLi 1 := by\n have ha := zetaA_analyticAt_one\n have hda : AnalyticAt \u2102 (deriv zetaA) 1 := ha.deriv\n have hne : zetaA 1 \u2260 0 := by rw [zetaA_one]; norm_num\n exact (analyticAt_const.sub analyticAt_id).mul\n (hda.div ha hne) |>.const_sub 1\n\n/-- On a punctured neighborhood of 1, hLi = (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6). -/\nlemma hLi_eq_of_ne {w : \u2102} (hw1 : w \u2260 1) (hw0 : riemannZeta w \u2260 0) :\n hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by\n have hA : zetaA w = (w - 1) * riemannZeta w := zetaA_apply hw1\n have hdA : deriv zetaA w = riemannZeta w + (w - 1) * deriv riemannZeta w := by\n have h1 : deriv (fun z => (z - 1) * riemannZeta z) w =\n deriv (fun z => z - 1) w * riemannZeta w +\n (w - 1) * deriv riemannZeta w :=\n deriv_mul ((differentiableAt_id.sub (differentiableAt_const 1)))\n (differentiableAt_riemannZeta hw1)\n have h2 : deriv (fun z => z - 1) w = 1 := by\n simp [deriv_sub, deriv_id'']\n have h3 : (fun z => (z - 1) * riemannZeta z) =\u1da0[\ud835\udcdd w] zetaA := by\n filter_upwards [eventually_ne_nhds hw1] with z hz using (zetaA_apply hz).symm\n rw [h3.deriv_eq, h1, h2, one_mul]\n rw [hLi, hdA, hA]\n have hw1' : w - 1 \u2260 0 := sub_ne_zero.mpr hw1\n field_simp [hw0, hw1']\n ring\n\n/-- The punctured-neighborhood form, for later contour work. -/\nlemma hLi_eq_near_one :\n \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by\n have hzero : \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), riemannZeta w \u2260 0 := by\n have h1 : (1 : \u2102) \u2208 {s : \u2102 | 1 \u2264 s.re} := by simp\n filter_upwards [eventually_mem_nhdsWithin] with w hw\n have hwre : 1 \u2264 w.re := by\n have := hw.2\n sorry\n exact riemannZeta_ne_zero_of_one_le_re hwre\n filter_upwards [hzero, eventually_mem_nhdsWithin] with w hw0 hw1\n exact hLi_eq_of_ne hw1 hw0\n\n/-! ## 3. The Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1 (operational definition) -/\n\n/-- The k-th Laurent coefficient of \u2212\u03b6\u2032/\u03b6 at s = 1:\n\u2212\u03b6\u2032/\u03b6(1+u) = u\u207b\u00b9 + \u03a3_{k\u22650} lcoeff k \u00b7 u^k (identification proved in\ntier ii\u2032-2/3; here lcoeff is DEFINED via the analytic hLi). -/\ndef lcoeff (k : \u2115) : \u2102 := iteratedDeriv (k + 1) hLi 1 / (k + 1) !\n\nlemma lcoeff_eq (k : \u2115) :\n lcoeff k = iteratedDeriv (k + 1) hLi 1 / (k + 1) ! := rfl\n\n/-- hLi's Taylor coefficient form: iteratedDeriv j hLi 1 / j ! = lcoeff (j\u22121). -/\nlemma hLi_iteratedDeriv_div_factorial {j : \u2115} (hj : 1 \u2264 j) :\n iteratedDeriv j hLi 1 / j ! = lcoeff (j - 1) := by\n rw [lcoeff]\n have : j = (j - 1) + 1 := by omega\n rw [this]\n\n/-! ## 4. The A-polynomial derivative: A(w) = w\u207f \u2212 (w\u22121)\u207f -/\n\n/-- Iterated derivatives of A(w) = w\u207f \u2212 (w\u22121)\u207f at 1:\nA^{(i)}(1) = n.descFactorial i for i < n, and A^{(n)}(1) = 0. -/\nlemma A_iter (n i : \u2115) (hi : i \u2264 n) :\n iteratedDeriv i (fun w => w ^ n - (w - 1) ^ n) (1 : \u2102) =\n if i < n then n.descFactorial i else 0 := by\n have hf : ContDiffAt \u2102 i (fun w : \u2102 => w ^ n) 1 :=\n (contDiff_id.pow n).contDiffAt\n have hg : ContDiffAt \u2102 i (fun w : \u2102 => (w - 1) ^ n) 1 :=\n ((contDiff_id.sub contDiff_const).pow n).contDiffAt\n rw [iteratedDeriv_sub hf hg]\n have h1 : iteratedDeriv i (fun w : \u2102 => w ^ n) 1 = n.descFactorial i := by\n rw [iteratedDeriv_pow]\n simp\n have h2 : iteratedDeriv i (fun w : \u2102 => (w - 1) ^ n) 1 =\n n.descFactorial i * (0 : \u2102) ^ (n - i) := by\n have e := iteratedDeriv_comp_sub_const i (fun w : \u2102 => w ^ n) (1 : \u2102)\n have e2 : iteratedDeriv i (fun w : \u2102 => (w - 1) ^ n) 1 =\n iteratedDeriv i (fun w : \u2102 => w ^ n) (1 - 1) := by\n have := congr_fun e 1\n convert this using 2\n rw [e2, iteratedDeriv_pow]\n simp\n rw [h1, h2]\n by_cases hin : i < n\n \u00b7 rw [if_pos hin]\n have : (0 : \u2102) ^ (n - i) = 0 := by\n apply zero_pow\n omega\n rw [this, mul_zero, sub_zero]\n \u00b7 rw [if_neg hin]\n have hin' : i = n := le_antisymm hi (by omega)\n subst hin'\n simp [Nat.descFactorial_self]\n\n/-! ## 5. The residue at w = 1: ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121) -/\n\n/-- The residue at w = 1 of the Lagarias-kernel integrand\nJ(w) = k_n(w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6(w)), packaged as (1/n!)\u00b7(d/dw)\u207f[(w\u207f\u2212(w\u22121)\u207f)hLi]\nat w = 1 (D-064 \u00a74 R1: (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi on a punctured\nneighborhood, by `hLi_eq_near_one`). -/\ndef ResW1 (n : \u2115) : \u2102 :=\n iteratedDeriv n (fun w => (w ^ n - (w - 1) ^ n) * hLi w) (1 : \u2102) / n !\n\n/-- The w = 1 residue value: ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121). -/\ntheorem ResW1_eq_sum (n : \u2115) :\n ResW1 n = \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n have hA : ContDiffAt \u2102 n (fun w : \u2102 => w ^ n - (w - 1) ^ n) 1 :=\n ((contDiff_id.pow n).sub ((contDiff_id.sub contDiff_const).pow n)).contDiffAt\n have hh : ContDiffAt \u2102 n hLi 1 := hLi_analyticAt_one.contDiffAt\n have hmul := iteratedDeriv_mul hA hh\n rw [ResW1, hmul]\n have hsum : \u2211 i \u2208 Finset.range (n + 1),\n n.choose i * iteratedDeriv i (fun w : \u2102 => w ^ n - (w - 1) ^ n) 1 *\n iteratedDeriv (n - i) hLi 1 =\n \u2211 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 := by\n apply Finset.sum_subset (Finset.range_le_iff.mpr (Nat.le_succ n))\n intro i hi\n rw [Finset.mem_range] at hi\n have hi0 : i \u2260 n := by omega\n rw [A_iter n i (by omega), if_pos (by omega)]\n \u00b7 rfl\n \u00b7 rw [Finset.mem_range] at *\n omega\n rw [hsum]\n have hfinal : (\u2211 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1) / n ! =\n \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n have hrewrite : \u2200 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 / n ! =\n (n.choose (n - i) : \u2102) * lcoeff (n - i - 1) := by\n intro i hi\n rw [Finset.mem_range] at hi\n have hcd : (n.choose i : \u2102) * (n.descFactorial i : \u2102) =\n n ! * n.choose i / (n - i) ! := by\n have h1 := Nat.choose_mul_factorial_mul_factorial (show i \u2264 n by omega)\n have h2 := Nat.factorial_mul_descFactorial (show i \u2264 n by omega)\n have : (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((i ! : \u2102) * ((n - i) ! : \u2102)) =\n (n ! : \u2102) * (n.choose i : \u2102) := by\n push_cast [h1, h2]\n ring\n have hfact : ((i ! : \u2102) * ((n - i) ! : \u2102)) \u2260 0 := by\n simp [Nat.factorial_ne_zero]\n have hthis := this\n field_simp at hthis \u22a2\n have h3 : (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((n - i) ! : \u2102) =\n (n ! : \u2102) * (n.choose i : \u2102) / 1 := by\n have h4 := hthis\n rw [mul_comm ((i ! : \u2102)) ((n - i) ! : \u2102)] at h4\n have h5 : (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((n - i) ! : \u2102) * (i ! : \u2102) =\n (n ! : \u2102) * (n.choose i : \u2102) := by\n rw [mul_comm ((n - i) ! : \u2102) (i ! : \u2102)] at h4\n calc (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((n - i) ! : \u2102) * (i ! : \u2102)\n = (n.choose i : \u2102) * (n.descFactorial i : \u2102) * (((n - i) ! : \u2102) * (i ! : \u2102)) := by ring\n _ = (n ! : \u2102) * (n.choose i : \u2102) := by\n have := h4\n ring_nf at this \u22a2\n convert this using 1\n ring\n exact (div_eq_one_iff_eq (by simp [Nat.factorial_ne_zero])).mpr h5\n field_simp at h3 \u22a2\n calc (n.choose i : \u2102) * (n.descFactorial i : \u2102)\n = ((n ! : \u2102) * (n.choose i : \u2102) / 1) / ((n - i) ! : \u2102) := by\n rw [\u2190 h3]\n field_simp\n ring\n _ = (n ! : \u2102) * (n.choose i : \u2102) / ((n - i) ! : \u2102) := by ring\n rw [hcd]\n have hni : n - i \u2265 1 := by omega\n rw [hLi_iteratedDeriv_div_factorial (j := n - i) (by omega)]\n rw [show n - i - 1 = n - i - 1 from rfl]\n have hcoe : ((n - i) ! : \u2102) \u2260 0 := by simp [Nat.factorial_ne_zero]\n field_simp\n rw [Nat.choose_symm (by omega : i \u2264 n)]\n ring\n rw [Finset.sum_div]\n rw [Finset.sum_congr rfl hrewrite]\n have hmap : \u2211 i \u2208 Finset.range n, (n.choose (n - i) : \u2102) * lcoeff (n - i - 1) =\n \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n rw [Finset.sum_range_reflect]\n apply Finset.sum_congr rfl\n intro i hi\n rw [Finset.mem_range] at hi\n have : n - 1 - i + 1 = n - i := by omega\n rw [this]\n have : n - (n - i) = i := by omega\n rw [Nat.choose_symm (show n - i \u2264 n by omega)]\n simp [this]\n ring\n exact hmap\n rw [hfinal]\n\nend NguyenRH1\n"
}
result 2026-08-21 21:00:46Z → 2026-08-21 21:00:46Z
{
"type": "create",
"filePath": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiResidue.lean",
"content": "/-\nNguyenRH1/LiResidue.lean \u2014 tier ii\u2032 sub-stage ii\u2032-1b (D-064 \u00a74 R1):\nthe w = 1 residue of the Lagarias-kernel integrand, computed exactly.\n\nContents (Part 1, this file's core):\n* `zetaA w = (w\u22121)\u00b7\u03b6(w)` extended by 1 at w = 1 \u2014 analytic at 1 with\n value 1 (removable singularity; Mathlib `riemannZeta_residue_one` +\n `differentiableOn_update_limUnder_of_bddAbove`).\n* `hLi w = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w)` \u2014 analytic at 1, hLi 1 = 1;\n agrees with (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6)(w) on a punctured neighborhood of 1\n (`hLi_eq_near_one`).\n* `lcoeff k` \u2014 the Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1, DEFINED as\n iteratedDeriv (k+1) hLi 1 / (k+1)! (operational; no Laurent series\n needed at this stage).\n* `ResW1 n` \u2014 the residue at w = 1 of J(w) = k_n(w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6(w)),\n computed by the Leibniz identity (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi\n (D-064 \u00a74 R1, verified algebraically in session 014):\n ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121) =: `ResW1_eq_sum`.\n\nArchive references: D-036, D-037, D-064 (R1), journal-014/015.\n-/\nimport Mathlib\nimport Zeta23.Statement\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. The regularized factor zetaA = (w\u22121)\u03b6(w) at w = 1 -/\n\n/-- `zetaA w = (w\u22121)\u00b7\u03b6(w)` with the removable singularity at w = 1 filled\nby the residue value 1. Analytic at 1 (`zetaA_analyticAt_one`), value\n`zetaA 1 = 1`. -/\ndef zetaA : \u2102 \u2192 \u2102 := Function.update (fun w => (w - 1) * riemannZeta w) 1 1\n\nlemma zetaA_apply {w : \u2102} (hw : w \u2260 1) : zetaA w = (w - 1) * riemannZeta w :=\n Function.update_of_ne hw _ _\n\nlemma zetaA_one : zetaA 1 = 1 := Function.update_self _ _ _\n\nlemma zetaA_tendsto : Tendsto (fun w => (w - 1) * riemannZeta w) (\ud835\udcdd[\u2260] 1) (\ud835\udcdd 1) :=\n riemannZeta_residue_one\n\n/-- The regularized factor is analytic at w = 1 (removable singularity). -/\nlemma zetaA_analyticAt_one : AnalyticAt \u2102 zetaA 1 := by\n have hdiff : DifferentiableOn \u2102 (fun w => (w - 1) * riemannZeta w)\n (Metric.ball 1 2 \\ {1}) := by\n intro w hw\n have hw1 : w \u2260 1 := hw.2\n exact (differentiableAt_id.sub (differentiableAt_const 1)).mul\n (differentiableAt_riemannZeta hw1) |>.differentiableWithinAt\n have hbd : BddAbove (Complex.norm \u2218 (fun w => (w - 1) * riemannZeta w)) ''\n (Metric.ball 1 2 \\ {1}) := by\n have hT := zetaA_tendsto\n rw [Metric.tendsto_nhdsWithin_nhds] at hT\n obtain \u27e8\u03b4, h\u03b40, h\u03b4\u27e9 := hT 1 one_pos\n refine \u27e82, ?_\u27e9\n rintro _ \u27e8z, hz, rfl\u27e9\n have h1 : dist (z - 1) 0 = \u2016z - 1\u2016 := by\n rw [dist_eq_norm]; simp [sub_zero]\n have hz1 : z \u2260 1 := hz.2\n have hzz : dist z 1 < \u03b4 := by\n have := hz.1\n rw [Metric.mem_ball, dist_comm] at this\n exact this\n have hlt := h\u03b4 (by rwa [dist_zero_right, h1] at *)\n have : \u2016(z - 1) * riemannZeta z\u2016 \u2264 \u2016(1 : \u2102)\u2016 + 1 := by\n have := norm_sub_le_of_le hlt\n calc \u2016(z - 1) * riemannZeta z\u2016\n \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 := by\n have := norm_sub_le ((z - 1) * riemannZeta z) 1\n linarith [this, hlt]\n _ \u2264 2 := by\n have h2 := hlt\n rw [norm_one]\n linarith [h2]\n exact this\n have h := differentiableOn_update_limUnder_of_bddAbove\n (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2)) hdiff hbd\n have hlim : limUnder (\ud835\udcdd[\u2260] (1 : \u2102)) (fun w => (w - 1) * riemannZeta w) = 1 :=\n zetaA_tendsto.limUnder_eq\n rw [hlim] at h\n have hopen : IsOpen (Metric.ball (1 : \u2102) 2) := Metric.isOpen_ball\n have han := h.analyticOnNhd hopen\n exact han.analyticAt (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2))\n\n/-- zetaA is nonzero on a neighborhood of 1 (value 1 there). -/\nlemma zetaA_ne_zero_near_one : \u2200\u1da0 w in \ud835\udcdd (1 : \u2102), zetaA w \u2260 0 :=\n (zetaA_analyticAt_one.continuousAt).eventually_ne (by rw [zetaA_one]; norm_num)\n\n/-- zetaA is analytic everywhere except possibly at 1 \u2014 and in fact also\nat 1; we record the off-1 version for quotient computations. -/\nlemma zetaA_analyticAt_of_ne {w : \u2102} (hw : w \u2260 1) : AnalyticAt \u2102 zetaA w := by\n have h : (fun w => (w - 1) * riemannZeta w) =\u1da0[\ud835\udcdd w] zetaA := by\n filter_upwards [eventually_ne_nhds hw] with z hz using (zetaA_apply hz).symm\n have ha : AnalyticAt \u2102 (fun w => (w - 1) * riemannZeta w) w := by\n exact (analyticAt_id.sub analyticAt_const).mul\n (differentiableAt_riemannZeta hw).analyticAt\n exact ha.congr h\n\n/-! ## 2. hLi w = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w): analytic at 1, value 1 -/\n\n/-- hLi(w) = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w) \u2014 the analytic-at-1 form of\n(w\u22121)(\u2212\u03b6\u2032/\u03b6)(w) (`hLi_eq_near_one`). hLi 1 = 1. -/\ndef hLi (w : \u2102) : \u2102 := 1 - (w - 1) * (deriv zetaA w / zetaA w)\n\nlemma hLi_one : hLi 1 = 1 := by simp [hLi]\n\nlemma hLi_analyticAt_one : AnalyticAt \u2102 hLi 1 := by\n have ha := zetaA_analyticAt_one\n have hda : AnalyticAt \u2102 (deriv zetaA) 1 := ha.deriv\n have hne : zetaA 1 \u2260 0 := by rw [zetaA_one]; norm_num\n exact (analyticAt_const.sub analyticAt_id).mul\n (hda.div ha hne) |>.const_sub 1\n\n/-- On a punctured neighborhood of 1, hLi = (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6). -/\nlemma hLi_eq_of_ne {w : \u2102} (hw1 : w \u2260 1) (hw0 : riemannZeta w \u2260 0) :\n hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by\n have hA : zetaA w = (w - 1) * riemannZeta w := zetaA_apply hw1\n have hdA : deriv zetaA w = riemannZeta w + (w - 1) * deriv riemannZeta w := by\n have h1 : deriv (fun z => (z - 1) * riemannZeta z) w =\n deriv (fun z => z - 1) w * riemannZeta w +\n (w - 1) * deriv riemannZeta w :=\n deriv_mul ((differentiableAt_id.sub (differentiableAt_const 1)))\n (differentiableAt_riemannZeta hw1)\n have h2 : deriv (fun z => z - 1) w = 1 := by\n simp [deriv_sub, deriv_id'']\n have h3 : (fun z => (z - 1) * riemannZeta z) =\u1da0[\ud835\udcdd w] zetaA := by\n filter_upwards [eventually_ne_nhds hw1] with z hz using (zetaA_apply hz).symm\n rw [h3.deriv_eq, h1, h2, one_mul]\n rw [hLi, hdA, hA]\n have hw1' : w - 1 \u2260 0 := sub_ne_zero.mpr hw1\n field_simp [hw0, hw1']\n ring\n\n/-- The punctured-neighborhood form, for later contour work. -/\nlemma hLi_eq_near_one :\n \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by\n have hzero : \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), riemannZeta w \u2260 0 := by\n have h1 : (1 : \u2102) \u2208 {s : \u2102 | 1 \u2264 s.re} := by simp\n filter_upwards [eventually_mem_nhdsWithin] with w hw\n have hwre : 1 \u2264 w.re := by\n have := hw.2\n sorry\n exact riemannZeta_ne_zero_of_one_le_re hwre\n filter_upwards [hzero, eventually_mem_nhdsWithin] with w hw0 hw1\n exact hLi_eq_of_ne hw1 hw0\n\n/-! ## 3. The Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1 (operational definition) -/\n\n/-- The k-th Laurent coefficient of \u2212\u03b6\u2032/\u03b6 at s = 1:\n\u2212\u03b6\u2032/\u03b6(1+u) = u\u207b\u00b9 + \u03a3_{k\u22650} lcoeff k \u00b7 u^k (identification proved in\ntier ii\u2032-2/3; here lcoeff is DEFINED via the analytic hLi). -/\ndef lcoeff (k : \u2115) : \u2102 := iteratedDeriv (k + 1) hLi 1 / (k + 1) !\n\nlemma lcoeff_eq (k : \u2115) :\n lcoeff k = iteratedDeriv (k + 1) hLi 1 / (k + 1) ! := rfl\n\n/-- hLi's Taylor coefficient form: iteratedDeriv j hLi 1 / j ! = lcoeff (j\u22121). -/\nlemma hLi_iteratedDeriv_div_factorial {j : \u2115} (hj : 1 \u2264 j) :\n iteratedDeriv j hLi 1 / j ! = lcoeff (j - 1) := by\n rw [lcoeff]\n have : j = (j - 1) + 1 := by omega\n rw [this]\n\n/-! ## 4. The A-polynomial derivative: A(w) = w\u207f \u2212 (w\u22121)\u207f -/\n\n/-- Iterated derivatives of A(w) = w\u207f \u2212 (w\u22121)\u207f at 1:\nA^{(i)}(1) = n.descFactorial i for i < n, and A^{(n)}(1) = 0. -/\nlemma A_iter (n i : \u2115) (hi : i \u2264 n) :\n iteratedDeriv i (fun w => w ^ n - (w - 1) ^ n) (1 : \u2102) =\n if i < n then n.descFactorial i else 0 := by\n have hf : ContDiffAt \u2102 i (fun w : \u2102 => w ^ n) 1 :=\n (contDiff_id.pow n).contDiffAt\n have hg : ContDiffAt \u2102 i (fun w : \u2102 => (w - 1) ^ n) 1 :=\n ((contDiff_id.sub contDiff_const).pow n).contDiffAt\n rw [iteratedDeriv_sub hf hg]\n have h1 : iteratedDeriv i (fun w : \u2102 => w ^ n) 1 = n.descFactorial i := by\n rw [iteratedDeriv_pow]\n simp\n have h2 : iteratedDeriv i (fun w : \u2102 => (w - 1) ^ n) 1 =\n n.descFactorial i * (0 : \u2102) ^ (n - i) := by\n have e := iteratedDeriv_comp_sub_const i (fun w : \u2102 => w ^ n) (1 : \u2102)\n have e2 : iteratedDeriv i (fun w : \u2102 => (w - 1) ^ n) 1 =\n iteratedDeriv i (fun w : \u2102 => w ^ n) (1 - 1) := by\n have := congr_fun e 1\n convert this using 2\n rw [e2, iteratedDeriv_pow]\n simp\n rw [h1, h2]\n by_cases hin : i < n\n \u00b7 rw [if_pos hin]\n have : (0 : \u2102) ^ (n - i) = 0 := by\n apply zero_pow\n omega\n rw [this, mul_zero, sub_zero]\n \u00b7 rw [if_neg hin]\n have hin' : i = n := le_antisymm hi (by omega)\n subst hin'\n simp [Nat.descFactorial_self]\n\n/-! ## 5. The residue at w = 1: ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121) -/\n\n/-- The residue at w = 1 of the Lagarias-kernel integrand\nJ(w) = k_n(w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6(w)), packaged as (1/n!)\u00b7(d/dw)\u207f[(w\u207f\u2212(w\u22121)\u207f)hLi]\nat w = 1 (D-064 \u00a74 R1: (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi on a punctured\nneighborhood, by `hLi_eq_near_one`). -/\ndef ResW1 (n : \u2115) : \u2102 :=\n iteratedDeriv n (fun w => (w ^ n - (w - 1) ^ n) * hLi w) (1 : \u2102) / n !\n\n/-- The w = 1 residue value: ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121). -/\ntheorem ResW1_eq_sum (n : \u2115) :\n ResW1 n = \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n have hA : ContDiffAt \u2102 n (fun w : \u2102 => w ^ n - (w - 1) ^ n) 1 :=\n ((contDiff_id.pow n).sub ((contDiff_id.sub contDiff_const).pow n)).contDiffAt\n have hh : ContDiffAt \u2102 n hLi 1 := hLi_analyticAt_one.contDiffAt\n have hmul := iteratedDeriv_mul hA hh\n rw [ResW1, hmul]\n have hsum : \u2211 i \u2208 Finset.range (n + 1),\n n.choose i * iteratedDeriv i (fun w : \u2102 => w ^ n - (w - 1) ^ n) 1 *\n iteratedDeriv (n - i) hLi 1 =\n \u2211 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 := by\n apply Finset.sum_subset (Finset.range_le_iff.mpr (Nat.le_succ n))\n intro i hi\n rw [Finset.mem_range] at hi\n have hi0 : i \u2260 n := by omega\n rw [A_iter n i (by omega), if_pos (by omega)]\n \u00b7 rfl\n \u00b7 rw [Finset.mem_range] at *\n omega\n rw [hsum]\n have hfinal : (\u2211 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1) / n ! =\n \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n have hrewrite : \u2200 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 / n ! =\n (n.choose (n - i) : \u2102) * lcoeff (n - i - 1) := by\n intro i hi\n rw [Finset.mem_range] at hi\n have hcd : (n.choose i : \u2102) * (n.descFactorial i : \u2102) =\n n ! * n.choose i / (n - i) ! := by\n have h1 := Nat.choose_mul_factorial_mul_factorial (show i \u2264 n by omega)\n have h2 := Nat.factorial_mul_descFactorial (show i \u2264 n by omega)\n have : (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((i ! : \u2102) * ((n - i) ! : \u2102)) =\n (n ! : \u2102) * (n.choose i : \u2102) := by\n push_cast [h1, h2]\n ring\n have hfact : ((i ! : \u2102) * ((n - i) ! : \u2102)) \u2260 0 := by\n simp [Nat.factorial_ne_zero]\n have hthis := this\n field_simp at hthis \u22a2\n have h3 : (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((n - i) ! : \u2102) =\n (n ! : \u2102) * (n.choose i : \u2102) / 1 := by\n have h4 := hthis\n rw [mul_comm ((i ! : \u2102)) ((n - i) ! : \u2102)] at h4\n have h5 : (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((n - i) ! : \u2102) * (i ! : \u2102) =\n (n ! : \u2102) * (n.choose i : \u2102) := by\n rw [mul_comm ((n - i) ! : \u2102) (i ! : \u2102)] at h4\n calc (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((n - i) ! : \u2102) * (i ! : \u2102)\n = (n.choose i : \u2102) * (n.descFactorial i : \u2102) * (((n - i) ! : \u2102) * (i ! : \u2102)) := by ring\n _ = (n ! : \u2102) * (n.choose i : \u2102) := by\n have := h4\n ring_nf at this \u22a2\n convert this using 1\n ring\n exact (div_eq_one_iff_eq (by simp [Nat.factorial_ne_zero])).mpr h5\n field_simp at h3 \u22a2\n calc (n.choose i : \u2102) * (n.descFactorial i : \u2102)\n = ((n ! : \u2102) * (n.choose i : \u2102) / 1) / ((n - i) ! : \u2102) := by\n rw [\u2190 h3]\n field_simp\n ring\n _ = (n ! : \u2102) * (n.choose i : \u2102) / ((n - i) ! : \u2102) := by ring\n rw [hcd]\n have hni : n - i \u2265 1 := by omega\n rw [hLi_iteratedDeriv_div_factorial (j := n - i) (by omega)]\n rw [show n - i - 1 = n - i - 1 from rfl]\n have hcoe : ((n - i) ! : \u2102) \u2260 0 := by simp [Nat.factorial_ne_zero]\n field_simp\n rw [Nat.choose_symm (by omega : i \u2264 n)]\n ring\n rw [Finset.sum_div]\n rw [Finset.sum_congr rfl hrewrite]\n have hmap : \u2211 i \u2208 Finset.range n, (n.choose (n - i) : \u2102) * lcoeff (n - i - 1) =\n \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n rw [Finset.sum_range_reflect]\n apply Finset.sum_congr rfl\n intro i hi\n rw [Finset.mem_range] at hi\n have : n - 1 - i + 1 = n - i := by omega\n rw [this]\n have : n - (n - i) = i := by omega\n rw [Nat.choose_symm (show n - i \u2264 n by omega)]\n simp [this]\n ring\n exact hmap\n rw [hfinal]\n\nend NguyenRH1\n",
"structuredPatch": [],
"originalFile": null
}
thinking (7349 chars)
I wrote a first draft but I left a `sorry` in `hLi_eq_near_one` and some proofs are likely broken (hcd's algebra got convoluted, hsum's structure is off, hmap's reindexing is shaky). Let me compile and fix iteratively. Also I should fix hLi_eq_near_one's sorry: the zero-free punctured neighborhood of 1 — ζ(w) ≠ 0 for w near 1 with... the simple argument: ζ has a pole at 1, so |ζ| → ∞, hence ζ ≠ 0 in a punctured nhd: from riemannZeta_residue_one: (s−1)ζ(s) → 1, so (s−1)ζ(s) ≠ 0 in a punctured nhd, hence ζ(s) ≠ 0 there. That's cleaner than the re ≥ 1 approach:
```
lemma hLi_eq_near_one :
∀ᶠ w in 𝓝[≠] (1 : ℂ), hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by
have hT := riemannZeta_residue_one
have hne : ∀ᶠ w in 𝓝[≠] (1 : ℂ), (w - 1) * riemannZeta w ≠ 0 := by
have := hT.eventually_ne (show (1 : ℂ) ≠ 0 by norm_num)
exact this
filter_upwards [hne, eventually_mem_nhdsWithin] with w hw hw1
have hz : riemannZeta w ≠ 0 := by
have h2 := hw
simp only [ne_eq, mul_eq_zero] at h2
push_neg at h2
exact h2.2
exact hLi_eq_of_ne hw1 hz
```
`Tendsto.eventually_ne : Tendsto f l (𝓝 a) → a ≠ b → ∀ᶠ x in l, f x ≠ b` ✓ exists.
Also fix hcd — the coefficient algebra got tangled. Let me simplify: the identity needed:
(n.choose i : ℂ) * (n.descFactorial i : ℂ) / n ! = (n.choose i : ℂ) / ((n - i) ! : ℂ)·... wait — actually what I need: C(n,i)·descFac(i)/n!·h^{(n−i)} = C(n,i)·lcoeff(n−i−1) with lcoeff(n−i−1) = h^{(n−i)}/(n−i)!. So need C(n,i)·descFac(n,i)/n! = C(n,i)/(n−i)! ⟺ descFac(n,i)/n! = 1/(n−i)! ⟺ descFac(n,i)·... ⟺ n!/(n−i)! — i.e. descFac(n,i) = n!/(n−i)! — via factorial_mul_descFactorial: (n−i)!·descFac(n,i) = n! ⟹ descFac(n,i) = n!/(n−i)! ✓ (division in ℂ of the cast equality ✓ clean).
So the clean version:
```
have hdesc : (n.descFactorial i : ℂ) = (n ! : ℂ) / ((n - i) ! : ℂ) := by
have h2 := Nat.factorial_mul_descFactorial (show i ≤ n by omega)
have hcast : ((n - i) ! : ℂ) * (n.descFactorial i : ℂ) = (n ! : ℂ) := by exact_mod_cast h2
rw [eq_div_iff_mul_eq (by simp [Nat.factorial_ne_zero])]
rw [mul_comm]
exact hcast
```
`eq_div_iff_mul_eq : a = b / c ↔ a * c = b` (c ≠ 0) — check name: `eq_div_iff_mul_eq (hc : c ≠ 0) : a = b / c ↔ a * c = b` ✓.
Then term rewriting:
C(n,i)·descFac(n,i)·h^{(n−i)}/n! = C(n,i)·(n!/(n−i)!)·h^{(n−i)}/n! = C(n,i)·h^{(n−i)}/(n−i)! = C(n,i)·lcoeff(n−i−1).
And C(n,i) = C(n,n−i) (Nat.choose_symm hi).
The sum reindexing: ∑_{i ∈ range n} f(n−i) where f(k) = C(n,k)·lcoeff(k−1)... i ↦ n−i maps range n = {0,...,n−1} to {1,...,n} = Icc 1 n: `Finset.sum_range_reflect`? — sum_range_reflect : ∑ i ∈ range n, f i = ∑ i ∈ range n, f (n − 1 − i). Hmm that maps to n−1−i ∈ {0,...,n−1}. My target is Icc 1 n. Alternative: sum over range (n+1) with the zero terms? Or use `Finset.sum_bij`. Simplest: convert the target sum to range form: ∑ j ∈ Icc 1 n, g j = ∑ i ∈ range n, g (i + 1): `Finset.sum_Icc_eq_sum_range`? there's `Finset.sum_Icc_eq_sum_range : ∑ i ∈ Icc m n, f i = ∑ i ∈ range (n + 1 - m), f (i + m)` ✓ I believe. So ∑ j ∈ Icc 1 n, g j = ∑ i ∈ range n, g (i+1). Then:
∑ i ∈ range n, C(n,i)·descFac·h^{(n−i)}/n! = ∑ i ∈ range n, C(n,i)·lcoeff(n−i−1)·... vs ∑ i ∈ range n, g(i+1) = ∑ i ∈ range n, C(n,i+1)·lcoeff(i). Via sum_range_reflect: ∑ i ∈ range n, a(i) = ∑ i ∈ range n, a(n−1−i): with a(i) = C(n,i)·lcoeff(n−i−1): a(n−1−i) = C(n,n−1−i)·lcoeff(n−(n−1−i)−1) = C(n,i+1)·lcoeff(i)·... C(n,n−1−i) = C(n,i+1) (choose_symm: n−(n−1−i) = i+1 ✓). ✓
Let me restructure hfinal cleanly:
```
have hterm : ∀ i ∈ Finset.range n,
(n.choose i : ℂ) * (n.descFactorial i : ℂ) * iteratedDeriv (n - i) hLi 1 / n ! =
(n.choose i : ℂ) * lcoeff (n - i - 1) := by
intro i hi
rw [Finset.mem_range] at hi
have hdesc : (n.descFactorial i : ℂ) = (n ! : ℂ) / ((n - i) ! : ℂ) := by
have h2 := Nat.factorial_mul_descFactorial (show i ≤ n by omega)
have hcast : ((n - i) ! : ℂ) * (n.descFactorial i : ℂ) = (n ! : ℂ) := by exact_mod_cast h2
rw [eq_div_iff_mul_eq (by simp [Nat.factorial_ne_zero])]
rw [mul_comm]
exact hcast
rw [hdesc]
have hni : 1 ≤ n - i := by omega
have hlc : lcoeff (n - i - 1) = iteratedDeriv (n - i) hLi 1 / ((n - i) ! : ℂ) := by
rw [hLi_iteratedDeriv_div_factorial (j := n - i) hni]
rw [hlc]
field_simp
ring
```
field_simp + ring for: C·(n!/(n−i)!)·h/n! = C·(h/(n−i)!) — with h = iteratedDeriv — field_simp [n! ≠ 0, (n−i)! ≠ 0] then ring ✓.
Then:
```
rw [Finset.sum_div]
rw [Finset.sum_congr rfl hterm]
-- now: ∑ i ∈ range n, C(n,i)·lcoeff(n−i−1) = ∑ j ∈ Icc 1 n, C(n,j)·lcoeff(j−1)
have hre : ∑ i ∈ Finset.range n, (n.choose i : ℂ) * lcoeff (n - i - 1) =
∑ j ∈ Finset.Icc 1 n, (n.choose j : ℂ) * lcoeff (j - 1) := by
rw [Finset.sum_range_reflect]
-- now ∑ i ∈ range n, C(n, n−1−i)·lcoeff(n−(n−1−i)−1) = C(n,n−1−i)·lcoeff(i)
rw [Finset.sum_Icc_eq_sum_range]
apply Finset.sum_congr rfl
intro i hi
rw [Finset.mem_range] at hi
have e1 : n - 1 - i + 1 = n - i := by omega
-- target after rewrites: C(n, n−1−i)·lcoeff(n−1−i−...)... let me compute in code
...
```
Hmm the reindexing needs care. Finset.sum_range_reflect : ∑ i ∈ range n, f i = ∑ i ∈ range n, f (n - 1 - i). So ∑_{i<n} a(i) = ∑_{i<n} a(n−1−i): with a(k) = C(n,k)·lcoeff(n−k−1): a(n−1−i) = C(n,n−1−i)·lcoeff(n−(n−1−i)−1) = C(n,n−1−i)·lcoeff(i). C(n,n−1−i) = C(n,n−(n−1−i)) = C(n,i+1) — Nat.choose_symm : n.choose (n − k) = n.choose k for k ≤ n: n.choose (n−1−i) = n.choose (n − (n−1−i)) = n.choose (i+1)? — choose_symm (h : k ≤ n) : n.choose (n - k) = n.choose k — so n.choose (n−1−i) = n.choose (i+1) iff (n−1−i) = n − (i+1) ✓ and k := i+1 ≤ n ✓. So a(n−1−i) = C(n,i+1)·lcoeff(i). And the target (after sum_Icc_eq_sum_range): ∑_{i<n} C(n,i+1)·lcoeff((i+1)−1) = ∑_{i<n} C(n,i+1)·lcoeff(i) ✓ MATCHES.
OK — let me rewrite the file with all fixes. Also fix `hsum`'s broken structure (I had a malformed Finset.sum_subset application). The sum over range (n+1) → range n: the i = n term vanishes because A^{(n)}(1) = 0:
```
have hsum : (∑ i ∈ Finset.range (n + 1),
n.choose i * iteratedDeriv i (fun w : ℂ => w ^ n - (w - 1) ^ n) 1 *
iteratedDeriv (n - i) hLi 1) =
∑ i ∈ Finset.range n,
n.choose i * (n.descFactorial i : ℂ) * iteratedDeriv (n - i) hLi 1 := by
rw [Finset.sum_range_succ]
simp [A_iter n n le_rfl]
apply Finset.sum_congr rfl
intro i hi
rw [Finset.mem_range] at hi
rw [A_iter n i (by omega), if_pos hi]
```
Finset.sum_range_succ : ∑ i ∈ range (n+1), f i = ∑ i ∈ range n, f i + f n ✓. f n = C(n,n)·0·... = 0: A_iter n n (le_refl) : iteratedDeriv n A 1 = if n < n then ... else 0 = 0: if_neg (lt_irrefl n): simp [A_iter n n le_rfl] should simplify f n to 0 (A_iter gives if n < n then _ else 0 = 0 ✓).
Also `iteratedDeriv_sub` needs ContDiffAt — provided hA separately: in A_iter I used hf/hg locally ✓.
The `iteratedDeriv_mul` result: Σ i ∈ range (n+1), n.choose i * iteratedDeriv i A 1 * iteratedDeriv (n−i) hLi 1 — from the signature: `iteratedDeriv n (f * g) x = ∑ i ∈ .range (n + 1), n.choose i * iteratedDeriv i f x * iteratedDeriv (n - i) g x` — note: n.choose i is ℕ — cast to ℂ? The lemma as displayed: `n.choose i * iteratedDeriv i f x * iteratedDeriv (n - i) g x` — for 𝕜 → 𝔸 with 𝔸 an algebra over 𝕜 — the choose is a natural scalar mult — for ℂ→ℂ it should elaborate as (n.choose i : ℂ) cast or nsmul. Fine.
Let me now rewrite the whole file cleanly.
The draft needs repair — rewriting with the cleaned-up coefficient algebra, the proper zero-free argument, and fixed reindexing.
tool: Write ok
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiResidue.lean",
"content": "/-\nNguyenRH1/LiResidue.lean \u2014 tier ii\u2032 sub-stage ii\u2032-1b (D-064 \u00a74 R1):\nthe w = 1 residue of the Lagarias-kernel integrand, computed exactly.\n\nContents (Part 1):\n* `zetaA w = (w\u22121)\u00b7\u03b6(w)` extended by 1 at w = 1 \u2014 analytic at 1 with\n value 1 (removable singularity; Mathlib `riemannZeta_residue_one` +\n `differentiableOn_update_limUnder_of_bddAbove`).\n* `hLi w = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w)` \u2014 analytic at 1, hLi 1 = 1;\n agrees with (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6)(w) on a punctured neighborhood of 1\n (`hLi_eq_near_one`).\n* `lcoeff k` \u2014 the Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1, DEFINED as\n iteratedDeriv (k+1) hLi 1 / (k+1)!.\n* `ResW1 n` \u2014 the residue at w = 1 of J(w) = k_n(w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6(w)),\n packaged as (1/n!)\u00b7(d/dw)\u207f[(w\u207f\u2212(w\u22121)\u207f)\u00b7hLi] at w = 1 (D-064 \u00a74 R1:\n (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi on a punctured neighborhood, by\n `hLi_eq_near_one`). Value: `ResW1_eq_sum`.\n\nArchive references: D-036, D-037, D-064 (R1), journal-014/015.\n-/\nimport Mathlib\nimport Zeta23.Statement\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. The regularized factor zetaA = (w\u22121)\u03b6(w) at w = 1 -/\n\n/-- `zetaA w = (w\u22121)\u00b7\u03b6(w)` with the removable singularity at w = 1 filled\nby the residue value 1. Analytic at 1 (`zetaA_analyticAt_one`), value\n`zetaA 1 = 1`. -/\ndef zetaA : \u2102 \u2192 \u2102 := Function.update (fun w => (w - 1) * riemannZeta w) 1 1\n\nlemma zetaA_apply {w : \u2102} (hw : w \u2260 1) : zetaA w = (w - 1) * riemannZeta w :=\n Function.update_of_ne hw _ _\n\nlemma zetaA_one : zetaA 1 = 1 := Function.update_self _ _ _\n\n/-- The regularized factor is analytic at w = 1 (removable singularity). -/\nlemma zetaA_analyticAt_one : AnalyticAt \u2102 zetaA 1 := by\n have hdiff : DifferentiableOn \u2102 (fun w => (w - 1) * riemannZeta w)\n (Metric.ball 1 2 \\ {1}) := by\n intro w hw\n have hw1 : w \u2260 1 := hw.2\n exact ((differentiableAt_id.sub (differentiableAt_const 1)).mul\n (differentiableAt_riemannZeta hw1)).differentiableWithinAt\n have hbd : BddAbove (Complex.norm \u2218 (fun w => (w - 1) * riemannZeta w)) ''\n (Metric.ball 1 2 \\ {1}) := by\n have hT := riemannZeta_residue_one\n rw [Metric.tendsto_nhdsWithin_nhds] at hT\n obtain \u27e8\u03b4, h\u03b40, h\u03b4\u27e9 := hT 1 one_pos\n refine \u27e82, ?_\u27e9\n rintro _ \u27e8z, hz, rfl\u27e9\n have hz1 : z \u2260 1 := hz.2\n have hlt := h\u03b4 (by\n rw [dist_eq_norm, sub_zero]\n exact hz.1)\n have h1 : \u2016(z - 1) * riemannZeta z - 1\u2016 < 1 := by\n have := hlt\n rwa [dist_eq_norm] at this\n have := norm_sub_le ((z - 1) * riemannZeta z) 1\n simp only [Complex.norm_eq_abs] at *\n have h2 : \u2016(z - 1) * riemannZeta z\u2016 \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 :=\n norm_sub_le ((z - 1) * riemannZeta z) 1\n rw [norm_one] at h2\n linarith [h1]\n have h := differentiableOn_update_limUnder_of_bddAbove\n (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2)) hdiff hbd\n have hlim : limUnder (\ud835\udcdd[\u2260] (1 : \u2102)) (fun w => (w - 1) * riemannZeta w) = 1 :=\n riemannZeta_residue_one.limUnder_eq\n rw [hlim] at h\n have han := h.analyticOnNhd Metric.isOpen_ball\n exact han.analyticAt (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2))\n\n/-- zetaA is nonzero on a neighborhood of 1 (value 1 there). -/\nlemma zetaA_ne_zero_near_one : \u2200\u1da0 w in \ud835\udcdd (1 : \u2102), zetaA w \u2260 0 :=\n (zetaA_analyticAt_one.continuousAt).eventually_ne (by rw [zetaA_one]; norm_num)\n\n/-- zetaA is analytic at any w \u2260 1 (agrees with (w\u22121)\u03b6 there). -/\nlemma zetaA_analyticAt_of_ne {w : \u2102} (hw : w \u2260 1) : AnalyticAt \u2102 zetaA w := by\n have h : (fun w => (w - 1) * riemannZeta w) =\u1da0[\ud835\udcdd w] zetaA := by\n filter_upwards [eventually_ne_nhds hw] with z hz using (zetaA_apply hz).symm\n have ha : AnalyticAt \u2102 (fun w => (w - 1) * riemannZeta w) w :=\n (analyticAt_id.sub analyticAt_const).mul\n (differentiableAt_riemannZeta hw).analyticAt\n exact ha.congr h\n\n/-! ## 2. hLi w = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w): analytic at 1, value 1 -/\n\n/-- hLi(w) = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w) \u2014 the analytic-at-1 form of\n(w\u22121)(\u2212\u03b6\u2032/\u03b6)(w) (`hLi_eq_near_one`). hLi 1 = 1. -/\ndef hLi (w : \u2102) : \u2102 := 1 - (w - 1) * (deriv zetaA w / zetaA w)\n\nlemma hLi_one : hLi 1 = 1 := by simp [hLi]\n\nlemma hLi_analyticAt_one : AnalyticAt \u2102 hLi 1 := by\n have ha := zetaA_analyticAt_one\n have hda : AnalyticAt \u2102 (deriv zetaA) 1 := ha.deriv\n have hne : zetaA 1 \u2260 0 := by rw [zetaA_one]; norm_num\n exact ((analyticAt_const.sub analyticAt_id).mul\n (hda.div ha hne)).const_sub 1\n\n/-- On the punctured plane minus zeros of \u03b6, hLi = (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6). -/\nlemma hLi_eq_of_ne {w : \u2102} (hw1 : w \u2260 1) (hw0 : riemannZeta w \u2260 0) :\n hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by\n have hA : zetaA w = (w - 1) * riemannZeta w := zetaA_apply hw1\n have hdA : deriv zetaA w = riemannZeta w + (w - 1) * deriv riemannZeta w := by\n have h1 : deriv (fun z => (z - 1) * riemannZeta z) w =\n deriv (fun z => z - 1) w * riemannZeta w +\n (w - 1) * deriv riemannZeta w :=\n deriv_mul ((differentiableAt_id.sub (differentiableAt_const 1)))\n (differentiableAt_riemannZeta hw1)\n have h2 : deriv (fun z => z - 1) w = 1 := by\n simp [deriv_sub, deriv_id'']\n have h3 : (fun z => (z - 1) * riemannZeta z) =\u1da0[\ud835\udcdd w] zetaA := by\n filter_upwards [eventually_ne_nhds hw1] with z hz using (zetaA_apply hz).symm\n rw [h3.deriv_eq, h1, h2, one_mul]\n rw [hLi, hdA, hA]\n have hw1' : w - 1 \u2260 0 := sub_ne_zero.mpr hw1\n field_simp [hw0, hw1']\n ring\n\n/-- On a punctured neighborhood of 1, hLi = (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6). -/\nlemma hLi_eq_near_one :\n \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by\n have hne : \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), (w - 1) * riemannZeta w \u2260 0 :=\n riemannZeta_residue_one.eventually_ne (show (1 : \u2102) \u2260 0 by norm_num)\n filter_upwards [hne, eventually_mem_nhdsWithin] with w hw hw1\n have hz : riemannZeta w \u2260 0 := by\n have h2 := hw\n simp only [ne_eq, mul_eq_zero] at h2\n push_neg at h2\n exact h2.2\n exact hLi_eq_of_ne hw1 hz\n\n/-! ## 3. The Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1 (operational definition) -/\n\n/-- The k-th Laurent coefficient of \u2212\u03b6\u2032/\u03b6 at s = 1, DEFINED as\niteratedDeriv (k+1) hLi 1 / (k+1)! (the power-series coefficient of the\nanalytic hLi; the identification with \u2212\u03b6\u2032/\u03b6's Laurent expansion is\n`hLi_eq_near_one`). -/\ndef lcoeff (k : \u2115) : \u2102 := iteratedDeriv (k + 1) hLi 1 / (k + 1) !\n\n/-- hLi's Taylor coefficients: iteratedDeriv j hLi 1 / j ! = lcoeff (j\u22121). -/\nlemma hLi_iteratedDeriv_div_factorial {j : \u2115} (hj : 1 \u2264 j) :\n iteratedDeriv j hLi 1 / j ! = lcoeff (j - 1) := by\n rw [lcoeff]\n have : j = (j - 1) + 1 := by omega\n rw [this]\n\n/-! ## 4. The A-polynomial derivative: A(w) = w\u207f \u2212 (w\u22121)\u207f -/\n\n/-- Iterated derivatives of A(w) = w\u207f \u2212 (w\u22121)\u207f at 1:\nA^{(i)}(1) = n.descFactorial i for i < n, and A^{(n)}(1) = 0. -/\nlemma A_iter (n i : \u2115) (hi : i \u2264 n) :\n iteratedDeriv i (fun w => w ^ n - (w - 1) ^ n) (1 : \u2102) =\n if i < n then n.descFactorial i else 0 := by\n have hf : ContDiffAt \u2102 i (fun w : \u2102 => w ^ n) 1 :=\n (contDiff_id.pow n).contDiffAt\n have hg : ContDiffAt \u2102 i (fun w : \u2102 => (w - 1) ^ n) 1 :=\n ((contDiff_id.sub contDiff_const).pow n).contDiffAt\n rw [iteratedDeriv_sub hf hg]\n have h1 : iteratedDeriv i (fun w : \u2102 => w ^ n) 1 = n.descFactorial i := by\n rw [iteratedDeriv_pow]\n simp\n have h2 : iteratedDeriv i (fun w : \u2102 => (w - 1) ^ n) 1 =\n n.descFactorial i * (0 : \u2102) ^ (n - i) := by\n have e := congr_fun (iteratedDeriv_comp_sub_const i (fun w : \u2102 => w ^ n) (1 : \u2102)) 1\n rw [iteratedDeriv_pow] at e\n simpa using e\n rw [h1, h2]\n by_cases hin : i < n\n \u00b7 rw [if_pos hin]\n have hz : (0 : \u2102) ^ (n - i) = 0 := zero_pow (by omega)\n rw [hz, mul_zero, sub_zero]\n \u00b7 rw [if_neg hin]\n have hin' : i = n := le_antisymm hi (by omega)\n subst hin'\n simp [Nat.descFactorial_self]\n\n/-! ## 5. The residue at w = 1: ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121) -/\n\n/-- The residue at w = 1 of the Lagarias-kernel integrand\nJ(w) = k_n(w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6(w)), packaged as (1/n!)\u00b7(d/dw)\u207f[(w\u207f\u2212(w\u22121)\u207f)hLi]\nat w = 1 (D-064 \u00a74 R1: (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi punctured near 1,\nby `hLi_eq_near_one`). -/\ndef ResW1 (n : \u2115) : \u2102 :=\n iteratedDeriv n (fun w => (w ^ n - (w - 1) ^ n) * hLi w) (1 : \u2102) / n !\n\n/-- The w = 1 residue value: ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121). -/\ntheorem ResW1_eq_sum (n : \u2115) :\n ResW1 n = \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n have hA : ContDiffAt \u2102 n (fun w : \u2102 => w ^ n - (w - 1) ^ n) 1 :=\n ((contDiff_id.pow n).sub ((contDiff_id.sub contDiff_const).pow n)).contDiffAt\n have hh : ContDiffAt \u2102 n hLi 1 := hLi_analyticAt_one.contDiffAt\n have hmul := iteratedDeriv_mul hA hh\n rw [ResW1, hmul]\n have hsum : (\u2211 i \u2208 Finset.range (n + 1),\n n.choose i * iteratedDeriv i (fun w : \u2102 => w ^ n - (w - 1) ^ n) 1 *\n iteratedDeriv (n - i) hLi 1) =\n \u2211 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 := by\n rw [Finset.sum_range_succ]\n simp [A_iter n n le_rfl]\n apply Finset.sum_congr rfl\n intro i hi\n rw [Finset.mem_range] at hi\n rw [A_iter n i (by omega), if_pos hi]\n rw [hsum]\n have hterm : \u2200 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 / n ! =\n (n.choose i : \u2102) * lcoeff (n - i - 1) := by\n intro i hi\n rw [Finset.mem_range] at hi\n have hdesc : (n.descFactorial i : \u2102) = (n ! : \u2102) / ((n - i) ! : \u2102) := by\n have h2 := Nat.factorial_mul_descFactorial (show i \u2264 n by omega)\n have hcast : ((n - i) ! : \u2102) * (n.descFactorial i : \u2102) = (n ! : \u2102) := by\n exact_mod_cast h2\n rw [eq_div_iff_mul_eq (by simp [Nat.factorial_ne_zero])]\n rw [mul_comm]\n exact hcast\n rw [hdesc]\n have hlc : lcoeff (n - i - 1) = iteratedDeriv (n - i) hLi 1 / ((n - i) ! : \u2102) := by\n rw [hLi_iteratedDeriv_div_factorial (j := n - i) (by omega)]\n rw [hlc]\n field_simp\n ring\n rw [Finset.sum_div]\n rw [Finset.sum_congr rfl hterm]\n have hre : (\u2211 i \u2208 Finset.range n, (n.choose i : \u2102) * lcoeff (n - i - 1)) =\n \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n rw [Finset.sum_range_reflect]\n rw [Finset.sum_Icc_eq_sum_range]\n apply Finset.sum_congr rfl\n intro i hi\n rw [Finset.mem_range] at hi\n have e1 : n - 1 - i + 1 = n - i := by omega\n have e2 : n - (n - 1 - i) = i + 1 := by omega\n have e3 : n.choose (n - 1 - i) = n.choose (i + 1) := by\n rw [show n - 1 - i = n - (i + 1) by omega]\n exact Nat.choose_symm (by omega)\n have e4 : n - (n - 1 - i) - 1 = i := by omega\n rw [e1, e3]\n have : n - (i + 1) - 1 = i := by omega\n rw [this]\n exact hre\n\nend NguyenRH1\n"
}
result 2026-08-21 21:03:56Z → 2026-08-21 21:03:56Z
{
"type": "update",
"filePath": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiResidue.lean",
"content": "/-\nNguyenRH1/LiResidue.lean \u2014 tier ii\u2032 sub-stage ii\u2032-1b (D-064 \u00a74 R1):\nthe w = 1 residue of the Lagarias-kernel integrand, computed exactly.\n\nContents (Part 1):\n* `zetaA w = (w\u22121)\u00b7\u03b6(w)` extended by 1 at w = 1 \u2014 analytic at 1 with\n value 1 (removable singularity; Mathlib `riemannZeta_residue_one` +\n `differentiableOn_update_limUnder_of_bddAbove`).\n* `hLi w = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w)` \u2014 analytic at 1, hLi 1 = 1;\n agrees with (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6)(w) on a punctured neighborhood of 1\n (`hLi_eq_near_one`).\n* `lcoeff k` \u2014 the Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1, DEFINED as\n iteratedDeriv (k+1) hLi 1 / (k+1)!.\n* `ResW1 n` \u2014 the residue at w = 1 of J(w) = k_n(w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6(w)),\n packaged as (1/n!)\u00b7(d/dw)\u207f[(w\u207f\u2212(w\u22121)\u207f)\u00b7hLi] at w = 1 (D-064 \u00a74 R1:\n (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi on a punctured neighborhood, by\n `hLi_eq_near_one`). Value: `ResW1_eq_sum`.\n\nArchive references: D-036, D-037, D-064 (R1), journal-014/015.\n-/\nimport Mathlib\nimport Zeta23.Statement\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. The regularized factor zetaA = (w\u22121)\u03b6(w) at w = 1 -/\n\n/-- `zetaA w = (w\u22121)\u00b7\u03b6(w)` with the removable singularity at w = 1 filled\nby the residue value 1. Analytic at 1 (`zetaA_analyticAt_one`), value\n`zetaA 1 = 1`. -/\ndef zetaA : \u2102 \u2192 \u2102 := Function.update (fun w => (w - 1) * riemannZeta w) 1 1\n\nlemma zetaA_apply {w : \u2102} (hw : w \u2260 1) : zetaA w = (w - 1) * riemannZeta w :=\n Function.update_of_ne hw _ _\n\nlemma zetaA_one : zetaA 1 = 1 := Function.update_self _ _ _\n\n/-- The regularized factor is analytic at w = 1 (removable singularity). -/\nlemma zetaA_analyticAt_one : AnalyticAt \u2102 zetaA 1 := by\n have hdiff : DifferentiableOn \u2102 (fun w => (w - 1) * riemannZeta w)\n (Metric.ball 1 2 \\ {1}) := by\n intro w hw\n have hw1 : w \u2260 1 := hw.2\n exact ((differentiableAt_id.sub (differentiableAt_const 1)).mul\n (differentiableAt_riemannZeta hw1)).differentiableWithinAt\n have hbd : BddAbove (Complex.norm \u2218 (fun w => (w - 1) * riemannZeta w)) ''\n (Metric.ball 1 2 \\ {1}) := by\n have hT := riemannZeta_residue_one\n rw [Metric.tendsto_nhdsWithin_nhds] at hT\n obtain \u27e8\u03b4, h\u03b40, h\u03b4\u27e9 := hT 1 one_pos\n refine \u27e82, ?_\u27e9\n rintro _ \u27e8z, hz, rfl\u27e9\n have hz1 : z \u2260 1 := hz.2\n have hlt := h\u03b4 (by\n rw [dist_eq_norm, sub_zero]\n exact hz.1)\n have h1 : \u2016(z - 1) * riemannZeta z - 1\u2016 < 1 := by\n have := hlt\n rwa [dist_eq_norm] at this\n have := norm_sub_le ((z - 1) * riemannZeta z) 1\n simp only [Complex.norm_eq_abs] at *\n have h2 : \u2016(z - 1) * riemannZeta z\u2016 \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 :=\n norm_sub_le ((z - 1) * riemannZeta z) 1\n rw [norm_one] at h2\n linarith [h1]\n have h := differentiableOn_update_limUnder_of_bddAbove\n (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2)) hdiff hbd\n have hlim : limUnder (\ud835\udcdd[\u2260] (1 : \u2102)) (fun w => (w - 1) * riemannZeta w) = 1 :=\n riemannZeta_residue_one.limUnder_eq\n rw [hlim] at h\n have han := h.analyticOnNhd Metric.isOpen_ball\n exact han.analyticAt (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2))\n\n/-- zetaA is nonzero on a neighborhood of 1 (value 1 there). -/\nlemma zetaA_ne_zero_near_one : \u2200\u1da0 w in \ud835\udcdd (1 : \u2102), zetaA w \u2260 0 :=\n (zetaA_analyticAt_one.continuousAt).eventually_ne (by rw [zetaA_one]; norm_num)\n\n/-- zetaA is analytic at any w \u2260 1 (agrees with (w\u22121)\u03b6 there). -/\nlemma zetaA_analyticAt_of_ne {w : \u2102} (hw : w \u2260 1) : AnalyticAt \u2102 zetaA w := by\n have h : (fun w => (w - 1) * riemannZeta w) =\u1da0[\ud835\udcdd w] zetaA := by\n filter_upwards [eventually_ne_nhds hw] with z hz using (zetaA_apply hz).symm\n have ha : AnalyticAt \u2102 (fun w => (w - 1) * riemannZeta w) w :=\n (analyticAt_id.sub analyticAt_const).mul\n (differentiableAt_riemannZeta hw).analyticAt\n exact ha.congr h\n\n/-! ## 2. hLi w = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w): analytic at 1, value 1 -/\n\n/-- hLi(w) = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w) \u2014 the analytic-at-1 form of\n(w\u22121)(\u2212\u03b6\u2032/\u03b6)(w) (`hLi_eq_near_one`). hLi 1 = 1. -/\ndef hLi (w : \u2102) : \u2102 := 1 - (w - 1) * (deriv zetaA w / zetaA w)\n\nlemma hLi_one : hLi 1 = 1 := by simp [hLi]\n\nlemma hLi_analyticAt_one : AnalyticAt \u2102 hLi 1 := by\n have ha := zetaA_analyticAt_one\n have hda : AnalyticAt \u2102 (deriv zetaA) 1 := ha.deriv\n have hne : zetaA 1 \u2260 0 := by rw [zetaA_one]; norm_num\n exact ((analyticAt_const.sub analyticAt_id).mul\n (hda.div ha hne)).const_sub 1\n\n/-- On the punctured plane minus zeros of \u03b6, hLi = (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6). -/\nlemma hLi_eq_of_ne {w : \u2102} (hw1 : w \u2260 1) (hw0 : riemannZeta w \u2260 0) :\n hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by\n have hA : zetaA w = (w - 1) * riemannZeta w := zetaA_apply hw1\n have hdA : deriv zetaA w = riemannZeta w + (w - 1) * deriv riemannZeta w := by\n have h1 : deriv (fun z => (z - 1) * riemannZeta z) w =\n deriv (fun z => z - 1) w * riemannZeta w +\n (w - 1) * deriv riemannZeta w :=\n deriv_mul ((differentiableAt_id.sub (differentiableAt_const 1)))\n (differentiableAt_riemannZeta hw1)\n have h2 : deriv (fun z => z - 1) w = 1 := by\n simp [deriv_sub, deriv_id'']\n have h3 : (fun z => (z - 1) * riemannZeta z) =\u1da0[\ud835\udcdd w] zetaA := by\n filter_upwards [eventually_ne_nhds hw1] with z hz using (zetaA_apply hz).symm\n rw [h3.deriv_eq, h1, h2, one_mul]\n rw [hLi, hdA, hA]\n have hw1' : w - 1 \u2260 0 := sub_ne_zero.mpr hw1\n field_simp [hw0, hw1']\n ring\n\n/-- On a punctured neighborhood of 1, hLi = (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6). -/\nlemma hLi_eq_near_one :\n \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by\n have hne : \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), (w - 1) * riemannZeta w \u2260 0 :=\n riemannZeta_residue_one.eventually_ne (show (1 : \u2102) \u2260 0 by norm_num)\n filter_upwards [hne, eventually_mem_nhdsWithin] with w hw hw1\n have hz : riemannZeta w \u2260 0 := by\n have h2 := hw\n simp only [ne_eq, mul_eq_zero] at h2\n push_neg at h2\n exact h2.2\n exact hLi_eq_of_ne hw1 hz\n\n/-! ## 3. The Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1 (operational definition) -/\n\n/-- The k-th Laurent coefficient of \u2212\u03b6\u2032/\u03b6 at s = 1, DEFINED as\niteratedDeriv (k+1) hLi 1 / (k+1)! (the power-series coefficient of the\nanalytic hLi; the identification with \u2212\u03b6\u2032/\u03b6's Laurent expansion is\n`hLi_eq_near_one`). -/\ndef lcoeff (k : \u2115) : \u2102 := iteratedDeriv (k + 1) hLi 1 / (k + 1) !\n\n/-- hLi's Taylor coefficients: iteratedDeriv j hLi 1 / j ! = lcoeff (j\u22121). -/\nlemma hLi_iteratedDeriv_div_factorial {j : \u2115} (hj : 1 \u2264 j) :\n iteratedDeriv j hLi 1 / j ! = lcoeff (j - 1) := by\n rw [lcoeff]\n have : j = (j - 1) + 1 := by omega\n rw [this]\n\n/-! ## 4. The A-polynomial derivative: A(w) = w\u207f \u2212 (w\u22121)\u207f -/\n\n/-- Iterated derivatives of A(w) = w\u207f \u2212 (w\u22121)\u207f at 1:\nA^{(i)}(1) = n.descFactorial i for i < n, and A^{(n)}(1) = 0. -/\nlemma A_iter (n i : \u2115) (hi : i \u2264 n) :\n iteratedDeriv i (fun w => w ^ n - (w - 1) ^ n) (1 : \u2102) =\n if i < n then n.descFactorial i else 0 := by\n have hf : ContDiffAt \u2102 i (fun w : \u2102 => w ^ n) 1 :=\n (contDiff_id.pow n).contDiffAt\n have hg : ContDiffAt \u2102 i (fun w : \u2102 => (w - 1) ^ n) 1 :=\n ((contDiff_id.sub contDiff_const).pow n).contDiffAt\n rw [iteratedDeriv_sub hf hg]\n have h1 : iteratedDeriv i (fun w : \u2102 => w ^ n) 1 = n.descFactorial i := by\n rw [iteratedDeriv_pow]\n simp\n have h2 : iteratedDeriv i (fun w : \u2102 => (w - 1) ^ n) 1 =\n n.descFactorial i * (0 : \u2102) ^ (n - i) := by\n have e := congr_fun (iteratedDeriv_comp_sub_const i (fun w : \u2102 => w ^ n) (1 : \u2102)) 1\n rw [iteratedDeriv_pow] at e\n simpa using e\n rw [h1, h2]\n by_cases hin : i < n\n \u00b7 rw [if_pos hin]\n have hz : (0 : \u2102) ^ (n - i) = 0 := zero_pow (by omega)\n rw [hz, mul_zero, sub_zero]\n \u00b7 rw [if_neg hin]\n have hin' : i = n := le_antisymm hi (by omega)\n subst hin'\n simp [Nat.descFactorial_self]\n\n/-! ## 5. The residue at w = 1: ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121) -/\n\n/-- The residue at w = 1 of the Lagarias-kernel integrand\nJ(w) = k_n(w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6(w)), packaged as (1/n!)\u00b7(d/dw)\u207f[(w\u207f\u2212(w\u22121)\u207f)hLi]\nat w = 1 (D-064 \u00a74 R1: (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi punctured near 1,\nby `hLi_eq_near_one`). -/\ndef ResW1 (n : \u2115) : \u2102 :=\n iteratedDeriv n (fun w => (w ^ n - (w - 1) ^ n) * hLi w) (1 : \u2102) / n !\n\n/-- The w = 1 residue value: ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121). -/\ntheorem ResW1_eq_sum (n : \u2115) :\n ResW1 n = \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n have hA : ContDiffAt \u2102 n (fun w : \u2102 => w ^ n - (w - 1) ^ n) 1 :=\n ((contDiff_id.pow n).sub ((contDiff_id.sub contDiff_const).pow n)).contDiffAt\n have hh : ContDiffAt \u2102 n hLi 1 := hLi_analyticAt_one.contDiffAt\n have hmul := iteratedDeriv_mul hA hh\n rw [ResW1, hmul]\n have hsum : (\u2211 i \u2208 Finset.range (n + 1),\n n.choose i * iteratedDeriv i (fun w : \u2102 => w ^ n - (w - 1) ^ n) 1 *\n iteratedDeriv (n - i) hLi 1) =\n \u2211 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 := by\n rw [Finset.sum_range_succ]\n simp [A_iter n n le_rfl]\n apply Finset.sum_congr rfl\n intro i hi\n rw [Finset.mem_range] at hi\n rw [A_iter n i (by omega), if_pos hi]\n rw [hsum]\n have hterm : \u2200 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 / n ! =\n (n.choose i : \u2102) * lcoeff (n - i - 1) := by\n intro i hi\n rw [Finset.mem_range] at hi\n have hdesc : (n.descFactorial i : \u2102) = (n ! : \u2102) / ((n - i) ! : \u2102) := by\n have h2 := Nat.factorial_mul_descFactorial (show i \u2264 n by omega)\n have hcast : ((n - i) ! : \u2102) * (n.descFactorial i : \u2102) = (n ! : \u2102) := by\n exact_mod_cast h2\n rw [eq_div_iff_mul_eq (by simp [Nat.factorial_ne_zero])]\n rw [mul_comm]\n exact hcast\n rw [hdesc]\n have hlc : lcoeff (n - i - 1) = iteratedDeriv (n - i) hLi 1 / ((n - i) ! : \u2102) := by\n rw [hLi_iteratedDeriv_div_factorial (j := n - i) (by omega)]\n rw [hlc]\n field_simp\n ring\n rw [Finset.sum_div]\n rw [Finset.sum_congr rfl hterm]\n have hre : (\u2211 i \u2208 Finset.range n, (n.choose i : \u2102) * lcoeff (n - i - 1)) =\n \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n rw [Finset.sum_range_reflect]\n rw [Finset.sum_Icc_eq_sum_range]\n apply Finset.sum_congr rfl\n intro i hi\n rw [Finset.mem_range] at hi\n have e1 : n - 1 - i + 1 = n - i := by omega\n have e2 : n - (n - 1 - i) = i + 1 := by omega\n have e3 : n.choose (n - 1 - i) = n.choose (i + 1) := by\n rw [show n - 1 - i = n - (i + 1) by omega]\n exact Nat.choose_symm (by omega)\n have e4 : n - (n - 1 - i) - 1 = i := by omega\n rw [e1, e3]\n have : n - (i + 1) - 1 = i := by omega\n rw [this]\n exact hre\n\nend NguyenRH1\n",
"structuredPatch": [
{
"oldStart": 2,
"oldLines": 7,
"newStart": 2,
"newLines": 7,
"lines": [
" NguyenRH1/LiResidue.lean \u2014 tier ii\u2032 sub-stage ii\u2032-1b (D-064 \u00a74 R1):",
" the w = 1 residue of the Lagarias-kernel integrand, computed exactly.",
" ",
"-Contents (Part 1, this file's core):",
"+Contents (Part 1):",
" * `zetaA w = (w\u22121)\u00b7\u03b6(w)` extended by 1 at w = 1 \u2014 analytic at 1 with",
" value 1 (removable singularity; Mathlib `riemannZeta_residue_one` +",
" `differentiableOn_update_limUnder_of_bddAbove`)."
]
},
{
"oldStart": 10,
"oldLines": 12,
"newStart": 10,
"newLines": 11,
"lines": [
" agrees with (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6)(w) on a punctured neighborhood of 1",
" (`hLi_eq_near_one`).",
" * `lcoeff k` \u2014 the Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1, DEFINED as",
"- iteratedDeriv (k+1) hLi 1 / (k+1)! (operational; no Laurent series",
"- needed at this stage).",
"+ iteratedDeriv (k+1) hLi 1 / (k+1)!.",
" * `ResW1 n` \u2014 the residue at w = 1 of J(w) = k_n(w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6(w)),",
"- computed by the Leibniz identity (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi",
"- (D-064 \u00a74 R1, verified algebraically in session 014):",
"- ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121) =: `ResW1_eq_sum`.",
"+ packaged as (1/n!)\u00b7(d/dw)\u207f[(w\u207f\u2212(w\u22121)\u207f)\u00b7hLi] at w = 1 (D-064 \u00a74 R1:",
"+ (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi on a punctured neighborhood, by",
"+ `hLi_eq_near_one`). Value: `ResW1_eq_sum`.",
" ",
" Archive references: D-036, D-037, D-064 (R1), journal-014/015.",
" -/"
]
},
{
"oldStart": 40,
"oldLines": 63,
"newStart": 39,
"newLines": 52,
"lines": [
" ",
" lemma zetaA_one : zetaA 1 = 1 := Function.update_self _ _ _",
" ",
"-lemma zetaA_tendsto : Tendsto (fun w => (w - 1) * riemannZeta w) (\ud835\udcdd[\u2260] 1) (\ud835\udcdd 1) :=",
"- riemannZeta_residue_one",
"-",
" /-- The regularized factor is analytic at w = 1 (removable singularity). -/",
" lemma zetaA_analyticAt_one : AnalyticAt \u2102 zetaA 1 := by",
" have hdiff : DifferentiableOn \u2102 (fun w => (w - 1) * riemannZeta w)",
" (Metric.ball 1 2 \\ {1}) := by",
" intro w hw",
" have hw1 : w \u2260 1 := hw.2",
"- exact (differentiableAt_id.sub (differentiableAt_const 1)).mul",
"- (differentiableAt_riemannZeta hw1) |>.differentiableWithinAt",
"+ exact ((differentiableAt_id.sub (differentiableAt_const 1)).mul",
"+ (differentiableAt_riemannZeta hw1)).differentiableWithinAt",
" have hbd : BddAbove (Complex.norm \u2218 (fun w => (w - 1) * riemannZeta w)) ''",
" (Metric.ball 1 2 \\ {1}) := by",
"- have hT := zetaA_tendsto",
"+ have hT := riemannZeta_residue_one",
" rw [Metric.tendsto_nhdsWithin_nhds] at hT",
" obtain \u27e8\u03b4, h\u03b40, h\u03b4\u27e9 := hT 1 one_pos",
" refine \u27e82, ?_\u27e9",
" rintro _ \u27e8z, hz, rfl\u27e9",
"- have h1 : dist (z - 1) 0 = \u2016z - 1\u2016 := by",
"- rw [dist_eq_norm]; simp [sub_zero]",
" have hz1 : z \u2260 1 := hz.2",
"- have hzz : dist z 1 < \u03b4 := by",
"- have := hz.1",
"- rw [Metric.mem_ball, dist_comm] at this",
"- exact this",
"- have hlt := h\u03b4 (by rwa [dist_zero_right, h1] at *)",
"- have : \u2016(z - 1) * riemannZeta z\u2016 \u2264 \u2016(1 : \u2102)\u2016 + 1 := by",
"- have := norm_sub_le_of_le hlt",
"- calc \u2016(z - 1) * riemannZeta z\u2016",
"- \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 := by",
"- have := norm_sub_le ((z - 1) * riemannZeta z) 1",
"- linarith [this, hlt]",
"- _ \u2264 2 := by",
"- have h2 := hlt",
"- rw [norm_one]",
"- linarith [h2]",
"- exact this",
"+ have hlt := h\u03b4 (by",
"+ rw [dist_eq_norm, sub_zero]",
"+ exact hz.1)",
"+ have h1 : \u2016(z - 1) * riemannZeta z - 1\u2016 < 1 := by",
"+ have := hlt",
"+ rwa [dist_eq_norm] at this",
"+ have := norm_sub_le ((z - 1) * riemannZeta z) 1",
"+ simp only [Complex.norm_eq_abs] at *",
"+ have h2 : \u2016(z - 1) * riemannZeta z\u2016 \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 :=",
"+ norm_sub_le ((z - 1) * riemannZeta z) 1",
"+ rw [norm_one] at h2",
"+ linarith [h1]",
" have h := differentiableOn_update_limUnder_of_bddAbove",
" (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2)) hdiff hbd",
" have hlim : limUnder (\ud835\udcdd[\u2260] (1 : \u2102)) (fun w => (w - 1) * riemannZeta w) = 1 :=",
"- zetaA_tendsto.limUnder_eq",
"+ riemannZeta_residue_one.limUnder_eq",
" rw [hlim] at h",
"- have hopen : IsOpen (Metric.ball (1 : \u2102) 2) := Metric.isOpen_ball",
"- have han := h.analyticOnNhd hopen",
"+ have han := h.analyticOnNhd Metric.isOpen_ball",
" exact han.analyticAt (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2))",
" ",
" /-- zetaA is nonzero on a neighborhood of 1 (value 1 there). -/",
" lemma zetaA_ne_zero_near_one : \u2200\u1da0 w in \ud835\udcdd (1 : \u2102), zetaA w \u2260 0 :=",
" (zetaA_analyticAt_one.continuousAt).eventually_ne (by rw [zetaA_one]; norm_num)",
" ",
"-/-- zetaA is analytic everywhere except possibly at 1 \u2014 and in fact also",
"-at 1; we record the off-1 version for quotient computations. -/",
"+/-- zetaA is analytic at any w \u2260 1 (agrees with (w\u22121)\u03b6 there). -/",
" lemma zetaA_analyticAt_of_ne {w : \u2102} (hw : w \u2260 1) : AnalyticAt \u2102 zetaA w := by",
" have h : (fun w => (w - 1) * riemannZeta w) =\u1da0[\ud835\udcdd w] zetaA := by",
" filter_upwards [eventually_ne_nhds hw] with z hz using (zetaA_apply hz).symm",
"- have ha : AnalyticAt \u2102 (fun w => (w - 1) * riemannZeta w) w := by",
"- exact (analyticAt_id.sub analyticAt_const).mul",
"+ have ha : AnalyticAt \u2102 (fun w => (w - 1) * riemannZeta w) w :=",
"+ (analyticAt_id.sub analyticAt_const).mul",
" (differentiableAt_riemannZeta hw).analyticAt",
" exact ha.congr h",
" "
]
},
{
"oldStart": 112,
"oldLines": 10,
"newStart": 100,
"newLines": 10,
"lines": [
" have ha := zetaA_analyticAt_one",
" have hda : AnalyticAt \u2102 (deriv zetaA) 1 := ha.deriv",
" have hne : zetaA 1 \u2260 0 := by rw [zetaA_one]; norm_num",
"- exact (analyticAt_const.sub analyticAt_id).mul",
"- (hda.div ha hne) |>.const_sub 1",
"+ exact ((analyticAt_const.sub analyticAt_id).mul",
"+ (hda.div ha hne)).const_sub 1",
" ",
"-/-- On a punctured neighborhood of 1, hLi = (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6). -/",
"+/-- On the punctured plane minus zeros of \u03b6, hLi = (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6). -/",
" lemma hLi_eq_of_ne {w : \u2102} (hw1 : w \u2260 1) (hw0 : riemannZeta w \u2260 0) :",
" hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by",
" have hA : zetaA w = (w - 1) * riemannZeta w := zetaA_apply hw1"
]
},
{
"oldStart": 135,
"oldLines": 30,
"newStart": 123,
"newLines": 28,
"lines": [
" field_simp [hw0, hw1']",
" ring",
" ",
"-/-- The punctured-neighborhood form, for later contour work. -/",
"+/-- On a punctured neighborhood of 1, hLi = (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6). -/",
" lemma hLi_eq_near_one :",
" \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by",
"- have hzero : \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), riemannZeta w \u2260 0 := by",
"- have h1 : (1 : \u2102) \u2208 {s : \u2102 | 1 \u2264 s.re} := by simp",
"- filter_upwards [eventually_mem_nhdsWithin] with w hw",
"- have hwre : 1 \u2264 w.re := by",
"- have := hw.2",
"- sorry",
"- exact riemannZeta_ne_zero_of_one_le_re hwre",
"- filter_upwards [hzero, eventually_mem_nhdsWithin] with w hw0 hw1",
"- exact hLi_eq_of_ne hw1 hw0",
"+ have hne : \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), (w - 1) * riemannZeta w \u2260 0 :=",
"+ riemannZeta_residue_one.eventually_ne (show (1 : \u2102) \u2260 0 by norm_num)",
"+ filter_upwards [hne, eventually_mem_nhdsWithin] with w hw hw1",
"+ have hz : riemannZeta w \u2260 0 := by",
"+ have h2 := hw",
"+ simp only [ne_eq, mul_eq_zero] at h2",
"+ push_neg at h2",
"+ exact h2.2",
"+ exact hLi_eq_of_ne hw1 hz",
" ",
" /-! ## 3. The Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1 (operational definition) -/",
" ",
"-/-- The k-th Laurent coefficient of \u2212\u03b6\u2032/\u03b6 at s = 1:",
"-\u2212\u03b6\u2032/\u03b6(1+u) = u\u207b\u00b9 + \u03a3_{k\u22650} lcoeff k \u00b7 u^k (identification proved in",
"-tier ii\u2032-2/3; here lcoeff is DEFINED via the analytic hLi). -/",
"+/-- The k-th Laurent coefficient of \u2212\u03b6\u2032/\u03b6 at s = 1, DEFINED as",
"+iteratedDeriv (k+1) hLi 1 / (k+1)! (the power-series coefficient of the",
"+analytic hLi; the identification with \u2212\u03b6\u2032/\u03b6's Laurent expansion is",
"+`hLi_eq_near_one`). -/",
" def lcoeff (k : \u2115) : \u2102 := iteratedDeriv (k + 1) hLi 1 / (k + 1) !",
" ",
"-lemma lcoeff_eq (k : \u2115) :",
"- lcoeff k = iteratedDeriv (k + 1) hLi 1 / (k + 1) ! := rfl",
"-",
"-/-- hLi's Taylor coefficient form: iteratedDeriv j hLi 1 / j ! = lcoeff (j\u22121). -/",
"+/-- hLi's Taylor coefficients: iteratedDeriv j hLi 1 / j ! = lcoeff (j\u22121). -/",
" lemma hLi_iteratedDeriv_div_factorial {j : \u2115} (hj : 1 \u2264 j) :",
" iteratedDeriv j hLi 1 / j ! = lcoeff (j - 1) := by",
" rw [lcoeff]"
]
},
{
"oldStart": 182,
"oldLines": 20,
"newStart": 168,
"newLines": 14,
"lines": [
" simp",
" have h2 : iteratedDeriv i (fun w : \u2102 => (w - 1) ^ n) 1 =",
" n.descFactorial i * (0 : \u2102) ^ (n - i) := by",
"- have e := iteratedDeriv_comp_sub_const i (fun w : \u2102 => w ^ n) (1 : \u2102)",
"- have e2 : iteratedDeriv i (fun w : \u2102 => (w - 1) ^ n) 1 =",
"- iteratedDeriv i (fun w : \u2102 => w ^ n) (1 - 1) := by",
"- have := congr_fun e 1",
"- convert this using 2",
"- rw [e2, iteratedDeriv_pow]",
"- simp",
"+ have e := congr_fun (iteratedDeriv_comp_sub_const i (fun w : \u2102 => w ^ n) (1 : \u2102)) 1",
"+ rw [iteratedDeriv_pow] at e",
"+ simpa using e",
" rw [h1, h2]",
" by_cases hin : i < n",
" \u00b7 rw [if_pos hin]",
"- have : (0 : \u2102) ^ (n - i) = 0 := by",
"- apply zero_pow",
"- omega",
"- rw [this, mul_zero, sub_zero]",
"+ have hz : (0 : \u2102) ^ (n - i) = 0 := zero_pow (by omega)",
"+ rw [hz, mul_zero, sub_zero]",
" \u00b7 rw [if_neg hin]",
" have hin' : i = n := le_antisymm hi (by omega)",
" subst hin'"
]
},
{
"oldStart": 205,
"oldLines": 8,
"newStart": 185,
"newLines": 8,
"lines": [
" ",
" /-- The residue at w = 1 of the Lagarias-kernel integrand",
" J(w) = k_n(w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6(w)), packaged as (1/n!)\u00b7(d/dw)\u207f[(w\u207f\u2212(w\u22121)\u207f)hLi]",
"-at w = 1 (D-064 \u00a74 R1: (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi on a punctured",
"-neighborhood, by `hLi_eq_near_one`). -/",
"+at w = 1 (D-064 \u00a74 R1: (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi punctured near 1,",
"+by `hLi_eq_near_one`). -/",
" def ResW1 (n : \u2115) : \u2102 :=",
" iteratedDeriv n (fun w => (w ^ n - (w - 1) ^ n) * hLi w) (1 : \u2102) / n !",
" "
]
},
{
"oldStart": 218,
"oldLines": 86,
"newStart": 198,
"newLines": 55,
"lines": [
" have hh : ContDiffAt \u2102 n hLi 1 := hLi_analyticAt_one.contDiffAt",
" have hmul := iteratedDeriv_mul hA hh",
" rw [ResW1, hmul]",
"- have hsum : \u2211 i \u2208 Finset.range (n + 1),",
"+ have hsum : (\u2211 i \u2208 Finset.range (n + 1),",
" n.choose i * iteratedDeriv i (fun w : \u2102 => w ^ n - (w - 1) ^ n) 1 *",
"- iteratedDeriv (n - i) hLi 1 =",
"+ iteratedDeriv (n - i) hLi 1) =",
" \u2211 i \u2208 Finset.range n,",
" n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 := by",
"- apply Finset.sum_subset (Finset.range_le_iff.mpr (Nat.le_succ n))",
"+ rw [Finset.sum_range_succ]",
"+ simp [A_iter n n le_rfl]",
"+ apply Finset.sum_congr rfl",
" intro i hi",
" rw [Finset.mem_range] at hi",
"- have hi0 : i \u2260 n := by omega",
"- rw [A_iter n i (by omega), if_pos (by omega)]",
"- \u00b7 rfl",
"- \u00b7 rw [Finset.mem_range] at *",
"- omega",
"+ rw [A_iter n i (by omega), if_pos hi]",
" rw [hsum]",
"- have hfinal : (\u2211 i \u2208 Finset.range n,",
"- n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1) / n ! =",
"+ have hterm : \u2200 i \u2208 Finset.range n,",
"+ n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 / n ! =",
"+ (n.choose i : \u2102) * lcoeff (n - i - 1) := by",
"+ intro i hi",
"+ rw [Finset.mem_range] at hi",
"+ have hdesc : (n.descFactorial i : \u2102) = (n ! : \u2102) / ((n - i) ! : \u2102) := by",
"+ have h2 := Nat.factorial_mul_descFactorial (show i \u2264 n by omega)",
"+ have hcast : ((n - i) ! : \u2102) * (n.descFactorial i : \u2102) = (n ! : \u2102) := by",
"+ exact_mod_cast h2",
"+ rw [eq_div_iff_mul_eq (by simp [Nat.factorial_ne_zero])]",
"+ rw [mul_comm]",
"+ exact hcast",
"+ rw [hdesc]",
"+ have hlc : lcoeff (n - i - 1) = iteratedDeriv (n - i) hLi 1 / ((n - i) ! : \u2102) := by",
"+ rw [hLi_iteratedDeriv_div_factorial (j := n - i) (by omega)]",
"+ rw [hlc]",
"+ field_simp",
"+ ring",
"+ rw [Finset.sum_div]",
"+ rw [Finset.sum_congr rfl hterm]",
"+ have hre : (\u2211 i \u2208 Finset.range n, (n.choose i : \u2102) * lcoeff (n - i - 1)) =",
" \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by",
"- have hrewrite : \u2200 i \u2208 Finset.range n,",
"- n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 / n ! =",
"- (n.choose (n - i) : \u2102) * lcoeff (n - i - 1) := by",
"- intro i hi",
"- rw [Finset.mem_range] at hi",
"- have hcd : (n.choose i : \u2102) * (n.descFactorial i : \u2102) =",
"- n ! * n.choose i / (n - i) ! := by",
"- have h1 := Nat.choose_mul_factorial_mul_factorial (show i \u2264 n by omega)",
"- have h2 := Nat.factorial_mul_descFactorial (show i \u2264 n by omega)",
"- have : (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((i ! : \u2102) * ((n - i) ! : \u2102)) =",
"- (n ! : \u2102) * (n.choose i : \u2102) := by",
"- push_cast [h1, h2]",
"- ring",
"- have hfact : ((i ! : \u2102) * ((n - i) ! : \u2102)) \u2260 0 := by",
"- simp [Nat.factorial_ne_zero]",
"- have hthis := this",
"- field_simp at hthis \u22a2",
"- have h3 : (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((n - i) ! : \u2102) =",
"- (n ! : \u2102) * (n.choose i : \u2102) / 1 := by",
"- have h4 := hthis",
"- rw [mul_comm ((i ! : \u2102)) ((n - i) ! : \u2102)] at h4",
"- have h5 : (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((n - i) ! : \u2102) * (i ! : \u2102) =",
"- (n ! : \u2102) * (n.choose i : \u2102) := by",
"- rw [mul_comm ((n - i) ! : \u2102) (i ! : \u2102)] at h4",
"- calc (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((n - i) ! : \u2102) * (i ! : \u2102)",
"- = (n.choose i : \u2102) * (n.descFactorial i : \u2102) * (((n - i) ! : \u2102) * (i ! : \u2102)) := by ring",
"- _ = (n ! : \u2102) * (n.choose i : \u2102) := by",
"- have := h4",
"- ring_nf at this \u22a2",
"- convert this using 1",
"- ring",
"- exact (div_eq_one_iff_eq (by simp [Nat.factorial_ne_zero])).mpr h5",
"- field_simp at h3 \u22a2",
"- calc (n.choose i : \u2102) * (n.descFactorial i : \u2102)",
"- = ((n ! : \u2102) * (n.choose i : \u2102) / 1) / ((n - i) ! : \u2102) := by",
"- rw [\u2190 h3]",
"- field_simp",
"- ring",
"- _ = (n ! : \u2102) * (n.choose i : \u2102) / ((n - i) ! : \u2102) := by ring",
"- rw [hcd]",
"- have hni : n - i \u2265 1 := by omega",
"- rw [hLi_iteratedDeriv_div_factorial (j := n - i) (by omega)]",
"- rw [show n - i - 1 = n - i - 1 from rfl]",
"- have hcoe : ((n - i) ! : \u2102) \u2260 0 := by simp [Nat.factorial_ne_zero]",
"- field_simp",
"- rw [Nat.choose_symm (by omega : i \u2264 n)]",
"- ring",
"- rw [Finset.sum_div]",
"- rw [Finset.sum_congr rfl hrewrite]",
"- have hmap : \u2211 i \u2208 Finset.range n, (n.choose (n - i) : \u2102) * lcoeff (n - i - 1) =",
"- \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by",
"- rw [Finset.sum_range_reflect]",
"- apply Finset.sum_congr rfl",
"- intro i hi",
"- rw [Finset.mem_range] at hi",
"- have : n - 1 - i + 1 = n - i := by omega",
"- rw [this]",
"- have : n - (n - i) = i := by omega",
"- rw [Nat.choose_symm (show n - i \u2264 n by omega)]",
"- simp [this]",
"- ring",
"- exact hmap",
"- rw [hfinal]",
"+ rw [Finset.sum_range_reflect]",
"+ rw [Finset.sum_Icc_eq_sum_range]",
"+ apply Finset.sum_congr rfl",
"+ intro i hi",
"+ rw [Finset.mem_range] at hi",
"+ have e1 : n - 1 - i + 1 = n - i := by omega",
"+ have e2 : n - (n - 1 - i) = i + 1 := by omega",
"+ have e3 : n.choose (n - 1 - i) = n.choose (i + 1) := by",
"+ rw [show n - 1 - i = n - (i + 1) by omega]",
"+ exact Nat.choose_symm (by omega)",
"+ have e4 : n - (n - 1 - i) - 1 = i := by omega",
"+ rw [e1, e3]",
"+ have : n - (i + 1) - 1 = i := by omega",
"+ rw [this]",
"+ exact hre",
" ",
" end NguyenRH1",
" "
]
}
],
"originalFile": "/-\nNguyenRH1/LiResidue.lean \u2014 tier ii\u2032 sub-stage ii\u2032-1b (D-064 \u00a74 R1):\nthe w = 1 residue of the Lagarias-kernel integrand, computed exactly.\n\nContents (Part 1, this file's core):\n* `zetaA w = (w\u22121)\u00b7\u03b6(w)` extended by 1 at w = 1 \u2014 analytic at 1 with\n value 1 (removable singularity; Mathlib `riemannZeta_residue_one` +\n `differentiableOn_update_limUnder_of_bddAbove`).\n* `hLi w = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w)` \u2014 analytic at 1, hLi 1 = 1;\n agrees with (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6)(w) on a punctured neighborhood of 1\n (`hLi_eq_near_one`).\n* `lcoeff k` \u2014 the Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1, DEFINED as\n iteratedDeriv (k+1) hLi 1 / (k+1)! (operational; no Laurent series\n needed at this stage).\n* `ResW1 n` \u2014 the residue at w = 1 of J(w) = k_n(w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6(w)),\n computed by the Leibniz identity (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi\n (D-064 \u00a74 R1, verified algebraically in session 014):\n ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121) =: `ResW1_eq_sum`.\n\nArchive references: D-036, D-037, D-064 (R1), journal-014/015.\n-/\nimport Mathlib\nimport Zeta23.Statement\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. The regularized factor zetaA = (w\u22121)\u03b6(w) at w = 1 -/\n\n/-- `zetaA w = (w\u22121)\u00b7\u03b6(w)` with the removable singularity at w = 1 filled\nby the residue value 1. Analytic at 1 (`zetaA_analyticAt_one`), value\n`zetaA 1 = 1`. -/\ndef zetaA : \u2102 \u2192 \u2102 := Function.update (fun w => (w - 1) * riemannZeta w) 1 1\n\nlemma zetaA_apply {w : \u2102} (hw : w \u2260 1) : zetaA w = (w - 1) * riemannZeta w :=\n Function.update_of_ne hw _ _\n\nlemma zetaA_one : zetaA 1 = 1 := Function.update_self _ _ _\n\nlemma zetaA_tendsto : Tendsto (fun w => (w - 1) * riemannZeta w) (\ud835\udcdd[\u2260] 1) (\ud835\udcdd 1) :=\n riemannZeta_residue_one\n\n/-- The regularized factor is analytic at w = 1 (removable singularity). -/\nlemma zetaA_analyticAt_one : AnalyticAt \u2102 zetaA 1 := by\n have hdiff : DifferentiableOn \u2102 (fun w => (w - 1) * riemannZeta w)\n (Metric.ball 1 2 \\ {1}) := by\n intro w hw\n have hw1 : w \u2260 1 := hw.2\n exact (differentiableAt_id.sub (differentiableAt_const 1)).mul\n (differentiableAt_riemannZeta hw1) |>.differentiableWithinAt\n have hbd : BddAbove (Complex.norm \u2218 (fun w => (w - 1) * riemannZeta w)) ''\n (Metric.ball 1 2 \\ {1}) := by\n have hT := zetaA_tendsto\n rw [Metric.tendsto_nhdsWithin_nhds] at hT\n obtain \u27e8\u03b4, h\u03b40, h\u03b4\u27e9 := hT 1 one_pos\n refine \u27e82, ?_\u27e9\n rintro _ \u27e8z, hz, rfl\u27e9\n have h1 : dist (z - 1) 0 = \u2016z - 1\u2016 := by\n rw [dist_eq_norm]; simp [sub_zero]\n have hz1 : z \u2260 1 := hz.2\n have hzz : dist z 1 < \u03b4 := by\n have := hz.1\n rw [Metric.mem_ball, dist_comm] at this\n exact this\n have hlt := h\u03b4 (by rwa [dist_zero_right, h1] at *)\n have : \u2016(z - 1) * riemannZeta z\u2016 \u2264 \u2016(1 : \u2102)\u2016 + 1 := by\n have := norm_sub_le_of_le hlt\n calc \u2016(z - 1) * riemannZeta z\u2016\n \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 := by\n have := norm_sub_le ((z - 1) * riemannZeta z) 1\n linarith [this, hlt]\n _ \u2264 2 := by\n have h2 := hlt\n rw [norm_one]\n linarith [h2]\n exact this\n have h := differentiableOn_update_limUnder_of_bddAbove\n (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2)) hdiff hbd\n have hlim : limUnder (\ud835\udcdd[\u2260] (1 : \u2102)) (fun w => (w - 1) * riemannZeta w) = 1 :=\n zetaA_tendsto.limUnder_eq\n rw [hlim] at h\n have hopen : IsOpen (Metric.ball (1 : \u2102) 2) := Metric.isOpen_ball\n have han := h.analyticOnNhd hopen\n exact han.analyticAt (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2))\n\n/-- zetaA is nonzero on a neighborhood of 1 (value 1 there). -/\nlemma zetaA_ne_zero_near_one : \u2200\u1da0 w in \ud835\udcdd (1 : \u2102), zetaA w \u2260 0 :=\n (zetaA_analyticAt_one.continuousAt).eventually_ne (by rw [zetaA_one]; norm_num)\n\n/-- zetaA is analytic everywhere except possibly at 1 \u2014 and in fact also\nat 1; we record the off-1 version for quotient computations. -/\nlemma zetaA_analyticAt_of_ne {w : \u2102} (hw : w \u2260 1) : AnalyticAt \u2102 zetaA w := by\n have h : (fun w => (w - 1) * riemannZeta w) =\u1da0[\ud835\udcdd w] zetaA := by\n filter_upwards [eventually_ne_nhds hw] with z hz using (zetaA_apply hz).symm\n have ha : AnalyticAt \u2102 (fun w => (w - 1) * riemannZeta w) w := by\n exact (analyticAt_id.sub analyticAt_const).mul\n (differentiableAt_riemannZeta hw).analyticAt\n exact ha.congr h\n\n/-! ## 2. hLi w = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w): analytic at 1, value 1 -/\n\n/-- hLi(w) = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)(w) \u2014 the analytic-at-1 form of\n(w\u22121)(\u2212\u03b6\u2032/\u03b6)(w) (`hLi_eq_near_one`). hLi 1 = 1. -/\ndef hLi (w : \u2102) : \u2102 := 1 - (w - 1) * (deriv zetaA w / zetaA w)\n\nlemma hLi_one : hLi 1 = 1 := by simp [hLi]\n\nlemma hLi_analyticAt_one : AnalyticAt \u2102 hLi 1 := by\n have ha := zetaA_analyticAt_one\n have hda : AnalyticAt \u2102 (deriv zetaA) 1 := ha.deriv\n have hne : zetaA 1 \u2260 0 := by rw [zetaA_one]; norm_num\n exact (analyticAt_const.sub analyticAt_id).mul\n (hda.div ha hne) |>.const_sub 1\n\n/-- On a punctured neighborhood of 1, hLi = (w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6). -/\nlemma hLi_eq_of_ne {w : \u2102} (hw1 : w \u2260 1) (hw0 : riemannZeta w \u2260 0) :\n hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by\n have hA : zetaA w = (w - 1) * riemannZeta w := zetaA_apply hw1\n have hdA : deriv zetaA w = riemannZeta w + (w - 1) * deriv riemannZeta w := by\n have h1 : deriv (fun z => (z - 1) * riemannZeta z) w =\n deriv (fun z => z - 1) w * riemannZeta w +\n (w - 1) * deriv riemannZeta w :=\n deriv_mul ((differentiableAt_id.sub (differentiableAt_const 1)))\n (differentiableAt_riemannZeta hw1)\n have h2 : deriv (fun z => z - 1) w = 1 := by\n simp [deriv_sub, deriv_id'']\n have h3 : (fun z => (z - 1) * riemannZeta z) =\u1da0[\ud835\udcdd w] zetaA := by\n filter_upwards [eventually_ne_nhds hw1] with z hz using (zetaA_apply hz).symm\n rw [h3.deriv_eq, h1, h2, one_mul]\n rw [hLi, hdA, hA]\n have hw1' : w - 1 \u2260 0 := sub_ne_zero.mpr hw1\n field_simp [hw0, hw1']\n ring\n\n/-- The punctured-neighborhood form, for later contour work. -/\nlemma hLi_eq_near_one :\n \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w) := by\n have hzero : \u2200\u1da0 w in \ud835\udcdd[\u2260] (1 : \u2102), riemannZeta w \u2260 0 := by\n have h1 : (1 : \u2102) \u2208 {s : \u2102 | 1 \u2264 s.re} := by simp\n filter_upwards [eventually_mem_nhdsWithin] with w hw\n have hwre : 1 \u2264 w.re := by\n have := hw.2\n sorry\n exact riemannZeta_ne_zero_of_one_le_re hwre\n filter_upwards [hzero, eventually_mem_nhdsWithin] with w hw0 hw1\n exact hLi_eq_of_ne hw1 hw0\n\n/-! ## 3. The Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1 (operational definition) -/\n\n/-- The k-th Laurent coefficient of \u2212\u03b6\u2032/\u03b6 at s = 1:\n\u2212\u03b6\u2032/\u03b6(1+u) = u\u207b\u00b9 + \u03a3_{k\u22650} lcoeff k \u00b7 u^k (identification proved in\ntier ii\u2032-2/3; here lcoeff is DEFINED via the analytic hLi). -/\ndef lcoeff (k : \u2115) : \u2102 := iteratedDeriv (k + 1) hLi 1 / (k + 1) !\n\nlemma lcoeff_eq (k : \u2115) :\n lcoeff k = iteratedDeriv (k + 1) hLi 1 / (k + 1) ! := rfl\n\n/-- hLi's Taylor coefficient form: iteratedDeriv j hLi 1 / j ! = lcoeff (j\u22121). -/\nlemma hLi_iteratedDeriv_div_factorial {j : \u2115} (hj : 1 \u2264 j) :\n iteratedDeriv j hLi 1 / j ! = lcoeff (j - 1) := by\n rw [lcoeff]\n have : j = (j - 1) + 1 := by omega\n rw [this]\n\n/-! ## 4. The A-polynomial derivative: A(w) = w\u207f \u2212 (w\u22121)\u207f -/\n\n/-- Iterated derivatives of A(w) = w\u207f \u2212 (w\u22121)\u207f at 1:\nA^{(i)}(1) = n.descFactorial i for i < n, and A^{(n)}(1) = 0. -/\nlemma A_iter (n i : \u2115) (hi : i \u2264 n) :\n iteratedDeriv i (fun w => w ^ n - (w - 1) ^ n) (1 : \u2102) =\n if i < n then n.descFactorial i else 0 := by\n have hf : ContDiffAt \u2102 i (fun w : \u2102 => w ^ n) 1 :=\n (contDiff_id.pow n).contDiffAt\n have hg : ContDiffAt \u2102 i (fun w : \u2102 => (w - 1) ^ n) 1 :=\n ((contDiff_id.sub contDiff_const).pow n).contDiffAt\n rw [iteratedDeriv_sub hf hg]\n have h1 : iteratedDeriv i (fun w : \u2102 => w ^ n) 1 = n.descFactorial i := by\n rw [iteratedDeriv_pow]\n simp\n have h2 : iteratedDeriv i (fun w : \u2102 => (w - 1) ^ n) 1 =\n n.descFactorial i * (0 : \u2102) ^ (n - i) := by\n have e := iteratedDeriv_comp_sub_const i (fun w : \u2102 => w ^ n) (1 : \u2102)\n have e2 : iteratedDeriv i (fun w : \u2102 => (w - 1) ^ n) 1 =\n iteratedDeriv i (fun w : \u2102 => w ^ n) (1 - 1) := by\n have := congr_fun e 1\n convert this using 2\n rw [e2, iteratedDeriv_pow]\n simp\n rw [h1, h2]\n by_cases hin : i < n\n \u00b7 rw [if_pos hin]\n have : (0 : \u2102) ^ (n - i) = 0 := by\n apply zero_pow\n omega\n rw [this, mul_zero, sub_zero]\n \u00b7 rw [if_neg hin]\n have hin' : i = n := le_antisymm hi (by omega)\n subst hin'\n simp [Nat.descFactorial_self]\n\n/-! ## 5. The residue at w = 1: ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121) -/\n\n/-- The residue at w = 1 of the Lagarias-kernel integrand\nJ(w) = k_n(w\u22121)\u00b7(\u2212\u03b6\u2032/\u03b6(w)), packaged as (1/n!)\u00b7(d/dw)\u207f[(w\u207f\u2212(w\u22121)\u207f)hLi]\nat w = 1 (D-064 \u00a74 R1: (w\u22121)^{n+1}J = [w\u207f\u2212(w\u22121)\u207f]\u00b7hLi on a punctured\nneighborhood, by `hLi_eq_near_one`). -/\ndef ResW1 (n : \u2115) : \u2102 :=\n iteratedDeriv n (fun w => (w ^ n - (w - 1) ^ n) * hLi w) (1 : \u2102) / n !\n\n/-- The w = 1 residue value: ResW1 n = \u03a3_{j=1}^n C(n,j)\u00b7lcoeff (j\u22121). -/\ntheorem ResW1_eq_sum (n : \u2115) :\n ResW1 n = \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n have hA : ContDiffAt \u2102 n (fun w : \u2102 => w ^ n - (w - 1) ^ n) 1 :=\n ((contDiff_id.pow n).sub ((contDiff_id.sub contDiff_const).pow n)).contDiffAt\n have hh : ContDiffAt \u2102 n hLi 1 := hLi_analyticAt_one.contDiffAt\n have hmul := iteratedDeriv_mul hA hh\n rw [ResW1, hmul]\n have hsum : \u2211 i \u2208 Finset.range (n + 1),\n n.choose i * iteratedDeriv i (fun w : \u2102 => w ^ n - (w - 1) ^ n) 1 *\n iteratedDeriv (n - i) hLi 1 =\n \u2211 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 := by\n apply Finset.sum_subset (Finset.range_le_iff.mpr (Nat.le_succ n))\n intro i hi\n rw [Finset.mem_range] at hi\n have hi0 : i \u2260 n := by omega\n rw [A_iter n i (by omega), if_pos (by omega)]\n \u00b7 rfl\n \u00b7 rw [Finset.mem_range] at *\n omega\n rw [hsum]\n have hfinal : (\u2211 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1) / n ! =\n \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n have hrewrite : \u2200 i \u2208 Finset.range n,\n n.choose i * (n.descFactorial i : \u2102) * iteratedDeriv (n - i) hLi 1 / n ! =\n (n.choose (n - i) : \u2102) * lcoeff (n - i - 1) := by\n intro i hi\n rw [Finset.mem_range] at hi\n have hcd : (n.choose i : \u2102) * (n.descFactorial i : \u2102) =\n n ! * n.choose i / (n - i) ! := by\n have h1 := Nat.choose_mul_factorial_mul_factorial (show i \u2264 n by omega)\n have h2 := Nat.factorial_mul_descFactorial (show i \u2264 n by omega)\n have : (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((i ! : \u2102) * ((n - i) ! : \u2102)) =\n (n ! : \u2102) * (n.choose i : \u2102) := by\n push_cast [h1, h2]\n ring\n have hfact : ((i ! : \u2102) * ((n - i) ! : \u2102)) \u2260 0 := by\n simp [Nat.factorial_ne_zero]\n have hthis := this\n field_simp at hthis \u22a2\n have h3 : (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((n - i) ! : \u2102) =\n (n ! : \u2102) * (n.choose i : \u2102) / 1 := by\n have h4 := hthis\n rw [mul_comm ((i ! : \u2102)) ((n - i) ! : \u2102)] at h4\n have h5 : (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((n - i) ! : \u2102) * (i ! : \u2102) =\n (n ! : \u2102) * (n.choose i : \u2102) := by\n rw [mul_comm ((n - i) ! : \u2102) (i ! : \u2102)] at h4\n calc (n.choose i : \u2102) * (n.descFactorial i : \u2102) * ((n - i) ! : \u2102) * (i ! : \u2102)\n = (n.choose i : \u2102) * (n.descFactorial i : \u2102) * (((n - i) ! : \u2102) * (i ! : \u2102)) := by ring\n _ = (n ! : \u2102) * (n.choose i : \u2102) := by\n have := h4\n ring_nf at this \u22a2\n convert this using 1\n ring\n exact (div_eq_one_iff_eq (by simp [Nat.factorial_ne_zero])).mpr h5\n field_simp at h3 \u22a2\n calc (n.choose i : \u2102) * (n.descFactorial i : \u2102)\n = ((n ! : \u2102) * (n.choose i : \u2102) / 1) / ((n - i) ! : \u2102) := by\n rw [\u2190 h3]\n field_simp\n ring\n _ = (n ! : \u2102) * (n.choose i : \u2102) / ((n - i) ! : \u2102) := by ring\n rw [hcd]\n have hni : n - i \u2265 1 := by omega\n rw [hLi_iteratedDeriv_div_factorial (j := n - i) (by omega)]\n rw [show n - i - 1 = n - i - 1 from rfl]\n have hcoe : ((n - i) ! : \u2102) \u2260 0 := by simp [Nat.factorial_ne_zero]\n field_simp\n rw [Nat.choose_symm (by omega : i \u2264 n)]\n ring\n rw [Finset.sum_div]\n rw [Finset.sum_congr rfl hrewrite]\n have hmap : \u2211 i \u2208 Finset.range n, (n.choose (n - i) : \u2102) * lcoeff (n - i - 1) =\n \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n rw [Finset.sum_range_reflect]\n apply Finset.sum_congr rfl\n intro i hi\n rw [Finset.mem_range] at hi\n have : n - 1 - i + 1 = n - i := by omega\n rw [this]\n have : n - (n - i) = i := by omega\n rw [Nat.choose_symm (show n - i \u2264 n by omega)]\n simp [this]\n ring\n exact hmap\n rw [hfinal]\n\nend NguyenRH1\n",
"autoRead": false
}
thinking (7670 chars)
Multiple errors:
1. `Complex.norm` unknown — the norm on ℂ is just `‖·‖` (norm from the NormedField instance), there's no `Complex.norm` constant. In the BddAbove I wrote `Complex.norm ∘ f` — use `norm ∘ f` (the global norm function) or `fun z => ‖f z‖`. The RemovableSingularity theorem statement uses `norm ∘ f` — so `norm` unqualified ✓. Fix: `(norm ∘ (fun w => (w - 1) * riemannZeta w))`.
2. Line 43: unsolved goals — the final `han.analyticAt` — structure: `h.analyticOnNhd Metric.isOpen_ball` — the dot `.analyticOnNhd` worked? The error at 43:53 (which is `han.analyticAt ...` — the analyticAt projection). AnalyticOnNhd ℂ f s — to get AnalyticAt f x from AnalyticOnNhd and x ∈ s-nhd: the API: `AnalyticOnNhd.analyticAt (hf : AnalyticOnNhd 𝕜 f s) (hx : s ∈ 𝓝 x)`? Hmm — maybe the right call: AnalyticOnNhd f s means ∀ x ∈ s, AnalyticAt f x? NO — AnalyticOnNhd f U := ∀ x ∈ U, ∃ nhd, analytic on it — actually `AnalyticOnNhd 𝕜 f s : Prop := ∀ x ∈ s, AnalyticAt 𝕜 f x`?? Let me check: I believe `AnalyticOnNhd 𝕜 f s : Prop := ∀ x ∈ s, AnalyticAt 𝕜 f x` — YES that's the definition (analytic at every point with a neighborhood). Then `han 1 (Metric.mem_ball_self (by norm_num))` : AnalyticAt zetaA 1. Fix.
3. Line 88: `(differentiableAt_riemannZeta hw).analyticAt` — differentiableAt_riemannZeta returns ∃ f', HasFDerivAt — use `.analyticAt` differently: for ℂ, DifferentiableAt ⟹ AnalyticAt: `DifferentiableAt.analyticAt (hd : DifferentiableAt ℂ f x) : AnalyticAt ℂ f x` ✓ that should be the name — the error says the projection failed because the existential needs unpacking: differentiableAt_riemannZeta hw : ∃ f', HasFDerivAt riemannZeta f' w — this IS DifferentiableAt (unfolds: DifferentiableAt ℂ f x := ∃ f', HasFDerivAt f f' x). The `.analyticAt` dot-projection on an ∃ — failed because Lean sees the raw ∃. Use `DifferentiableAt.analyticAt (differentiableAt_riemannZeta hw)`? — will type-class unify DifferentiableAt with the ∃? DifferentiableAt is DEFINED as ∃ f', HasFDerivAt — defeq, so the projection should work... the error says "The environment does not contain Exists.analyticAt" — so dot notation failed. Use explicit: `(differentiableAt_riemannZeta hw).analyticAt` fails; write `DifferentiableAt.analyticAt (differentiableAt_riemannZeta hw)`. Hmm — is the name right? For ℂ: differentiableAt ⟹ analyticAt — the lemma: `DifferentiableAt.analyticAt (h : DifferentiableAt ℂ f x) : AnalyticAt ℂ f x` ✓ I believe exists.
4. Line 104: `.const_sub` on AnalyticAt — the AnalyticAt.mul result was an ∃ (HasFPowerSeriesAt) — AnalyticAt is also an ∃. Dot projection on it fails. Use explicit applications: `AnalyticAt.const_sub 1 (AnalyticAt.mul (AnalyticAt.sub analyticAt_const analyticAt_id) (AnalyticAt.div hda ha hne))`. Check AnalyticAt.const_sub signature: `AnalyticAt.const_sub (c) (hf : AnalyticAt f x) : AnalyticAt (c - f) x`? or (hf).const_sub c — hmm. In Mathlib: `AnalyticAt.const_sub (hf : AnalyticAt 𝕜 f x) (c : E) : AnalyticAt 𝕜 (c - f) x`? Hmm — for hLi = 1 − X: use AnalyticAt.sub instead: analyticAt_const.sub hX ✓ cleaner:
```
lemma hLi_analyticAt_one : AnalyticAt ℂ hLi 1 := by
have ha := zetaA_analyticAt_one
have hda : AnalyticAt ℂ (deriv zetaA) 1 := ha.deriv
have hne : zetaA 1 ≠ 0 := by rw [zetaA_one]; norm_num
have hprod : AnalyticAt ℂ (fun w => (w - 1) * (deriv zetaA w / zetaA w)) 1 :=
(analyticAt_id.sub analyticAt_const).mul (hda.div ha hne)
exact analyticAt_const.sub hprod
```
5. Line 120: `rw [h3.deriv_eq, h1, h2, one_mul]` — h3.deriv_eq rewrites deriv zetaA w → deriv (fun z => (z−1)*ζ) w — direction wrong: h3 : f =ᶠ zetaA, h3.deriv_eq : deriv f w = deriv zetaA w — so rw [h3.deriv_eq] rewrites `deriv (fun z => (z−1)*ζ) w` to `deriv zetaA w` — but the goal has `deriv zetaA w` on the LHS, and I want to rewrite it TO the explicit form: use `rw [← h3.deriv_eq]` to go the other way, then rw [h1, h2, one_mul]. Fix.
6. Line 117: simp [deriv_sub, deriv_id''] — deriv_sub unused warning; deriv (fun z => z − 1) w = 1: simpler: `deriv_sub` needs differentiability args — use `simp [deriv_id'']` only? deriv (fun z => z − 1) w = deriv id w − deriv const w... simplest: `deriv_fun_sub`... Let me use: have h2 : deriv (fun z => z - 1) w = 1 := by simp [deriv_sub_const] — there's `deriv_sub_const : deriv (fun x => f x - c) x = deriv f x`? and deriv_id''. Actually simplest: `deriv_id''` for the identity; fun z => z − 1 = id − 1: deriv = deriv id = 1: `by simp [deriv_sub_const, deriv_id'']`. I'll try `by simp`.
7. Line 145/149 syntax errors — the lcoeff def: `def lcoeff (k : ℕ) : ℂ := iteratedDeriv (k + 1) hLi 1 / (k + 1) !` — `(k + 1) !` with SPACE before ! causes parse error — factorial notation needs `(k + 1)!` no space? The errors at 145:65 "unexpected token '/--'" — the doc comment placement after def... and 149:31 — `lcoeff_eq` I removed in rewrite — wait the current file has `/-! ## 3 -/` then lcoeff def then hLi_iteratedDeriv_div_factorial — the parse errors at 145/149 suggest `(k + 1) !` is the culprit: in Lean 4, `n !` with a space IS valid? — `n !` is notation `Nat.factorial n` — with space should work... 145:65 is column 65 — `iteratedDeriv (k + 1) hLi 1 / (k + 1) !` — hmm 65 is near the end. The parse error "unexpected token '/--'" at 145 — line 145 is the doc comment `/-- hLi's Taylor coefficients...` — so the def before it failed to terminate — the `(k + 1) !` likely parsed weirdly. Use `(k + 1)!` (no space). Same for `n !` everywhere: in ResW1 def I have `/ n !` — with space — Mathlib style uses `n !` with space and it works... Hmm, actually in Mathlib `n !` with a space is standard (factorial postfix). The parse error might be from `lcoeff (k : ℕ) : ℂ := iteratedDeriv (k + 1) hLi 1 / (k + 1) !` — the `/ (k + 1) !` — the parser might read `!` as something else after the parenthesized expr with space. In Mathlib it's written `(k + 1)!` typically. Let me use no-space form `(k + 1)!` and `n !`→`n !`... I'll use `n !` where already working elsewhere (hmm — actually in LiSkeleton.lean, did I use factorial? No). Safest: `(k + 1)!` and `(n)!`? `n !` with space should be fine as `n` is an identifier — `(k + 1) !` with parenthesized expr then space then ! — might parse as two separate terms. Use `(k + 1)!` and `n !`.
Hmm wait, the errors at 145:65 and 149:31 are "unexpected token" — let me just fix the spacing and recompile.
8. NormedAddCommGroup ℕ synth failure (line 159) — that's in A_iter: `iteratedDeriv_pow` at ℂ needs... no — the error "failed to synthesize NormedAddCommGroup ℕ" — from `iteratedDeriv_comp_sub_const i (fun w : ℂ => w ^ n) (1 : ℂ)` — the function fun w => w^n has type ℂ → ℂ but I need to annotate the DOMAIN of the lambda properly; `(fun w : ℂ => w ^ n)` ✓ — hmm, or it's `iteratedDeriv_pow` in h1: `rw [iteratedDeriv_pow]` then `simp` — the simp goal... Actually line 159 is in `h2`'s proof (the e/congr_fun/simpa block). The `simpa using e` — the target has `iteratedDeriv i (fun w : ℂ => (w - 1) ^ n) 1 = n.descFactorial i * (0 : ℂ) ^ (n - i)` and e : `iteratedDeriv i (fun z => (z - 1) ^ n) 1 = n.descFactorial i * (1 - 1) ^ (n - i)` — simpa should close ((1−1) = 0). The ℕ instance error — from `iteratedDeriv_comp_sub_const`'s implicit scalar field — with f : ℂ → ℂ fine... The NormedAddCommGroup ℕ error is bizarre — maybe from `simp` in h1 expanding `1 ^ (n - i)` where 1 : ℂ vs ℕ confusion... Actually `h1`'s simp: iteratedDeriv i (fun w : ℂ => w^n) 1 = descFac n i·1^(n−i) = descFac n i: `simp` should close — but the RHS of my h1 statement is `n.descFactorial i` (a ℕ cast to ℂ) ✓.
Let me fix all these and recompile. Also the `simp only [Complex.norm_eq_abs] at *` line — remove (no Complex.norm).
Let me apply the fixes.
Multiple small errors — fixing: the `norm` qualification, analyticAt projections, deriv_eq direction, factorial spacing.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiResidue.lean'\ns = open(p, encoding='utf-8').read()\n\n# 1. Complex.norm -> norm\ns = s.replace(\"BddAbove (Complex.norm \u2218 (fun w => (w - 1) * riemannZeta w)) ''\",\n \"BddAbove (norm \u2218 (fun w => (w - 1) * riemannZeta w)) ''\")\n\n# 2. fix the boundedness block (remove Complex.norm_eq_abs line)\ns = s.replace(\"\"\" have h1 : \u2016(z - 1) * riemannZeta z - 1\u2016 < 1 := by\n have := hlt\n rwa [dist_eq_norm] at this\n have := norm_sub_le ((z - 1) * riemannZeta z) 1\n simp only [Complex.norm_eq_abs] at *\n have h2 : \u2016(z - 1) * riemannZeta z\u2016 \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 :=\n norm_sub_le ((z - 1) * riemannZeta z) 1\n rw [norm_one] at h2\n linarith [h1]\"\"\",\n\"\"\" have h1 : \u2016(z - 1) * riemannZeta z - 1\u2016 < 1 := by\n have := hlt\n rwa [dist_eq_norm] at this\n have h2 : \u2016(z - 1) * riemannZeta z\u2016 \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 :=\n norm_sub_le ((z - 1) * riemannZeta z) 1\n rw [norm_one] at h2\n linarith [h1]\"\"\")\n\n# 3. analyticAt from analyticOnNhd membership\ns = s.replace(\"\"\" have han := h.analyticOnNhd Metric.isOpen_ball\n exact han.analyticAt (Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2))\"\"\",\n\"\"\" have han := h.analyticOnNhd Metric.isOpen_ball\n exact han 1 (Metric.mem_ball_self (by norm_num : (0 : \u211d) < 2))\"\"\")\n\n# 4. DifferentiableAt.analyticAt explicit\ns = s.replace(\"(differentiableAt_riemannZeta hw).analyticAt\",\n \"DifferentiableAt.analyticAt (differentiableAt_riemannZeta hw)\")\n\n# 5. hLi_analyticAt_one restructure\ns = s.replace(\"\"\" exact ((analyticAt_const.sub analyticAt_id).mul\n (hda.div ha hne)).const_sub 1\"\"\",\n\"\"\" have hprod : AnalyticAt \u2102 (fun w => (w - 1) * (deriv zetaA w / zetaA w)) 1 :=\n (analyticAt_id.sub analyticAt_const).mul (hda.div ha hne)\n exact analyticAt_const.sub hprod\"\"\")\n\n# 6. deriv_eq direction + deriv (z - 1)\ns = s.replace(\"\"\" have h2 : deriv (fun z => z - 1) w = 1 := by\n simp [deriv_sub, deriv_id'']\n have h3 : (fun z => (z - 1) * riemannZeta z) =\u1da0[\ud835\udcdd w] zetaA := by\n filter_upwards [eventually_ne_nhds hw1] with z hz using (zetaA_apply hz).symm\n rw [h3.deriv_eq, h1, h2, one_mul]\"\"\",\n\"\"\" have h2 : deriv (fun z => z - 1) w = 1 := by\n simp [deriv_sub_const, deriv_id'']\n have h3 : (fun z => (z - 1) * riemannZeta z) =\u1da0[\ud835\udcdd w] zetaA := by\n filter_upwards [eventually_ne_nhds hw1] with z hz using (zetaA_apply hz).symm\n rw [\u2190 h3.deriv_eq, h1, h2, one_mul]\"\"\")\n\n# 7. push_neg deprecation -> push Not\ns = s.replace(\"push_neg at h2\", \"push Not at h2\")\n\n# 8. factorial spacing\ns = s.replace(\"iteratedDeriv (k + 1) hLi 1 / (k + 1) !\", \"iteratedDeriv (k + 1) hLi 1 / (k + 1)!\")\ns = s.replace(\"iteratedDeriv n (fun w => (w ^ n - (w - 1) ^ n) * hLi w) (1 : \u2102) / n !\",\n \"iteratedDeriv n (fun w => (w ^ n - (w - 1) ^ n) * hLi w) (1 : \u2102) / n !\")\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiResidue.lean 2>&1 | head -50",
"description": "Apply fixes and recompile LiResidue.lean",
"timeout": 420000
}
thinking (4848 chars)
More issues to fix:
1. `norm ∘ f` — `norm` is being parsed weirdly (LE ℂ instance error suggests `norm` resolved to something wrong). The BddAbove's image set: `norm ∘ f '' s` — write it as `(fun z => ‖f z‖) '' s` explicitly.
2. `DifferentiableAt.analyticAt` unknown — check the real name. In Mathlib: differentiable at a point in ℂ ⟹ analytic there. Candidates: `DifferentiableAt.analyticAt`, `HasDerivAt.analyticAt`, or via DifferentiableOn... Let me grep.
3. Line 144: `(k + 1)!` still failing — "unexpected token '!'; expected command" at 144:63. Hmm — the lcoeff def: `def lcoeff (k : ℕ) : ℂ := iteratedDeriv (k + 1) hLi 1 / (k + 1)!` — column 63... `(k + 1)!` — the postfix ! might not exist as notation in this context?? But Mathlib uses `n !` extensively (with space). The issue: `(k + 1)!` without space — in Lean4 Mathlib, `n !` needs... hmm actually `n !` IS valid (Mathlib writes `n !` with a space before !). Let me use `Nat.factorial (k + 1)` explicitly to avoid the notation issue — safest.
Wait — the error "unexpected token '!'; expected command" — that means the previous expression ended and `!` started a new command — so `(k + 1)!` ISN'T parsed as postfix factorial?? Actually in Lean 4 the factorial notation is `n !` with a SPACE: `10000 !` etc. Without space `n!` might not parse (Lean might treat `!` specially). And `n !` WITH space after an identifier works, but `(k + 1) !` after a parenthesis with space — should also work... earlier error at 145:65 was "unexpected token '/--'" — meaning the def failed to parse after `!`. Hmm — maybe the issue is that `!` postfix notation requires `Nat` and the elaborate needs to know the type: `(k + 1) !` with k : ℕ — fine. But the REAL issue might be: the factorial postfix `!` in this Mathlib version is written `n !` and the parser accepted `n !` in other files... Let me just use `Nat.factorial (k + 1)` — unambiguous.
Actually wait — line 213:78 and 190:72 similar "unexpected token" — those are in ResW1 def and ResW1_eq_sum: `/ n !` with space — after `/ n` the `!` starts fresh?? Hmm — "expected no space before or term" suggests `(n - i) !` etc. Let me look: line 190:72 — probably `hLi_iteratedDeriv_div_factorial`'s `j !` — I'll replace ALL factorial postfix with Nat.factorial explicitly? That's heavy — actually, let me check how LiSkeleton.lean (which compiled) writes factorials... it doesn't use them. But Mathlib files use `n !` constantly — so the notation exists. The problem could be `open ... Nat`? or the postfix `!` requires `open scoped Nat`? In current Mathlib, factorial notation `n !` is `Nat.factorial n` with scoped notation in `Nat` namespace?? No — it's global postfix... Let me check quickly.
4. Line 158: `NormedAddCommGroup ℕ` + `HSub ℂ ℂ ℕ` — in A_iter: `iteratedDeriv i (fun w : ℂ => (w - 1) ^ n) 1` — `(w - 1)` where 1 might elaborate as ℕ? The `(w - 1)` with w : ℂ: 1 : ℂ ✓ should be fine... HSub ℂ ℂ ℕ error — somewhere `? - ?` got ℕ result type... In h2's e: `congr_fun (iteratedDeriv_comp_sub_const i (fun w : ℂ => w ^ n) (1 : ℂ)) 1` — iteratedDeriv_comp_sub_const (n f s) : iteratedDeriv n (fun z ↦ f (z - s)) = fun t ↦ iteratedDeriv n f (t - s) — with f = (fun w : ℂ => w ^ n), s = (1 : ℂ): produces iteratedDeriv i (fun z ↦ (z - 1)^n) = fun t ↦ iteratedDeriv i (·^n) (t − 1) — congr_fun at 1: iteratedDeriv i (fun z ↦ (z−1)^n) 1 = iteratedDeriv i (·^n) (1 − 1) — hmm that matches my target... The HSub ℂ ℂ ℕ — from `1 - 1`?? The congr_fun ... 1 with 1 : ℕ?? — `congr_fun e 1` — the 1 here is ℂ but might be elaborated as ℕ from the lemma's ℕ parameter context! `congr_fun e 1` — e : iteratedDeriv i ... = fun t ↦ ... — congr_fun e x needs x : ℂ; writing `congr_fun e 1` — the literal 1 elaborates to ℂ ✓ should be fine... The `HSub ℂ ℂ ℕ` error suggests some subtraction got ℕ type. In the target of h2: `iteratedDeriv i (fun w : ℂ => (w - 1) ^ n) 1 = n.descFactorial i * (0 : ℂ) ^ (n - i)` — n.descFactorial i : ℕ cast to ℂ; `(0 : ℂ) ^ (n - i)` — n − i : ℕ ✓ fine... Actually — `simpa using e` — e might have `f (z - s)` form with s : ℂ — matching (w−1) with w : ℂ ✓.
Hmm, the `NormedAddCommGroup ℕ` at 158:4 — line 158 is `rw [iteratedDeriv_sub hf hg]`?? No — line 158 might be h1 or h2. The `iteratedDeriv i` with i : ℕ — iteratedDeriv expects n : ℕ ✓. NormedAddCommGroup ℕ — maybe from `n.descFactorial i` being elaborated as a function into ℕ — the target equality's RHS `n.descFactorial i` (ℕ) coerced to ℂ — should be fine...
Let me just fix the obvious ones and recompile to see precise locations:
- BddAbove image set: explicit lambda form.
- DifferentiableAt.analyticAt: find the right name (grep).
- factorial: use `Nat.factorial (k+1)` and `n !` consistently — first check how the notation is enabled.
- A_iter's errors: restructure.
Let me grep for the analyticAt-from-differentiableAt name and factorial notation.
Let me check the right names for these failing pieces.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"DifferentiableAt.analyticAt\\|HasDerivAt.analyticAt\" Mathlib/ --include=*.lean | head -4; grep -rn \"theorem analyticAt_of_differentiableAt\" Mathlib/ --include=*.lean | head -3; grep -rn \"notation \\\"!\\\"\\|scoped.*\\\"!\\\"\" Mathlib/Data/Nat/Factorial/Basic.lean Mathlib/Data/Nat/Factorial/Defs.lean 2>/dev/null | head -4",
"description": "Find analyticAt-of-differentiableAt and factorial notation"
}
thinking (6584 chars)
Two findings:
1. Factorial notation `n !` is **scoped notation** — needs `open Nat` or `open scoped Nat` (or write `Nat.factorial n`). That's the parse failure. Fix: add `open scoped Nat` at the top or use Nat.factorial explicitly. I'll add `open scoped Nat` — wait, is it in a scope? `scoped notation:10000 n "!" => Nat.factorial n` — the scope is probably `Nat` — `open Nat` opens it (but that brings many Nat lemmas into scope — risky). `open scoped Nat` — same scope... The notation is declared `scoped notation` inside `namespace Nat`? Then `open Nat` activates it. Simpler: use `Nat.factorial` explicitly everywhere — no scope needed. But there are many occurrences... Let me add `open scoped Nat` — hmm, is the scope named `Nat`? `scoped notation` inside `namespace Nat` creates scope `Nat`. `open scoped Nat` activates without opening constants ✓. Let me use that.
Wait — but LiBasePoints.lean might already use factorials... it compiled fine. Let me check how it opens scopes... Actually simpler to check with grep how zeta-23 or our files write `!`.
2. No `DifferentiableAt.analyticAt` found — the differentiable⟹analytic direction at a point: the right lemma might be `DifferentiableAt.analyticAt` nonexistent; instead use `AnalyticAt` built from DifferentiableOn + isOpen: for a single point w ≠ 1: ζ differentiable on ball w r minus {1} (open) ⟹ analyticOnNhd ⟹ analyticAt. That's heavier per call site. Alternative: `AnalyticAt` via `AnalyticOnNhd.analyticAt`? For zetaA_analyticAt_of_ne: ζ differentiable at w ≠ 1... Let me find how one proves AnalyticAt from differentiability: `DifferentiableOn.analyticOnNhd (hd : DifferentiableOn ℂ f s) (ho : IsOpen s)` ✓ exists. So:
```
lemma zetaA_analyticAt_of_ne {w : ℂ} (hw : w ≠ 1) : AnalyticAt ℂ zetaA w := by
have h1 : DifferentiableOn ℂ (fun z => (z - 1) * riemannZeta z) (Metric.ball w (dist w 1)) := by
intro z hz
have hz1 : z ≠ 1 := by
intro heq
rw [heq] at hz
exact lt_irrefl _ hz
exact ((differentiableAt_id.sub (differentiableAt_const 1)).mul
(differentiableAt_riemannZeta hz1)).differentiableWithinAt
have h2 : AnalyticOnNhd ℂ (fun z => (z - 1) * riemannZeta z) (Metric.ball w (dist w 1)) :=
h1.analyticOnNhd Metric.isOpen_ball
have h3 : AnalyticAt ℂ (fun z => (z - 1) * riemannZeta z) w := h2 w (Metric.mem_ball_self ?_)
...congr with zetaA
```
Hmm — Metric.mem_ball_self needs dist w 1 > 0 (w ≠ 1 ✓ dist_pos.mpr hw). And the ball is a nhd of w ✓. Then congr: zetaA =ᶠ[𝓝 w] (fun z => (z−1)ζ z) — already have (filter_upwards eventually_ne_nhds).
Alternatively — is there `DifferentiableAt.analyticAt` under a different name? Maybe `AnalyticAt` from `HasFDerivAt`: in ℂ, `HasFDerivAt` ⟹ AnalyticAt — `HasFDerivAt.analyticAt`? Hmm — no hits. The DifferentiableOn+isOpen path is standard. Actually — wait, maybe simpler: `analyticAt_riemannZeta` EXISTS in the vendored ZetaBounds (agent reported: `theorem analyticAt_riemannZeta {s : ℂ} (s_ne_one : s ≠ 1) : AnalyticAt ...` ✓ vendored!). So:
```
have ha : AnalyticAt ℂ (fun w => (w - 1) * riemannZeta w) w :=
(analyticAt_id.sub analyticAt_const).mul (analyticAt_riemannZeta hw)
```
analyticAt_riemannZeta is in Zeta23.FromPNTPlus (ZetaBounds) — import Zeta23.FromPNTPlus.ZetaBounds. ✓ much cleaner. But is it `AnalyticAt ℂ riemannZeta s`? The agent listed: `theorem analyticAt_riemannZeta {s : ℂ} (s_ne_one : s ≠ 1)` ✓. Import needed: Zeta23.FromPNTPlus.ZetaBounds.
3. The `norm ∘ f` BddAbove issue: write `(fun z => ‖(z - 1) * riemannZeta z‖) '' (Metric.ball 1 2 \ {1})` — BddAbove of that image. LE ℂ error was from norm ∘ f composition parsing — using the explicit lambda avoids it.
4. A_iter's `iteratedDeriv_sub` pattern mismatch: the goal's integrand is `fun w => w ^ n - (w - 1) ^ n` and iteratedDeriv_sub expects `fun w => f w - g w` = pointwise sub of two lambdas — the pattern `(fun w => w^n) - (fun w => (w−1)^n)` — Lean sees `fun w => w^n − (w−1)^n` which is DEFEQ to `(fun w => w^n) − (fun w => (w−1)^n)`? By Pi.sub_apply: (f − g) w = f w − g w — so `fun w => f w − g w` is η-expansion — rw with iteratedDeriv_sub needs the exact syntactic form `(fun w => w^n) − fun w => (w−1)^n`. Fix: `show iteratedDeriv i ((fun w : ℂ => w ^ n) - (fun w : ℂ => (w - 1) ^ n)) 1 = _`:
```
have hsub : (fun w : ℂ => w ^ n - (w - 1) ^ n) = (fun w : ℂ => w ^ n) - (fun w : ℂ => (w - 1) ^ n) := by
funext w; simp [Pi.sub_apply]
rw [hsub, iteratedDeriv_sub hf hg, h1, h2]
```
(from STATE gotchas: Pi.sub_apply simp after .sub ✓).
5. `NormedAddCommGroup ℕ` + `HSub ℂ ℂ ℕ` at line 158: probably from the same elaboration issue in h2 (the `simpa using e`) — with h2 restructured it may vanish. Let me rewrite h2 cleanly:
```
have h2 : iteratedDeriv i (fun w : ℂ => (w - 1) ^ n) 1 =
n.descFactorial i * (0 : ℂ) ^ (n - i) := by
have e := congr_fun (iteratedDeriv_comp_sub_const i (fun w : ℂ => w ^ n) (1 : ℂ)) 1
rw [iteratedDeriv_pow] at e
simpa using e
```
e : iteratedDeriv i (fun z ↦ (z − 1)^n) 1 = n.descFactorial i * (1 − 1)^(n − i) — simpa should normalize (1−1) → 0 and match. The `iteratedDeriv_comp_sub_const i f s` with s = (1 : ℂ): the lambda in the lemma is `fun z ↦ f (z - s)` = fun z ↦ (z−1)^n ✓ matches our `fun w : ℂ => (w - 1) ^ n`? f = (fun w : ℂ => w ^ n): f (z − 1) = (z−1)^n ✓.
Hmm the HSub ℂ ℂ ℕ error at 158:30 — from `e` elaboration maybe: `congr_fun (iteratedDeriv_comp_sub_const i (fun w : ℂ => w ^ n) (1 : ℂ)) 1` — the final `1` (the evaluation point) — with congr_fun e x, x : ℂ — literal 1 : ℂ ✓... but the error says HSub ℂ ℂ ℕ — so somewhere `? − ? : ℕ`... `iteratedDeriv_comp_sub_const i f s` — the signature: (n : ℕ) (f : 𝕜 → F) (s : 𝕜) — so my call `iteratedDeriv_comp_sub_const i (fun w : ℂ => w ^ n) (1 : ℂ)` — hmm the implicit 𝕜 gets unified ℂ ✓ and F = ℂ ✓. e's type: iteratedDeriv i (fun z ↦ (z − 1) ^ n) = fun t ↦ iteratedDeriv i (fun w => w^n) (t − 1) — wait, the RHS lambda is `fun t ↦ iteratedDeriv i f (t - s)` with f = (fun w => w^n), s = 1 — congr_fun at 1: iteratedDeriv i (·^n) (1 − 1) — then rw [iteratedDeriv_pow] at e: iteratedDeriv i (·^n) x = descFac n i * x^(n−i) at x = 1−1 = 0 ✓. e : iteratedDeriv i (fun z ↦ (z − 1)^n) 1 = n.descFactorial i * (1 - 1)^(n - i). Target: ... = n.descFactorial i * (0 : ℂ)^(n−i): simpa using e should close. The ℕ errors might be from `iteratedDeriv_pow` rewriting inside e producing casts. Let me just try the restructure and see.
Actually — one more: maybe simpler to avoid the comp lemma: use `iteratedDeriv_comp_add_const` with (w − 1) = (w + (−1))... The comp_sub_const is fine.
Let me apply all fixes.
The factorial notation is scoped (`Nat`), and `analyticAt_riemannZeta` exists in the vendored ZetaBounds. Applying all fixes.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiResidue.lean'\ns = open(p, encoding='utf-8').read()\n\n# import + scope\ns = s.replace(\"\"\"import Mathlib\nimport Zeta23.Statement\n\nopen Zeta23 Complex Filter Topology\"\"\",\n\"\"\"import Mathlib\nimport Zeta23.Statement\nimport Zeta23.FromPNTPlus.ZetaBounds\n\nopen Zeta23 Complex Filter Topology\nopen scoped Nat\"\"\")\n\n# BddAbove image: explicit lambda\ns = s.replace(\"BddAbove (norm \u2218 (fun w => (w - 1) * riemannZeta w)) ''\",\n \"BddAbove ((fun z => \u2016(z - 1) * riemannZeta z\u2016) ''\")\n\n# analyticAt_riemannZeta from ZetaBounds\ns = s.replace(\"\"\" have ha : AnalyticAt \u2102 (fun w => (w - 1) * riemannZeta w) w :=\n (analyticAt_id.sub analyticAt_const).mul\n DifferentiableAt.analyticAt (differentiableAt_riemannZeta hw)\n exact ha.congr h\"\"\",\n\"\"\" have ha : AnalyticAt \u2102 (fun w => (w - 1) * riemannZeta w) w :=\n (analyticAt_id.sub analyticAt_const).mul (analyticAt_riemannZeta hw)\n exact ha.congr h\"\"\")\n\n# A_iter: function-sub form\ns = s.replace(\"\"\" rw [iteratedDeriv_sub hf hg]\n have h1 : iteratedDeriv i (fun w : \u2102 => w ^ n) 1 = n.descFactorial i := by\n rw [iteratedDeriv_pow]\n simp\"\"\",\n\"\"\" have hsub : (fun w : \u2102 => w ^ n - (w - 1) ^ n) =\n (fun w : \u2102 => w ^ n) - (fun w : \u2102 => (w - 1) ^ n) := by\n funext w\n simp [Pi.sub_apply]\n rw [hsub, iteratedDeriv_sub hf hg]\n have h1 : iteratedDeriv i (fun w : \u2102 => w ^ n) 1 = n.descFactorial i := by\n rw [iteratedDeriv_pow]\n simp\"\"\")\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiResidue.lean 2>&1 | head -50",
"description": "Apply second round of fixes and recompile",
"timeout": 420000
}
thinking (6623 chars)
Progress on several fronts. Remaining:
1. Line 53: syntax error `':='; expected ')'` — my BddAbove replace broke the parentheses: `BddAbove ((fun z => ‖(z - 1) * riemannZeta z‖) ''` — missing closing paren for the `(fun ...)` before `''`: should be `BddAbove ((fun z => ‖(z - 1) * riemannZeta z‖) '' (Metric.ball 1 2 \ {1}))` — the `''` binds to the lambda ✓ but the outer paren count: `BddAbove ((fun z => ...) '' (...))` — my replacement produced `BddAbove ((fun z => ...) '' (Metric.ball 1 2 \ {1})` — let me look at the actual line.
2. Line 45: unsolved goals — from the broken BddAbove cascading.
3. Line 149: `this : j = j - 1 + 1` then goal has `iteratedDeriv (j - 1 + 1) ... = iteratedDeriv (j - 1 + 1 - 1 + 1) ...` — the rw [this] rewrote j everywhere INCLUDING in the RHS lcoeff (j − 1) — turning it into lcoeff (j−1+1−1). The goal: ... = lcoeff (j − 1): after rw [this] both sides got rewritten. Fix: rw [this] only on LHS — or better: don't use `this`; instead: lcoeff (j−1) = iteratedDeriv ((j−1)+1) hLi 1 / ((j−1)+1)! — and (j−1)+1 = j (omega):
```
lemma hLi_iteratedDeriv_div_factorial {j : ℕ} (hj : 1 ≤ j) :
iteratedDeriv j hLi 1 / j ! = lcoeff (j - 1) := by
rw [lcoeff]
congr 2 <;> omega -- (j−1)+1 = j for the iteratedDeriv arg and (j−1)+1! = j!
```
`congr 2` on iteratedDeriv ((j−1)+1) hLi 1 / ((j−1)+1)! = iteratedDeriv j hLi 1 / j ! — splits into iteratedDeriv arg equality ((j−1)+1 = j) and factorial arg — omega closes both? congr 2 gives: (j−1)+1 = j and ↑((j−1)+1)! = ↑j ! — omega for first; the factorial equality needs congr: (j−1)+1 = j ⟹ factorial equal — omega can't prove cast-factorial equality. Better:
```
rw [lcoeff, show j - 1 + 1 = j from by omega]
```
rw [show j - 1 + 1 = j from by omega] rewrites `j - 1 + 1` to `j` in the lcoeff unfolding — goal becomes iteratedDeriv j hLi 1 / j ! = iteratedDeriv j hLi 1 / j ! — rfl ✓ (rw auto-closes).
4. Line 159: `NormedAddCommGroup ℕ` + `HSub ℂ ℂ ℕ` — in A_iter's h1: `rw [iteratedDeriv_pow]; simp` — the issue: iteratedDeriv_pow : iteratedDeriv k (· ^ m) x = m.descFactorial k * x ^ (m - k) — the `(· ^ m)` notation is `fun x => x ^ m` ✓. After rw, simp should close `n.descFactorial i * 1 ^ (n - i) = n.descFactorial i`. The HSub ℂ ℂ ℕ error at 159:30 — hmm 159 is h1's line or h2's. The `1 ^ (n - i)` — with 1 : ℂ ✓. The ℕ error — maybe from `n.descFactorial i` cast `(n.descFactorial i : ℂ)` — in my h1 statement I wrote `= n.descFactorial i` — the cast: the LHS is ℂ so n.descFactorial i gets cast to ℂ ✓... The `NormedAddCommGroup ℕ` — perhaps `iteratedDeriv i (fun w : ℂ => w ^ n) 1` — the `w ^ n` with w : ℂ, n : ℕ ✓...
Hmm — line 159:4 error and 159:30 — let me see the actual line numbers. The A_iter block after my hsub insert — 159 might be the `simp [Pi.sub_apply]` in hsub? or h1's simp. The `HSub ℂ ℂ ℕ` — subtraction ℂ − ℂ expecting result ℕ?? — from `(w - 1) ^ n` where the elaborator picked... In hsub: `(fun w : ℂ => w ^ n - (w - 1) ^ n) = (fun w : ℂ => w ^ n) - (fun w : ℂ => (w - 1) ^ n)` — funext w; simp [Pi.sub_apply] — Pi.sub_apply : (f − g) x = f x − g x ✓ goal becomes w^n − (w−1)^n = w^n − (w−1)^n ✓ simp closes. Hmm.
Actually the `HSub ℂ ℂ ℕ` at 159:30 — probably in h2: `congr_fun (iteratedDeriv_comp_sub_const i (fun w : ℂ => w ^ n) (1 : ℂ)) 1` — wait no. Let me get the exact line content by reading the file around 155–170.
5. Line 169: `rw [hsub, iteratedDeriv_sub hf hg]` — the rw [hsub] failed: "did not find pattern fun w => w ^ n - (w - 1) ^ n" — because hsub's LHS is `(fun w => w ^ n - (w - 1) ^ n)` WITHOUT the : ℂ annotation matching the goal's elaborated form (the goal has `fun w => w ^ n - (w - 1) ^ n` with w : ℂ inferred — should match... "did not find occurrence" — because hsub's LHS has explicit `(fun w : ℂ => ...)` while the goal's lambda is `(fun w => ...)` with w's type inferred — these are the same after elaboration... hmm, but rw uses syntactic matching up to reducible defeq — the explicit annotation shouldn't matter. Unless the goal's function is displayed differently (e.g., the goal has `fun w => w ^ n - (w - 1) ^ n` — same). The error shows target `iteratedDeriv i (fun w => w ^ n - (w - 1) ^ n) 1 = ...` and pattern not found — weird. Maybe hsub's elaboration created `(fun w : ℂ => w ^ n - (w - 1) ^ n)` where the inner `(w - 1)` got different instance args... Use `show` instead:
```
rw [show (fun w : ℂ => w ^ n - (w - 1) ^ n) =
(fun w : ℂ => w ^ n) - (fun w : ℂ => (w - 1) ^ n) from by
funext w; simp [Pi.sub_apply], iteratedDeriv_sub hf hg]
```
Or use `conv_lhs => rw [show ...]`. Or simplest: `change iteratedDeriv i ((fun w : ℂ => w ^ n) - (fun w : ℂ => (w - 1) ^ n)) 1 = _` (defeq via Pi.sub_apply) then rw [iteratedDeriv_sub hf hg].
6. Line 204: `rw [ResW1, hmul]` — hmul : iteratedDeriv n (fun w => (w^n − (w−1)^n) * hLi w) 1 = ∑ ... — the ResW1 def's function is `fun w => (w ^ n - (w - 1) ^ n) * hLi w` — hmul's LHS should match after rw [ResW1]... the error says pattern `iteratedDeriv n ((fun w => w ^ n - (w - 1) ^ n) * hLi) 1` not found in target `iteratedDeriv n (fun w => (w ^ n - (w - 1) ^ n) * hLi w) 1 / ↑n ! = ...` — the target has `fun w => (w^n − (w−1)^n) * hLi w` (application form) vs hmul's `(fun w => w^n − (w−1)^n) * hLi` (function product). Defeq by Pi.mul_apply but rw needs syntactic match. Fix: make hmul's statement use the application form:
```
have hmul : iteratedDeriv n (fun w => (w ^ n - (w - 1) ^ n) * hLi w) 1 =
∑ i ∈ Finset.range (n + 1),
n.choose i * iteratedDeriv i (fun w : ℂ => w ^ n - (w - 1) ^ n) 1 *
iteratedDeriv (n - i) hLi 1 := by
have h := iteratedDeriv_mul hA hh
rw [show (fun w => (w ^ n - (w - 1) ^ n) * hLi w) =
(fun w : ℂ => w ^ n - (w - 1) ^ n) * hLi from by
funext w; simp [Pi.mul_apply]]
exact h
```
(from STATE gotchas: Pi.mul_apply simp after .mul ✓ — noted in handoff!)
7. The hsum's `simp [A_iter n n le_rfl]` — after rw [Finset.sum_range_succ], goal: (∑ i ∈ range n, f i) + f n = ∑ i ∈ range n, g i — simp [A_iter n n le_rfl] simplifies f n to 0 (A_iter gives `if n < n then _ else 0` = 0), then need ∑ f = ∑ g via sum_congr. The simp might close the +f n = +0 part. Then `apply Finset.sum_congr rfl; intro i hi; rw [A_iter n i (by omega), if_pos hi]`. Note the choose cast: hmul's sum has `n.choose i * ...` — with n.choose i : ℕ cast? In iteratedDeriv_mul for ℂ: the statement `n.choose i * iteratedDeriv i f x * ...` — choose cast to ℂ via `· • ` or cast — whatever it elaborates as, matching.
Let me apply these fixes: lines for BddAbove parens, hLi_iteratedDeriv_div_factorial congr, A_iter show-form, hmul application form.
Fixing the paren break, the congr form, the function-sub/product form mismatches.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && sed -n '50,56p' NguyenRH1/LiResidue.lean",
"description": "View broken BddAbove line"
}
thinking (2834 chars)
Fixing remaining issues:
1. Line 61 (hbd): the hδ application — `hδ (by rwa [dist_eq_norm, sub_zero] exact hz.1)` — the structure: hδ needs `z ∈ {1}ᶜ` and `dist z 1 < δ` — my by-block produced the wrong thing. hz.1 : z ∈ Metric.ball 1 2 — that's `dist z 1 < 2`, not what hδ wants. I need `dist z 1 < δ` — I don't have it! The ball(1,2) might be bigger than δ. Restructure: use the punctured ball around 1 of radius min δ 2: s := Metric.ball 1 (min δ 2). Simpler: extract the δ first, then use ball 1 (δ/2) as the neighborhood s:
```
have hT := riemannZeta_residue_one
rw [Metric.tendsto_nhdsWithin_nhds] at hT
obtain ⟨δ, hδ0, hδ⟩ := hT 1 one_pos
-- work on s := Metric.ball 1 (δ/2)
have hdiff : DifferentiableOn ℂ (fun w => (w - 1) * riemannZeta w) (Metric.ball 1 (δ/2) \ {1}) := ...
have hbd : BddAbove ((fun z => ‖(z - 1) * riemannZeta z‖) '' (Metric.ball 1 (δ/2) \ {1})) := by
refine ⟨2, ?_⟩
rintro _ ⟨z, hz, rfl⟩
have hz1 : z ≠ 1 := hz.2
have hdist : dist z 1 < δ := by
have := hz.1
rw [Metric.mem_ball] at this
linarith [this, hδ0]
have h1 := hδ (Set.mem_compl_singleton_iff.mpr hz1) hdist
rw [dist_eq_norm] at h1
have h2 : ‖(z - 1) * riemannZeta z‖ ≤ ‖(z - 1) * riemannZeta z - 1‖ + ‖(1 : ℂ)‖ :=
norm_sub_le ((z - 1) * riemannZeta z) 1
rw [norm_one] at h2
linarith [h1]
have h := differentiableOn_update_limUnder_of_bddAbove
(Metric.ball_mem_nhds 1 (by positivity : (0 : ℝ) < δ / 2)) hdiff hbd
```
Note: hδ's signature from the display: `hδ : ∀ ⦃x : ℂ⦄, x ∈ {1}ᶜ → dist x 1 < δ → dist ((x - 1) * riemannZeta x) 1 < 1` — needs x ∈ {1}ᶜ (the nhdsWithin set) ✓ Set.mem_compl_singleton_iff.mpr hz1.
And hdiff on ball 1 (δ/2) — same proof.
2. Line 157: `NormedAddCommGroup ℕ` + `HSub ℂ ℂ ℕ` — in A_iter, which line? 157 is the `rw [show (fun w : ℂ => ...) = ...]` — the show's funext proof: `funext w; simp [Pi.sub_apply]` — hmm, no. Let me count lines: A_iter starts ~line 150. Line 157: likely `rw [iteratedDeriv_pow]` in h1, or the show line. The `HSub ℂ ℂ ℕ` — a subtraction ℂ − ℂ with expected result ℕ — bizarre. OH WAIT — I bet it's in h1: `iteratedDeriv i (fun w : ℂ => w ^ n) 1 = n.descFactorial i` — the RHS: `n.descFactorial i` where the expected type is ℂ — cast ✓. Hmm no. Let me look at lines 155–165 directly.
3. Line 163: the `rw [show ... , iteratedDeriv_sub hf hg]` — pattern `fun w => w ^ n - (w - 1) ^ n` not found — the `show`-based rw — the LHS of my show is `(fun w : ℂ => w ^ n - (w - 1) ^ n)` — the goal has `fun w => w ^ n - (w - 1) ^ n` — should match... unless elaboration differs. Let me look at the actual current state of the A_iter block in the file and rewrite it wholesale instead of patching. Also hmul's rwa has the same issue at 204.
Let me read the current A_iter block and rewrite it + the hmul block carefully.
Let me look at the current state of the broken blocks and rewrite them directly.
tool: Read ok
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiResidue.lean",
"offset": 148,
"limit": 75
}
result 2026-08-21 21:11:56Z → 2026-08-22 17:27:08Z
{
"type": "text",
"file": {
"filePath": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiRBound.lean",
"content": "\n/-- The unit-interval IBP: over each integer interval [k, k+1] (k \u2265 1),\n\u222b B\u0303\u2081\u00b7x^{\u2212s\u22121} = (s+1)\u00b7\u222b B\u0303\u2082\u00b7x^{\u2212s\u22122} (boundary terms vanish: B\u0303\u2082 = 0 at\nthe integers). -/\ntheorem intervalIntegral_b1_cpow (k : \u2115) (hk : 1 \u2264 k) (s : \u2102) (hs : s \u2260 -1) :\n \u222b x in (k : \u211d)..(k + 1 : \u211d), (B1 x : \u2102) * (x : \u2102) ^ (-s - 1)\n = (s + 1) * \u222b x in (k : \u211d)..(k + 1 : \u211d), (b2Fun x : \u2102) * (x : \u2102) ^ (-s - 2) := by\n have hk0 : (0:\u211d) < (k : \u211d) := by exact_mod_cast hk\n have hu : ContinuousOn (fun x : \u211d => (b2Fun x : \u2102)) (Set.Icc (k : \u211d) (k + 1 : \u211d)) :=\n (continuous_ofReal.comp continuous_b2Fun).continuousOn\n have hv : ContinuousOn (fun x : \u211d => (x : \u2102) ^ (-s - 1)) (Set.Icc (k : \u211d) (k + 1 : \u211d)) := by\n intro x hx\n have hx0 : x \u2260 0 := by\n have : (k : \u211d) \u2264 x := hx.1\n linarith",
"numLines": 15,
"startLine": 98,
"totalLines": 146
}
}
thinking (2873 chars)
I see the issues now:
1. Line 157 (`HSub ℂ ℂ ℕ` + `NormedAddCommGroup ℕ`): the lemma statement `iteratedDeriv i (fun w => w ^ n - (w - 1) ^ n) (1 : ℂ) = if i < n then n.descFactorial i else 0` — the lambda `fun w => w ^ n - (w - 1) ^ n` — w's type is UNANNOTATED! Lean must infer it from context: iteratedDeriv needs 𝕜 — from the point `(1 : ℂ)` it infers 𝕜 = ℂ, so w : ℂ ✓... but `n.descFactorial i` in the RHS — the `if i < n then n.descFactorial i else 0` — the else 0 : ℂ, so descFactorial casts to ℂ ✓. Where's the HSub ℂ ℂ ℕ? — maybe the issue: the lambda's body `w ^ n - (w - 1) ^ n` — with w : ℂ, `(w - 1)` — the `1` here — is it ℂ? Should be from w : ℂ ✓. Hmm — but the error at 157:4/157:30 is about the STATEMENT line itself — `(1 : ℂ)` at position 30 — col 30 is `(1 : ℂ)`... The errors "NormedAddCommGroup ℕ" and "HSub ℂ ℂ ℕ" — these come from `iteratedDeriv i (fun w => ...) (1 : ℂ)` — iteratedDeriv's signature: `iteratedDeriv (n : ℕ) (f : 𝕜 → F) (x : 𝕜)` — with x := (1 : ℂ): 𝕜 := ℂ; then f : ℂ → F — the lambda `fun w => w^n − (w−1)^n` — with w : ℂ from the function type, F = ℂ ✓... UNLESS the elaborator tried to unify the lambda's domain with the point's type and got confused, elaborating the lambda at ℕ first?? The `if i < n then n.descFactorial i else 0` — the `0` : ℂ ✓... Hmm, the HSub ℂ ℂ ℕ error suggests somewhere `(? : ℂ) − (? : ℂ) : ℕ` — maybe from `(w - 1) ^ n` where `^ n` with n : ℕ — fine...
Actually — I bet the issue: `iteratedDeriv i` where i : ℕ, and `iteratedDeriv` takes n : ℕ ✓; but the LAMBDA `fun w => w ^ n - (w - 1) ^ n` — Lean elaborates `w ^ n` — with w fresh and n : ℕ — if the domain type isn't pinned yet, `w ^ n` could elaborate in ℕ with w : ℕ!! Then `w - 1` in ℕ, and the subtraction of the two ℂ-typed... The `(1 : ℂ)` annotation is at the END of the expression (iteratedDeriv's third arg) — elaboration order might elaborate the lambda BEFORE unifying with the point's type. The lambda `fun w => w ^ n - (w - 1) ^ n` — no type annotation on w — Lean defaults: `w ^ n` — `^` needs Monoid; `w - 1` needs Sub — defaults to... could be ℕ! That's exactly the HSub ℂ ℂ ℕ / NormedAddCommGroup ℕ errors — the elaborator picked w : ℕ somewhere then tried to unify with ℂ.
FIX: annotate w : ℂ in the lemma statement: `iteratedDeriv i (fun w : ℂ => w ^ n - (w - 1) ^ n) (1 : ℂ)`. Same for the ResW1 def's lambda: `fun w : ℂ => (w ^ n - (w - 1) ^ n) * hLi w`.
2. Line 163's rw [show ...] failure: same root cause — the statement's lambda without annotation elaborated differently from the show's annotated one. After fixing the statement annotation, the show should match.
3. hmul's rwa: same annotation fix.
4. hbd's restructure (dist issue).
Let me apply these fixes: annotate lambdas in A_iter statement, ResW1 def, and rewrite hbd. Also the `deriv_sub_const` unused warning — cosmetic, leave it (or drop the argument).
Root cause found: the lambdas need explicit `: ℂ` annotations — elaboration was defaulting `w` to ℕ. Fixing all of them plus the hbd restructure.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiResidue.lean'\ns = open(p, encoding='utf-8').read()\n\n# 1. annotate lambda in A_iter statement\ns = s.replace(\"iteratedDeriv i (fun w => w ^ n - (w - 1) ^ n) (1 : \u2102) =\",\n \"iteratedDeriv i (fun w : \u2102 => w ^ n - (w - 1) ^ n) (1 : \u2102) =\")\n\n# 2. annotate lambda in ResW1 def\ns = s.replace(\"iteratedDeriv n (fun w => (w ^ n - (w - 1) ^ n) * hLi w) (1 : \u2102) / n !\",\n \"iteratedDeriv n (fun w : \u2102 => (w ^ n - (w - 1) ^ n) * hLi w) (1 : \u2102) / n !\")\n\n# 3. rewrite hbd with correct radius handling\nold_hbd = s[s.index(\" have hbd : BddAbove ((fun z => \u2016(z - 1) * riemannZeta z\u2016) ''\"):s.index(\" have h := differentiableOn_update_limUnder_of_bddAbove\")]\nnew_hbd = \"\"\" have hT := riemannZeta_residue_one\n rw [Metric.tendsto_nhdsWithin_nhds] at hT\n obtain \u27e8\u03b4, h\u03b40, h\u03b4\u27e9 := hT 1 one_pos\n have hdiff : DifferentiableOn \u2102 (fun w => (w - 1) * riemannZeta w)\n (Metric.ball 1 (\u03b4 / 2) \\\\ {1}) := by\n intro w hw\n have hw1 : w \u2260 1 := hw.2\n exact ((differentiableAt_id.sub (differentiableAt_const 1)).mul\n (differentiableAt_riemannZeta hw1)).differentiableWithinAt\n have hbd : BddAbove ((fun z => \u2016(z - 1) * riemannZeta z\u2016) ''\n (Metric.ball 1 (\u03b4 / 2) \\\\ {1})) := by\n refine \u27e82, ?_\u27e9\n rintro _ \u27e8z, hz, rfl\u27e9\n have hz1 : z \u2260 1 := hz.2\n have hdist : dist z 1 < \u03b4 := by\n have := hz.1\n rw [Metric.mem_ball] at this\n linarith [this, h\u03b40]\n have h1 := h\u03b4 (Set.mem_compl_singleton_iff.mpr hz1) hdist\n rw [dist_eq_norm] at h1\n have h2 : \u2016(z - 1) * riemannZeta z\u2016 \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 :=\n norm_sub_le ((z - 1) * riemannZeta z) 1\n rw [norm_one] at h2\n linarith [h1]\n\"\"\"\ns = s.replace(old_hbd, new_hbd)\n\n# 4. remove the old hdiff (now duplicated)\nold_hdiff_first = \"\"\" have hdiff : DifferentiableOn \u2102 (fun w => (w - 1) * riemannZeta w)\n (Metric.ball 1 2 \\\\ {1}) := by\n intro w hw\n have hw1 : w \u2260 1 := hw.2\n exact ((differentiableAt_id.sub (differentiableAt_const 1)).mul\n (differentiableAt_riemannZeta hw1)).differentiableWithinAt\n\"\"\"\n# remove only the FIRST occurrence (before hT)\nidx_hT = s.index(\" have hT := riemannZeta_residue_one\")\nidx_first = s.index(old_hdiff_first)\nif idx_first < idx_hT:\n s = s[:idx_first] + s[idx_first:].replace(old_hdiff_first, \"\", 1)\n\n# 5. fix the ball radius in the final analytic call\ns = s.replace(\"(Metric.ball_mem_nhds 1 (by norm_num : (0 : \u211d) < 2)) hdiff hbd\",\n \"(Metric.ball_mem_nhds 1 (by positivity : (0 : \u211d) < \u03b4 / 2)) hdiff hbd\")\ns = s.replace(\"exact han 1 (Metric.mem_ball_self (by norm_num : (0 : \u211d) < 2))\",\n \"exact han 1 (Metric.mem_ball_self (by positivity : (0 : \u211d) < \u03b4 / 2))\")\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiResidue.lean 2>&1 | head -40",
"description": "Apply fourth round of fixes and recompile",
"timeout": 420000
}
thinking (3892 chars)
`Finset.sum_range_reflect (f) (n) : (∑ j ∈ range n, f (n - 1 - j)) = ∑ j ∈ range n, f j` — so ← gives the reflection.
For the Icc→range conversion: `Finset.sum_Icc_eq_sum_range` doesn't exist. Options: `Finset.sum_Ico_eq_sum_range`? Let me just do the reindexing via `Finset.sum_bij` or simpler: Icc 1 n = Ioc 0 n, and there's `Finset.sum_Ioc_eq_sum_range`? Alternatively note Icc 1 n = (range (n+1)).erase 0 with `Finset.sum_range_succ_comm`? Hmm.
Cleanest robust approach: avoid the Icc entirely — change the theorem statement to sum over `Finset.range n` with j ↦ j+1? NO — the target form `∑ j ∈ Finset.Icc 1 n` matches D-064's Σ_{j=1}^n — keep the statement. For the reindexing use `Finset.sum_bij`:
```
apply Finset.sum_bij (fun i _ => n - i) (fun i hi => ...) ...
```
That's verbose. Alternative: `Finset.sum_Ico_reflect`? — there was `prod_Ico_reflect` in the imports — `Finset.sum_Ico_reflect (f) (h : a ≤ b) : ∑ i ∈ Ico a b, f (a + b - i) = ∑ i ∈ Ico a b, f i`? Hmm.
Simplest reliable: prove the reindexing equality directly via sum_range_reflect + sum_Icc_eq_sum_range-by-hand:
∑ j ∈ Icc 1 n, g j = ∑ i ∈ range n, g (i + 1):
```
have hIcc : Finset.Icc 1 n = (Finset.range (n + 1)).erase 0 := by
ext j
simp [Finset.mem_Icc, Finset.mem_range, Finset.mem_erase]
omega
rw [hIcc, Finset.sum_erase]
-- ∑ j ∈ range (n+1), g j − g 0 = ∑ i ∈ range n, g(i) + g n − g 0 ... messy
```
Hmm. Alternative cleanest: `Finset.sum_Icc_eq_sum_range` might exist under `Finset.sum_Icc_eq_sum_range` in a different file... it didn't grep. There's `Finset.sum_Ico_eq_sum_range`? Let me check via grep for "Ico.*range" sum lemmas... Actually there's `Finset.sum_range_succ_sub_sum`...
New approach — skip the reindexing gymnastics: prove the sum equality by `Finset.sum_bij` with the explicit bijection i ↦ n−i from range n to Icc 1 n:
```
apply Finset.sum_bij (fun i _ => n - i)
· intro i hi
rw [Finset.mem_range] at hi
simp [Finset.mem_Icc]
omega
· intro i hi
simp
· intro a b ha hb hab
rw [Finset.mem_range] at ha hb
omega
· intro j hj
rw [Finset.mem_Icc] at hj
use n - j
rw [Finset.mem_range]
constructor
· omega
· omega
```
Finset.sum_bij signature: `Finset.sum_bij (i : ∀ a ∈ s, ι) (hi : ∀ a ha, i a ha ∈ t) (h : ∀ a ha, f a = g (i a ha)) (i_inj : InjOn i s) (i_surj : ∀ b ∈ t, ∃ a ha, i a ha = b) : ∑ x ∈ s, f x = ∑ x ∈ t, g x` — the argument order varies by Mathlib version: `sum_bij (i) (hi) (h) (i_inj) (i_surj)`. Let me write:
```
apply Finset.sum_bij (fun i _ => n - i)
· intro i hi
rw [Finset.mem_range] at hi
rw [Finset.mem_Icc]
omega
· intro i hi
rw [Finset.mem_range] at hi
have e1 : n - (n - i) = i := by omega
have e2 : n.choose (n - i) = n.choose i := Nat.choose_symm (by omega)
rw [e1, e2]
· intro a b ha hb hab
rw [Finset.mem_range] at ha hb
omega
· intro j hj
rw [Finset.mem_Icc] at hj
exact ⟨n - j, by rw [Finset.mem_range]; omega, by omega⟩
```
Wait — sum_bij's third argument `h : ∀ a ha, f a = g (i a ha)`: f i = (choose i)·lcoeff(n−i−1), g (i) = (choose i)·lcoeff(i−1), i a ha = n − a: g (n−a) = (choose (n−a))·lcoeff((n−a)−1). Need: (choose a)·lcoeff(n−a−1) = (choose (n−a))·lcoeff(n−a−1) ⟸ choose a = choose (n−a) (Nat.choose_symm: n.choose (n − a) = n.choose a for a ≤ n ✓ direction: n.choose (n−a) = n.choose a — choose_symm gives exactly this ✓). So:
```
· intro i hi
rw [Finset.mem_range] at hi
have e2 : n.choose (n - i) = n.choose i := Nat.choose_symm (by omega)
rw [e2]
```
After rw [e2] both sides: (choose i)·lcoeff(n−i−1) = (choose i)·lcoeff(n−i−1) — wait the RHS: g (n−i) = (n.choose (n−i))·lcoeff((n−i)−1) — after rw [e2]: (n.choose i)·lcoeff(n−i−1) — matches f i exactly ✓ rfl by rw.
Let me replace hre's body with the sum_bij approach. Also fix hterm's field_simp and h2's norm_add_le.
Applying fixes: the norm calc, field_simp with nonzero facts, and a `sum_bij` reindexing.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiResidue.lean'\ns = open(p, encoding='utf-8').read()\n\n# 1. h2 norm calc fix\ns = s.replace(\"\"\" have h2 : \u2016(z - 1) * riemannZeta z\u2016 \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 := by\n have h3 : (z - 1) * riemannZeta z = ((z - 1) * riemannZeta z - 1) + 1 := by ring\n rw [h3]\n exact norm_add_le _ _\"\"\",\n\"\"\" have h2 : \u2016(z - 1) * riemannZeta z\u2016 \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 := by\n have h3 : (z - 1) * riemannZeta z = ((z - 1) * riemannZeta z - 1) + 1 := by ring\n calc \u2016(z - 1) * riemannZeta z\u2016 = \u2016((z - 1) * riemannZeta z - 1) + 1\u2016 := by rw [h3]\n _ \u2264 \u2016(z - 1) * riemannZeta z - 1\u2016 + \u2016(1 : \u2102)\u2016 := norm_add_le _ _\"\"\")\n\n# 2. hterm field_simp with ne facts\ns = s.replace(\"\"\" rw [hlc]\n field_simp\n ring\"\"\",\n\"\"\" rw [hlc]\n have hf1 : (n ! : \u2102) \u2260 0 := by simp [Nat.factorial_ne_zero]\n have hf2 : ((n - i) ! : \u2102) \u2260 0 := by simp [Nat.factorial_ne_zero]\n field_simp [hf1, hf2]\n ring\"\"\")\n\n# 3. hre via sum_bij\nold_hre = s[s.index(\" have hre : (\u2211 i \u2208 Finset.range n, (n.choose i : \u2102) * lcoeff (n - i - 1)) =\"):]\nold_hre = old_hre[:old_hre.index(\" exact hre\") + len(\" exact hre\")]\nnew_hre = \"\"\" have hre : (\u2211 i \u2208 Finset.range n, (n.choose i : \u2102) * lcoeff (n - i - 1)) =\n \u2211 j \u2208 Finset.Icc 1 n, (n.choose j : \u2102) * lcoeff (j - 1) := by\n apply Finset.sum_bij (fun i _ => n - i)\n \u00b7 intro i hi\n rw [Finset.mem_range] at hi\n rw [Finset.mem_Icc]\n omega\n \u00b7 intro i hi\n rw [Finset.mem_range] at hi\n have e2 : n.choose (n - i) = n.choose i := Nat.choose_symm (by omega)\n rw [e2]\n \u00b7 intro a b ha hb hab\n rw [Finset.mem_range] at ha hb\n omega\n \u00b7 intro j hj\n rw [Finset.mem_Icc] at hj\n exact \u27e8n - j, by rw [Finset.mem_range]; omega, by omega\u27e9\n exact hre\"\"\"\ns = s.replace(old_hre, new_hre)\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiResidue.lean 2>&1 | head -40",
"description": "Apply sixth round of fixes and recompile",
"timeout": 420000
}
thinking (2132 chars)
Almost there — three remaining:
1. Line 68: `rw [h3]` in the calc — h3 rewrites the goal `(z-1)*ζ z = ((z-1)*ζ z − 1) + 1` — but rw [h3] on the goal `‖(z - 1) * riemannZeta z‖ = ‖((z - 1) * riemannZeta z - 1) + 1‖` — rewrites `(z-1)*ζ z` EVERYWHERE (including inside the RHS!), producing the loop `−1 + 1` mess. Classic. Fix: `conv_lhs => rw [h3]`:
```
calc ‖(z - 1) * riemannZeta z‖ = ‖((z - 1) * riemannZeta z - 1) + 1‖ := by
conv_lhs => rw [h3]
_ ≤ ‖(z - 1) * riemannZeta z - 1‖ + ‖(1 : ℂ)‖ := norm_add_le _ _
```
2. Line 242 "No goals to be solved" — hterm's `field_simp [hf1, hf2]; ring` — field_simp closed the goal and ring had nothing. Remove the ring:
```
field_simp [hf1, hf2]
```
Hmm — but will field_simp fully close? The remaining equality after clearing denominators: C·n!·h·((n−i)!) = C·h·(n!·((n−i)!))... field_simp normalizes and closes trivial goals ✓ if it leaves something, I'll see.
3. Line 255: sum_bij's i_inj goal got mangled: `∀ a₂ ∈ Finset.range n, n - i = n - a₂ → i = a₂` with `rw [e2]` error — the second bullet (h : ∀ a ha, f a = g (i a ha)) — my e2 rewrite pattern `n.choose (n - i)` not found — wait the error shows the goal is the INJ goal, not the value goal — the rw [e2] error happened in the value bullet, but the displayed goal is the inj goal?? The error at 255:10 — the bullet structure misaligned: sum_bij's arguments in this Mathlib version might have a DIFFERENT order! The goals: (1) hi : ∀ a ha, i a ha ∈ t ✓ (first bullet OK); (2) h : ∀ a ha, f a = g (i a ha) — my second bullet got the i_inj goal instead — so the argument order differs: probably sum_bij (i) (hi) (i_inj) (i_surj) (h) or (i) (hi) (h) (i_surj) (i_inj)... The displayed: after my second bullet's `rw [Finset.mem_range] at hi`, the goal became `∀ a₂ ∈ Finset.range n, n - i = n - a₂ → i = a₂` — that's the INJECTIVITY goal — so sum_bij's third expected argument is i_inj, not h. Signature: `Finset.sum_bij (i : ∀ a ∈ s, ι) (hi : ∀ a ha, i a ha ∈ t) (i_inj : InjOn i s) (i_surj : ∀ b ∈ t, ∃ a ha, i a ha = b) (h : ∀ a ha, f a = g (i a ha)) : ∑ = ∑`?? Hmm — let me check the actual signature.
Three small fixes. Let me check the exact `sum_bij` signature first.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem Finset.sum_bij \\|lemma Finset.sum_bij \" Mathlib/Algebra/BigOperators/Basic.lean | head -3; grep -A3 \"theorem Finset.sum_bij \" Mathlib/Algebra/BigOperators/Basic.lean | head -6",
"description": "Check Finset.sum_bij signature"
}
thinking (208 chars)
LiResidue.lean compiles clean! Only a warning-free output (the "patched" print and no errors). Let me verify no errors remain and check the full picture — also run a quick axiom check on the new declarations.
LiResidue.lean compiles clean. Verifying with a fresh full check plus axiom audit.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && export PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiResidue.lean 2>&1 | head -10; echo \"=== exit: $?\" && cat > PrintAxioms.lean << 'EOF'\n/- Session 016 axiom audit: ii\u2032-1b(i) new declarations. -/\nimport Mathlib\nimport NguyenRH1.LiResidue\n\nopen NguyenRH1\n\n#print axioms ResW1_eq_sum\n#print axioms zetaA_analyticAt_one\n#print axioms hLi_analyticAt_one\n#print axioms hLi_eq_near_one\n#print axioms A_iter\nEOF\nlake env lean PrintAxioms.lean 2>&1 | head -8",
"description": "Verify clean compile and axiom audit",
"timeout": 420000
}
thinking (1728 chars)
ii′-1b(i) is COMPLETE and axiom-clean:
- `zetaA` analytic at 1 (removable singularity)
- `hLi` analytic at 1, hLi 1 = 1, hLi_eq_near_one
- `lcoeff` (operational Laurent coefficients)
- `A_iter` (A-polynomial derivatives)
- `ResW1_eq_sum` : ResW1 n = Σ_{j=1}^n C(n,j)·lcoeff(j−1) — the w=1 residue value, exactly as designed.
Session 016 has delivered ii′-1b(i). The remaining pieces of ii′-1b: (ii) principal-part integral ∮ P = ResW1, (iii) R holomorphic at 1 + rectangle residue theorem. Given the session length already (many iterations), let me assess: continue with (ii) now or wrap the session cleanly with (i) committed?
Per the pacing rules (§8.5): sub-stages should end in clean committed states. ii′-1b(i) is a clean, self-contained deliverable (the residue VALUE theorem). Committing now is sensible. But the user is engaged and said "let's go" — I should continue working. However, this response is getting long and the natural commit boundary is here. Let me commit ii′-1b(i) and continue with (ii) in the same session if feasible — the user is on telegram, so they'll read the summary later anyway. Let me commit first (crash-safe per §8.4 NOTE: save artifacts IMMEDIATELY).
For the commit: journal entry should note ii′-1b in progress with (i) done. Actually — per protocol, journal/STATE are session-END artifacts. Since I'm mid-session and continuing, the clean approach: commit the working file with a WIP note (crash-safety), then continue with (ii). Let me do a quick WIP commit of LiResidue.lean, then push forward with (ii).
Actually — better practice per §8.4: "save artifacts IMMEDIATELY when produced (crash-safe)". So: commit LiResidue.lean + PrintAxioms.lean now with a WIP message, then continue.
ii′-1b(i) is complete and axiom-clean. Committing immediately for crash-safety, then continuing with part (ii).
tool: Bash
input
{
"command": "cd /d/Python/Quantum && git add research/lean/NguyenRH1/NguyenRH1/LiResidue.lean research/lean/NguyenRH1/PrintAxioms.lean && git -c user.name=\"NGUYEN-RH-1\" -c user.email=\"research@local\" commit -m \"$(cat <<'EOF'\nSession 016 (WIP): ii'-1b(i) \u2014 the w=1 residue value theorem\n\nLiResidue.lean Part 1, PROVED (axiom audit: 3 standard axioms only):\n- zetaA = (w-1)*zeta(w) extended by 1 at 1: analytic (removable\n singularity via riemannZeta_residue_one + Mathlib RemovableSingularity)\n- hLi = 1 - (w-1)*(zetaA'/zetaA): analytic at 1, hLi 1 = 1, agrees with\n (w-1)(-zeta'/zeta) on a punctured nhd of 1 (hLi_eq_near_one)\n- lcoeff k := iteratedDeriv (k+1) hLi 1 / (k+1)! (operational Laurent\n coefficients of -zeta'/zeta at 1)\n- A_iter: derivatives of A(w) = w^n - (w-1)^n at 1\n- ResW1_eq_sum: the w=1 residue of the Lagarias-kernel integrand equals\n sum_{j=1}^n C(n,j)*lcoeff(j-1) \u2014 via iteratedDeriv_mul (Leibniz),\n exactly as designed in D-064 R1 / verified numerically session 014.\nEOF\n)\" && git log --oneline -1",
"description": "WIP commit of ii\u2032-1b(i)"
}
thinking (7493 chars)
Committed. Now ii′-1b(ii): the principal-part integral ∮ P = ResW1.
Setup: P(w) = Σ_{i=1}^{n+1} A_i/(w−1)^i with A_i = F^{(n+1−i)}(1)/(n+1−i)!, F(w) = (wⁿ−(w−1)ⁿ)hLi(w). The claim: on any rectangle with 1 in its interior, RectangleIntegral' P z w = A_1 = ResW1 n.
Wait — actually for the assembly in (iii), I need P to be the FULL principal part of J at 1. The A_i's: A_i = (1/(n+1−i)!)·(d/dw)^{n+1−i}[(w−1)^{n+1}J(w)]|₁. And (w−1)^{n+1}J(w) = [wⁿ−(w−1)ⁿ]hLi(w) =: F(w) near 1 (punctured). So A_i = F^{(n+1−i)}(1)/(n+1−i)! and the residue A_1 = F^{(n)}(1)/n! = ResW1 n ✓ by definition of ResW1.
Define:
```
def ppart (n : ℕ) (w : ℂ) : ℂ := ∑ i ∈ Finset.Icc 1 (n+1), (Acoeff n i) / (w - 1)^i
def Acoeff (n i : ℕ) : ℂ := iteratedDeriv (n + 1 - i) (fun w : ℂ => (w ^ n - (w - 1) ^ n) * hLi w) 1 / (n + 1 - i)!
```
Then ∮ P = Acoeff n 1 = ResW1 n (Acoeff n 1 = iteratedDeriv n F 1 / n! = ResW1 ✓ definitionally).
The integral: pull to a small square around 1 (RectanglePullToNhdOfPole'') — actually for the FINAL assembly in (iii), the rectangle is the big D-036 one; the residue theorem machinery (residueTheorem_finset) handles the simple-pole parts; for P I need:
RectangleIntegral' P z w = Acoeff n 1 whenever 1 is interior to the rectangle AND P's only pole (1) is inside.
Proof: P = Acoeff n 1/(w−1) + Σ_{i=2}^{n+1} Acoeff n i/(w−1)^i.
- RectangleIntegral' (fun w => Acoeff n 1/(w−1)) z w = Acoeff n 1 via `ResidueTheoremInRectangle` (needs Rectangle z w ∈ 𝓝 1 = interior ✓).
- Σ_{i≥2} terms integrate to 0: each term Acoeff n i/(w−1)^i = deriv of G_i(w) := −Acoeff n i/((i−1)(w−1)^{i−1}); G_i differentiable on RectangleBorder-neighborhood (1 off the border since 1 is interior ✓); the rectangle integral of a derivative over the closed boundary = 0 by FTC per side.
For the FTC per side: HIntegral (G') x₁ x₂ y = G(x₂+iy) − G(x₁+iy): `intervalIntegral.integral_deriv_eq_sub (h : ∀ x ∈ [[x₁,x₂]], HasDerivAt G (G' x) (x + y*I)) (hint : IntervalIntegrable ...)`. The sides parametrized: HIntegral f x₁ x₂ y = ∫ x in x₁..x₂, f (x + y*I). With f = G': = G(x₂+iy) − G(x₁+iy) if (x ↦ G(x+iy))' = G'(x+iy)·1 ✓ chain rule.
VIntegral f x y₁ y₂ = ∫ y in y₁..y₂, f (x + y*I): with f = G': the derivative of (y ↦ G(x+iy)) is G'(x+iy)·I: so ∫ G'(x+iy) dy = (G(x+iy₂) − G(x+iy₁))/I. The RectangleIntegral = H bottom − H top + I·V right − I·V left: summing:
[G(b) − G(a)] − [G(d) − G(c)] + I·[(G(d) − G(c))/I] − I·[(G(b) − G(a))/I] = 0 ✓ where a,b,c,d corners.
This is mechanical but needs the parametrization FTC done carefully. Is there a ready Mathlib lemma for "rectangle integral of a derivative with primitive differentiable on the border"? Hmm — the vendored `HolomorphicOn.vanishesOnRectangle` : HolomorphicOn f U + Rectangle ⊆ U ⟹ RectangleIntegral f z w = 0 — if G' were holomorphic on a set containing the rectangle... G_i is holomorphic off {1} — and the rectangle CONTAINS 1 — so can't apply directly. BUT — use the pull-to-square first: RectanglePullToNhdOfPole'' reduces to a small square around 1; on the small square, G_i is still singular at center (1) — vanishesOnRectangle doesn't apply either (1 is inside the small square). Hmm — so the primitive-FTC per-side argument is unavoidable... OR use the ML-style trick: A_i/(w−1)^i = (1/(1−i))·deriv(1/(w−1)^{i−1})·... and use `ResidueTheoremOnRectangleWithSimplePole`-style decomposition — no.
Alternative cleaner route for the i ≥ 2 terms: use `RectangleIntegral'_eq_sumResiduesIn`-style... no.
Alternative: use Cauchy's theorem for a function with a primitive: is there a Mathlib lemma `RectangleIntegral f z w = 0` if f has a primitive holomorphic on the rectangle MINUS a point not on the border? The primitive is differentiable ON the border — the standard proof via FTC per side. Let me just do the FTC computation directly — it's about 80–120 lines with the parametrization details.
Actually — wait. Simpler: the i ≥ 2 sum has the primitive G(w) = −Σ_{i=2}^{n+1} Acoeff n i/((i−1)(w−1)^{i−1}) which is differentiable on the whole BORDER (1 is interior, not on border). The rectangle integral of G' over the boundary: each side is a straight segment; FTC applies to G on each closed segment (G differentiable on a neighborhood of each point of the segment — since the border avoids 1 and G is meromorphic with pole only at 1, G is holomorphic in a nhd of every border point ✓). So per side: ∫_side G' = G(end) − G(start). Sum around: 0.
In Lean: HIntegral G' x₁ x₂ y = ∫_{x₁}^{x₂} G'(x + y·I) dx. The integrand: G'(x + yI) = d/dx[G(x+yI)] (chain: HasDerivAt (fun x => G (x + y*I)) (deriv G (x+yI) * 1) x ✓ (HasDerivAt.comp with (fun x => x + yI) derivative 1)). Then `intervalIntegral.integral_deriv_eq_sub (hderiv : ∀ x ∈ [[x₁,x₂]], HasDerivAt (fun x => G (x+yI)) (G' x) x) (hint : IntervalIntegrable (G' ∘ (·+yI)))`: gives ∫ = G(x₂+yI) − G(x₁+yI) ✓. The HasDerivAt for each x on the segment: G is differentiable at x+yI (≠ 1 — border point ≠ 1 ✓ since 1 interior not on border ✓). IntervalIntegrable: G' continuous on the segment ✓ (holomorphic there) ⟹ integrable.
This is doable. Let me estimate the full ii′-1b(ii): P def + Acoeff + the pull-to-square + the i≥2 vanishing + assemble ≈ 200–300 lines. And then (iii) needs R's holomorphic-at-1 + residueTheorem_finset application ≈ 300+ lines. Session 016 already delivered (i); (ii) now, (iii) likely session 017.
Hmm — wait, actually there's a subtlety with the pull-to-square approach: `RectanglePullToNhdOfPole''` gives: RectangleIntegral' f z w = RectangleIntegral' f (small square) for f holomorphic on Rectangle \ {p} — but P has the pole AT 1 — P is NOT holomorphic on Rectangle \ {1}?? P IS holomorphic off {1} (rational function with pole only at 1) ✓. So:
RectangleIntegral' P z w = RectangleIntegral' P (square_c 1) for small c (eventually all c > 0 small).
Then on the small square: P = A_1/(w−1) + [i≥2 sum]. The [i≥2 sum] integral on the small square: the square's border avoids 1 ✓ and the primitive G works on the border ✓ so FTC gives 0. And A_1/(w−1) via ResidueTheoremInRectangle ✓.
Actually — do I even need the pull-to-square? Directly on the big rectangle: P = A_1/(w−1) + G' where G' is the i≥2 sum (with primitive G holomorphic off {1}): RectangleIntegral' (A_1/(w−1) + G') = RectangleIntegral' (A_1/(w−1)) + RectangleIntegral' G' = A_1 + 0 — needs RectangleIntegral'.add (linearity — vendored `RectangleBorderIntegrable.add` + the integral of a sum = sum of integrals — should exist) and the two pieces. So NO pull-to-square needed:
- RectangleIntegral' (fun w => A_1/(w−1)) z w = A_1 via ResidueTheoremInRectangle (needs 1 interior ✓).
- RectangleIntegral' G' z w = 0 via the FTC-per-side argument (G differentiable on border ✓ — 1 interior so border avoids 1 ✓).
Both on the big rectangle directly.
So ii′-1b(ii) needs:
1. `rectInt'_derivative_of_hasDerivOn_border` (generic): if G differentiable on a nhd of each border point, RectangleIntegral' (deriv G) z w = 0. Hmm — more precisely: RectangleIntegral (fun s => deriv G s) z w = 0 (the 2πi factor irrelevant). Via per-side FTC.
2. Acoeff/ppart defs + P = A_1/(w−1) + G' decomposition.
3. RectangleIntegral'.add / linearity.
4. ResidueTheoremInRectangle application.
5. Assemble: rectInt'_ppart : RectangleIntegral' (ppart n) z w = ResW1 n (when 1 interior).
For step 1, the per-side FTC — the RectangleIntegral unfolds into HIntegral/VIntegral sums. Let me check the vendored RectangleIntegral def and whether there's FTC for HIntegral/VIntegral already. Let me look at the def.
Continuing with ii′-1b(ii): the principal-part integral. Checking the rectangle integral definition for the FTC-per-side argument.
tool: Bash
input
{
"command": "sed -n '30,80p' /d/Python/Quantum/zeta-23-lean/Zeta23/FromPNTPlus/ResidueCalcOnRectangles.lean",
"description": "Read HIntegral/VIntegral/RectangleIntegral definitions"
}
thinking (5616 chars)
The definitions are plain interval integrals. The FTC approach: for a function G : ℂ → ℂ differentiable on a neighborhood of the border, with G' = deriv G:
RectangleIntegral (deriv G) z w =
HIntegral G' z.re w.re z.im − HIntegral G' z.re w.re w.im + VIntegral G' w.re z.im w.im − VIntegral G' z.re z.im w.im
HIntegral G' x₁ x₂ y = ∫_{x₁}^{x₂} G'(x + yI) dx = G(x₂ + yI) − G(x₁ + yI) via `intervalIntegral.integral_deriv_eq_sub`.
The relevant Mathlib lemma: `intervalIntegral.integral_deriv_eq_sub (h : ∀ x ∈ Set.uIcc a b, HasDerivAt f (f' x) x) (h' : IntervalIntegrable f' volume a b) : ∫ x in a..b, f' x = f b - f a` — need f' = deriv (fun x => G (x + y*I)). The chain rule: HasDerivAt (fun x => G (x + y*I)) (deriv G (x+y*I)) x? deriv (fun x => G (x + y*I)) x = deriv G (x+y*I) · 1 (the inner function x ↦ x + yI has derivative 1). So:
```
have hside : ∫ x in x₁..x₂, deriv G (x + y*I) = G (x₂ + y*I) - G (x₁ + y*I) := by
have hd : ∀ x ∈ Set.uIcc x₁ x₂, HasDerivAt (fun x => G (x + y*I)) (deriv G (x + y*I)) x := by
intro x hx
have hG : HasDerivAt G (deriv G (x + y*I)) (x + y*I) := (hGd (x + y*I)).hasDerivAt -- G differentiable at border points
have hc : HasDerivAt (fun x => x + y*I) 1 x := by
have := hasDerivAt_id x
-- x ↦ x + y*I has derivative 1
...
convert hG.comp x hc using 1
simp
have hint : IntervalIntegrable (fun x => deriv G (x + y*I)) volume x₁ x₂ := by
apply ContinuousOn.intervalIntegrable ... -- deriv G continuous on border nhd (G analytic there ⟹ deriv continuous? G holomorphic ⟹ deriv G holomorphic? If G is differentiable on an OPEN set containing the border, deriv G is continuous? For complex functions, differentiability on open sets ⟹ analytic ⟹ deriv analytic/continuous ✓.)
have := intervalIntegral.integral_deriv_eq_sub hd hint
rw [this]
```
Hmm wait — the FTC lemma's f is the parametrized function: integral_deriv_eq_sub (h : ∀ x ∈ uIcc, HasDerivAt f (f' x) x) : ∫ f' = f b − f a — with f := fun x => G (x + y*I), f' := fun x => deriv G (x + y*I)·1 = deriv G (x+y*I). ✓.
The differentiability of G at border points: G is meromorphic with pole only at 1; border avoids 1 ⟹ G differentiable at each border point ✓.
The integrability: deriv G continuous on the segment: G differentiable on an open nhd of the border ⟹ G analytic there ⟹ deriv G analytic ⟹ continuous ✓ (AnalyticOnNhd.continuousOn.deriv? or DifferentiableOn.continuousOn for deriv — deriv of a holomorphic function is holomorphic: `DifferentiableOn.deriv`? there's `DifferentiableOn.deriv (hd : DifferentiableOn ℂ f s) (ho : IsOpen s) : DifferentiableOn ℂ (deriv f) s`? I believe `DifferentiableOn.deriv` exists ✓ — and continuousOn from differentiableOn).
For G := our specific primitive (finite sum of (w−1)^{-k} terms) — differentiability at border points: each term (w−1)^{-k} differentiable off {1}; finite sum ✓. Even simpler than the abstract argument: G is a rational function with pole only at 1 — differentiable wherever w ≠ 1 ✓ directly (no analyticity machinery needed — `DifferentiableAt.div` etc.).
Also `deriv G = the i≥2 sum`: G(w) = −Σ_{i=2}^{n+1} A_i/((i−1)(w−1)^{i−1}): deriv G (w) = Σ_{i=2}^{n+1} A_i/(w−1)^i =: Ptail(w) — compute via deriv_sum + deriv of (w−1)^{-(i−1)}: d/dw [(w−1)^{-(i−1)}] = −(i−1)(w−1)^{-i} ✓ (deriv_zpow or deriv of (w−1)^(−(i−1) : ℤ)) — the terms: A_i/((i−1))·(w−1)^{-(i−1)} with negation: G = Σ_{i=2}^{n+1} −(A_i/((i−1):ℂ))·(w−1)^{-((i−1):ℤ)}: deriv = Σ −(A_i/(i−1))·(−(i−1))(w−1)^{-(i−1)−1} = Σ A_i (w−1)^{-i} ✓. With zpow: deriv_zpow (m : ℤ) — `deriv_zpow (m : ℤ) (x) : deriv (· ^ m) x = m * x ^ (m - 1)`? there's `deriv_zpow` ✓ I believe.
OK — this is all standard. Estimate ~200 lines for part (ii). Let me write it as Part 2 of LiResidue.lean (appended, or a new file LiPrincipal.lean — separate file keeps compile times modular: new file `LiPrincipal.lean` importing LiResidue).
Structure of LiPrincipal.lean:
1. `Acoeff (n i : ℕ) : ℂ := iteratedDeriv (n + 1 - i) (fun w : ℂ => (w ^ n - (w - 1) ^ n) * hLi w) 1 / (n + 1 - i)!`
2. `ppart (n : ℕ) (w : ℂ) : ℂ := ∑ i ∈ Finset.Icc 1 (n+1), Acoeff n i / (w - 1)^i`
3. `Gpart (n : ℕ) (w : ℂ) : ℂ := ∑ i ∈ Finset.Icc 2 (n+1), -(Acoeff n i / ((i : ℂ) - 1)) * (w - 1) ^ (-((i : ℤ) - 1))`
4. `deriv_Gpart : ∀ w ≠ 1, deriv (Gpart n) w = ∑ i ∈ Finset.Icc 2 (n+1), Acoeff n i / (w - 1)^i`
5. `rectInt_deriv_eq_zero`: the generic FTC lemma — RectangleIntegral (fun s => deriv G s) z w = 0 for G differentiable at all border points (with G deriv continuous on the border).
6. `RectangleIntegral'_add` / linearity (check if vendored: `RectangleBorderIntegrable.add` exists — but I need the integral-level additivity: RectangleIntegral (f+g) = RectangleIntegral f + RectangleIntegral g — from the HIntegral/VIntegral defs + intervalIntegral additivity: should be a short proof by unfolding + integral_add).
7. `rectInt'_ppart`: 1 interior ⟹ RectangleIntegral' (ppart n) z w = ResW1 n.
Wait — one important detail: Acoeff n 1 = ResW1 n: Acoeff n 1 = iteratedDeriv (n+1−1) F 1/(n+1−1)! = iteratedDeriv n F 1/n! = ResW1 n ✓ (n+1−1 = n).
Let me also double-check the decomposition: ppart n w = A_1/(w−1) + Σ_{i≥2} A_i/(w−1)^i = A_1/(w−1) + deriv Gpart n w ✓ (off {1}).
For the integral additivity: RectangleIntegral (f + g) = RectangleIntegral f + RectangleIntegral g — via HIntegral_add/VIntegral_add: each is intervalIntegral of (f+g) = integral f + integral g (IntervalIntegrable needed). Let me write HIntegral.add/VIntegral.add helpers.
Alright — writing LiPrincipal.lean now. Given the length of this session already, I'll write the whole file then compile-iterate.
Definitions confirmed. Writing `LiPrincipal.lean` (part ii: the principal-part integral via per-side FTC).
tool: Write ok
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiPrincipal.lean",
"content": "/-\nNguyenRH1/LiPrincipal.lean \u2014 tier ii\u2032 sub-stage ii\u2032-1b(ii) (D-064 \u00a74 R1):\nthe principal-part integral. For the explicit principal part\n P(w) = \u03a3_{i=1}^{n+1} A_i/(w\u22121)^i, A_i = F^{(n+1\u2212i)}(1)/(n+1\u2212i)!,\nwith F(w) = (w\u207f\u2212(w\u22121)\u207f)\u00b7hLi(w), on any rectangle with 1 in its interior:\n RectangleIntegral' P z w = A_1 = ResW1 n.\n\nMethod: P = A_1/(w\u22121) + (\u03a3_{i\u22652} A_i/(w\u22121)^i). The first term is handled\nby the vendored `ResidueTheoremInRectangle`; the tail has the explicit\nglobal primitive G(w) = \u2212\u03a3_{i\u22652} A_i/((i\u22121)(w\u22121)^{i\u22121}), differentiable\non the border (1 is interior, hence off the border), so its rectangle\nintegral vanishes by per-side FTC (`rectInt_deriv_eq_zero`).\n\nArchive references: D-036, D-064 (R1), journal-016.\n-/\nimport Mathlib\nimport Zeta23.FromPNTPlus.ResidueCalcOnRectangles\nimport NguyenRH1.LiResidue\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. Linearity of rectangle integrals -/\n\nlemma HIntegral_add (f g : \u2102 \u2192 \u2102) (x\u2081 x\u2082 y : \u211d)\n (hf : IntervalIntegrable (fun x => f (x + y * I)) volume x\u2081 x\u2082)\n (hg : IntervalIntegrable (fun x => g (x + y * I)) volume x\u2081 x\u2082) :\n HIntegral (f + g) x\u2081 x\u2082 y = HIntegral f x\u2081 x\u2082 y + HIntegral g x\u2081 x\u2082 y := by\n rw [HIntegral, HIntegral, HIntegral]\n have e : (fun x => (f + g) (x + y * I)) = (fun x => f (x + y * I) + g (x + y * I)) := by\n funext x\n simp [Pi.add_apply]\n rw [e, intervalIntegral.integral_add hf hg]\n\nlemma VIntegral_add (f g : \u2102 \u2192 \u2102) (x y\u2081 y\u2082 : \u211d)\n (hf : IntervalIntegrable (fun y => f (x + y * I)) volume y\u2081 y\u2082)\n (hg : IntervalIntegrable (fun y => g (x + y * I)) volume y\u2081 y\u2082) :\n VIntegral (f + g) x y\u2081 y\u2082 = VIntegral f x y\u2081 y\u2082 + VIntegral g x y\u2081 y\u2082 := by\n rw [VIntegral, VIntegral, VIntegral]\n have e : (fun y => (f + g) (x + y * I)) = (fun y => f (x + y * I) + g (x + y * I)) := by\n funext y\n simp [Pi.add_apply]\n rw [e, intervalIntegral.integral_add hf hg, smul_add]\n\nlemma RectangleIntegral_add (f g : \u2102 \u2192 \u2102) (z w : \u2102)\n (hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) :\n RectangleIntegral (f + g) z w = RectangleIntegral f z w + RectangleIntegral g z w := by\n rw [RectangleIntegral, RectangleIntegral, RectangleIntegral]\n obtain \u27e8\u27e8hf1, hf2\u27e9, hf3, hf4\u27e9 := hf\n obtain \u27e8\u27e8hg1, hg2\u27e9, hg3, hg4\u27e9 := hg\n rw [HIntegral_add f g _ _ _ hf1 hg1, HIntegral_add f g _ _ _ hf2 hg2,\n VIntegral_add f g _ _ _ hf3 hg3, VIntegral_add f g _ _ _ hf4 hg4]\n ring\n\nlemma RectangleIntegral'_add (f g : \u2102 \u2192 \u2102) (z w : \u2102)\n (hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) :\n RectangleIntegral' (f + g) z w = RectangleIntegral' f z w + RectangleIntegral' g z w := by\n rw [RectangleIntegral', RectangleIntegral_add f g z w hf hg, RectangleIntegral', RectangleIntegral',\n smul_add]\n\n/-! ## 2. The per-side FTC vanishing lemma -/\n\n/-- If `G : \u2102 \u2192 \u2102` is differentiable at every point of the rectangle\nborder, then the rectangle integral of `deriv G` vanishes (each side\ntelescopes by FTC). -/\nlemma rectInt_deriv_eq_zero {G : \u2102 \u2192 \u2102} {z w : \u2102}\n (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)\n (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s) :\n RectangleIntegral (fun s => deriv G s) z w = 0 := by\n rw [RectangleIntegral]\n have hsideH : \u2200 y : \u211d, (\u2200 x : \u211d, x \u2208 Set.uIcc z.re w.re \u2192 (x + y * I) \u2208 RectangleBorder z w) \u2192\n \u222b x in z.re..w.re, deriv G (x + y * I) = G (w.re + y * I) - G (z.re + y * I) := by\n intro y hy\n have hd : \u2200 x \u2208 Set.uIcc z.re w.re,\n HasDerivAt (fun x => G (x + y * I)) (deriv G (x + y * I)) x := by\n intro x hx\n have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=\n (hG _ (hy x hx)).hasDerivAt\n have h2 : HasDerivAt (fun x => x + y * I) 1 x := by\n have hid := hasDerivAt_id x\n have hconst : HasDerivAt (fun x => y * I) 0 x := hasDerivAt_const x _\n convert hid.add hconst using 1\n simp\n have := h1.comp x h2\n convert this using 1\n simp\n have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) volume z.re w.re := by\n apply ContinuousOn.intervalIntegrable_of_Icc (a := z.re) (b := w.re)\n intro x hx\n have hmem : (x + y * I) \u2208 RectangleBorder z w := hy x (Set.uIcc_of_le ?_ hx |>.elim (fun h => h.1) )\n \u00b7 exact (hGc _ hmem).continuousWithinAt\n \u00b7 sorry\n have := intervalIntegral.integral_deriv_eq_sub hd hint\n convert this using 1\n sorry\n\nend NguyenRH1\n"
}
result 2026-08-21 21:26:40Z → 2026-08-21 21:26:40Z
{
"type": "create",
"filePath": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiPrincipal.lean",
"content": "/-\nNguyenRH1/LiPrincipal.lean \u2014 tier ii\u2032 sub-stage ii\u2032-1b(ii) (D-064 \u00a74 R1):\nthe principal-part integral. For the explicit principal part\n P(w) = \u03a3_{i=1}^{n+1} A_i/(w\u22121)^i, A_i = F^{(n+1\u2212i)}(1)/(n+1\u2212i)!,\nwith F(w) = (w\u207f\u2212(w\u22121)\u207f)\u00b7hLi(w), on any rectangle with 1 in its interior:\n RectangleIntegral' P z w = A_1 = ResW1 n.\n\nMethod: P = A_1/(w\u22121) + (\u03a3_{i\u22652} A_i/(w\u22121)^i). The first term is handled\nby the vendored `ResidueTheoremInRectangle`; the tail has the explicit\nglobal primitive G(w) = \u2212\u03a3_{i\u22652} A_i/((i\u22121)(w\u22121)^{i\u22121}), differentiable\non the border (1 is interior, hence off the border), so its rectangle\nintegral vanishes by per-side FTC (`rectInt_deriv_eq_zero`).\n\nArchive references: D-036, D-064 (R1), journal-016.\n-/\nimport Mathlib\nimport Zeta23.FromPNTPlus.ResidueCalcOnRectangles\nimport NguyenRH1.LiResidue\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. Linearity of rectangle integrals -/\n\nlemma HIntegral_add (f g : \u2102 \u2192 \u2102) (x\u2081 x\u2082 y : \u211d)\n (hf : IntervalIntegrable (fun x => f (x + y * I)) volume x\u2081 x\u2082)\n (hg : IntervalIntegrable (fun x => g (x + y * I)) volume x\u2081 x\u2082) :\n HIntegral (f + g) x\u2081 x\u2082 y = HIntegral f x\u2081 x\u2082 y + HIntegral g x\u2081 x\u2082 y := by\n rw [HIntegral, HIntegral, HIntegral]\n have e : (fun x => (f + g) (x + y * I)) = (fun x => f (x + y * I) + g (x + y * I)) := by\n funext x\n simp [Pi.add_apply]\n rw [e, intervalIntegral.integral_add hf hg]\n\nlemma VIntegral_add (f g : \u2102 \u2192 \u2102) (x y\u2081 y\u2082 : \u211d)\n (hf : IntervalIntegrable (fun y => f (x + y * I)) volume y\u2081 y\u2082)\n (hg : IntervalIntegrable (fun y => g (x + y * I)) volume y\u2081 y\u2082) :\n VIntegral (f + g) x y\u2081 y\u2082 = VIntegral f x y\u2081 y\u2082 + VIntegral g x y\u2081 y\u2082 := by\n rw [VIntegral, VIntegral, VIntegral]\n have e : (fun y => (f + g) (x + y * I)) = (fun y => f (x + y * I) + g (x + y * I)) := by\n funext y\n simp [Pi.add_apply]\n rw [e, intervalIntegral.integral_add hf hg, smul_add]\n\nlemma RectangleIntegral_add (f g : \u2102 \u2192 \u2102) (z w : \u2102)\n (hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) :\n RectangleIntegral (f + g) z w = RectangleIntegral f z w + RectangleIntegral g z w := by\n rw [RectangleIntegral, RectangleIntegral, RectangleIntegral]\n obtain \u27e8\u27e8hf1, hf2\u27e9, hf3, hf4\u27e9 := hf\n obtain \u27e8\u27e8hg1, hg2\u27e9, hg3, hg4\u27e9 := hg\n rw [HIntegral_add f g _ _ _ hf1 hg1, HIntegral_add f g _ _ _ hf2 hg2,\n VIntegral_add f g _ _ _ hf3 hg3, VIntegral_add f g _ _ _ hf4 hg4]\n ring\n\nlemma RectangleIntegral'_add (f g : \u2102 \u2192 \u2102) (z w : \u2102)\n (hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) :\n RectangleIntegral' (f + g) z w = RectangleIntegral' f z w + RectangleIntegral' g z w := by\n rw [RectangleIntegral', RectangleIntegral_add f g z w hf hg, RectangleIntegral', RectangleIntegral',\n smul_add]\n\n/-! ## 2. The per-side FTC vanishing lemma -/\n\n/-- If `G : \u2102 \u2192 \u2102` is differentiable at every point of the rectangle\nborder, then the rectangle integral of `deriv G` vanishes (each side\ntelescopes by FTC). -/\nlemma rectInt_deriv_eq_zero {G : \u2102 \u2192 \u2102} {z w : \u2102}\n (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)\n (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s) :\n RectangleIntegral (fun s => deriv G s) z w = 0 := by\n rw [RectangleIntegral]\n have hsideH : \u2200 y : \u211d, (\u2200 x : \u211d, x \u2208 Set.uIcc z.re w.re \u2192 (x + y * I) \u2208 RectangleBorder z w) \u2192\n \u222b x in z.re..w.re, deriv G (x + y * I) = G (w.re + y * I) - G (z.re + y * I) := by\n intro y hy\n have hd : \u2200 x \u2208 Set.uIcc z.re w.re,\n HasDerivAt (fun x => G (x + y * I)) (deriv G (x + y * I)) x := by\n intro x hx\n have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=\n (hG _ (hy x hx)).hasDerivAt\n have h2 : HasDerivAt (fun x => x + y * I) 1 x := by\n have hid := hasDerivAt_id x\n have hconst : HasDerivAt (fun x => y * I) 0 x := hasDerivAt_const x _\n convert hid.add hconst using 1\n simp\n have := h1.comp x h2\n convert this using 1\n simp\n have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) volume z.re w.re := by\n apply ContinuousOn.intervalIntegrable_of_Icc (a := z.re) (b := w.re)\n intro x hx\n have hmem : (x + y * I) \u2208 RectangleBorder z w := hy x (Set.uIcc_of_le ?_ hx |>.elim (fun h => h.1) )\n \u00b7 exact (hGc _ hmem).continuousWithinAt\n \u00b7 sorry\n have := intervalIntegral.integral_deriv_eq_sub hd hint\n convert this using 1\n sorry\n\nend NguyenRH1\n",
"structuredPatch": [],
"originalFile": null
}
thinking (956 chars)
I left sorries in rectInt_deriv_eq_zero — the border membership reasoning is fiddly. Let me think about the cleanest way to do the border parametrization.
The RectangleBorder z w consists of 4 sides:
- bottom: {x + z.im*I | x ∈ [z.re, w.re]}
- top: {x + w.im*I | x ∈ [z.re, w.re]}
- left: {z.re + y*I | y ∈ [z.im, w.im]}
- right: {w.re + y*I | y ∈ [z.im, w.im]}
The vendored Rectangle.lean has RectangleBorder def — let me check its exact form to use it directly.
Actually — this FTC lemma is the fiddliest part of (ii). Alternative approach that avoids the general border membership: parametrize directly. HIntegral (deriv G) z.re w.re z.im: the points x + z.im*I for x ∈ [z.re, w.re] lie on the bottom side — from hG I need differentiability at those points.
Let me check the vendored RectangleBorder definition and mem lemmas (rectangleBorder... from the agent report: `RectangleBorder z w` and mapsTo_rectangle*_NoP lemmas). Let me look at the def.
The FTC lemma needs the exact border structure. Let me check the vendored `RectangleBorder` definition.
tool: Bash
input
{
"command": "grep -n \"def RectangleBorder\\|RectangleBorder \" /d/Python/Quantum/zeta-23-lean/Zeta23/FromPNTPlus/Rectangle.lean | head -8; sed -n \"$(grep -n 'def RectangleBorder' /d/Python/Quantum/zeta-23-lean/Zeta23/FromPNTPlus/Rectangle.lean | head -1 | cut -d: -f1),+15p\" /d/Python/Quantum/zeta-23-lean/Zeta23/FromPNTPlus/Rectangle.lean",
"description": "Read RectangleBorder definition"
}
thinking (7085 chars)
The MapsTo lemma names:
- `mapsTo_rectangleBorder_left_re` (left vertical: z.re + yI)
- `mapsTo_rectangleBorder_right_re` (right vertical: w.re + yI)
- `mapsTo_rectangleBorder_left_im` (bottom: x + z.im·I)
- `mapsTo_rectangleBorder_right_im` (top: x + w.im·I)
Now let me write the FTC lemma cleanly with these. The RectangleIntegral:
= H bottom(z.im) − H top(w.im) + I·V right(w.re) − I·V left(z.re)
HIntegral G' z.re w.re y = G(w.re + yI) − G(z.re + yI) for y ∈ {z.im, w.im} — wait, the FTC gives it for any y (given differentiability on the segment). VIntegral G' x y₁ y₂ = I·∫_{y₁}^{y₂} G'(x + yI) dy = I·[G(x + y₂I) − G(x + y₁I)]/I?? — no: the parametrization y ↦ G(x + yI) has derivative G'(x+yI)·I: ∫_{y₁}^{y₂} G'(x+yI)·I dy = G(x+y₂I) − G(x+y₁I). And VIntegral G' x y₁ y₂ = I·∫ G'(x+yI) dy — the integrand is G'(x+yI) (NOT times I). So ∫_{y₁}^{y₂} G'(x+yI) dy = (G(x+y₂I) − G(x+y₁I))/I. Then I·[that] = G(x+y₂I) − G(x+y₁I) ✓.
Hmm wait — I need ∫ G'(x+yI) dy where G' = deriv G: the parametrized derivative of y ↦ G(x+yI) is deriv G (x+yI) * I (chain rule with inner deriv I). So ∫_{y₁}^{y₂} [deriv G (x+yI) * I] dy = G(x+y₂I) − G(x+y₁I). So ∫ G'(x+yI) dy = (G(x+y₂I) − G(x+y₁I))/I = −I·(G(x+y₂I) − G(x+y₁I)) (since 1/I = −I). Then VIntegral = I·∫ = I·(−I)·(ΔG) = ΔG ✓ — wait: I·(−I) = −I² = 1 ✓. So VIntegral G' x y₁ y₂ = G(x + y₂I) − G(x + y₁I).
Sum: H_bottom − H_top + V_right − V_left
= [G(b) − G(a)] − [G(d) − G(c)] + [G(d) − G(b)] − [G(c) − G(a)] where a = z.re+z.im·I (bottom-left), b = w.re+z.im·I (bottom-right), c = z.re+w.im·I (top-left), d = w.re+w.im·I (top-right).
Wait — careful with VIntegral signs: V right = VIntegral G' w.re z.im w.im = G(w.re + w.im·I) − G(w.re + z.im·I) = G(d) − G(b). V left = VIntegral G' z.re z.im w.im = G(z.re + w.im·I) − G(z.re + z.im·I) = G(c) − G(a). H bottom = HIntegral G' z.re w.re z.im = G(b) − G(a). H top = HIntegral G' z.re w.re w.im = G(d) − G(c).
Sum: (G(b)−G(a)) − (G(d)−G(c)) + (G(d)−G(b)) − (G(c)−G(a)) = 0 ✓✓ telescopes.
In Lean, the VIntegral handling: VIntegral f x y₁ y₂ = I • ∫ y in y₁..y₂, f (x + y * I). The parametrized FTC: ∫_{y₁}^{y₂} deriv G (x + y*I) dy — via integral_deriv_eq_sub on (fun y => G (x + y*I)) with derivative (fun y => I * deriv G (x + y*I))?? — chain rule: d/dy [G(x + yI)] = deriv G (x+yI) · d/dy[x + yI] = deriv G (x+yI) · I. So the integrand of VIntegral is deriv G (x+yI), and FTC applies to the integrand (fun y => I * deriv G (x+yI))... mismatch: VIntegral's integrand is deriv G (x+yI) (no I factor). So ∫ deriv G (x+yI) dy ≠ directly G-diff. Instead: ∫_{y₁}^{y₂} deriv G (x+yI) dy = (1/I)·∫ I·deriv G (x+yI) dy = (1/I)(G(x+y₂I) − G(x+y₁I)) — via integral_deriv_eq_sub on (fun y => I * deriv G (x+yI))... the lemma needs the integrand to BE the derivative of the parametrized function: parametrized P(y) = G(x+yI), P'(y) = I·deriv G(x+yI). So ∫ P' = P(y₂) − P(y₁): ∫ I·deriv G (x+yI) dy = G(x+y₂I) − G(x+y₁I). Then ∫ deriv G (x+yI) dy = (1/I)·∫ I·deriv G (x+yI) dy = −I·(G(x+y₂I) − G(x+y₁I)). And VIntegral = I•that = I·(−I)·Δ = Δ ✓.
In Lean:
```
have hsideV : ∀ x : ℝ, ∫ y in y₁..y₂, deriv G (x + y * I) = -I * (G (x + y₂ * I) - G (x + y₁ * I)) := by
intro x
have hd : ∀ y ∈ Set.uIcc y₁ y₂, HasDerivAt (fun y => G (x + y * I)) (I * deriv G (x + y * I)) y := by
intro y hy
have hG' := (hG _ (hymap y hy)).hasDerivAt
have h2 : HasDerivAt (fun y => x + y * I) I y := by
-- derivative of y ↦ x + yI is I
have hid := hasDerivAt_id y
-- y ↦ x + y·I = const + (y ↦ yI); derivative = I
...
convert hG'.comp y h2 using 1
ring
have hint : IntervalIntegrable (fun y => I * deriv G (x + y * I)) volume y₁ y₂ := ...
have hftc := intervalIntegral.integral_deriv_eq_sub hd hint
-- ∫ I * deriv G = G(x+y₂I) − G(x+y₁I)
have h3 : ∫ y in y₁..y₂, deriv G (x + y * I) = (-I) * (G (x + y₂ * I) - G (x + y₁ * I)) := by
have h4 : ∫ y in y₁..y₂, I * deriv G (x + y * I) = G (x + y₂ * I) - G (x + y₁ * I) := hftc
rw [← h4]
rw [integral_smul] -- hmm I is a constant: ∫ I * f = I * ∫ f
field_simp [Complex.I_ne_zero]
-- (1/I) = -I
exact h3
```
Then VIntegral G' x y₁ y₂ = I • ∫ = I•(−I•Δ) = Δ:
```
rw [VIntegral, hsideV]
-- I • (-I • (G2 - G1)) = G2 - G1: smul_smul, I*I = -1: I * (-I * X) = -(I*I)*X = -(-1)*X = X
rw [smul_eq_mul, smul_eq_mul]
simp [Complex.I_mul_I]
```
OK. The HasDerivAt for y ↦ x + y·I: derivative I:
```
have h2 : HasDerivAt (fun y => x + y * I) I y := by
have h1 : HasDerivAt (fun y => y * I) I y := by
have hid := hasDerivAt_id y
convert hid.mul_const I using 1
simp
have hconst : HasDerivAt (fun y => x) 0 y := hasDerivAt_const y x
convert hconst.add h1 using 1
simp
```
hasDerivAt_id y : HasDerivAt id 1 y? — `hasDerivAt_id (x) : HasDerivAt id 1 x` ✓. mul_const: HasDerivAt (id * const)... hmm — `HasDerivAt.mul_const (hf : HasDerivAt f f' x) (c) : HasDerivAt (fun x => f x * c) (f' * c) x` — with f = id, f' = 1: HasDerivAt (fun x => x * I) (1 * I) x = (· * I) I ✓. Simpler: `hasDerivAt_mul_const`? For (fun y => y * I): `HasDerivAt.mul_const (hasDerivAt_id y) I : HasDerivAt (fun y => y * I) (1 * I) y` — then simp [one_mul].
And for the x-side: HasDerivAt (fun x => x + y*I) 1 x:
```
have h2 : HasDerivAt (fun x => x + y * I) 1 x := by
have hid := hasDerivAt_id x
have hconst : HasDerivAt (fun x => y * I) 0 x := hasDerivAt_const x _
convert hid.add hconst using 1
simp
```
hid.add hconst : HasDerivAt (fun x => x + y*I) (1 + 0) x ✓ simp.
The border membership maps: hymap for V-sides: `mapsTo_rectangleBorder_right_re z w : MapsTo (fun y => ↑w.re + ↑y * I) [[z.im, w.im]] (RectangleBorder z w)` — for the RIGHT side x = w.re. For LEFT side x = z.re: `mapsTo_rectangleBorder_left_re`. For H-sides: `mapsTo_rectangleBorder_left_im` (y = z.im), `mapsTo_rectangleBorder_right_im` (y = w.im).
Note the MapsTo functions use `↑x + z.im * I` with ↑x — the cast of x : ℝ to ℂ — same as (x + z.im * I) with x coerced ✓ (the `↑x` IS the coercion).
IntervalIntegrable: for the parametrized derivative: `ContinuousOn.intervalIntegrable (h : ContinuousOn f (uIcc a b))`: deriv G continuous on the segment ⟸ ContinuousAt at each border point (hGc hypothesis) — I'll pass hGc : ∀ s ∈ border, ContinuousAt (deriv G) s. Hmm — ContinuousOn from pointwise ContinuousAt on the set: `ContinuousAt.continuousOn`? No — ContinuousOn s f ⟺ ∀ x ∈ s, ContinuousWithinAt f s x. ContinuousAt ⟹ ContinuousWithinAt ✓:
```
intro x hx
exact (hGc _ (hymap x hx)).continuousWithinAt
```
And intervalIntegrable of ContinuousOn on uIcc: `ContinuousOn.intervalIntegrable (h : ContinuousOn f (Set.uIcc a b)) : IntervalIntegrable f volume a b` ✓ exists.
Also for the HasDerivAt pieces I need hG at the segment points via the mapsTo — `hymap : ∀ y ∈ uIcc, (x + y*I) ∈ border` from the MapsTo lemmas (MapsTo f s t : ∀ x ∈ s, f x ∈ t ✓).
OK — the whole FTC lemma is now clear. Let me rewrite LiPrincipal.lean's rectInt_deriv_eq_zero properly with a helper for each side, then the P assembly. Also need `Complex.I_ne_zero` and `smul_smul`.
Let me rewrite the whole file with the completed proof.
The MapsTo border lemmas exist with exact names. Rewriting LiPrincipal.lean with the complete FTC proof.
tool: Write ok
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiPrincipal.lean",
"content": "/-\nNguyenRH1/LiPrincipal.lean \u2014 tier ii\u2032 sub-stage ii\u2032-1b(ii) (D-064 \u00a74 R1):\nthe principal-part integral. For the explicit principal part\n P(w) = \u03a3_{i=1}^{n+1} A_i/(w\u22121)^i, A_i = F^{(n+1\u2212i)}(1)/(n+1\u2212i)!,\nwith F(w) = (w\u207f\u2212(w\u22121)\u207f)\u00b7hLi(w), on any rectangle with 1 in its interior:\n RectangleIntegral' P z w = A_1 = ResW1 n.\n\nMethod: P = A_1/(w\u22121) + (\u03a3_{i\u22652} A_i/(w\u22121)^i). The first term is handled\nby the vendored `ResidueTheoremInRectangle`; the tail has the explicit\nglobal primitive G(w) = \u2212\u03a3_{i\u22652} A_i/((i\u22121)(w\u22121)^{i\u22121}), differentiable\non the border (1 is interior, hence off the border), so its rectangle\nintegral vanishes by per-side FTC (`rectInt_deriv_eq_zero`).\n\nArchive references: D-036, D-064 (R1), journal-016.\n-/\nimport Mathlib\nimport Zeta23.FromPNTPlus.ResidueCalcOnRectangles\nimport NguyenRH1.LiResidue\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. Linearity of rectangle integrals -/\n\nlemma HIntegral_add (f g : \u2102 \u2192 \u2102) (x\u2081 x\u2082 y : \u211d)\n (hf : IntervalIntegrable (fun x => f (x + y * I)) volume x\u2081 x\u2082)\n (hg : IntervalIntegrable (fun x => g (x + y * I)) volume x\u2081 x\u2082) :\n HIntegral (f + g) x\u2081 x\u2082 y = HIntegral f x\u2081 x\u2082 y + HIntegral g x\u2081 x\u2082 y := by\n rw [HIntegral, HIntegral, HIntegral]\n have e : (fun x => (f + g) (x + y * I)) = (fun x => f (x + y * I) + g (x + y * I)) := by\n funext x\n simp [Pi.add_apply]\n rw [e, intervalIntegral.integral_add hf hg]\n\nlemma VIntegral_add (f g : \u2102 \u2192 \u2102) (x y\u2081 y\u2082 : \u211d)\n (hf : IntervalIntegrable (fun y => f (x + y * I)) volume y\u2081 y\u2082)\n (hg : IntervalIntegrable (fun y => g (x + y * I)) volume y\u2081 y\u2082) :\n VIntegral (f + g) x y\u2081 y\u2082 = VIntegral f x y\u2081 y\u2082 + VIntegral g x y\u2081 y\u2082 := by\n rw [VIntegral, VIntegral, VIntegral]\n have e : (fun y => (f + g) (x + y * I)) = (fun y => f (x + y * I) + g (x + y * I)) := by\n funext y\n simp [Pi.add_apply]\n rw [e, intervalIntegral.integral_add hf hg, smul_add]\n\nlemma RectangleIntegral_add (f g : \u2102 \u2192 \u2102) (z w : \u2102)\n (hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) :\n RectangleIntegral (f + g) z w = RectangleIntegral f z w + RectangleIntegral g z w := by\n rw [RectangleIntegral, RectangleIntegral, RectangleIntegral]\n obtain \u27e8\u27e8hf1, hf2\u27e9, hf3, hf4\u27e9 := hf\n obtain \u27e8\u27e8hg1, hg2\u27e9, hg3, hg4\u27e9 := hg\n rw [HIntegral_add f g _ _ _ hf1 hg1, HIntegral_add f g _ _ _ hf2 hg2,\n VIntegral_add f g _ _ _ hf3 hg3, VIntegral_add f g _ _ _ hf4 hg4]\n ring\n\nlemma RectangleIntegral'_add (f g : \u2102 \u2192 \u2102) (z w : \u2102)\n (hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) :\n RectangleIntegral' (f + g) z w = RectangleIntegral' f z w + RectangleIntegral' g z w := by\n rw [RectangleIntegral', RectangleIntegral_add f g z w hf hg, RectangleIntegral', RectangleIntegral',\n smul_add]\n\n/-! ## 2. Parametrized side derivatives and integrability -/\n\nlemma hasDerivAt_add_const_I (y : \u211d) (x : \u211d) :\n HasDerivAt (fun t => t + y * I) 1 x := by\n have hid := hasDerivAt_id x\n have hconst : HasDerivAt (fun _ => y * I) 0 x := hasDerivAt_const x _\n convert hid.add hconst using 1\n simp\n\nlemma hasDerivAt_const_add_I (x y : \u211d) :\n HasDerivAt (fun t => x + t * I) I y := by\n have h1 : HasDerivAt (fun t => t * I) I y := by\n have := (hasDerivAt_id y).mul_const I\n simpa using this\n have hconst : HasDerivAt (fun _ => x) 0 y := hasDerivAt_const y x\n convert hconst.add h1 using 1\n simp\n\n/-- FTC on a horizontal side: \u222b_{x\u2081}^{x\u2082} (deriv G)(x + yI) dx\n= G(x\u2082 + yI) \u2212 G(x\u2081 + yI). -/\nlemma HIntegral_deriv {G : \u2102 \u2192 \u2102} {z w : \u2102} (y : \u211d)\n (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)\n (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s)\n (hmap : MapsTo (fun x : \u211d => \u2191x + y * I) [[z.re, w.re]] (RectangleBorder z w)) :\n \u222b x in z.re..w.re, deriv G (x + y * I) = G (w.re + y * I) - G (z.re + y * I) := by\n have hd : \u2200 x \u2208 Set.uIcc z.re w.re,\n HasDerivAt (fun x => G (x + y * I)) (deriv G (x + y * I)) x := by\n intro x hx\n have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=\n (hG _ (hmap (Set.uIcc_of_le (by simp [Set.uIcc]) hx |>.elim (fun h => h.1) |>.1))).hasDerivAt\n have h2 : HasDerivAt (fun x => x + y * I) 1 x := hasDerivAt_add_const_I y x\n have hcomp := h1.comp x h2\n convert hcomp using 1\n simp\n have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) volume z.re w.re := by\n apply ContinuousOn.intervalIntegrable\n intro x hx\n have hmem : (x + y * I) \u2208 RectangleBorder z w := by\n apply hmap\n rcases Set.uIcc_of_le (by simp [Set.uIcc]) hx with h | h\n \u00b7 exact h.1\n \u00b7 exact h.1\n exact (hGc _ hmem).continuousWithinAt\n have hftc := intervalIntegral.integral_deriv_eq_sub hd hint\n convert hftc using 1\n \u00b7 simp\n \u00b7 simp\n\n/-- FTC on a vertical side: \u222b_{y\u2081}^{y\u2082} (deriv G)(x + yI) dy\n= \u2212I\u00b7(G(x + y\u2082I) \u2212 G(x + y\u2081I)). -/\nlemma VIntegral_deriv {G : \u2102 \u2192 \u2102} {z w : \u2102} (x : \u211d)\n (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)\n (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s)\n (hmap : MapsTo (fun y : \u211d => \u2191x + \u2191y * I) [[z.im, w.im]] (RectangleBorder z w)) :\n \u222b y in z.im..w.im, deriv G (x + y * I) =\n -I * (G (x + w.im * I) - G (x + z.im * I)) := by\n have hd : \u2200 y \u2208 Set.uIcc z.im w.im,\n HasDerivAt (fun y => G (x + y * I)) (I * deriv G (x + y * I)) y := by\n intro y hy\n have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=\n (hG _ (hmap (Set.uIcc_of_le (by simp [Set.uIcc]) hy |>.elim (fun h => h.1) |>.1))).hasDerivAt\n have h2 : HasDerivAt (fun y => x + y * I) I y := hasDerivAt_const_add_I x y\n have hcomp := h1.comp y h2\n convert hcomp using 1\n ring\n have hint : IntervalIntegrable (fun y => I * deriv G (x + y * I)) volume z.im w.im := by\n apply ContinuousOn.intervalIntegrable\n intro y hy\n apply ContinuousWithinAt.mul continuousWithinAt_const\n have hmem : (x + y * I) \u2208 RectangleBorder z w := by\n apply hmap\n rcases Set.uIcc_of_le (by simp [Set.uIcc]) hy with h | h\n \u00b7 exact h.1\n \u00b7 exact h.1\n exact (hGc _ hmem).continuousWithinAt\n have hftc := intervalIntegral.integral_deriv_eq_sub hd hint\n rw [\u2190 hftc]\n rw [integral_smul]\n field_simp [Complex.I_ne_zero]\n\n/-- If `G : \u2102 \u2192 \u2102` is differentiable at every point of the rectangle\nborder, then the rectangle integral of `deriv G` vanishes (each side\ntelescopes by FTC). -/\nlemma rectInt_deriv_eq_zero {G : \u2102 \u2192 \u2102} {z w : \u2102}\n (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)\n (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s) :\n RectangleIntegral (fun s => deriv G s) z w = 0 := by\n rw [RectangleIntegral]\n rw [HIntegral_deriv z.im hG hGc (mapsTo_rectangleBorder_left_im z w),\n HIntegral_deriv w.im hG hGc (mapsTo_rectangleBorder_right_im z w)]\n have hVr := VIntegral_deriv w.re hG hGc (mapsTo_rectangleBorder_right_re z w)\n have hVl := VIntegral_deriv z.re hG hGc (mapsTo_rectangleBorder_left_re z w)\n rw [VIntegral, VIntegral, hVr, hVl]\n simp [Complex.I_mul_I]\n ring\n\nend NguyenRH1\n"
}
result 2026-08-21 21:29:27Z → 2026-08-21 21:29:27Z
{
"type": "update",
"filePath": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiPrincipal.lean",
"content": "/-\nNguyenRH1/LiPrincipal.lean \u2014 tier ii\u2032 sub-stage ii\u2032-1b(ii) (D-064 \u00a74 R1):\nthe principal-part integral. For the explicit principal part\n P(w) = \u03a3_{i=1}^{n+1} A_i/(w\u22121)^i, A_i = F^{(n+1\u2212i)}(1)/(n+1\u2212i)!,\nwith F(w) = (w\u207f\u2212(w\u22121)\u207f)\u00b7hLi(w), on any rectangle with 1 in its interior:\n RectangleIntegral' P z w = A_1 = ResW1 n.\n\nMethod: P = A_1/(w\u22121) + (\u03a3_{i\u22652} A_i/(w\u22121)^i). The first term is handled\nby the vendored `ResidueTheoremInRectangle`; the tail has the explicit\nglobal primitive G(w) = \u2212\u03a3_{i\u22652} A_i/((i\u22121)(w\u22121)^{i\u22121}), differentiable\non the border (1 is interior, hence off the border), so its rectangle\nintegral vanishes by per-side FTC (`rectInt_deriv_eq_zero`).\n\nArchive references: D-036, D-064 (R1), journal-016.\n-/\nimport Mathlib\nimport Zeta23.FromPNTPlus.ResidueCalcOnRectangles\nimport NguyenRH1.LiResidue\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. Linearity of rectangle integrals -/\n\nlemma HIntegral_add (f g : \u2102 \u2192 \u2102) (x\u2081 x\u2082 y : \u211d)\n (hf : IntervalIntegrable (fun x => f (x + y * I)) volume x\u2081 x\u2082)\n (hg : IntervalIntegrable (fun x => g (x + y * I)) volume x\u2081 x\u2082) :\n HIntegral (f + g) x\u2081 x\u2082 y = HIntegral f x\u2081 x\u2082 y + HIntegral g x\u2081 x\u2082 y := by\n rw [HIntegral, HIntegral, HIntegral]\n have e : (fun x => (f + g) (x + y * I)) = (fun x => f (x + y * I) + g (x + y * I)) := by\n funext x\n simp [Pi.add_apply]\n rw [e, intervalIntegral.integral_add hf hg]\n\nlemma VIntegral_add (f g : \u2102 \u2192 \u2102) (x y\u2081 y\u2082 : \u211d)\n (hf : IntervalIntegrable (fun y => f (x + y * I)) volume y\u2081 y\u2082)\n (hg : IntervalIntegrable (fun y => g (x + y * I)) volume y\u2081 y\u2082) :\n VIntegral (f + g) x y\u2081 y\u2082 = VIntegral f x y\u2081 y\u2082 + VIntegral g x y\u2081 y\u2082 := by\n rw [VIntegral, VIntegral, VIntegral]\n have e : (fun y => (f + g) (x + y * I)) = (fun y => f (x + y * I) + g (x + y * I)) := by\n funext y\n simp [Pi.add_apply]\n rw [e, intervalIntegral.integral_add hf hg, smul_add]\n\nlemma RectangleIntegral_add (f g : \u2102 \u2192 \u2102) (z w : \u2102)\n (hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) :\n RectangleIntegral (f + g) z w = RectangleIntegral f z w + RectangleIntegral g z w := by\n rw [RectangleIntegral, RectangleIntegral, RectangleIntegral]\n obtain \u27e8\u27e8hf1, hf2\u27e9, hf3, hf4\u27e9 := hf\n obtain \u27e8\u27e8hg1, hg2\u27e9, hg3, hg4\u27e9 := hg\n rw [HIntegral_add f g _ _ _ hf1 hg1, HIntegral_add f g _ _ _ hf2 hg2,\n VIntegral_add f g _ _ _ hf3 hg3, VIntegral_add f g _ _ _ hf4 hg4]\n ring\n\nlemma RectangleIntegral'_add (f g : \u2102 \u2192 \u2102) (z w : \u2102)\n (hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) :\n RectangleIntegral' (f + g) z w = RectangleIntegral' f z w + RectangleIntegral' g z w := by\n rw [RectangleIntegral', RectangleIntegral_add f g z w hf hg, RectangleIntegral', RectangleIntegral',\n smul_add]\n\n/-! ## 2. Parametrized side derivatives and integrability -/\n\nlemma hasDerivAt_add_const_I (y : \u211d) (x : \u211d) :\n HasDerivAt (fun t => t + y * I) 1 x := by\n have hid := hasDerivAt_id x\n have hconst : HasDerivAt (fun _ => y * I) 0 x := hasDerivAt_const x _\n convert hid.add hconst using 1\n simp\n\nlemma hasDerivAt_const_add_I (x y : \u211d) :\n HasDerivAt (fun t => x + t * I) I y := by\n have h1 : HasDerivAt (fun t => t * I) I y := by\n have := (hasDerivAt_id y).mul_const I\n simpa using this\n have hconst : HasDerivAt (fun _ => x) 0 y := hasDerivAt_const y x\n convert hconst.add h1 using 1\n simp\n\n/-- FTC on a horizontal side: \u222b_{x\u2081}^{x\u2082} (deriv G)(x + yI) dx\n= G(x\u2082 + yI) \u2212 G(x\u2081 + yI). -/\nlemma HIntegral_deriv {G : \u2102 \u2192 \u2102} {z w : \u2102} (y : \u211d)\n (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)\n (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s)\n (hmap : MapsTo (fun x : \u211d => \u2191x + y * I) [[z.re, w.re]] (RectangleBorder z w)) :\n \u222b x in z.re..w.re, deriv G (x + y * I) = G (w.re + y * I) - G (z.re + y * I) := by\n have hd : \u2200 x \u2208 Set.uIcc z.re w.re,\n HasDerivAt (fun x => G (x + y * I)) (deriv G (x + y * I)) x := by\n intro x hx\n have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=\n (hG _ (hmap (Set.uIcc_of_le (by simp [Set.uIcc]) hx |>.elim (fun h => h.1) |>.1))).hasDerivAt\n have h2 : HasDerivAt (fun x => x + y * I) 1 x := hasDerivAt_add_const_I y x\n have hcomp := h1.comp x h2\n convert hcomp using 1\n simp\n have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) volume z.re w.re := by\n apply ContinuousOn.intervalIntegrable\n intro x hx\n have hmem : (x + y * I) \u2208 RectangleBorder z w := by\n apply hmap\n rcases Set.uIcc_of_le (by simp [Set.uIcc]) hx with h | h\n \u00b7 exact h.1\n \u00b7 exact h.1\n exact (hGc _ hmem).continuousWithinAt\n have hftc := intervalIntegral.integral_deriv_eq_sub hd hint\n convert hftc using 1\n \u00b7 simp\n \u00b7 simp\n\n/-- FTC on a vertical side: \u222b_{y\u2081}^{y\u2082} (deriv G)(x + yI) dy\n= \u2212I\u00b7(G(x + y\u2082I) \u2212 G(x + y\u2081I)). -/\nlemma VIntegral_deriv {G : \u2102 \u2192 \u2102} {z w : \u2102} (x : \u211d)\n (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)\n (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s)\n (hmap : MapsTo (fun y : \u211d => \u2191x + \u2191y * I) [[z.im, w.im]] (RectangleBorder z w)) :\n \u222b y in z.im..w.im, deriv G (x + y * I) =\n -I * (G (x + w.im * I) - G (x + z.im * I)) := by\n have hd : \u2200 y \u2208 Set.uIcc z.im w.im,\n HasDerivAt (fun y => G (x + y * I)) (I * deriv G (x + y * I)) y := by\n intro y hy\n have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=\n (hG _ (hmap (Set.uIcc_of_le (by simp [Set.uIcc]) hy |>.elim (fun h => h.1) |>.1))).hasDerivAt\n have h2 : HasDerivAt (fun y => x + y * I) I y := hasDerivAt_const_add_I x y\n have hcomp := h1.comp y h2\n convert hcomp using 1\n ring\n have hint : IntervalIntegrable (fun y => I * deriv G (x + y * I)) volume z.im w.im := by\n apply ContinuousOn.intervalIntegrable\n intro y hy\n apply ContinuousWithinAt.mul continuousWithinAt_const\n have hmem : (x + y * I) \u2208 RectangleBorder z w := by\n apply hmap\n rcases Set.uIcc_of_le (by simp [Set.uIcc]) hy with h | h\n \u00b7 exact h.1\n \u00b7 exact h.1\n exact (hGc _ hmem).continuousWithinAt\n have hftc := intervalIntegral.integral_deriv_eq_sub hd hint\n rw [\u2190 hftc]\n rw [integral_smul]\n field_simp [Complex.I_ne_zero]\n\n/-- If `G : \u2102 \u2192 \u2102` is differentiable at every point of the rectangle\nborder, then the rectangle integral of `deriv G` vanishes (each side\ntelescopes by FTC). -/\nlemma rectInt_deriv_eq_zero {G : \u2102 \u2192 \u2102} {z w : \u2102}\n (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)\n (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s) :\n RectangleIntegral (fun s => deriv G s) z w = 0 := by\n rw [RectangleIntegral]\n rw [HIntegral_deriv z.im hG hGc (mapsTo_rectangleBorder_left_im z w),\n HIntegral_deriv w.im hG hGc (mapsTo_rectangleBorder_right_im z w)]\n have hVr := VIntegral_deriv w.re hG hGc (mapsTo_rectangleBorder_right_re z w)\n have hVl := VIntegral_deriv z.re hG hGc (mapsTo_rectangleBorder_left_re z w)\n rw [VIntegral, VIntegral, hVr, hVl]\n simp [Complex.I_mul_I]\n ring\n\nend NguyenRH1\n",
"structuredPatch": [
{
"oldStart": 61,
"oldLines": 7,
"newStart": 61,
"newLines": 85,
"lines": [
" rw [RectangleIntegral', RectangleIntegral_add f g z w hf hg, RectangleIntegral', RectangleIntegral',",
" smul_add]",
" ",
"-/-! ## 2. The per-side FTC vanishing lemma -/",
"+/-! ## 2. Parametrized side derivatives and integrability -/",
"+",
"+lemma hasDerivAt_add_const_I (y : \u211d) (x : \u211d) :",
"+ HasDerivAt (fun t => t + y * I) 1 x := by",
"+ have hid := hasDerivAt_id x",
"+ have hconst : HasDerivAt (fun _ => y * I) 0 x := hasDerivAt_const x _",
"+ convert hid.add hconst using 1",
"+ simp",
"+",
"+lemma hasDerivAt_const_add_I (x y : \u211d) :",
"+ HasDerivAt (fun t => x + t * I) I y := by",
"+ have h1 : HasDerivAt (fun t => t * I) I y := by",
"+ have := (hasDerivAt_id y).mul_const I",
"+ simpa using this",
"+ have hconst : HasDerivAt (fun _ => x) 0 y := hasDerivAt_const y x",
"+ convert hconst.add h1 using 1",
"+ simp",
"+",
"+/-- FTC on a horizontal side: \u222b_{x\u2081}^{x\u2082} (deriv G)(x + yI) dx",
"+= G(x\u2082 + yI) \u2212 G(x\u2081 + yI). -/",
"+lemma HIntegral_deriv {G : \u2102 \u2192 \u2102} {z w : \u2102} (y : \u211d)",
"+ (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)",
"+ (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s)",
"+ (hmap : MapsTo (fun x : \u211d => \u2191x + y * I) [[z.re, w.re]] (RectangleBorder z w)) :",
"+ \u222b x in z.re..w.re, deriv G (x + y * I) = G (w.re + y * I) - G (z.re + y * I) := by",
"+ have hd : \u2200 x \u2208 Set.uIcc z.re w.re,",
"+ HasDerivAt (fun x => G (x + y * I)) (deriv G (x + y * I)) x := by",
"+ intro x hx",
"+ have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=",
"+ (hG _ (hmap (Set.uIcc_of_le (by simp [Set.uIcc]) hx |>.elim (fun h => h.1) |>.1))).hasDerivAt",
"+ have h2 : HasDerivAt (fun x => x + y * I) 1 x := hasDerivAt_add_const_I y x",
"+ have hcomp := h1.comp x h2",
"+ convert hcomp using 1",
"+ simp",
"+ have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) volume z.re w.re := by",
"+ apply ContinuousOn.intervalIntegrable",
"+ intro x hx",
"+ have hmem : (x + y * I) \u2208 RectangleBorder z w := by",
"+ apply hmap",
"+ rcases Set.uIcc_of_le (by simp [Set.uIcc]) hx with h | h",
"+ \u00b7 exact h.1",
"+ \u00b7 exact h.1",
"+ exact (hGc _ hmem).continuousWithinAt",
"+ have hftc := intervalIntegral.integral_deriv_eq_sub hd hint",
"+ convert hftc using 1",
"+ \u00b7 simp",
"+ \u00b7 simp",
"+",
"+/-- FTC on a vertical side: \u222b_{y\u2081}^{y\u2082} (deriv G)(x + yI) dy",
"+= \u2212I\u00b7(G(x + y\u2082I) \u2212 G(x + y\u2081I)). -/",
"+lemma VIntegral_deriv {G : \u2102 \u2192 \u2102} {z w : \u2102} (x : \u211d)",
"+ (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)",
"+ (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s)",
"+ (hmap : MapsTo (fun y : \u211d => \u2191x + \u2191y * I) [[z.im, w.im]] (RectangleBorder z w)) :",
"+ \u222b y in z.im..w.im, deriv G (x + y * I) =",
"+ -I * (G (x + w.im * I) - G (x + z.im * I)) := by",
"+ have hd : \u2200 y \u2208 Set.uIcc z.im w.im,",
"+ HasDerivAt (fun y => G (x + y * I)) (I * deriv G (x + y * I)) y := by",
"+ intro y hy",
"+ have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=",
"+ (hG _ (hmap (Set.uIcc_of_le (by simp [Set.uIcc]) hy |>.elim (fun h => h.1) |>.1))).hasDerivAt",
"+ have h2 : HasDerivAt (fun y => x + y * I) I y := hasDerivAt_const_add_I x y",
"+ have hcomp := h1.comp y h2",
"+ convert hcomp using 1",
"+ ring",
"+ have hint : IntervalIntegrable (fun y => I * deriv G (x + y * I)) volume z.im w.im := by",
"+ apply ContinuousOn.intervalIntegrable",
"+ intro y hy",
"+ apply ContinuousWithinAt.mul continuousWithinAt_const",
"+ have hmem : (x + y * I) \u2208 RectangleBorder z w := by",
"+ apply hmap",
"+ rcases Set.uIcc_of_le (by simp [Set.uIcc]) hy with h | h",
"+ \u00b7 exact h.1",
"+ \u00b7 exact h.1",
"+ exact (hGc _ hmem).continuousWithinAt",
"+ have hftc := intervalIntegral.integral_deriv_eq_sub hd hint",
"+ rw [\u2190 hftc]",
"+ rw [integral_smul]",
"+ field_simp [Complex.I_ne_zero]",
" ",
" /-- If `G : \u2102 \u2192 \u2102` is differentiable at every point of the rectangle",
" border, then the rectangle integral of `deriv G` vanishes (each side"
]
},
{
"oldStart": 71,
"oldLines": 31,
"newStart": 149,
"newLines": 13,
"lines": [
" (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s) :",
" RectangleIntegral (fun s => deriv G s) z w = 0 := by",
" rw [RectangleIntegral]",
"- have hsideH : \u2200 y : \u211d, (\u2200 x : \u211d, x \u2208 Set.uIcc z.re w.re \u2192 (x + y * I) \u2208 RectangleBorder z w) \u2192",
"- \u222b x in z.re..w.re, deriv G (x + y * I) = G (w.re + y * I) - G (z.re + y * I) := by",
"- intro y hy",
"- have hd : \u2200 x \u2208 Set.uIcc z.re w.re,",
"- HasDerivAt (fun x => G (x + y * I)) (deriv G (x + y * I)) x := by",
"- intro x hx",
"- have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=",
"- (hG _ (hy x hx)).hasDerivAt",
"- have h2 : HasDerivAt (fun x => x + y * I) 1 x := by",
"- have hid := hasDerivAt_id x",
"- have hconst : HasDerivAt (fun x => y * I) 0 x := hasDerivAt_const x _",
"- convert hid.add hconst using 1",
"- simp",
"- have := h1.comp x h2",
"- convert this using 1",
"- simp",
"- have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) volume z.re w.re := by",
"- apply ContinuousOn.intervalIntegrable_of_Icc (a := z.re) (b := w.re)",
"- intro x hx",
"- have hmem : (x + y * I) \u2208 RectangleBorder z w := hy x (Set.uIcc_of_le ?_ hx |>.elim (fun h => h.1) )",
"- \u00b7 exact (hGc _ hmem).continuousWithinAt",
"- \u00b7 sorry",
"- have := intervalIntegral.integral_deriv_eq_sub hd hint",
"- convert this using 1",
"- sorry",
"+ rw [HIntegral_deriv z.im hG hGc (mapsTo_rectangleBorder_left_im z w),",
"+ HIntegral_deriv w.im hG hGc (mapsTo_rectangleBorder_right_im z w)]",
"+ have hVr := VIntegral_deriv w.re hG hGc (mapsTo_rectangleBorder_right_re z w)",
"+ have hVl := VIntegral_deriv z.re hG hGc (mapsTo_rectangleBorder_left_re z w)",
"+ rw [VIntegral, VIntegral, hVr, hVl]",
"+ simp [Complex.I_mul_I]",
"+ ring",
" ",
" end NguyenRH1",
" "
]
}
],
"originalFile": "/-\nNguyenRH1/LiPrincipal.lean \u2014 tier ii\u2032 sub-stage ii\u2032-1b(ii) (D-064 \u00a74 R1):\nthe principal-part integral. For the explicit principal part\n P(w) = \u03a3_{i=1}^{n+1} A_i/(w\u22121)^i, A_i = F^{(n+1\u2212i)}(1)/(n+1\u2212i)!,\nwith F(w) = (w\u207f\u2212(w\u22121)\u207f)\u00b7hLi(w), on any rectangle with 1 in its interior:\n RectangleIntegral' P z w = A_1 = ResW1 n.\n\nMethod: P = A_1/(w\u22121) + (\u03a3_{i\u22652} A_i/(w\u22121)^i). The first term is handled\nby the vendored `ResidueTheoremInRectangle`; the tail has the explicit\nglobal primitive G(w) = \u2212\u03a3_{i\u22652} A_i/((i\u22121)(w\u22121)^{i\u22121}), differentiable\non the border (1 is interior, hence off the border), so its rectangle\nintegral vanishes by per-side FTC (`rectInt_deriv_eq_zero`).\n\nArchive references: D-036, D-064 (R1), journal-016.\n-/\nimport Mathlib\nimport Zeta23.FromPNTPlus.ResidueCalcOnRectangles\nimport NguyenRH1.LiResidue\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. Linearity of rectangle integrals -/\n\nlemma HIntegral_add (f g : \u2102 \u2192 \u2102) (x\u2081 x\u2082 y : \u211d)\n (hf : IntervalIntegrable (fun x => f (x + y * I)) volume x\u2081 x\u2082)\n (hg : IntervalIntegrable (fun x => g (x + y * I)) volume x\u2081 x\u2082) :\n HIntegral (f + g) x\u2081 x\u2082 y = HIntegral f x\u2081 x\u2082 y + HIntegral g x\u2081 x\u2082 y := by\n rw [HIntegral, HIntegral, HIntegral]\n have e : (fun x => (f + g) (x + y * I)) = (fun x => f (x + y * I) + g (x + y * I)) := by\n funext x\n simp [Pi.add_apply]\n rw [e, intervalIntegral.integral_add hf hg]\n\nlemma VIntegral_add (f g : \u2102 \u2192 \u2102) (x y\u2081 y\u2082 : \u211d)\n (hf : IntervalIntegrable (fun y => f (x + y * I)) volume y\u2081 y\u2082)\n (hg : IntervalIntegrable (fun y => g (x + y * I)) volume y\u2081 y\u2082) :\n VIntegral (f + g) x y\u2081 y\u2082 = VIntegral f x y\u2081 y\u2082 + VIntegral g x y\u2081 y\u2082 := by\n rw [VIntegral, VIntegral, VIntegral]\n have e : (fun y => (f + g) (x + y * I)) = (fun y => f (x + y * I) + g (x + y * I)) := by\n funext y\n simp [Pi.add_apply]\n rw [e, intervalIntegral.integral_add hf hg, smul_add]\n\nlemma RectangleIntegral_add (f g : \u2102 \u2192 \u2102) (z w : \u2102)\n (hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) :\n RectangleIntegral (f + g) z w = RectangleIntegral f z w + RectangleIntegral g z w := by\n rw [RectangleIntegral, RectangleIntegral, RectangleIntegral]\n obtain \u27e8\u27e8hf1, hf2\u27e9, hf3, hf4\u27e9 := hf\n obtain \u27e8\u27e8hg1, hg2\u27e9, hg3, hg4\u27e9 := hg\n rw [HIntegral_add f g _ _ _ hf1 hg1, HIntegral_add f g _ _ _ hf2 hg2,\n VIntegral_add f g _ _ _ hf3 hg3, VIntegral_add f g _ _ _ hf4 hg4]\n ring\n\nlemma RectangleIntegral'_add (f g : \u2102 \u2192 \u2102) (z w : \u2102)\n (hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) :\n RectangleIntegral' (f + g) z w = RectangleIntegral' f z w + RectangleIntegral' g z w := by\n rw [RectangleIntegral', RectangleIntegral_add f g z w hf hg, RectangleIntegral', RectangleIntegral',\n smul_add]\n\n/-! ## 2. The per-side FTC vanishing lemma -/\n\n/-- If `G : \u2102 \u2192 \u2102` is differentiable at every point of the rectangle\nborder, then the rectangle integral of `deriv G` vanishes (each side\ntelescopes by FTC). -/\nlemma rectInt_deriv_eq_zero {G : \u2102 \u2192 \u2102} {z w : \u2102}\n (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)\n (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s) :\n RectangleIntegral (fun s => deriv G s) z w = 0 := by\n rw [RectangleIntegral]\n have hsideH : \u2200 y : \u211d, (\u2200 x : \u211d, x \u2208 Set.uIcc z.re w.re \u2192 (x + y * I) \u2208 RectangleBorder z w) \u2192\n \u222b x in z.re..w.re, deriv G (x + y * I) = G (w.re + y * I) - G (z.re + y * I) := by\n intro y hy\n have hd : \u2200 x \u2208 Set.uIcc z.re w.re,\n HasDerivAt (fun x => G (x + y * I)) (deriv G (x + y * I)) x := by\n intro x hx\n have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=\n (hG _ (hy x hx)).hasDerivAt\n have h2 : HasDerivAt (fun x => x + y * I) 1 x := by\n have hid := hasDerivAt_id x\n have hconst : HasDerivAt (fun x => y * I) 0 x := hasDerivAt_const x _\n convert hid.add hconst using 1\n simp\n have := h1.comp x h2\n convert this using 1\n simp\n have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) volume z.re w.re := by\n apply ContinuousOn.intervalIntegrable_of_Icc (a := z.re) (b := w.re)\n intro x hx\n have hmem : (x + y * I) \u2208 RectangleBorder z w := hy x (Set.uIcc_of_le ?_ hx |>.elim (fun h => h.1) )\n \u00b7 exact (hGc _ hmem).continuousWithinAt\n \u00b7 sorry\n have := intervalIntegral.integral_deriv_eq_sub hd hint\n convert this using 1\n sorry\n\nend NguyenRH1\n",
"autoRead": false
}
thinking (3616 chars)
Issues:
1. The `e` rewrite failing: the target has `(f + g) (↑x + ↑y * I)` with CASTS (↑x, ↑y) while e has `(f + g) (x + y * I)` without visible casts — the HIntegral def uses `x + y * I` where x : ℝ coerced — displayed as ↑x + ↑y * I. My e's lambda: `fun x => (f + g) (x + y * I)` — same coercion — but the display shows the e was created fine; the rw [e, ...] failed because... e : (fun x => (f + g) (x + ↑y * I)) = fun x => f (↑x + ↑y * I) + g (↑x + ↑y * I) — and the target: `∫ (x : ℝ) in x₁..x₂, (f + g) (↑x + ↑y * I) = ...` — rw [e] should rewrite the integrand... The error says pattern `fun x => (f + g) (x + ↑y * I)` not found — the target integrand is `(f + g) (↑x + ↑y * I)` — e's LHS is `(f + g) (x + ↑y * I)` — the DIFFERENCE: `↑x + ↑y * I` vs `x + ↑y * I` — the coercion on x! In e I wrote `(x + y * I)` where x : ℝ — the coercion is implicit: displayed as `(x + ↑y * I)` with x UNCAST?? The error display: pattern `fun x => (f + g) (x + ↑y * I)` — x without ↑. And target has `↑x + ↑y * I`. So in my e the `x + y * I` elaborated with x : ℂ somehow? No — x : ℝ (the lambda domain from HIntegral's integrand `fun x => f (x + y * I)` with x : ℝ). The coercion of x into ℂ: `↑x + ↑y * I`. But e's display shows `(x + ↑y * I)` — no ↑ on x — meaning in e's elaboration, x was treated as ℂ?? Then e's type: (fun x : ℂ => ...) — mismatch with target's (fun x : ℝ => ...). That's why rw fails: e is about ℂ-typed x!
Fix: annotate e's lambda domain: `(fun x : ℝ => ...)`:
```
have e : (fun x : ℝ => (f + g) (x + y * I)) = (fun x : ℝ => f (x + y * I) + g (x + y * I)) := by
funext x
simp [Pi.add_apply]
```
Hmm — but with x : ℝ, `(f + g) (x + y * I)` requires x + y*I : ℂ — coercion ↑x inserted automatically ✓.
Actually simpler: skip e entirely — the integrand (f+g)(x+yI) = f(x+yI)+g(x+yI) by Pi.add_apply definitionally: `intervalIntegral.integral_add hf hg` expects the integrand in the form f+g pointwise: the lemma: `intervalIntegral.integral_add (hf : IntervalIntegrable f ...) (hg : IntervalIntegrable g ...) : ∫ (f x + g x) = ∫ f + ∫ g`. The target integrand is `fun x => (f+g)(x+yI)` — I need to massage to `fun x => f (x+yI) + g (x+yI)`. Since Pi.add_apply is defeq, use `show` or `simp only [Pi.add_apply]`:
```
rw [HIntegral, HIntegral, HIntegral]
simp only [Pi.add_apply]
exact intervalIntegral.integral_add hf hg
```
`Pi.add_apply : (f + g) x = f x + g x` — simp only rewrites the integrand occurrence ✓ (simp works up to matching under binders ✓).
2. hf1 type: RectangleBorderIntegrable's components are `IntegrableOn (fun x => f (↑x + ↑z.im * I)) (Set.Ioc z.re w.re) volume` — IntegrableOn over Ioc, not IntervalIntegrable! Check the vendored RectangleBorderIntegrable def: from the earlier agent grep: `def RectangleBorderIntegrable (f : ℂ → E) (z w : ℂ) : Prop :=` — its fields are IntegrableOn forms. IntervalIntegrable f volume a b is `IntegrableOn f (Ioc a b) volume`-equivalent: `IntervalIntegrable` is DEFINED as IntegrableOn (uIoc a b)? IntervalIntegrable f μ a b := IntegrableOn f (Ioc a b) μ ∧ IntegrableOn f (Ioc b a) μ — actually `IntervalIntegrable f μ a b : Prop := IntegrableOn f (uIoc a b) μ` — and uIoc a b = Ioc (min a b) (max a b). So hf1 : IntegrableOn (fun x => f (↑x+↑z.im*I)) (Set.Ioc z.re w.re) volume — if z.re ≤ w.re, uIoc = Ioc ✓ convertible via `IntervalIntegrable` def — need z.re ≤ w.re hypothesis OR use the IntegrableOn directly: intervalIntegral.integral_add works with IntervalIntegrable args. The vendored rectangle integral theorems all carry `zRe_le_wRe` hypotheses — I should too. Let me check the exact def of RectangleBorderIntegrable.
Let me check the `RectangleBorderIntegrable` definition to align the integrability forms.
tool: Bash
input
{
"command": "grep -n \"def RectangleBorderIntegrable\" -A 8 /d/Python/Quantum/zeta-23-lean/Zeta23/FromPNTPlus/ResidueCalcOnRectangles.lean | head -12",
"description": "Read RectangleBorderIntegrable definition"
}
thinking (2011 chars)
RectangleBorderIntegrable's components ARE IntervalIntegrable — hf1 : IntervalIntegrable (fun x => f (x + z.im * I)) volume z.re w.re ✓. So my RectangleIntegral_add just needs the right destructuring: hf is a 4-tuple (and structure): `obtain ⟨hf1, hf2, hf3, hf4⟩ := hf` (it's a 4-way ∧, not nested pairs — ∧ ∧ ∧: obtain ⟨hf1, hf2, hf3, hf4⟩ works for right-nested ∧? The def: A ∧ B ∧ C ∧ D = A ∧ (B ∧ (C ∧ D)) — obtain ⟨a, b, c, d⟩ handles nested ✓).
But wait — there's ALREADY `RectangleBorderIntegrable.add` (line 157) in the vendored file! It proves exactly RectangleIntegral (f+g) = RectangleIntegral f + RectangleIntegral g. So I don't need my own HIntegral_add/VIntegral_add/RectangleIntegral_add — use the vendored one. And for RectangleIntegral' additivity: derive from it. Let me check if there's a primed version... and just use it:
```
lemma RectangleIntegral'_add (f g : ℂ → ℂ) (z w : ℂ)
(hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) :
RectangleIntegral' (f + g) z w = RectangleIntegral' f z w + RectangleIntegral' g z w := by
rw [RectangleIntegral', RectangleBorderIntegrable.add hf hg, RectangleIntegral', RectangleIntegral', smul_add]
```
Delete my HIntegral_add/VIntegral_add/RectangleIntegral_add entirely. Also fix the hmap/uIcc mess in HIntegral_deriv/VIntegral_deriv — the `Set.uIcc_of_le (by simp [Set.uIcc]) hx |>.elim ...` hack — let me think: hx : x ∈ Set.uIcc z.re w.re — need z.re ≤ w.re? uIcc a b = Icc (min) (max) — membership gives min ≤ x ≤ max. The MapsTo needs x ∈ [[z.re, w.re]] = uIcc — same set ✓ so `hmap hx` works directly if [[z.re, w.re]] unfolds to uIcc — `[[a,b]]` notation IS uIcc ✓ so `hmap hx` directly! Let me simplify:
```
have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=
(hG _ (hmap hx)).hasDerivAt
```
Wait — MapsTo f s t x hx : f x ∈ t for x ∈ s ✓ so `hmap hx : (x + y * I) ∈ RectangleBorder z w` ✓ directly (since [[z.re, w.re]] = uIcc z.re w.re defeq ✓).
Let me rewrite the whole file cleanly.
The vendored `RectangleBorderIntegrable.add` already exists — simplifying. Also fixing the MapsTo application (uIcc is definitionally `[[·,·]]`).
tool: Write ok
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiPrincipal.lean",
"content": "/-\nNguyenRH1/LiPrincipal.lean \u2014 tier ii\u2032 sub-stage ii\u2032-1b(ii) (D-064 \u00a74 R1):\nthe principal-part integral. For the explicit principal part\n P(w) = \u03a3_{i=1}^{n+1} A_i/(w\u22121)^i, A_i = F^{(n+1\u2212i)}(1)/(n+1\u2212i)!,\nwith F(w) = (w\u207f\u2212(w\u22121)\u207f)\u00b7hLi(w), on any rectangle with 1 in its interior:\n RectangleIntegral' P z w = A_1 = ResW1 n.\n\nMethod: P = A_1/(w\u22121) + (\u03a3_{i\u22652} A_i/(w\u22121)^i). The first term is handled\nby the vendored `ResidueTheoremInRectangle`; the tail has the explicit\nglobal primitive G(w) = \u2212\u03a3_{i\u22652} A_i/((i\u22121)(w\u22121)^{i\u22121}), differentiable\non the border (1 is interior, hence off the border), so its rectangle\nintegral vanishes by per-side FTC (`rectInt_deriv_eq_zero`).\n\nArchive references: D-036, D-064 (R1), journal-016.\n-/\nimport Mathlib\nimport Zeta23.FromPNTPlus.ResidueCalcOnRectangles\nimport NguyenRH1.LiResidue\n\nopen Zeta23 Complex Filter Topology\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. Additivity of the primed rectangle integral -/\n\nlemma RectangleIntegral'_add (f g : \u2102 \u2192 \u2102) (z w : \u2102)\n (hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) :\n RectangleIntegral' (f + g) z w = RectangleIntegral' f z w + RectangleIntegral' g z w := by\n rw [RectangleIntegral', RectangleBorderIntegrable.add hf hg, RectangleIntegral', RectangleIntegral',\n smul_add]\n\n/-! ## 2. Parametrized side derivatives and integrability -/\n\nlemma hasDerivAt_add_const_I (y : \u211d) (x : \u211d) :\n HasDerivAt (fun t => t + y * I) 1 x := by\n have hid := hasDerivAt_id x\n have hconst : HasDerivAt (fun _ => y * I) 0 x := hasDerivAt_const x _\n convert hid.add hconst using 1\n simp\n\nlemma hasDerivAt_const_add_I (x y : \u211d) :\n HasDerivAt (fun t => x + t * I) I y := by\n have h1 : HasDerivAt (fun t => t * I) I y := by\n have := (hasDerivAt_id y).mul_const I\n simpa using this\n have hconst : HasDerivAt (fun _ => x) 0 y := hasDerivAt_const y x\n convert hconst.add h1 using 1\n simp\n\n/-- FTC on a horizontal side: \u222b_{x\u2081}^{x\u2082} (deriv G)(x + yI) dx\n= G(x\u2082 + yI) \u2212 G(x\u2081 + yI). -/\nlemma HIntegral_deriv {G : \u2102 \u2192 \u2102} {z w : \u2102} (y : \u211d)\n (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)\n (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s)\n (hmap : MapsTo (fun x : \u211d => \u2191x + y * I) [[z.re, w.re]] (RectangleBorder z w)) :\n \u222b x in z.re..w.re, deriv G (x + y * I) = G (w.re + y * I) - G (z.re + y * I) := by\n have hd : \u2200 x \u2208 Set.uIcc z.re w.re,\n HasDerivAt (fun x => G (x + y * I)) (deriv G (x + y * I)) x := by\n intro x hx\n have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=\n (hG _ (hmap hx)).hasDerivAt\n have h2 : HasDerivAt (fun x => x + y * I) 1 x := hasDerivAt_add_const_I y x\n have hcomp := h1.comp x h2\n convert hcomp using 1\n simp\n have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) volume z.re w.re := by\n apply ContinuousOn.intervalIntegrable\n intro x hx\n exact (hGc _ (hmap hx)).continuousWithinAt\n have hftc := intervalIntegral.integral_deriv_eq_sub hd hint\n convert hftc using 1\n \u00b7 simp\n \u00b7 simp\n\n/-- FTC on a vertical side: \u222b_{y\u2081}^{y\u2082} (deriv G)(x + yI) dy\n= \u2212I\u00b7(G(x + y\u2082I) \u2212 G(x + y\u2081I)). -/\nlemma VIntegral_deriv {G : \u2102 \u2192 \u2102} {z w : \u2102} (x : \u211d)\n (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)\n (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s)\n (hmap : MapsTo (fun y : \u211d => \u2191x + \u2191y * I) [[z.im, w.im]] (RectangleBorder z w)) :\n \u222b y in z.im..w.im, deriv G (x + y * I) =\n -I * (G (x + w.im * I) - G (x + z.im * I)) := by\n have hd : \u2200 y \u2208 Set.uIcc z.im w.im,\n HasDerivAt (fun y => G (x + y * I)) (I * deriv G (x + y * I)) y := by\n intro y hy\n have h1 : HasDerivAt G (deriv G (x + y * I)) (x + y * I) :=\n (hG _ (hmap hy)).hasDerivAt\n have h2 : HasDerivAt (fun y => x + y * I) I y := hasDerivAt_const_add_I x y\n have hcomp := h1.comp y h2\n convert hcomp using 1\n ring\n have hint : IntervalIntegrable (fun y => I * deriv G (x + y * I)) volume z.im w.im := by\n apply ContinuousOn.intervalIntegrable\n intro y hy\n exact ContinuousWithinAt.mul continuousWithinAt_const\n ((hGc _ (hmap hy)).continuousWithinAt)\n have hftc := intervalIntegral.integral_deriv_eq_sub hd hint\n rw [\u2190 hftc, integral_smul]\n field_simp [Complex.I_ne_zero]\n\n/-- If `G : \u2102 \u2192 \u2102` is differentiable at every point of the rectangle\nborder, then the rectangle integral of `deriv G` vanishes (each side\ntelescopes by FTC). -/\nlemma rectInt_deriv_eq_zero {G : \u2102 \u2192 \u2102} {z w : \u2102}\n (hG : \u2200 s \u2208 RectangleBorder z w, DifferentiableAt \u2102 G s)\n (hGc : \u2200 s \u2208 RectangleBorder z w, ContinuousAt (deriv G) s) :\n RectangleIntegral (fun s => deriv G s) z w = 0 := by\n rw [RectangleIntegral]\n rw [HIntegral_deriv z.im hG hGc (mapsTo_rectangleBorder_left_im z w),\n HIntegral_deriv w.im hG hGc (mapsTo_rectangleBorder_right_im z w)]\n have hVr := VIntegral_deriv w.re hG hGc (mapsTo_rectangleBorder_right_re z w)\n have hVl := VIntegral_deriv z.re hG hGc (mapsTo_rectangleBorder_left_re z w)\n rw [VIntegral, VIntegral, hVr, hVl]\n simp [Complex.I_mul_I]\n ring\n\nend NguyenRH1\n"
}
result 2026-08-21 21:31:49Z → 2026-08-29 00:21:55Z
{
"type": "update",
"filePath": "D:\\Python\\quantum-deploy\\docroot\\app.cgi",
"content": "#!/opt/alt/python311/bin/python3.11\n\"\"\"WSGI->CGI adapter \u2014 runs the RH-WEBSITE Django app on Apache shared hosting.\n\nApache rewrites every non-file request to /app.cgi/<path> (see .htaccess).\nwsgiref's CGIHandler bridges the CGI environment onto Django's WSGI app.\n\"\"\"\nimport os\nimport sys\n\nDOCROOT = os.path.dirname(os.path.abspath(__file__))\nAPP = os.path.join(DOCROOT, \"app\")\n\n# Vendored pure-Python deps (Django 5.2, markdown) + the project package.\nsys.path.insert(0, os.path.join(APP, \"vendor\"))\nsys.path.insert(0, os.path.join(APP, \"web\"))\n\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"rhweb.settings\")\n# Apache mounts us at /app.cgi/<path>; present clean root URLs to Django.\nos.environ[\"SCRIPT_NAME\"] = \"\"\n\nfrom wsgiref.handlers import CGIHandler\n\nfrom rhweb.wsgi import application\n\n\ndef _script_url_fix(environ, start_response):\n \"\"\"PEP 3333 fix for non-ASCII URLs (e.g. resources files with Greek\n letters/dashes in their names).\n\n wsgiref's read_environ() already latin-1-mangles PATH_INFO (and any\n REDIRECT_* var that is itself transcodable) so Django can re-decode\n it \u2014 do NOT touch PATH_INFO here (a second mangle breaks routing,\n 404s). But SCRIPT_URL and REDIRECT_URL pass through read_environ\n UNCHANGED as proper unicode, and Django's get_script_name() then\n crashes encoding them as iso-8859-1 (UnicodeEncodeError -> 500).\n Mangle exactly those two.\"\"\"\n for key in (\"SCRIPT_URL\", \"REDIRECT_URL\"):\n v = environ.get(key)\n if v:\n environ[key] = v.encode(\"utf-8\", \"surrogateescape\") \\\n .decode(\"latin-1\")\n return application(environ, start_response)\n\n\nCGIHandler().run(_script_url_fix)\n",
"structuredPatch": [
{
"oldStart": 9,
"oldLines": 17,
"newStart": 9,
"newLines": 6,
"lines": [
" ",
" DOCROOT = os.path.dirname(os.path.abspath(__file__))",
" APP = os.path.join(DOCROOT, \"app\")",
"-",
"-",
"-def _dbg(msg):",
"- if \"resources\" in (os.environ.get(\"PATH_INFO\") or \"\"):",
"- with open(os.path.join(APP, \"debug-environ.txt\"), \"a\",",
"- encoding=\"utf-8\") as fh:",
"- fh.write(msg + \"\\n\")",
"-",
"-",
"-_dbg(\"TOP fsenc=\" + sys.getfilesystemencoding()",
"- + \" PATH_INFO=\" + repr(os.environ.get(\"PATH_INFO\")))",
" ",
" # Vendored pure-Python deps (Django 5.2, markdown) + the project package.",
" sys.path.insert(0, os.path.join(APP, \"vendor\"))"
]
},
{
"oldStart": 33,
"oldLines": 56,
"newStart": 22,
"newLines": 25,
"lines": [
" ",
" from rhweb.wsgi import application",
" ",
"-_dbg(\"AFTER-IMPORT PATH_INFO=\" + repr(os.environ.get(\"PATH_INFO\")))",
" ",
"-from urllib.parse import unquote_to_bytes",
"+def _script_url_fix(environ, start_response):",
"+ \"\"\"PEP 3333 fix for non-ASCII URLs (e.g. resources files with Greek",
"+ letters/dashes in their names).",
" ",
"-",
"-def _pep3333_paths(environ, start_response):",
"- \"\"\"Normalize Apache's path vars to the PEP 3333 form Django needs.",
"-",
"- Apache hands these vars either percent-encoded (mod_rewrite path)",
"- or UTF-8-decoded (direct CGI path). Django (a) crashes with",
"- UnicodeEncodeError on any non-latin-1 char (500) and (b) needs the",
"- decoded path for URL resolution (else the resolver sees %XX and 404s).",
"- So: bytes -> unquote -> re-mangle as latin-1. SCRIPT_URL/REDIRECT_URL",
"- (set by mod_rewrite) are consulted by get_script_name BEFORE",
"- PATH_INFO \u2014 all three must be normalized.\"\"\"",
"- if \"resources\" in (environ.get(\"PATH_INFO\") or \"\"):",
"- with open(os.path.join(APP, \"debug-environ.txt\"), \"a\",",
"- encoding=\"utf-8\") as fh:",
"- fh.write(\"ENTRY PATH_INFO=\" + repr(environ.get(\"PATH_INFO\"))",
"- + \" SCRIPT_URL=\" + repr(environ.get(\"SCRIPT_URL\")) + \"\\n\")",
"- for key in (\"PATH_INFO\", \"SCRIPT_URL\", \"REDIRECT_URL\"):",
"+ wsgiref's read_environ() already latin-1-mangles PATH_INFO (and any",
"+ REDIRECT_* var that is itself transcodable) so Django can re-decode",
"+ it \u2014 do NOT touch PATH_INFO here (a second mangle breaks routing,",
"+ 404s). But SCRIPT_URL and REDIRECT_URL pass through read_environ",
"+ UNCHANGED as proper unicode, and Django's get_script_name() then",
"+ crashes encoding them as iso-8859-1 (UnicodeEncodeError -> 500).",
"+ Mangle exactly those two.\"\"\"",
"+ for key in (\"SCRIPT_URL\", \"REDIRECT_URL\"):",
" v = environ.get(key)",
" if v:",
"- raw = unquote_to_bytes(v) # %XX-decodes; utf-8-encodes str first",
"- environ[key] = raw.decode(\"latin-1\")",
"- if \"resources\" in (environ.get(\"PATH_INFO\") or \"\"):",
"- with open(os.path.join(APP, \"debug-environ.txt\"), \"a\",",
"- encoding=\"utf-8\") as fh:",
"- fh.write(repr({k: environ.get(k) for k in",
"- (\"PATH_INFO\", \"SCRIPT_NAME\", \"SCRIPT_URL\",",
"- \"REDIRECT_URL\", \"REQUEST_METHOD\", \"HTTP_HOST\")})",
"- + \"\\n\")",
"- try:",
"- from django.core.handlers.wsgi import WSGIRequest",
"- req = WSGIRequest(dict(environ))",
"- fh.write(\"path_info=\" + repr(req.path_info) + \"\\n\")",
"- from django.urls import resolve",
"- m = resolve(req.path_info)",
"- fh.write(\"match=\" + repr(m.kwargs) + \"\\n\")",
"- except Exception as e: # noqa: BLE001",
"- fh.write(\"ERR \" + repr(e) + \"\\n\")",
"- try:",
"- raw = open(\"/proc/self/environ\", \"rb\").read()",
"- for entry in raw.split(b\"\\x00\"):",
"- if entry.startswith((b\"PATH_INFO=\", b\"SCRIPT_URL=\")):",
"- fh.write(\"ENVBYTES \" + repr(entry) + \"\\n\")",
"- except Exception as e: # noqa: BLE001",
"- fh.write(\"ENVBYTES ERR \" + repr(e) + \"\\n\")",
"+ environ[key] = v.encode(\"utf-8\", \"surrogateescape\") \\",
"+ .decode(\"latin-1\")",
" return application(environ, start_response)",
" ",
" ",
"-CGIHandler().run(_pep3333_paths)",
"+CGIHandler().run(_script_url_fix)",
" "
]
}
],
"originalFile": "#!/opt/alt/python311/bin/python3.11\n\"\"\"WSGI->CGI adapter \u2014 runs the RH-WEBSITE Django app on Apache shared hosting.\n\nApache rewrites every non-file request to /app.cgi/<path> (see .htaccess).\nwsgiref's CGIHandler bridges the CGI environment onto Django's WSGI app.\n\"\"\"\nimport os\nimport sys\n\nDOCROOT = os.path.dirname(os.path.abspath(__file__))\nAPP = os.path.join(DOCROOT, \"app\")\n\n\ndef _dbg(msg):\n if \"resources\" in (os.environ.get(\"PATH_INFO\") or \"\"):\n with open(os.path.join(APP, \"debug-environ.txt\"), \"a\",\n encoding=\"utf-8\") as fh:\n fh.write(msg + \"\\n\")\n\n\n_dbg(\"TOP fsenc=\" + sys.getfilesystemencoding()\n + \" PATH_INFO=\" + repr(os.environ.get(\"PATH_INFO\")))\n\n# Vendored pure-Python deps (Django 5.2, markdown) + the project package.\nsys.path.insert(0, os.path.join(APP, \"vendor\"))\nsys.path.insert(0, os.path.join(APP, \"web\"))\n\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"rhweb.settings\")\n# Apache mounts us at /app.cgi/<path>; present clean root URLs to Django.\nos.environ[\"SCRIPT_NAME\"] = \"\"\n\nfrom wsgiref.handlers import CGIHandler\n\nfrom rhweb.wsgi import application\n\n_dbg(\"AFTER-IMPORT PATH_INFO=\" + repr(os.environ.get(\"PATH_INFO\")))\n\nfrom urllib.parse import unquote_to_bytes\n\n\ndef _pep3333_paths(environ, start_response):\n \"\"\"Normalize Apache's path vars to the PEP 3333 form Django needs.\n\n Apache hands these vars either percent-encoded (mod_rewrite path)\n or UTF-8-decoded (direct CGI path). Django (a) crashes with\n UnicodeEncodeError on any non-latin-1 char (500) and (b) needs the\n decoded path for URL resolution (else the resolver sees %XX and 404s).\n So: bytes -> unquote -> re-mangle as latin-1. SCRIPT_URL/REDIRECT_URL\n (set by mod_rewrite) are consulted by get_script_name BEFORE\n PATH_INFO \u2014 all three must be normalized.\"\"\"\n if \"resources\" in (environ.get(\"PATH_INFO\") or \"\"):\n with open(os.path.join(APP, \"debug-environ.txt\"), \"a\",\n encoding=\"utf-8\") as fh:\n fh.write(\"ENTRY PATH_INFO=\" + repr(environ.get(\"PATH_INFO\"))\n + \" SCRIPT_URL=\" + repr(environ.get(\"SCRIPT_URL\")) + \"\\n\")\n for key in (\"PATH_INFO\", \"SCRIPT_URL\", \"REDIRECT_URL\"):\n v = environ.get(key)\n if v:\n raw = unquote_to_bytes(v) # %XX-decodes; utf-8-encodes str first\n environ[key] = raw.decode(\"latin-1\")\n if \"resources\" in (environ.get(\"PATH_INFO\") or \"\"):\n with open(os.path.join(APP, \"debug-environ.txt\"), \"a\",\n encoding=\"utf-8\") as fh:\n fh.write(repr({k: environ.get(k) for k in\n (\"PATH_INFO\", \"SCRIPT_NAME\", \"SCRIPT_URL\",\n \"REDIRECT_URL\", \"REQUEST_METHOD\", \"HTTP_HOST\")})\n + \"\\n\")\n try:\n from django.core.handlers.wsgi import WSGIRequest\n req = WSGIRequest(dict(environ))\n fh.write(\"path_info=\" + repr(req.path_info) + \"\\n\")\n from django.urls import resolve\n m = resolve(req.path_info)\n fh.write(\"match=\" + repr(m.kwargs) + \"\\n\")\n except Exception as e: # noqa: BLE001\n fh.write(\"ERR \" + repr(e) + \"\\n\")\n try:\n raw = open(\"/proc/self/environ\", \"rb\").read()\n for entry in raw.split(b\"\\x00\"):\n if entry.startswith((b\"PATH_INFO=\", b\"SCRIPT_URL=\")):\n fh.write(\"ENVBYTES \" + repr(entry) + \"\\n\")\n except Exception as e: # noqa: BLE001\n fh.write(\"ENVBYTES ERR \" + repr(e) + \"\\n\")\n return application(environ, start_response)\n\n\nCGIHandler().run(_pep3333_paths)\n",
"autoRead": false
}
thinking (10227 chars)
Multiple type issues:
1. `hasDerivAt_add_const_I`: the `.add` application — HasDerivAt.add (hf : HasDerivAt f f' x) (hg : HasDerivAt g g' x) : HasDerivAt (f+g) (f'+g') x — the issue: `hid.add hconst` — hid : HasDerivAt id 1 x — the dot `.add` — hid's type: HasDerivAt id 1 x — hmm, hasDerivAt_id returns `HasDerivAt id 1 x`? — maybe it's `hasDerivAt_id (x) : HasDerivAt id 1 x` ✓. hconst : HasDerivAt (fun _ => y*I) 0 x — the application fails with hconst expected `?m.54 ?m.56 x` — meaning the dot-projection `.add` resolved weirdly. Use explicit: `HasDerivAt.add hid hconst` — hmm same. The issue might be `hasDerivAt_id x` — check: `hasDerivAt_id (x : 𝕜) : HasDerivAt id 1 x` ✓ standard. And `.add` — `HasDerivAt.add (hf : HasDerivAt f f' x) (hg : HasDerivAt g g' x) : HasDerivAt (fun x => f x + g x) (f' + g') x` ✓. So `hid.add hconst : HasDerivAt (fun x => x + y*I) (1 + 0) x` ✓ then `convert this using 1; simp`. The error at 40:18 "has type HasDerivAt (fun x => ↑y * I) 0 x but is expected HasDerivAt ?m.54 ?m.56 x" — the ?m.54 unresolved — because `hid.add hconst` — Lean couldn't determine f/f' from hid (id)? Maybe hasDerivAt_id's result is `HasDerivAt id 1 x` — f := id, f' := 1 ✓ concrete... The `?m` suggests elaboration order issue — use explicit HasDerivAt.add hid hconst with named form:
```
have h := HasDerivAt.add (hasDerivAt_id x) (hasDerivAt_const x (y * I))
simpa using h
```
h : HasDerivAt (fun x => id x + (fun _ => y*I) x) (1 + 0) x = HasDerivAt (fun x => x + y*I) (1+0) x — simpa (1+0 = 1, id x = x) ✓.
2. `(hasDerivAt_id y).mul_const I` — mul_const expects a scalar of the same field — y : ℝ! hasDerivAt_id y is for y : ℝ (the identity on ℝ) — I need the identity on ℂ? No wait — in hasDerivAt_const_add_I, the parametrization is over ℝ (y : ℝ) but the map is t ↦ x + t·I : ℝ → ℂ. HasDerivAt here is for ℝ → ℂ maps (real derivative of a complex-valued function). hasDerivAt_id y : HasDerivAt id 1 y — over which field? HasDerivAt for functions between normed spaces over ℝ? The generic HasDerivAt is for functions 𝕜 → F over 𝕜 (same field). For ℝ → ℂ, the derivative is the real derivative: HasDerivAt (fun t : ℝ => t * I) I y — t*I : ℂ with t : ℝ — this is t ↦ Complex.ofReal t * I — the derivative is I as a complex number: HasDerivAt (fun t : ℝ => t * I) I y — provable via `HasDerivAt.mul_const`? hasDerivAt_id y is ℝ→ℝ. I need `(fun t : ℝ => t) ` composed with ofReal then * I:
t ↦ (t : ℂ): HasDerivAt (fun t : ℝ => (t : ℂ)) 1 y — `Complex.hasDerivAt_ofReal`? or via ofRealCLM. Then (fun t => (t:ℂ) * I): HasDerivAt (fun t => (t:ℂ) * I) (1 * I) y via .mul_const — mul_const for ℂ-valued over... hmm — HasDerivAt.mul_const : HasDerivAt f f' x → HasDerivAt (fun x => f x * c) (f' * c) x — for f : ℝ → ℂ with c : ℂ ✓ works (real derivative of complex function): f' : ℂ. So:
```
have h1 : HasDerivAt (fun t : ℝ => (t : ℂ)) 1 y := by
-- via ofReal: Complex.ofRealCLM derivative
exact Complex.hasDerivAt_ofReal?
```
Hmm — let me check what's available: `Complex.hasDerivAt_ofReal`? There's `hasDerivAt_ofReal`? The CLM: `Complex.ofRealCLM : ℝ →L[ℝ] ℂ` — `ContinuousLinearMap.hasDerivAt (f : E →L[𝕜] F) : HasDerivAt f f x` ✓ — ofRealCLM's derivative is ofRealCLM itself = (· * 1)... (ofRealCLM) t = ↑t: HasDerivAt (fun t => ↑t) (ofRealCLM) y where ofRealCLM as a derivative value: HasDerivAt f (f' : F) — for linear maps, HasDerivAt f (f) x with f' = f (the CLM applied)... hmm the HasDerivAt's f' for a CLM L is L 1 = ofReal 1 = 1:
```
have hof : HasDerivAt (fun t : ℝ => (t : ℂ)) 1 y := by
have h := Complex.ofRealCLM.hasDerivAt (x := y)
simpa using h
```
`ContinuousLinearMap.hasDerivAt : HasDerivAt f f x` — f's derivative is f itself as a continuous linear map — for ofRealCLM: HasDerivAt ofRealCLM ofRealCLM y — and ofRealCLM 1 = 1 — `simpa using h` should give HasDerivAt (↑·) 1 y.
Then h1 : HasDerivAt (fun t => (t:ℂ) * I) (1 * I) y := (hof).mul_const I — then simplify 1*I = I.
Then hconst.add h1: HasDerivAt (fun t => x + t*I) (0 + I) y ✓.
Wait — but mul_const for the ℂ-valued map: `HasDerivAt.mul_const (hf : HasDerivAt f f' x) (c : ℂ) : HasDerivAt (fun x => f x * c) (f' * c) x` — for f : ℝ → ℂ, c : ℂ ✓.
Hmm — actually check: hasDerivAt_id y with y : ℝ gives HasDerivAt id 1 y — and earlier I used `(hasDerivAt_id y).mul_const I` — the error "argument I has type ℂ but expected ℝ" — because hasDerivAt_id y was the ℝ identity and mul_const wanted a real scalar. Right.
3. `MapsTo` unknown identifier — need `Set.MapsTo` qualified or `open Set`. The vendored file has `open ... Set`? My file has `open Zeta23 Complex Filter Topology` — MapsTo is `Set.MapsTo`. Add `Set` to opens or qualify. The vendored MapsTo lemmas use unqualified `MapsTo` — they're stated in namespace Zeta23 with Set open. In my file: qualify `Set.MapsTo` in the hypotheses, but the vendored lemma names (mapsTo_rectangleBorder_left_im) produce `MapsTo` — I can write `Set.MapsTo` in my statements and apply the vendored lemmas (same thing). Add `open Set` to the file opens — simplest. Hmm — `open Set` might shadow other things (Set.Icc vs...). The vendored file uses `open Complex Set Topology Filter Asymptotics Real`. I'll add `Set` to my opens.
4. `h2` application type mismatch in HIntegral_deriv (line 65): `h1.comp x h2` — h1 : HasDerivAt G (deriv G (x+y*I)) (x+y*I) — h2 : HasDerivAt (fun x => x + y*I) 1 x — HasDerivAt.comp (hg : HasDerivAt g g' (f x)) (hf : HasDerivAt f f' x) : HasDerivAt (g ∘ f) (g' * f') x — h1.comp x h2 — wait the signature: `HasDerivAt.comp (hg : HasDerivAt g g' (f x)) (hf : HasDerivAt f f' x) : HasDerivAt (g ∘ f) (g' * f') x` — application: h1.comp x h2 ✓ standard form (comp takes x explicitly). The error: h2 "has type HasDerivAt (fun x => x + ↑y * I) 1 ↑x but expected ?m.183 ?m.185 x" — the `↑x` — h2's point is ↑x (cast) vs x — hasDerivAt_add_const_I y x : HasDerivAt (fun t => t + y * I) 1 x — x : ℝ ✓ — the display shows ↑x — the elaboration lifted x into ℂ?? — because in `h1.comp x h2`, comp expects hf : HasDerivAt f f' x with f : ? → ? and g at (f x): h1's point is (x + y * I) : ℂ — so f x = x + y*I needs x coerced to ℂ — Lean inferred f : ℂ → ℂ and x : ℂ, casting my x : ℝ to ↑x. But the inner parametrization is over ℝ! The HasDerivAt.comp for g : ℂ → ℂ and f : ℝ → ℂ — mixed-field composition is NOT HasDerivAt.comp (which needs same field!). PROBLEM: the chain rule for g ∘ f with f : ℝ → ℂ and g : ℂ → ℂ — the fields differ (ℝ for the real parameter, ℂ for g's holomorphic derivative). The composition's derivative is g'(f(x))·f'(x) as a complex number — the relevant lemma: `HasDerivAt.comp` requires g : 𝕜 → 𝕜 over the same 𝕜. For mixed: there's `HasDerivAt.comp_of_real`? or `HasDerivAt.comp'`? Hmm — actually for f : ℝ → ℂ differentiable (real derivative) and g : ℂ → ℂ holomorphic (complex derivative): the composition f(t) path in ℂ: (g∘f)'(t) = g'(f(t))·f'(t) — this is `HasDerivAt.comp` with 𝕜 = ... no. There should be a lemma for real-parameter curves into complex functions: `HasDerivAt.comp` doesn't apply; but there's `HasDerivAt.comp_hasDerivAt`? or use `HasFDerivAt.comp` with different scalars?? Hmm — actually the standard trick: g analytic ⟹ its real derivative along the path: use `HasDerivAt.comp` where BOTH are over ℝ? g's complex derivative gives the real derivative along any real-direction: HasDerivAt g (g' • (1 : ℂ)) — as a real-linear map: g is ℝ-differentiable with derivative (z ↦ g'·z): so the composition: HasFDerivAt-style. The cleanest Mathlib lemma: `HasDerivAt.comp` is for same-field. For mixed: `HasDerivAt.comp_ofReal`? Hmm. Alternative: `HasDerivAt.comp` exists in two flavors... Let me think about what the vendored PNT+ code does for parametrized sides — they must have faced this. Actually — the standard Mathlib lemma for this: `HasDerivAt.comp` with signature `(hg : HasDerivAt g (g') (f x)) (hf : HasDerivAt f (f') x) : HasDerivAt (g ∘ f) (g' * f') x` — fields: f : 𝕜 → F, g : F → F'... HasDerivAt is defined for functions between normed spaces over the SAME field 𝕜. For f : ℝ → ℂ and g : ℂ → ℂ: g is differentiable over ℂ; the composition over ℝ — the chain rule works with g's ℂ-derivative restricted to a real-linear map: the relevant instance: g is also ℝ-differentiable (DifferentiableAt ℂ g s → DifferentiableAt ℝ g s? — `DifferentiableAt.restrict_scalars`! There's `DifferentiableAt.restrict_scalars (h : DifferentiableAt ℂ f x) : DifferentiableAt ℝ f x` ✓ exists in Mathlib for restricted scalars. And then HasFDerivAt.comp for ℝ maps. The HasDerivAt (1-dimensional) version: `HasDerivAt.restrict_scalars`? Hmm.
This is getting heavy. Alternative cleaner approach for the side FTCs: AVOID the mixed-field chain rule by using `HasFDerivAt.comp` with CLMs? — or sidestep entirely: note that for our specific G (rational functions of (w−1)), the side integrands' antiderivatives are explicit — the FTC needs (x ↦ G(x+yI))' = G'(x+yI): prove it via `HasDerivAt.scomp`? Hmm.
Actually — the RIGHT Mathlib lemma: `HasDerivAt.comp` does exist in a version for f : 𝕜 → F, g : F → F' over the same field 𝕜... For f : ℝ → ℂ (𝕜 = ℝ, F = ℂ) and g : ℂ → ℂ (𝕜 = ℂ) — different fields. The composition's derivative over ℝ: need g ℝ-differentiable. `HasDerivAt.comp` in Mathlib is stated for g over the SAME 𝕜 as f. There's `HasDerivAt.comp` and `HasDerivAt.comp_hasDerivAt`...
The cleanest available: `HasFDerivAt.comp` (Fréchet, any normed spaces over the same field ℝ): G's HasFDerivAt (as a ℂ-differentiable function, restrict scalars to ℝ) with derivative the CLM (z ↦ G'·z); the path γ(x) = x + yI has HasFDerivAt with derivative (t ↦ t·1). Chain: (G∘γ)' = (z ↦ G'·z) ∘ (t ↦ t·1) = (t ↦ G'·t·1) = (t ↦ G'·t): so HasFDerivAt (G∘γ) (t ↦ G'·t) x — then to HasDerivAt: the 1-dim HasDerivAt from HasFDerivAt via `HasFDerivAt.hasDerivAt`? — for functions into ℂ over ℝ, HasDerivAt f f' x ⟺ HasFDerivAt f (f' • (1:ℝ→L[ℝ]ℂ))... there's `hasDerivAt_iff_hasFDerivAt`?
Simplest robust hack: use `HasDerivAt.comp` with g viewed as a real function via restrict_scalars at the HasDerivAt level. Is there `HasDerivAt.restrict_scalars`? Let me grep. Actually — maybe easier: there IS a mixed composition lemma `HasDerivAt.comp` in Mathlib for this exact case? Let me grep for comp variants.
The mixed-field chain rule needs the right lemma. Let me check what's available.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem HasDerivAt.restrict_scalars\\|lemma HasDerivAt.restrict_scalars\\|restrict_scalars.*HasDerivAt\" Mathlib/ --include=*.lean | head -4; grep -rn \"hasDerivAt_ofReal\\|ofRealCLM\" Mathlib/Analysis/Complex/Basic.lean | head -5; grep -rn \"theorem HasDerivAt.comp\\b\" Mathlib/Analysis/Calculus/Deriv/Comp.lean | head -3",
"description": "Find restrict_scalars and composition lemmas for mixed fields"
}
thinking (6935 chars)
`HasDerivAt.comp` is for functions on an ALGEBRA (same field) — for f : ℝ → ℂ and g : ℂ → ℂ, hmm — actually wait: HasDerivAt in Mathlib is defined for functions h : 𝕜 → F where F is a normed ALGEBRA over 𝕜? No — HasDerivAt works for functions from a field 𝕜 into a normed algebra? Let me check: `HasDerivAt (f : 𝕜 → F) (f' : F) (x : 𝕜)` — F must be a normed algebra over 𝕜 for the * in the chain rule. For f : ℝ → ℂ: 𝕜 = ℝ, F = ℂ (ℂ is a normed algebra over ℝ ✓). For g : ℂ → ℂ: 𝕜 = ℂ, F = ℂ. The composition g ∘ f : ℝ → ℂ with g ℂ-differentiable: the chain rule needs g's derivative as a REAL-linear map on the path — g is ℝ-differentiable (restrict_scalars) and its real derivative at g'(z)·(path direction). HasDerivAt.comp with hh₂ : HasDerivAt h₂ h₂' (h x): if h₂ : ℂ → ℂ has HasDerivAt over ℂ (h₂' : ℂ), and h : ℝ → ℂ has HasDerivAt over ℝ (h' : ℂ) — can I apply comp? The comp lemma is stated for all functions over the SAME field 𝕜 (h₂ : 𝕜 → F, h : 𝕜 → F). With 𝕜 = ℂ, h : ℂ → ℂ — but my h is ℝ → ℂ — different domain. So no.
For my case (real parameter, complex path into holomorphic g), the composition (g∘h) : ℝ → ℂ: its derivative is h₂'(h(x)) * h'(x) — where h₂' is the COMPLEX derivative (a complex number) and h' is the real derivative (a complex number) — and the product is in ℂ. The comp lemma with 𝕜 = ℝ, F = ℂ, h₂ : ℂ → ℂ viewed as a map over ℝ?? — h₂'s HasDerivAt over ℝ would be h₂'(z)·1 → the real derivative of h₂ at z is the real-linear map t ↦ h₂'(z)·t — as a HasDerivAt (1-dim) it's h₂'(z)·1? hmm HasDerivAt (h₂ : ℝ→?) — h₂ has domain ℂ not ℝ — incompatible.
The standard resolution in Mathlib: use `HasDerivAt.comp` with the restriction-of-scalars version of h₂'s derivative, OR use `HasFDerivAt.comp` (which composes over a common field — with h₂'s HasFDerivAt restricted to ℝ). The cleanest for our specific inner functions (h(x) = x + yI, h(x) = x + tI):
The path functions h : ℝ → ℂ are of the form x ↦ c + x·u (affine with complex direction u). HasDerivAt h u x — proved directly (u as the derivative). Then (G∘h)'(x) = G'(h(x))·u: via `HasDerivAt.comp`? — no. Use `HasFDerivAt.comp`: G has HasFDerivAt (G' • (1 : ℂ →L[ℂ] ℂ)) at h(x) (from complex differentiability); restricted to ℝ: HasFDerivAt G (G' • (1 : ℂ →L[ℝ] ℂ))? Hmm.
SIMPLER PATH: for the FTC, I don't need the abstract chain rule — I can prove the parametrized HasDerivAt directly from G's holomorphicity via the definition of the derivative as a limit, but that's ugly.
MUCH SIMPLER PATH: use `HasDerivAt.comp` indirectly through Complex.ofRealCLM composition: h(x) = x + y·I = (fun t : ℝ => (t : ℂ)) composed with translation: h = (fun z => z + y·I) ∘ ofRealCLM-applied... h(x) = ofReal x + y·I: define hC : ℂ → ℂ := fun z => z + y·I (holomorphic, HasDerivAt hC 1) and ofR : ℝ → ℂ := fun t => ↑t: h = hC ∘ ofR? — (hC ∘ ofR)(x) = ↑x + y·I ✓! Then chain: HasDerivAt ofR 1 x (ofRealCLM as derivative = (· ↦ ↑1·...) hmm — ofR's HasDerivAt: `Complex.ofRealCLM.hasDerivAt (x) : HasDerivAt ofRealCLM ofRealCLM x` — as HasDerivAt (1-dim over ℝ into ℂ): HasDerivAt ofRealCLM (ofRealCLM 1)?? — ContinuousLinearMap.hasDerivAt : HasDerivAt f f x where the second f is the CLM itself as the derivative — but HasDerivAt for ℝ → ℂ expects f' : ℂ (a vector, not a map)! The 1-dim HasDerivAt f f' x with f' : F — and CLM.hasDerivAt gives HasFDerivAt f (f : E →L F) — the conversion: HasFDerivAt f L x ⟺ HasDerivAt f (L 1) x for functions into 1-dim... For f : ℝ → ℂ: HasDerivAt f f' x ⟺ HasFDerivAt f (fun t => t • f')?? — `hasDerivAt_iff_hasFDerivAt`? Hmm.
OK — let me step back and use a DIFFERENT, simpler formulation that avoids the mixed chain rule entirely: the FTC lemma `intervalIntegral.integral_deriv_eq_sub` needs HasDerivAt over ℝ for the parametrized function P(x) = G(x + yI). Instead of the chain rule, prove P's HasDerivAt directly from G's complex differentiability via the two-variable limit — no, ugly.
ALTERNATIVE: use `HasDerivAt.comp` with everything over ℂ? Make the parameter complex? NO — the interval integral is over ℝ.
BEST AVAILABLE: `HasDerivAt.scomp` — from the doc comment: "If you are looking for the chain rule with h₂ taking values in a vector space, use HasDerivAt.scomp" — scomp is for h₂ : F → F' (different target spaces)! `HasDerivAt.scomp (hg : HasDerivAt h₂ h₂' (h x)) (hh : HasDerivAt h h' x) : HasDerivAt (h₂ ∘ h) (h₂' • h') x`? — hmm the h₂' • h' — h₂' is a linear map F → F' and h' ∈ F: h₂' • h' — but for complex g : ℂ → ℂ with h₂' : ℂ... hmm the doc says comp is "on an algebra" — with h₂ taking values in an algebra (multiplication available), and scomp for vector-space-valued h₂. For our g : ℂ → ℂ with h : ℝ → ℂ: g's HasDerivAt over ℂ — scomp needs h₂ : ? over which field... Both comp and scomp need the same base field for h and h₂? — HasDerivAt.comp (hh₂ : HasDerivAt h₂ h₂' (h x)) (hh : HasDerivAt h h' x) — the field 𝕜 is shared: h₂, h both : 𝕜 → F. My h : ℝ → ℂ has 𝕜 = ℝ; h₂ : ℂ → ℂ has 𝕜 = ℂ. Incompatible regardless.
THE CLEAN SOLUTION: lift the real parameter to complex via ofReal: P(x) = G(x + yI) for x : ℝ. Write P = G ∘ (ofRealCLM) with a SHIFT: P = (fun z => G (z + yI)) ∘ ofReal: ofReal : ℝ → ℂ (CLM, HasDerivAt ofRealCLM ... hmm the f' value). Let me look at how HasDerivAt works for CLM-valued: for f = ofRealCLM : ℝ →L[ℝ] ℂ: `ContinuousLinearMap.hasDerivAt (f : E →L[𝕜] F) (x : E) : HasDerivAt f f x`?? — HasDerivAt f f' x with f' : F? or HasFDerivAt f (f) x? In Mathlib: `ContinuousLinearMap.hasDerivAt (f : E →L[𝕜] F) : HasDerivAt f (f 1) x`?? no... Let me just check: for a CLM L, HasFDerivAt L L x (derivative is itself). And HasDerivAt (1-dim domain) f f' x ⟺ HasFDerivAt f ((1 : 𝕜) • ... ) hmm — there's `HasFDerivAt.hasDerivAt`? or `hasDerivAt_iff_hasFDerivAt` : HasDerivAt f f' x ↔ HasFDerivAt f (smulRight (1:ℝ) f'·...)? I recall `hasDerivAt_iff_hasFDerivAt : HasDerivAt f f' x ↔ HasFDerivAt f (smulRight (1 : 𝕜 →L[𝕜] 𝕜) f' · hmm...
Honestly the pragmatic path: for the ofReal composition:
(G ∘ ofR)(x) with G holomorphic at ↑x + c:
HasDerivAt (G ∘ ofR) (G'(↑x + c) * 1)?? — the real derivative of G∘ofR = G'(ofR x) * (ofR's derivative 1) = G'(ofR x): via `HasDerivAt.comp` — ofR : ℝ → ℂ is the issue again...
There's a MUCH simpler standard trick used in PNT-style Lean code: the parametrized side derivative via `HasDerivAt.comp` with h₂ = G (over ℂ) and h = the path (over ℂ)? — but the parameter is real... Actually wait — maybe I'm overcomplicating: HasDerivAt in Mathlib is for functions h : 𝕜 → F with F a normed space over 𝕜 — for h : ℝ → ℂ: 𝕜 = ℝ, F = ℂ ✓. The chain rule HasDerivAt.comp (hh₂ : HasDerivAt h₂ h₂' (h x)) (hh : HasDerivAt h h' x) — the h₂ here: is its domain necessarily 𝕜? Looking at the signature: h₂ : ? — in Comp.lean the section variables: {h₂ : 𝕜' → F'}? — the doc comment says "the function h₂ is a function on an algebra" — suggesting h₂ : F → F' where F is an algebra?? Let me read the actual variable declarations in Comp.lean.
Let me read the variable declarations in Comp.lean to see if a mixed-field composition exists.
tool: Bash
input
{
"command": "sed -n '1,60p' /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib/Mathlib/Analysis/Calculus/Deriv/Comp.lean | grep -n \"variable\\|section\" | head -15",
"description": "Check Comp.lean variable declarations"
}
thinking (1512 chars)
`ContinuousLinearMap.hasDerivAt : HasDerivAt e (e 1) x` — for a CLM e, HasDerivAt e (e 1) x. For ofRealCLM: HasDerivAt ofRealCLM (ofRealCLM 1) x = HasDerivAt ofRealCLM 1 x (ofRealCLM 1 = ↑1 = 1 ✓ `ofRealCLM_apply` : ofRealCLM x = ↑x, so ofRealCLM 1 = 1 ✓).
So:
```
have hof : HasDerivAt (fun t : ℝ => (t : ℂ)) 1 y := by
have h := Complex.ofRealCLM.hasDerivAt (x := y)
rw [Complex.ofRealCLM_apply] at h
simpa using h
```
Hmm — `Complex.ofRealCLM.hasDerivAt (x := y)` — gives HasDerivAt ofRealCLM (ofRealCLM 1) y — ofRealCLM 1 = ↑1 = 1 — and ofRealCLM as a function = fun t => ↑t — simpa should align (ofRealCLM t = ↑t by ofRealCLM_apply ✓ simp lemma).
Then h1 : HasDerivAt (fun t : ℝ => (t : ℂ) * I) (1 * I) y := hof.mul_const I — `HasDerivAt.mul_const (hf : HasDerivAt f f' x) (c) : HasDerivAt (fun x => f x * c) (f' * c) x` — with f' = 1 : 1 * I = I ✓ simpa.
Then hconst.add h1 : HasDerivAt (fun t => x + t * I) (0 + I) y — simpa (0 + I = I) ✓.
And then in HIntegral_deriv: h1.comp x h2 with h1 : HasDerivAt G (deriv G (x+y*I)) (x+y*I), h2 : HasDerivAt (fun t => t + y*I) 1 x — comp: h₂ := G, h₂' := deriv G (x+y*I), h := (fun t => t + y*I), h' := 1: result HasDerivAt (G ∘ (fun t => t + y*I)) (deriv G (x+y*I) * 1) x — convert: (G ∘ path) x = G (x + y*I) ✓ and deriv*1 = deriv ✓ `convert this using 1; simp`.
Similarly VIntegral_deriv: h2 : HasDerivAt (fun t => x + t*I) I y — comp gives (G∘path) (deriv G (x+y*I) * I) ✓.
Also the `MapsTo` unknown — add `open Set`.
Let me apply all fixes.
`HasDerivAt.comp` supports the mixed ℝ→ℂ → ℂ→ℂ case via the algebra tower. Fixing the path-derivative lemmas and adding `open Set`.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiPrincipal.lean'\ns = open(p, encoding='utf-8').read()\n\ns = s.replace(\"open Zeta23 Complex Filter Topology\", \"open Zeta23 Complex Filter Topology Set\")\n\ns = s.replace(\"\"\"lemma hasDerivAt_add_const_I (y : \u211d) (x : \u211d) :\n HasDerivAt (fun t => t + y * I) 1 x := by\n have hid := hasDerivAt_id x\n have hconst : HasDerivAt (fun _ => y * I) 0 x := hasDerivAt_const x _\n convert hid.add hconst using 1\n simp\"\"\",\n\"\"\"lemma hasDerivAt_add_const_I (y : \u211d) (x : \u211d) :\n HasDerivAt (fun t : \u211d => t + y * I) 1 x := by\n have h := HasDerivAt.add (hasDerivAt_id x) (hasDerivAt_const x (y * I))\n simpa using h\"\"\")\n\ns = s.replace(\"\"\"lemma hasDerivAt_const_add_I (x y : \u211d) :\n HasDerivAt (fun t => x + t * I) I y := by\n have h1 : HasDerivAt (fun t => t * I) I y := by\n have := (hasDerivAt_id y).mul_const I\n simpa using this\n have hconst : HasDerivAt (fun _ => x) 0 y := hasDerivAt_const y x\n convert hconst.add h1 using 1\n simp\"\"\",\n\"\"\"lemma hasDerivAt_const_add_I (x y : \u211d) :\n HasDerivAt (fun t : \u211d => x + t * I) I y := by\n have hof : HasDerivAt (fun t : \u211d => (t : \u2102)) 1 y := by\n have h := Complex.ofRealCLM.hasDerivAt (x := y)\n simpa using h\n have h1 : HasDerivAt (fun t : \u211d => (t : \u2102) * I) I y := by\n have := hof.mul_const I\n simpa using this\n have h := HasDerivAt.add (hasDerivAt_const y x) h1\n simpa using h\"\"\")\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiPrincipal.lean 2>&1 | head -40",
"description": "Fix path derivative lemmas and recompile",
"timeout": 420000
}
thinking (6151 chars)
More issues:
1. Line 38: `(hasDerivAt_id x).add_const (y * I)` — hasDerivAt_id x is `HasDerivAt id 1 x` for the REAL x — but the elaborator expected `HasDerivAt ofReal 1 x` — because add_const's c := y*I : ℂ and f must map into ℂ: hasDerivAt_id x : HasDerivAt id 1 x with id : ℝ → ℝ — f' = 1 : ℝ, but add_const needs f' : ℂ. The target function fun t : ℝ => t + y*I : ℝ → ℂ — its derivative is (1 : ℂ) (the complex 1, from ↑t's derivative). So the identity must be the COMPLEX-valued identity: (fun t : ℝ => (t : ℂ)) = ofReal: `(hasDerivAt_id x).ofReal_comp`? or use ofRealCLM again:
```
lemma hasDerivAt_add_const_I (y : ℝ) (x : ℝ) :
HasDerivAt (fun t : ℝ => t + y * I) 1 x := by
have hof : HasDerivAt (fun t : ℝ => (t : ℂ)) 1 x := by
have h := Complex.ofRealCLM.hasDerivAt (x := x)
rw [Complex.ofRealCLM_apply] at h
exact h
have h := hof.add_const (y * I)
simpa using h
```
hof : HasDerivAt (fun t => ↑t) 1 x; .add_const (↑y*I) : HasDerivAt (fun t => ↑t + ↑y*I) 1 x ✓ and `fun t : ℝ => t + y * I` — t coerced: ↑t + ↑y*I ✓ simpa aligns.
2. Line 49: `h1.const_add x` — h1 : HasDerivAt (fun t => ↑t * I) I y — const_add x : HasDerivAt (fun t => x + ↑t*I) I y ✓ — error "?m.82 ?m.83 ?m.84" — const_add's elaboration issue — write explicit: `HasDerivAt.const_add x h1` — the error shows it expected `?m.82 ?m.83 ?m.84` — maybe const_add has the args flipped: `HasDerivAt.const_add (c : F) (hf : HasDerivAt f f' x)` ✓ as I used. The ?m suggests the dot form h1.const_add resolved to a wrong const_add (maybe a different namespace). Use explicit `HasDerivAt.const_add _ h1`? Hmm. Or: since x : ℝ and the function is fun t => ↑x + ↑t * I — the constant ↑x: `HasDerivAt.const_add (↑x) h1` — try that.
3. Line 64: `hasDerivAt_add_const_I y x` has type `HasDerivAt (fun t : ℝ => ↑t + ↑y * I) 1 x` but expected `HasDerivAt (fun x : ℂ => x + ↑y * I) 1 ↑x` — in HIntegral_deriv: `h2 : HasDerivAt (fun x => x + y * I) 1 x := hasDerivAt_add_const_I y x` — the GOAL's lambda `fun x => x + y * I` with x : ℝ — Lean elaborated x as ℂ (because comp expects h : ℂ → ℂ? NO — comp allows h : 𝕜 → 𝕜' = ℝ → ℂ ✓). The issue: my h2's stated type `HasDerivAt (fun x => x + y * I) 1 x` — the lambda `fun x => x + y * I` elaborated with x : ℂ (from the y * I : ℂ unification: x + (y*I) : ℂ forces x : ℂ!). The lemma hasDerivAt_add_const_I has domain ℝ. So in HIntegral_deriv I should write h2's lambda as `fun x : ℝ => x + y * I` — with x : ℝ, x + y*I coerces ↑x + ↑y*I ✓ matches hasDerivAt_add_const_I's statement ✓. Fix: h2 : HasDerivAt (fun x : ℝ => x + y * I) 1 x := hasDerivAt_add_const_I y x.
4. Line 65: h2 argument mismatch `?m.196 ?m.198 x` — cascade from h2's wrong elaboration.
5. Line 71: ContinuousWithinAt mismatch — `ContinuousAt.continuousWithinAt (hGc ...)` — continuousWithinAt needs the set as first explicit arg: `ContinuousAt.continuousWithinAt (h : ContinuousAt f x) : ContinuousWithinAt f s x` — the s is implicit, unified with (Set.uIcc z.re w.re) ✓ — the error shows type mismatch on the function: `deriv G` vs `fun x => deriv G (↑x + ↑y * I)` — the goal needs continuity of the COMPOSITE (fun x => deriv G (↑x+↑y*I)) at x within uIcc, but hGc gives continuity of deriv G at the POINT (x+y*I) (a plain point, not a set-neighborhood issue) — ContinuousAt (deriv G) (x+y*I) ⟹ ContinuousWithinAt (deriv G) (univ or any set) (x+y*I) — but I need continuity of the COMPOSITION x ↦ deriv G (x+y*I) — that needs the chain: ContinuousAt (fun x => deriv G (x+y*I)) x ⟸ ContinuousAt (deriv G) (x+y*I) + continuity of the path (x ↦ x+y*I) at x: `ContinuousAt.comp` — for continuous maps (any spaces): ContinuousAt.comp (hg : ContinuousAt g (f x)) (hf : ContinuousAt f x) : ContinuousAt (g ∘ f) x ✓ exists (topology). So:
```
intro x hx
have hpath : ContinuousAt (fun x : ℝ => x + y * I) x := by
have hof : ContinuousAt (fun t : ℝ => (t : ℂ)) x := Complex.continuous_ofReal.continuousAt
exact hof.add_const (y * I) -- hmm ContinuousAt.add_const exists? for continuous: `ContinuousAt.add_const`? there's `ContinuousAt.add_const`? or (hof.add (continuousAt_const))
exact (hGc _ (hmap hx)).comp hpath |>.continuousWithinAt
```
`Complex.continuous_ofReal : Continuous ofReal` ✓ exists. ContinuousAt.add_const : ContinuousAt f x → ContinuousAt (fun x => f x + c) x ✓ exists.
Hmm — this is getting deep. The cleaner overall approach for hint: G is differentiable at every border point; differentiability ⟹ continuity of G AND of deriv G on an OPEN neighborhood of each border point (since differentiability at a point in ℂ gives a whole neighborhood? NO — differentiability at a point only gives continuity at that point, but deriv G exists only where G is differentiable... For our SPECIFIC G (rational in (w−1)), deriv G is CONTINUOUS off {1} directly. My hypothesis hGc : ∀ s ∈ border, ContinuousAt (deriv G) s — the composite needs path composition. It's fine — one more composition lemma.
Actually — simpler: strengthen to `ContinuousOn (deriv G) (border)`? No wait — I still need the composite's ContinuousOn over uIcc, which = (deriv G) ∘ path with path mapping uIcc → border: ContinuousOn.comp — let me restructure hint via ContinuousOn.comp:
```
have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) volume z.re w.re := by
apply ContinuousOn.intervalIntegrable
have hcon : ContinuousOn (deriv G) (RectangleBorder z w) := by
intro s hs
exact (hGc s hs).continuousWithinAt
have hpath : ContinuousOn (fun x : ℝ => x + y * I) (Set.uIcc z.re w.re) := by
apply Continuous.continuousOn
have hof : Continuous (fun t : ℝ => (t : ℂ)) := Complex.continuous_ofReal
exact hof.add_const (y * I)
exact hcon.comp hpath (by intro x hx; exact hmap hx)
```
ContinuousOn.comp (hg : ContinuousOn g t) (hf : ContinuousOn f s) (h : MapsTo f s t) : ContinuousOn (g ∘ f) s ✓ exists. And Continuous.add_const : Continuous f → Continuous (fun x => f x + c) ✓ exists.
Same for VIntegral_deriv's hint.
Let me apply these fixes: hasDerivAt_add_const_I (ofReal version), const_add explicit, h2 lambda annotations (fun x : ℝ), hint restructure via ContinuousOn.comp for both H and V.
The composite continuity needs `ContinuousOn.comp`, and the identity needs the complex-valued form. Rewriting the affected blocks.
tool: Bash ok
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiPrincipal.lean'\ns = open(p, encoding='utf-8').read()\n\ns = s.replace(\"\"\"lemma hasDerivAt_add_const_I (y : \u211d) (x : \u211d) :\n HasDerivAt (fun t : \u211d => t + y * I) 1 x := by\n simpa using (hasDerivAt_id x).add_const (y * I)\"\"\",\n\"\"\"lemma hasDerivAt_add_const_I (y : \u211d) (x : \u211d) :\n HasDerivAt (fun t : \u211d => t + y * I) 1 x := by\n have hof : HasDerivAt (fun t : \u211d => (t : \u2102)) 1 x := by\n have h := Complex.ofRealCLM.hasDerivAt (x := x)\n rw [Complex.ofRealCLM_apply] at h\n exact h\n have h := hof.add_const (y * I)\n simpa using h\"\"\")\n\ns = s.replace(\"\"\" have h1 : HasDerivAt (fun t : \u211d => (t : \u2102) * I) I y := by\n have := hof.mul_const I\n simpa using this\n have h := h1.const_add x\n simpa using h\"\"\",\n\"\"\" have h1 : HasDerivAt (fun t : \u211d => (t : \u2102) * I) I y := by\n have := hof.mul_const I\n simpa using this\n have h := HasDerivAt.const_add x h1\n simpa using h\"\"\")\n\n# HIntegral_deriv: annotate h2's lambda domain and fix hint\ns = s.replace(\"\"\" have h2 : HasDerivAt (fun x => x + y * I) 1 x := hasDerivAt_add_const_I y x\n have hcomp := h1.comp x h2\n convert hcomp using 1\n simp\n have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) volume z.re w.re := by\n apply ContinuousOn.intervalIntegrable\n intro x hx\n exact (hGc _ (hmap hx)).continuousWithinAt\"\"\",\n\"\"\" have h2 : HasDerivAt (fun x : \u211d => x + y * I) 1 x := hasDerivAt_add_const_I y x\n have hcomp := h1.comp x h2\n convert hcomp using 1\n simp\n have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) MeasureTheory.volume z.re w.re := by\n apply ContinuousOn.intervalIntegrable\n have hcon : ContinuousOn (deriv G) (RectangleBorder z w) := by\n intro s hs\n exact (hGc s hs).continuousWithinAt\n have hpath : ContinuousOn (fun x : \u211d => x + y * I) (Set.uIcc z.re w.re) := by\n apply Continuous.continuousOn\n have hof : Continuous (fun t : \u211d => (t : \u2102)) := Complex.continuous_ofReal\n exact hof.add_const (y * I)\n exact hcon.comp hpath (by intro x hx; exact hmap hx)\"\"\")\n\n# VIntegral_deriv: fix hint similarly\ns = s.replace(\"\"\" have hint : IntervalIntegrable (fun y => I * deriv G (x + y * I)) MeasureTheory.volume z.im w.im := by\n apply ContinuousOn.intervalIntegrable\n intro y hy\n exact ContinuousWithinAt.mul continuousWithinAt_const\n ((hGc _ (hmap hy)).continuousWithinAt)\"\"\",\n\"\"\" have hint : IntervalIntegrable (fun y => I * deriv G (x + y * I)) MeasureTheory.volume z.im w.im := by\n apply ContinuousOn.intervalIntegrable\n have hcon : ContinuousOn (deriv G) (RectangleBorder z w) := by\n intro s hs\n exact (hGc s hs).continuousWithinAt\n have hpath : ContinuousOn (fun y : \u211d => x + y * I) (Set.uIcc z.im w.im) := by\n apply Continuous.continuousOn\n have hof : Continuous (fun t : \u211d => (t : \u2102)) := Complex.continuous_ofReal\n have hmul : Continuous (fun t : \u211d => (t : \u2102) * I) := hof.mul_const I\n exact hmul.const_add x\n have hcomp : ContinuousOn (fun y : \u211d => I * deriv G (x + y * I)) (Set.uIcc z.im w.im) := by\n apply ContinuousOn.mul continuousOn_const\n exact hcon.comp hpath (by intro y hy; exact hmap hy)\n exact hcomp\"\"\")\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiPrincipal.lean 2>&1 | head -40",
"description": "Apply fixes round 3 and recompile",
"timeout": 420000
}
result 2026-08-21 21:40:49Z → 2026-08-26 21:17:51Z
R-004-finite-height-li-theorem.md # R-004 — Explicit finite-height Li theorem: λ_n > 0 for all n ≤ (T₀−1)² = 8.999…×10²⁴ Date: 2026-08-19 | Session: 008 | Track: C (task 3.8) Tag: **[PROVED-CONDITIONAL(computational RH-to-height-T₀; computational finite verification)]** — R-bound FULLY TRACED 2026-08-19 (D-056, task 4.5a: reference-point method, A = 10.5, B₀ = 48 with the honest C₀ incl. log log term; digamma remainder 1.2/|w|² proved; E-028 verified, 26× slack); N₀ = 80 000 (6.25× overlap with Misguich–Voros). M₀ remains grid-verified (E-023 S1; additive ~53). Margin convexity: PROVED (D-057, task 4.5b; E-029 ALL CHECKS PASS). History: tag downgraded then restored same day (D-054 erratum: broken D-039/D-036-§1 proofs; repairs D-056–D-059). ## Statement Let λ_n = Σ′_ρ [1−(1−1/ρ)ⁿ] be the Li coefficients of the Riemann zeta function. Assume the Riemann hypothesis verified to height T₀ = 3×10¹² (Platt–Trudgian 2021, interval arithmetic). Then **λ_n > 0 for every 1 ≤ n ≤ N₁ := (T₀−1)² = 8 999 999 999 994 000 000 000 001 ≈ 9.0×10²⁴.** Conservative variant (using Lagarias's printed bridge window (1.16) instead of the traced proof): N₁* = T₀²/(4 log²T₀) = 2.726×10²¹. This is the first assembled EXPLICIT finite-height Li bound: the chain "RH to height T₀ + fully traced constants ⟹ λ_n > 0 to n ~ T₀²" existed
thinking (7149 chars)
The same errors persist in a pattern: the elaborator is unifying the lambdas' domain with ℂ instead of ℝ. Key insight: `HasDerivAt.const_add x h1` fails — const_add's signature: `HasDerivAt.const_add (c : F) (hf : HasDerivAt f f' x) : HasDerivAt (fun x => c + f x) f' x` — hmm, the error `?m.82 ?m.83 ?m.84` — the x : ℝ and h1's domain ℝ — maybe const_add's c must be in the same space F = ℂ — x : ℝ cast to ℂ ✓ should coerce... The `?m.82` suggests HasDerivAt.const_add isn't resolving its type arguments from h1 — maybe const_add has signature `HasDerivAt.const_add (c : F) (hf : HasDerivAt f f' x)` with F implicit — h1 : HasDerivAt (fun t => ↑t * I) I y — F = ℂ ✓ f = fun t => ↑t*I, f' = I, x = y ✓ — should unify... unless the elaborator tries to unify the RESULT `fun x => c + f x` with something first and gets stuck. The pattern of failures `?m.N ?m.N ?m.N` for all these suggests the elaborator is struggling with the generic HasDerivAt form.
Line 69's error is the tell: `hasDerivAt_add_const_I y x : HasDerivAt (fun t : ℝ => ↑t + ↑y * I) 1 x` but expected `HasDerivAt (fun x : ℂ => x + ↑y * I) 1 ↑x` — the GOAL (in HIntegral_deriv's h2) has `fun x => x + y * I` with x elaborated as ℂ! So my h2 statement's lambda `fun x : ℝ => x + y * I`... wait I FIXED that to `fun x : ℝ => x + y * I` — did the replacement apply? The error at 69:53 says the expected type is `HasDerivAt (fun (x : ℂ) => ...)` — so the h2 statement STILL has the unannotated lambda — my replacement targeted `have h2 : HasDerivAt (fun x => x + y * I) 1 x := hasDerivAt_add_const_I y x` — and replaced with `fun x : ℝ => ...` — but the error persists, meaning the replacement didn't match (maybe the text had different whitespace). Let me check the current file state around those lines. Actually the error at 69:53 shows `hasDerivAt_add_const_I y x has type ... but expected HasDerivAt (fun (x : ℂ) => x + ↑y * I) 1 ↑x` — so the h2 line still elaborates the lambda at ℂ. My replace string must not have matched. Let me check.
Also the deeper issue at 76/77: `hint` has type IntervalIntegrable (fun x => deriv G (↑x + ↑y * I)) but expected IntervalIntegrable (deriv ?m) — the FTC lemma `intervalIntegral.integral_deriv_eq_sub hd hint` — its signature: `integral_deriv_eq_sub (h : ∀ x ∈ uIcc a b, HasDerivAt f (f' x) x) (h' : IntervalIntegrable f' volume a b) : ∫ f' = f b - f a` — the hint must be about f' where f' is the SAME function named in hd. hd : ∀ x ∈ uIcc, HasDerivAt (fun x => G (x + y*I)) (deriv G (x + y*I)) x — so f' := fun x => deriv G (x + y*I) ✓ and hint's type matches that ✓. The error says expected `IntervalIntegrable (deriv ?m.256)` — so Lean unified f' := deriv ?m — because hd's HasDerivAt gave f' := deriv G (x+y*I) and the elaborator unified f' with `deriv ?m` form?? — the HasDerivAt in hd has derivative VALUE `deriv G (x + y*I)` which is an APPLICATION deriv G (x+y*I) — Lean tried to match it as `deriv ?m ?x`?? — that would set ?m := G and then hint needs IntervalIntegrable (deriv G) — mismatch with my hint's composite form. AH — the issue: my hd has `HasDerivAt (fun x => G (x + y * I)) (deriv G (x + y * I)) x` — Lean unified the derivative slot with the PATTERN deriv ?f ?x — no wait, HasDerivAt's second arg is the derivative VALUE, any term: deriv G (x+y*I) is fine as a value. Then integral_deriv_eq_sub hd hint expects hint : IntervalIntegrable (fun x => deriv G (x + y*I)) — and mine has exactly that — the error shows expected `IntervalIntegrable (deriv ?m.256)` — hmm ?m.256 — the elaborator unified the derivative as `deriv ?m` — meaning somewhere it pattern-matched `deriv G (x + y*I)` as `deriv ?m.256 ?x` with ?m.256 := G — but then hint needs IntervalIntegrable (deriv G) — while mine is the composite. This happens because integral_deriv_eq_sub's f' is determined by hd's derivative slot — which is the APPLICATION deriv G (x+y*I) — the elaborator unified f' := fun x => deriv G (x+y*I) correctly... but the error shows deriv ?m.256 as a bare function. Maybe the issue: my hd's derivative is written `deriv G (x + y * I)` and Lean's elaboration of `deriv G` — `deriv (fun w => G w)` — fine. Hmm — actually looking again: the error at 77:57 says hint has type `IntervalIntegrable (fun x => deriv G (↑x + ↑y * I)) ...` but expected `IntervalIntegrable (deriv ?m.256) ...` — so integral_deriv_eq_sub's hint slot unified f' := deriv ?m.256 (a bare deriv of an unknown function). That's because hd's derivative slots were unified as `deriv ?m.256 x` — the HasDerivAt's derivative value `deriv G (x + y*I)` got unified as `deriv ?m x` with ?m := G — i.e., Lean PREFERED to unify the derivative slot with the deriv-APPLICATION FORM rather than as an opaque value. That comes from `intervalIntegral.integral_deriv_eq_sub`'s signature: `(h : ∀ x ∈ uIcc a b, HasDerivAt f (f' x) x)` — when applying with my hd, f' is unified pointwise: f' x =?= deriv G (x + y*I) — the elaborator chose f' := deriv G and x := x + y*I?? — eta-expansion: f' x = (deriv G) (x+y*I) with f' := deriv G ∘ (· + y*I)... Lean's unification picked f' := deriv ?m.256 and the point as x — getting confused. The robust fix: make hd's derivative slot syntactically a plain application of a named function: introduce `G' := fun s => deriv G s`? — or name the derivative function: `let Gp := fun s => deriv G s`. Then hd : HasDerivAt P (Gp (x+y*I)) x — and hint : IntervalIntegrable (fun x => Gp (x+y*I)) — both about Gp explicitly — unification clean.
Hmm — actually simpler: avoid integral_deriv_eq_sub's unification entirely by using `intervalIntegral.integral_eq_sub_of_hasDerivAt (h : HasDerivAt f (f' x) x) (hint : IntervalIntegrable f')`?? — or the version with the derivative as a function: `intervalIntegral.integral_eq_sub_of_hasDerivAt (hderiv : ∀ x ∈ uIcc, HasDerivAt G (G' x) x) (hcont : ContinuousOn G' (uIcc a b))` — there's `intervalIntegral.integral_eq_sub_of_hasDerivAt` which takes G' CONTINUOUS (no integrability arg): `integral_eq_sub_of_hasDerivAt (h : ∀ x ∈ uIcc a b, HasDerivAt f (f' x) x) (h' : ContinuousOn f' (uIcc a b)) : ∫ x in a..b, f' x = f b - f a` ✓ that exists I believe. With f' := fun x => deriv G (x + y*I) made explicit in both — the unification issue remains unless the derivative function is a named atom.
Cleanest: define the side derivative function explicitly:
```
set Gp : ℂ → ℂ := fun s => deriv G s
```
Then hd : ∀ x ∈ uIcc, HasDerivAt (fun x => G (x + y*I)) (Gp (x + y*I)) x and hint/continuity about (fun x => Gp (x+y*I)). The unification of f' := fun x => Gp (x+y*I) works compositionally.
Actually — the real fix is simpler: the FTC application should be `intervalIntegral.integral_deriv_eq_sub hd hint` with hint's type EXACTLY matching `IntervalIntegrable (fun x => deriv G (x + y*I))` — which it is! The error might be that integral_deriv_eq_sub's elaboration, given hd FIRST (which pins f' via HasDerivAt's second slot), has trouble. Let me pass the functions explicitly: `intervalIntegral.integral_deriv_eq_sub (f := fun x => G (x + y * I)) (f' := fun x => deriv G (x + y * I)) hd hint` — explicit f/f' args (if they're explicit — check signature). Let me check integral_deriv_eq_sub's exact signature.
The FTC unification needs explicit function arguments. Let me check the exact signature.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem intervalIntegral.integral_deriv_eq_sub\\|theorem intervalIntegral.integral_eq_sub_of_hasDerivAt\" Mathlib/ --include=*.lean | head -4; grep -A4 \"theorem intervalIntegral.integral_deriv_eq_sub \" Mathlib/MeasureTheory/Integral/FundThmCalculus.lean 2>/dev/null | head -8; grep -rn \"theorem intervalIntegral.integral_deriv_eq_sub \" Mathlib/ --include=*.lean -A3 | head -8",
"description": "Check integral_deriv_eq_sub signature"
}
thinking (754 chars)
`intervalIntegral.integral_eq_sub_of_hasDerivAt (hderiv : ∀ x ∈ uIcc a b, HasDerivAt f (f' x) x) (hint : IntervalIntegrable f' volume a b) : ∫ y in a..b, f' y = f b - f a` — this is the right lemma (the one I was using under the wrong name `integral_deriv_eq_sub` — which is a different lemma for real functions!). Note `integral_deriv_eq_sub (hderiv : ∀ x ∈ [[a,b]], DifferentiableAt ℝ f x)` at line 1176 — that's the ABS-continuity real version. So use `integral_eq_sub_of_hasDerivAt` with explicit f/f' — the f/f' are implicit {f f'} presumably — pass explicitly: `intervalIntegral.integral_eq_sub_of_hasDerivAt (f := fun x => G (x + y * I)) (f' := fun x => deriv G (x + y * I)) hd hint`.
Let me fix both FTC applications with explicit function args.
Found it — I need `integral_eq_sub_of_hasDerivAt` (not `integral_deriv_eq_sub`) with explicit function arguments.
tool: Bash ok
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiPrincipal.lean'\ns = open(p, encoding='utf-8').read()\n\ns = s.replace(\"\"\" have hftc := intervalIntegral.integral_deriv_eq_sub hd hint\n convert hftc using 1\n \u00b7 simp\n \u00b7 simp\"\"\",\n\"\"\" have hftc := intervalIntegral.integral_eq_sub_of_hasDerivAt\n (f := fun x => G (x + y * I)) (f' := fun x => deriv G (x + y * I)) hd hint\n convert hftc using 1\n \u00b7 simp\n \u00b7 simp\"\"\")\n\ns = s.replace(\"\"\" have hftc := intervalIntegral.integral_deriv_eq_sub hd hint\n rw [\u2190 hftc, integral_smul]\n field_simp [Complex.I_ne_zero]\"\"\",\n\"\"\" have hftc := intervalIntegral.integral_eq_sub_of_hasDerivAt\n (f := fun y => G (x + y * I)) (f' := fun y => I * deriv G (x + y * I)) hd hint\n rw [\u2190 hftc, integral_smul]\n field_simp [Complex.I_ne_zero]\"\"\")\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiPrincipal.lean 2>&1 | head -40",
"description": "Use correct FTC lemma with explicit args",
"timeout": 420000
}
result 2026-08-21 21:43:04Z → 2026-08-24 20:43:37Z
done NguyenRH1/LiTightR.lean:3593:36: error: unexpected token '/--'; expected ':=' NguyenRH1/LiTightR.lean:3592:2: error: invalid 'calc' step, relation expected ?m.236 NguyenRH1/LiTightR.lean:3570:46: error: unsolved goals case neg t : ℝ ht : 10 ≤ t k : ℕ hk : ¬⌊t⌋₊ + 1 ≤ k ⊢ farGRightMaj t k ≤ farGRightMajCombo k NguyenRH1/LiTightR.lean:3674:35: error: unsolved goals t : ℝ ht : 10 ≤ t hsplit : ∑' (k : ℕ), farGRightMaj t k = ∑ k ∈ Finset.range 11, farGRightMaj t k + ∑' (k : ℕ), farGRightMaj t (k + 11) k : ℕ hk : k < 11 ⊢ 10 ≤ t NguyenRH1/LiTightR.lean:3678:5: error: (deterministic) timeout at `whnf`, maximum number of heartbeats (200000) has been reached Note: Use `set_option maxHeartbeats <num>` to set the limit.
thinking (1127 chars)
The pervasive issue: my hd's lambda `fun x => G (x + y * I)` is being elaborated with x : ℂ (because G : ℂ → ℂ forces the argument to be ℂ), but the parametrization needs x : ℝ (with coercion). The lambda `fun x => G (x + y * I)` — G's argument must be ℂ, so x : ℂ! Of course — I need to write `fun x : ℝ => G (↑x + ↑y * I)` — the lambda domain annotation x : ℝ makes the coercion explicit. That's the root of ALL these mismatches: the parametrized function must be `fun x : ℝ => G (x + y * I)` where x : ℝ and (x + y*I) coerces — but writing G (x + y*I) with x : ℝ requires the coercion — Lean inserts it: G (↑x + ↑y * I) ✓. So in hd, h2, the FTC f/f' args — ALL lambdas must be annotated (x : ℝ).
Fixes:
1. hd's statement: `HasDerivAt (fun x : ℝ => G (x + y * I)) (deriv G (x + y * I)) x` — with x : ℝ annotated ✓.
2. h2: `HasDerivAt (fun x : ℝ => x + y * I) 1 x` — already annotated? The error at 69 says expected `(fun (x : ℂ) => ...)` — so the h2 in the file still has the unannotated form. My earlier replacement didn't match. Let me look at the actual file content for these lines and fix them all by direct line edits.
The root issue is now clear: every parametrized lambda needs explicit `(x : ℝ)` annotations. Let me look at the current state and fix them all directly.
tool: Read ok
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiPrincipal.lean",
"offset": 42,
"limit": 80
}
result 2026-08-21 21:43:48Z → 2026-08-25 05:28:45Z
{
"type": "text",
"file": {
"filePath": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiContour.lean",
"content": "\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. The unit ordinate window and the perimeter count hypothesis -/\n\n/-- The nontrivial zeros with ordinate in the unit window [a, a+1]. -/\ndef zeroWindow (a : \u211d) : Set \u2102 :=\n {\u03c1 | IsNontrivialZero \u03c1 \u2227 a \u2264 \u03c1.im \u2227 \u03c1.im \u2264 a + 1}\n\n/-- Finiteness of the unit ordinate window (via Zeta23 `zerosIn_finite`). -/\ntheorem zeroWindow_finite (a : \u211d) : (zeroWindow a).Finite := by\n apply Set.Finite.subset (zerosIn_finite (a - 1) (a + 1))\n intro \u03c1 h\u03c1\n refine \u27e8h\u03c1.1, ?_, h\u03c1.2.2\u27e9\n linarith [h\u03c1.2.1]\n\n/-- A nontrivial zero has multiplicity \u2265 1 (zeroMult is the analytic\norder). Bridges the mult-weighted perimeter count to the plain window\ncardinality (card \u2264 \u03a3 mult). -/\ntheorem one_le_zeroMult {\u03c1 : \u2102} (h\u03c1 : IsNontrivialZero \u03c1) : 1 \u2264 zeroMult \u03c1 := by\n have h\u03c11 : \u03c1 \u2260 1 := by\n rintro rfl\n have h := h\u03c1.2.2\n rw [Complex.one_re] at h\n exact (lt_irrefl (1 : \u211d)) h\n have htop := zeta_order_ne_top_of_ne h\u03c11\n have hne : analyticOrderAt riemannZeta \u03c1 \u2260 0 :=\n (analyticAt_riemannZeta h\u03c11).analyticOrderAt_ne_zero.mpr h\u03c1.1\n exact ENat.toNat_pos hne htop\n\n/-- [PERIMETER \u2014 Trudgian 2014 N(T)/S(T), D-062 \u00a74] The unit-window\nzero-count bound: the multiplicity-weighted count of nontrivial zeros\nwith ordinates in [t, t+1] is at most \u0108\u2080(t+1) (t \u2265 2). Declared\ncounting input for the L3 pigeonhole and the tight R-bound; \u0108\u2080 =\n`C0hat` is D-056 \u00a72's honest majorant (LiSkeleton).\n[Erratum 2026-08-23 (session 035): strengthened from the unweighted\nset-card form `(Nat.card (zeroWindow t) : \u211d) \u2264 \u0108\u2080(t+1)` to the\nmult-weighted form \u2014 Trudgian's N(T) counts zeros with multiplicity,\nand the mult-weighted form is what the 5f/ii\u2032-6 near sums\n(zeroMult-weighted, from `seriesFun`) consume; the set-card encoding\nunder-captured the declared source (a second ii\u2032-1a-class encoding\ndefect, found at the point of consumption). The set-card bound follows\nfrom this form via `one_le_zeroMult` (card \u2264 \u03a3 mult); the two\nconsumers (exists_zero_avoiding_T, exists_gapCircle_radius) adapted.] -/\ndef ZeroCountProp : Prop :=\n \u2200 t : \u211d, 2 \u2264 t \u2192\n (((zeroWindow_finite t).toFinset.sum fun \u03c1 => zeroMult \u03c1) : \u211d) \u2264 C0hat (t + 1)\n",
"numLines": 50,
"startLine": 40,
"totalLines": 647
}
}
thinking (4734 chars)
Now I can see the file state clearly. The issues:
1. Line 54: `HasDerivAt.const_add x h1` — h1 : HasDerivAt (fun t : ℝ => ↑t * I) I y — const_add's expected form `?m.82 ?m.83 ?m.84` — the dot/explicit application issue. Let me check HasDerivAt.const_add's actual signature — maybe it's `HasDerivAt.const_add (c : F) (hf : HasDerivAt f f' x) : HasDerivAt (fun x => c + f x) f' x`? The error `?m.82 ?m.83 ?m.84` — maybe it's actually `HasDerivAt.const_add (c) (hf)` but the metavariables come from h1's `↑t * I` elaboration — the `↑t` is a coercion `Complex.ofReal t` — h1's function displays as `fun t => ↑t * I` ✓ that's fine as a concrete function. The `?m` in the error is Lean failing to elaborate `HasDerivAt.const_add x h1` — perhaps const_add takes (c) as the FIRST explicit arg and my x : ℝ needs to be ℂ: `HasDerivAt.const_add (↑x) h1`? Let me write `(↑x : ℂ)`.
Hmm wait — actually the issue may be `HasDerivAt.const_add` doesn't exist with that exact name — from the STATE handoff gotcha: "HasDerivAt.add_const adds to VALUE (use .comp for precomposition)" — so `HasDerivAt.add_const` exists. Is `HasDerivAt.const_add` the right name for the other side? There's `HasDerivAt.const_add (c : F) (hf : HasDerivAt f f' x) : HasDerivAt (fun x => c + f x) f' x` — I believe it exists. The error pattern `?m.82 ?m.83 ?m.84` — the elaborator couldn't determine the implicit {F} — because h1's type `HasDerivAt (fun t => ↑t * I) I y` — the `I` is the DERIVATIVE VALUE (f' := I : ℂ) and the point y : ℝ. For const_add: F = ℂ, f = (fun t => ↑t * I), f' = I, x = y ✓ should unify... unless h1's type isn't what I think — `hof.mul_const I` gave `HasDerivAt (fun t => (↑t) * I) (1 * I) y` and simpa reduced to `... I y`. Fine.
Let me just try `HasDerivAt.const_add (↑x : ℂ) h1`.
2. Line 69: `h2 : HasDerivAt (fun x => x + y * I) 1 x := hasDerivAt_add_const_I y x` — the lambda `fun x => x + y * I` — with NO domain annotation, the elaborator picks ℂ (since the expected type from... nothing pins it to ℝ — the hasDerivAt_add_const_I provides (fun t : ℝ => t + y*I) but the ASSIGNMENT `have h2 : T := proof` — the stated type T has `fun x => x + y*I` unannotated → elaborated independently → x : ℂ (because y*I : ℂ forces x : ℂ via +). FIX: annotate `fun x : ℝ => x + y * I`.
3. Line 65: same issue in hd's lambda: `fun x => G (x + y * I)` — G : ℂ → ℂ forces x : ℂ. FIX: `fun x : ℝ => G (x + y * I)`.
4. Line 92: same in VIntegral_deriv's hd: `fun y => G (x + y * I)` — annotate `fun y : ℝ => G (x + y * I)`.
5. Line 96: h2 : HasDerivAt (fun y => x + y * I) I y — annotate `fun y : ℝ => x + y * I`.
6. Line 70/97: `h1.comp x h2` — the comp's h must be the path fun x : ℝ => x + y*I ✓ after annotation; and HasDerivAt.comp's mixed signature handles ℝ→ℂ then ℂ→ℂ ✓. But `convert hcomp using 1; simp` — the goal HasDerivAt (fun x : ℝ => G (x+y*I)) (deriv G (x+y*I)) x vs hcomp : HasDerivAt (G ∘ (fun x : ℝ => x+y*I)) (deriv G (x+y*I) * 1) x — convert using 1: (G ∘ path) = (fun x => G (x+y*I)) ✓ comp_apply; deriv*1 = deriv ✓ simp [mul_one, Function.comp_apply].
7. Line 73's hint (H-side): `intro x hx; exact (hGc _ (hmap hx)).continuousWithinAt` — the ContinuousAt.continuousWithinAt's set: needs the composite's continuity! My earlier restructure to ContinuousOn.comp didn't get applied to the H-side (line 73-76 still has the old form — my replacement only changed the V-side hint? Looking at the file: H-side hint (line 73-76) has the OLD simple form (intro x hx; exact (hGc _ (hmap hx)).continuousWithinAt) — wrong (continuity of deriv G at the point vs continuity of the composite). And V-side hint (100-113) has the new hcon/hpath form. Fix H-side hint like V-side (without the I factor):
```
have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) MeasureTheory.volume z.re w.re := by
apply ContinuousOn.intervalIntegrable
have hcon : ContinuousOn (deriv G) (RectangleBorder z w) := by
intro s hs
exact (hGc s hs).continuousWithinAt
have hpath : ContinuousOn (fun x : ℝ => x + y * I) (Set.uIcc z.re w.re) := by
apply Continuous.continuousOn
have hof : Continuous (fun t : ℝ => (t : ℂ)) := Complex.continuous_ofReal
exact hof.add_const (y * I)
exact hcon.comp hpath (by intro x hx; exact hmap hx)
```
`Continuous.add_const : Continuous f → Continuous (fun x => f x + c) x` ✓.
8. The MapsTo application hmap hx: `hmap hx` — MapsTo f s t : ∀ ⦃x⦄, x ∈ s → f x ∈ t — the binders are instance-implicit: `hmap hx` works (hmap applied to the proof) ✓.
9. hint's ContinuousOn.intervalIntegrable — signature: `ContinuousOn.intervalIntegrable (h : ContinuousOn f (uIcc a b)) : IntervalIntegrable f volume a b` ✓.
Let me apply all these fixes with Edit tool (precise replacements).
Now I see all the issues clearly — the lambdas need `: ℝ` domain annotations and the H-side hint needs the composite-continuity form. Fixing precisely.
tool: Edit
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiPrincipal.lean",
"old_string": " have h := HasDerivAt.const_add x h1\n simpa using h",
"new_string": " have h := HasDerivAt.const_add (\u2191x : \u2102) h1\n simpa using h"
}
thinking (7266 chars)
Down to a handful of errors:
1. Line 72 (HIntegral_deriv hd): `convert hcomp using 1; simp` — "simp made no progress". The goal after convert: HasDerivAt (fun x : ℝ => G (x+y*I)) (deriv G (x+y*I)) x vs hcomp : HasDerivAt (G ∘ (fun x : ℝ => x+y*I)) (deriv G (x+y*I) * 1) x. convert using 1 left some goal that simp can't close. Fix: `convert hcomp using 1` produces goals: (fun x : ℝ => G (x+y*I)) = G ∘ (fun x : ℝ => x+y*I) and deriv G (x+y*I) = deriv G (x+y*I)*1. First: funext/Function.comp_apply rfl-ish: `simp [Function.comp_apply]`? or the goal order flipped. Let me instead do:
```
have hcomp := h1.comp x h2
rw [Function.comp_apply, mul_one] at hcomp
exact hcomp
```
hcomp : HasDerivAt (G ∘ path) (deriv G (x+y*I) * 1) x — Function.comp_apply : (g ∘ f) x = g (f x) — rewrites the function application; but hcomp's function is (G ∘ path) as a whole — rw [Function.comp_apply] at hcomp needs an application point... the function in HasDerivAt is (G ∘ path) — comp_apply applies to (G∘path) x but hcomp has it unapplied. Use `simp only [Function.comp_apply, mul_one] at hcomp` — comp_apply as simp lemma rewrites (G∘path) ?x → G (path ?x) — should work on the unapplied... Actually HasDerivAt's first arg is the function — simp only [Function.comp_apply] normalizes `(G ∘ path) x` occurrences but the bare function... Alternative: `simpa using hcomp` (simpa with comp_apply + mul_one): `simpa [Function.comp_apply] using hcomp` — simpa normalizes hcomp's type (G∘path → G∘path applications) and matches the goal. Let me use:
```
have hcomp := h1.comp x h2
simpa [Function.comp_apply] using hcomp
```
Same for V-side with mul I: `simpa [Function.comp_apply] using hcomp` — hcomp : HasDerivAt (G∘path) (deriv G (x+y*I) * I) y — goal: HasDerivAt (fun y : ℝ => G (x+y*I)) (I * deriv G (x+y*I)) y — the derivative value: deriv G * I vs I * deriv G — need mul_comm! The comp gives h₂' * h' = deriv G (x+y*I) * I; goal has I * deriv G (x+y*I) — `simpa [Function.comp_apply, mul_comm] using hcomp` or restructure the goal to deriv G * I. Let me change the V-side's hd target to `(deriv G (x + y * I)) * I` and adjust the final assembly (the FTC then gives ∫ deriv G * I directly matching hftc's I * ... hmm — cleaner: keep the comp result and change hint/final to match: hftc gives ∫ (fun y => I * deriv G (x+y*I)) — wait hftc's f' = fun y => I * deriv G (x+y*I) — the comp gives derivative value deriv G * I — for the FTC's f' I wrote fun y => I * deriv G (x+y*I) — MISMATCH (I*X vs X*I — equal by mul_comm but syntactically different — the explicit f' arg fixes it: f' := fun y : ℝ => I * deriv G (x + y * I) ✓ and hd must have derivative values I * deriv G (x+y*I) — from comp with mul_comm:
```
have hcomp := h1.comp y h2
rw [mul_comm] at hcomp -- deriv G (x+y*I) * I → I * deriv G (x+y*I)
simpa [Function.comp_apply] using hcomp
```
2. Line 86 "No goals to be solved" — line 86 is in HIntegral_deriv's hftc convert block: `convert hftc using 1; · simp; · simp` — the FIRST simp closed both?? or the convert produced 0 goals and the bulleted simps error. hftc : ∫ (fun x => deriv G (x+y*I)) = G (w.re+y*I) − G (z.re+y*I) — wait the FTC gives f b − f a = G (w.re + y*I) − G (z.re + y*I) ✓ and the goal: ∫ x in z.re..w.re, deriv G (x+y*I) = G (w.re+y*I) − G (z.re+y*I) — these should match exactly after the explicit f/f' — the integrals: ∫ x in z.re..w.re, (fun x => deriv G (x+y*I)) x vs ∫ x in z.re..w.re, deriv G (↑x+↑y*I) — beta: the FTC's statement has f' y applied — should be defeq-identical. The convert using 1 with two simps — the second simp has no goals. Just use `exact hftc` (after checking the statement matches) or `convert hftc using 1` alone. Let me simplify to:
```
convert hftc using 2
```
hmm — or just `simpa using hftc`. Let me use simpa for both sides' final steps.
3. Line 105 `ring_nf made no progress` — V-side hcomp's `convert hcomp using 1; ring` — replaced by simpa approach.
4. Line 122: `integral_smul` unknown — for interval integrals it's `intervalIntegral.integral_smul`? or `MeasureTheory.integral_smul`? For ∫ over sets/intervals: `intervalIntegral.integral_smul (c) (f) : ∫ x in a..b, c • f x = c • ∫ x in a..b, f x`? or `integral_smul` in MeasureTheory — the generic `MeasureTheory.integral_smul`? The name for ∫ (c • f) = c • ∫ f: `integral_smul` should exist in MeasureTheory.Integral.Bochner — maybe namespaced: `MeasureTheory.integral_smul`? or for interval: `intervalIntegral.integral_smul`? Let me handle the constant differently: ∫ I * deriv G = I * ∫ deriv G — use `intervalIntegral.integral_smul` if exists, else `MeasureTheory.integral_smul`. Actually — since I know the goal: ∫ (I * deriv G) with I a constant complex: `intervalIntegral.integral_const_mul`? hmm — `integral_const_mul (c : ℂ) (f : ℝ → ℂ) : ∫ x, c * f x = c * ∫ x, f x` — for Bochner: `integral_const_mul` ✓ exists in MeasureTheory.Integral.Bochner. For interval integral: reduce to the set integral or use `intervalIntegral.integral_smul`. Let me grep quickly... actually simpler: the step is ∫_{z.im}^{w.im} deriv G (x+y*I) dy = −I * (G(x+w.im*I) − G(x+z.im*I)). From hftc: ∫ I·deriv G = ΔG. So ∫ deriv G = (1/I)·ΔG = −I·ΔG:
```
have h4 : ∫ y in z.im..w.im, deriv G (x + y * I) =
-I * (G (x + w.im * I) - G (x + z.im * I)) := by
have h5 : ∫ y in z.im..w.im, I * deriv G (x + y * I) = G (x + w.im * I) - G (x + z.im * I) := hftc
have h6 : ∫ y in z.im..w.im, I * deriv G (x + y * I) = I * ∫ y in z.im..w.im, deriv G (x + y * I) := by
rw [intervalIntegral.integral_smul]
rw [h6] at h5
field_simp [Complex.I_ne_zero] at h5 ⊢
-- h5 : I * ∫ = ΔG ⟹ ∫ = ΔG / I = -I·ΔG
```
intervalIntegral.integral_smul — check name: for interval integrals, `intervalIntegral.integral_smul (c) (f) : ∫ x in a..b, c • f x ∂μ = c • ∫ x in a..b, f x ∂μ` — I think exists. If not: `MeasureTheory.integral_smul`. Then from I * ∫ = ΔG: ∫ = ΔG/I = −I·ΔG: field_simp with I ≠ 0. Actually simpler: ∫ deriv G = ∫ (1/I)·(I·deriv G)... let me do:
```
have hI : I ≠ 0 := Complex.I_ne_zero
calc ∫ y in z.im..w.im, deriv G (x + y * I)
= (1 / I) * (G (x + w.im * I) - G (x + z.im * I)) := by
have h6 : I * ∫ y in z.im..w.im, deriv G (x + y * I) = G (x + w.im * I) - G (x + z.im * I) := by
rw [← intervalIntegral.integral_smul]
exact hftc
field_simp [hI] at *
linarith
_ = -I * (G (x + w.im * I) - G (x + z.im * I)) := by
field_simp [hI]
```
Hmm messy. Cleanest: from I * ∫ = ΔG get ∫ = ΔG/I by `eq_div_of_mul_eq`? and 1/I = −I via `Complex.inv_I : I⁻¹ = -I` ✓ exists I believe. Let me write:
```
have h6 : I * ∫ y in z.im..w.im, deriv G (x + y * I) = G (x + w.im * I) - G (x + z.im * I) := by
rw [← intervalIntegral.integral_smul]
exact hftc
have h7 : ∫ y in z.im..w.im, deriv G (x + y * I) = (G (x + w.im * I) - G (x + z.im * I)) / I := by
rw [← h6]
field_simp [Complex.I_ne_zero]
rw [h7, Complex.div_I]
```
`Complex.div_I : z / I = -I * z`? There's `Complex.inv_I : I⁻¹ = -I` ✓ and z/I = z·I⁻¹. div_I: `Complex.div_I (z : ℂ) : z / I = -(z * I)`? Let me use inv_I: z/I = z·(1/I) = z·(−I) = −I·z ✓.
Let me check intervalIntegral.integral_smul and Complex.inv_I quickly, then apply all fixes.
Let me verify the remaining lemma names before fixing.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem intervalIntegral.integral_smul\\b\" Mathlib/ --include=*.lean | head -2; grep -rn \"theorem Complex.inv_I\\|lemma Complex.inv_I\" Mathlib/Data/Complex/Basic.lean | head -2; grep -rn \"theorem integral_smul\\b\" Mathlib/MeasureTheory/Integral/Bochner.lean Mathlib/MeasureTheory/Integral/Bochner/*.lean 2>/dev/null | head -2",
"description": "Verify integral_smul and Complex.inv_I names"
}
thinking (4854 chars)
`intervalIntegral.integral_smul` EXISTS (used at TaylorIntegral.lean:137, CauchyIntegral.lean:215 as `← intervalIntegral.integral_smul`) — so `intervalIntegral.integral_smul (c) (f) : ∫ x in a..b, c • f x = c • ∫ x in a..b, f x` ✓.
Now the full fix list for the remaining errors:
1. hd (H-side): `convert hcomp using 1; simp` — replace with `simpa [Function.comp_apply] using hcomp`.
2. H-side hftc convert block: `convert hftc using 1; · simp; · simp` — the "No goals" at 86 — simplify to `simpa using hftc` or just `exact hftc` after checking the exact form. The goal: ∫ x in z.re..w.re, deriv G (↑x+↑y*I) = G (↑w.re+↑y*I) − G (↑z.re+↑y*I); hftc : ∫ (fun x => deriv G (x+y*I)) = f b − f a = G (w.re+y*I) − G (z.re+y*I) — the explicit f/f' I passed: (f := fun x : ℝ => G (x + y * I)) (f' := fun x : ℝ => deriv G (x + y * I)) — the FTC's conclusion: ∫ y in a..b, f' y = f b − f a with a = z.re, b = w.re ✓ = G (w.re+y*I) − G (z.re+y*I) ✓ — but is the integral's integrand displayed as (fun x => deriv G (x+y*I)) x vs deriv G (↑x+↑y*I) — beta reduction — `exact hftc` should work if everything matches; use `simpa using hftc` to be safe.
3. V-side hd: same simpa pattern.
4. V-side final: `rw [← hftc, integral_smul]; field_simp` — hftc : ∫ (fun y => I * deriv G (x+y*I)) = G(x+w.im*I) − G(x+z.im*I). I want ∫ deriv G = −I·ΔG:
```
have h6 : I * ∫ y in z.im..w.im, deriv G (x + y * I) = G (x + w.im * I) - G (x + z.im * I) := by
rw [← intervalIntegral.integral_smul]
exact hftc
have h7 : ∫ y in z.im..w.im, deriv G (x + y * I) = I⁻¹ * (G (x + w.im * I) - G (x + z.im * I)) := by
rw [← h6]
field_simp [Complex.I_ne_zero]
rw [h7, Complex.inv_I]
```
Wait — after rw [← intervalIntegral.integral_smul], the goal becomes ∫ (fun y => I • deriv G (x+y*I)) — hftc's integrand is `I * deriv G (x+y*I)` — • vs * : for ℂ, • is smul — `smul_eq_mul` simp. Let me write: rw [← intervalIntegral.integral_smul, smul_eq_mul]; exact hftc. Hmm — hftc has `I * deriv G (x+y*I)` (mul form) and integral_smul produces `I • ...` — smul_eq_mul converts ✓.
Then h7's proof: after rw [← h6], goal ∫ = I⁻¹·ΔG — from I·∫ = ΔG: ∫ = I⁻¹·ΔG ⟺ I·∫ = I·(I⁻¹ΔG) = ΔG ✓ — the proof `rw [← h6]; field_simp [Complex.I_ne_zero]` — rw [← h6] rewrites ΔG to I·∫: goal ∫ = I⁻¹·(I·∫) — field_simp with I≠0: I⁻¹·I = 1 ✓ closes. Alternatively: `rw [← h6]; simp [Complex.I_ne_zero]`... let me do:
```
have h7 : ∫ y in z.im..w.im, deriv G (x + y * I) = I⁻¹ * (G (x + w.im * I) - G (x + z.im * I)) := by
have h8 : I * ∫ y in z.im..w.im, deriv G (x + y * I) = I * (I⁻¹ * (G (x + w.im * I) - G (x + z.im * I))) := by
rw [← h6]
field_simp [Complex.I_ne_zero]
exact (mul_right_cancel₀ Complex.I_ne_zero h8)
```
Hmm — simpler: `eq_of_mul_eq_mul_left Complex.I_ne_zero`? The cleanest: from I·∫ = ΔG: ∫ = ΔG/I: `eq_div_of_mul_eq Complex.I_ne_zero (by rw [mul_comm]; exact h6)`? `eq_div_of_mul_eq (hc : c ≠ 0) (h : a * c = b) : a = b / c` ✓: h6 : I·∫ = ΔG: mul_comm: ∫·I = ΔG: eq_div_of_mul_eq I_ne_zero: ∫ = ΔG/I ✓. Then ΔG/I = ΔG·I⁻¹ = ΔG·(−I) = −I·ΔG:
```
rw [h7, Complex.inv_I]
ring
```
h7 : ∫ = ΔG/I; rw [div_eq_mul_inv, Complex.inv_I]: = ΔG·(−I): ring: −I·ΔG ✓ matches target −I·ΔG ✓.
Let me write the final form directly:
```
have h7 : ∫ y in z.im..w.im, deriv G (x + y * I) = (G (x + w.im * I) - G (x + z.im * I)) / I :=
eq_div_of_mul_eq Complex.I_ne_zero (by rw [mul_comm]; exact h6)
rw [h7, div_eq_mul_inv, Complex.inv_I]
ring
```
5. rectInt_deriv_eq_zero's `rw [HIntegral_deriv ...]` — the pattern mismatch: the goal has `HIntegral (fun s => deriv G s) z.re w.re z.im` and HIntegral_deriv's LHS is `∫ x in z.re..w.re, deriv G (x + y * I)` — the HIntegral def unfolds to the interval integral — HIntegral_deriv's statement is about the ∫ form — the rw needs HIntegral unfolded first: `rw [RectangleIntegral, HIntegral, HIntegral, VIntegral, VIntegral]` — unfold all four, then the goal has the ∫ forms, then rw [HIntegral_deriv ...] matches. Let me restructure:
```
rw [RectangleIntegral]
rw [HIntegral, HIntegral, VIntegral, VIntegral]
rw [HIntegral_deriv z.im hG hGc (mapsTo_rectangleBorder_left_im z w),
HIntegral_deriv w.im hG hGc (mapsTo_rectangleBorder_right_im z w)]
have hVr := VIntegral_deriv w.re hG hGc (mapsTo_rectangleBorder_right_re z w)
have hVl := VIntegral_deriv z.re hG hGc (mapsTo_rectangleBorder_left_re z w)
rw [hVr, hVl]
simp [Complex.I_mul_I]
ring
```
Hmm — VIntegral unfolds to I • ∫ — after rw [VIntegral, VIntegral] the goal has I • ∫ ... — then rw [hVr, hVl] rewrites the ∫ parts ✓ then the algebra: [G(b)−G(a)] − [G(d)−G(c)] + I•(−I·(G(d)−G(b))) − I•(−I·(G(c)−G(a))): I•(−I·X) = X: simp [smul_eq_mul, Complex.I_mul_I] then ring.
Wait — the smul: I • (−I * X) — smul_eq_mul: I * (−I * X) = −(I*I)·X = −(−1)·X = X ✓ simp [smul_eq_mul, Complex.I_mul_I]; ring ✓.
Let me apply all these fixes.
Applying the final round of fixes to LiPrincipal.
tool: Bash ok
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiPrincipal.lean'\ns = open(p, encoding='utf-8').read()\n\n# 1. H-side hd: simpa\ns = s.replace(\"\"\" have hcomp := h1.comp x h2\n convert hcomp using 1\n simp\n have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) MeasureTheory.volume z.re w.re := by\"\"\",\n\"\"\" have hcomp := h1.comp x h2\n simpa [Function.comp_apply] using hcomp\n have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) MeasureTheory.volume z.re w.re := by\"\"\")\n\n# 2. H-side hftc: simpa\ns = s.replace(\"\"\" have hftc := intervalIntegral.integral_eq_sub_of_hasDerivAt\n (f := fun x : \u211d => G (x + y * I)) (f' := fun x : \u211d => deriv G (x + y * I)) hd hint\n convert hftc using 1\n \u00b7 simp\n \u00b7 simp\"\"\",\n\"\"\" have hftc := intervalIntegral.integral_eq_sub_of_hasDerivAt\n (f := fun x : \u211d => G (x + y * I)) (f' := fun x : \u211d => deriv G (x + y * I)) hd hint\n simpa using hftc\"\"\")\n\n# 3. V-side hd: simpa\ns = s.replace(\"\"\" have hcomp := h1.comp y h2\n convert hcomp using 1\n ring\"\"\",\n\"\"\" have hcomp := h1.comp y h2\n simpa [Function.comp_apply] using hcomp\"\"\")\n\n# 4. V-side final computation\ns = s.replace(\"\"\" have hftc := intervalIntegral.integral_eq_sub_of_hasDerivAt\n (f := fun y : \u211d => G (x + y * I)) (f' := fun y : \u211d => I * deriv G (x + y * I)) hd hint\n rw [\u2190 hftc, integral_smul]\n field_simp [Complex.I_ne_zero]\"\"\",\n\"\"\" have hftc := intervalIntegral.integral_eq_sub_of_hasDerivAt\n (f := fun y : \u211d => G (x + y * I)) (f' := fun y : \u211d => I * deriv G (x + y * I)) hd hint\n have h6 : I * \u222b y in z.im..w.im, deriv G (x + y * I) =\n G (x + w.im * I) - G (x + z.im * I) := by\n rw [\u2190 intervalIntegral.integral_smul, smul_eq_mul]\n exact hftc\n have h7 : \u222b y in z.im..w.im, deriv G (x + y * I) =\n (G (x + w.im * I) - G (x + z.im * I)) / I :=\n eq_div_of_mul_eq Complex.I_ne_zero (by rw [mul_comm]; exact h6)\n rw [h7, div_eq_mul_inv, Complex.inv_I]\n ring\"\"\")\n\n# 5. rectInt_deriv_eq_zero: unfold first\ns = s.replace(\"\"\" rw [RectangleIntegral]\n rw [HIntegral_deriv z.im hG hGc (mapsTo_rectangleBorder_left_im z w),\n HIntegral_deriv w.im hG hGc (mapsTo_rectangleBorder_right_im z w)]\n have hVr := VIntegral_deriv w.re hG hGc (mapsTo_rectangleBorder_right_re z w)\n have hVl := VIntegral_deriv z.re hG hGc (mapsTo_rectangleBorder_left_re z w)\n rw [VIntegral, VIntegral, hVr, hVl]\n simp [Complex.I_mul_I]\n ring\"\"\",\n\"\"\" rw [RectangleIntegral, HIntegral, HIntegral, VIntegral, VIntegral]\n rw [HIntegral_deriv z.im hG hGc (mapsTo_rectangleBorder_left_im z w),\n HIntegral_deriv w.im hG hGc (mapsTo_rectangleBorder_right_im z w)]\n have hVr := VIntegral_deriv w.re hG hGc (mapsTo_rectangleBorder_right_re z w)\n have hVl := VIntegral_deriv z.re hG hGc (mapsTo_rectangleBorder_left_re z w)\n rw [hVr, hVl]\n simp [smul_eq_mul, Complex.I_mul_I]\n ring\"\"\")\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiPrincipal.lean 2>&1 | head -40",
"description": "Apply final fixes and recompile LiPrincipal",
"timeout": 420000
}
result 2026-08-21 21:49:34Z → 2026-08-26 06:06:18Z
NguyenRH1/LiDogLeg.lean:430:4: error: No goals to be solved
thinking (8148 chars)
Down to three stubborn ones:
1&2 (lines 71, 101): `exact hcomp` fails — the function `(G ∘ fun x => ↑x + ↑y * I)` vs `(fun x => G (↑x + ↑y * I))` and derivative `deriv G (...) * 1` vs `deriv G (...)`. The defeq: Function.comp G path x = G (path x) — `Function.comp_apply` — as functions: `G ∘ path` and `fun x => G (path x)` ARE equal (by funext of comp_apply ✓ defeq). But exact failed with "has type ... but is expected to have type" — meaning defeq unification FAILED — the two function forms are not definitionally equal in Lean 4?? `f ∘ g` is defined as `fun x => f (g x)` — Function.comp is a def: `Function.comp f g = fun x => f (g x)` ✓ so they ARE defeq. Why did exact fail? Because the DERIVATIVE value also differs: `deriv G (↑x+↑y*I) * 1` vs `deriv G (↑x+↑y*I)` — `* 1` — mul_one — defeq by `mul_one` lemma — but defeq unification does apply lemmas?? No! Defeq is only definitional equalities (beta/eta/delta/iota), NOT lemma rewrites. `a * 1` vs `a` — for a : ℂ, `a * 1` reduces to `a`?? Multiplication in ℂ: `a * 1` — the `Mul.mul a 1` — doesn't reduce definitionally (it's an instance method). So `deriv G x * 1 ≠ defeq deriv G x`. Need `mul_one` rewrite. So: `rw [mul_one] at hcomp; exact hcomp`. For the V-side: `deriv G (...) * I` vs `I * deriv G (...)` — mul_comm — same issue: `rw [mul_comm] at hcomp; exact hcomp`.
3. Line 120: after the rw sequence, the goal became `∫ (fun y => I • deriv G ...) = ΔG` and then `smul_eq_mul` — pattern `?a • ?b` not found?? The display shows the goal HAS `I • deriv G (↑x + ↑x_1 * I)` — so smul_eq_mul SHOULD match... The error is on the LAST `smul_eq_mul` in my sequence `[← smul_eq_mul, ← intervalIntegral.integral_smul, smul_eq_mul]` — after ← intervalIntegral.integral_smul produced `∫ (I • deriv G ...)`, the final `smul_eq_mul` rewrites `I • deriv G ...` → `I * deriv G ...` — pattern `?a • ?b` SHOULD match `I • deriv G (↑x + ↑x_1 * I)`... The error says not found — maybe the issue: the whole goal is `∫ (x_1 : ℝ) in ..., I • deriv G (↑x + ↑x_1 * I) = ...` — the • is inside the integral binder — rw [smul_eq_mul] should find it... Hmm — the error message shows the pattern `?a • ?b` NOT found in `∫ (x_1 : ℝ) in z.im..w.im, I • deriv G (↑x + ↑x_1 * I) = G (↑x + ↑w.im * I) - G (↑x + ↑z.im * I)` — the `I • deriv G` IS there... unless the • shown is a different smul (HSMul instance) and smul_eq_mul is about a different one? `smul_eq_mul : a • b = a * b` — for a,b in a monoid — for ℂ, • = * with the algebra smul: `smul_eq_mul` for `Mul`? There are multiple smul_eq_mul variants: for monoids `smul_eq_mul (a b : M) : a • b = a * b` ✓ — the • in the goal is from integral_smul's `c • f x` — pointwise function smul: `(I • deriv G) x = I • (deriv G x)` — with I : ℂ and the function ℂ-valued — the pointwise smul on functions vs the complex mul — `smul_eq_mul` might match the FUNCTION smul differently... The robust fix: use `smul_eq_mul` via simp: `simp only [smul_eq_mul]`? or `Pi.smul_apply` then smul_eq_mul. Let me restructure the h6 proof:
```
have h6 : I * ∫ y in z.im..w.im, deriv G (x + y * I) =
G (x + w.im * I) - G (x + z.im * I) := by
have e := intervalIntegral.integral_smul (μ := MeasureTheory.volume) (c := I)
(f := fun y : ℝ => deriv G (x + y * I)) (a := z.im) (b := w.im)
-- e : ∫ y in z.im..w.im, I • deriv G (x+y*I) = I • ∫ ...
rw [smul_eq_mul] at e
rw [e]
-- goal ∫ (I • deriv G ...) ... hmm e's LHS integrand: I • deriv G (x+y*I) — as a function application: (I • deriv G) y — pointwise — vs hftc's `I * deriv G (x+y*I)` (plain mul)
```
The hftc's integrand is written as `I * deriv G (x + y * I)` — plain multiplication of two complex numbers. e's LHS integrand: `(I • fun y => deriv G (x+y*I)) y` = I • deriv G (x+y*I) — the pointwise smul applied — displayed as `I • deriv G (↑x + ↑x_1 * I)`. smul_eq_mul : a • b = a * b — should unify a := I, b := deriv G (...) — unless the • is `SMul.smul` of the ALGEBRA smul on ℂ (which IS mul but through a different instance path — Algebra.toSMul). smul_eq_mul might be stated for the `Mul.toSMul` instance (nsmul?). For an algebra A over 𝕜: a • b for a : 𝕜, b : A — here I : ℂ, deriv G : ℂ — the smul is the ℂ-action on ℂ (Algebra.id?) — `smul_eq_mul` for algebra: `smul_eq_mul (a b : A) : a • b = a * b` ✓ exists for algebra over itself... Let me just use `simp only [smul_eq_mul]` which normalizes all smul-to-mul conversions, or use `show` to state the integrand in mul form directly in hftc: change hftc's f' to `fun y : ℝ => I • deriv G (x + y * I)` — then hd must produce I • ... — comp gives I * ... — convert * to • in hd's simpa: `simpa [Function.comp_apply, smul_eq_mul] using hcomp`??
SIMPLER: eliminate the whole smul dance — restate the VIntegral FTC to avoid I•: from hftc : ∫ (I·G') = ΔG, I want VIntegral G' x y₁ y₂ = I•∫ G' = ΔG ✓ DIRECTLY: VIntegral G' x y₁ y₂ = I • ∫ y, deriv G (x+y*I) dy and I * ∫ = ΔG by h6 — so VIntegral = I • ∫ = ΔG — but I need ∫ = −I·ΔG for the telescoping at rectInt level... wait — let me recompute: at rectInt_deriv_eq_zero, the V-sides contribute VIntegral G' w.re z.im w.im − VIntegral G' z.re z.im w.im = I•∫_right − I•∫_left. If VIntegral G' x y₁ y₂ = I • ∫ deriv G (x+y*I) dy and h6 : I * ∫ deriv G (x+y*I) = ΔG(x) — then I • ∫ = ΔG(x) as a complex number (I•∫ = I*∫ by smul_eq_mul at the OUTER level — the outer • is on the integral VALUE (a complex number) — smul_eq_mul for complex works there? I • (integral value) with both ℂ — algebra smul on ℂ = mul ✓ should be fine with `smul_eq_mul`).
So: VIntegral_deriv x = ∫ y in z.im..w.im, deriv G (x + y * I) = -I * (G (x + w.im * I) - G (x + z.im * I)) — h6 : I * ∫ = ΔG ⟹ ∫ = ΔG/I = I⁻¹·ΔG = −I·ΔG ✓. The h6 proof from hftc: hftc : ∫ (fun y => I * deriv G (x+y*I)) = ΔG. I need: I * ∫ (fun y => deriv G (x+y*I)) = ΔG. The identity: ∫ (I * f) = I * ∫ f — that's `intervalIntegral.integral_smul` with the smul being ℂ-on-ℂ — c := I, f := fun y => deriv G (x+y*I): integral_smul : ∫ y in a..b, (I • f) y = I • ∫ f — LHS integrand (I • f) y — pointwise smul — is it syntactically `I * f y`? For ℂ: (I • f) y = I • (f y) = I * (f y) via smul_eq_mul — so:
```
have h6 : I * ∫ y in z.im..w.im, deriv G (x + y * I) =
G (x + w.im * I) - G (x + z.im * I) := by
have e := intervalIntegral.integral_smul (μ := MeasureTheory.volume) (c := I)
(f := fun y : ℝ => deriv G (x + y * I)) (a := z.im) (b := w.im)
rw [smul_eq_mul] at e
rw [e.symm] -- hmm direction
```
Wait — integral_smul : ∫ (c • f) = c • ∫ f. e : ∫ y in z.im..w.im, (I • fun y => deriv G (x+y*I)) y = I • ∫ ... — rw [smul_eq_mul] at e: converts the OUTER I • ∫ → I * ∫ ✓ AND possibly the inner (I • f) y — smul_eq_mul at e rewrites all • to *: the inner becomes (fun y => I * deriv G (x+y*I)) y?? — smul_eq_mul on `(I • f) y` — the function smul applied — smul_eq_mul is about a • b = a * b for elements — (I • f) y is `Pi.smul` (function-level) — different instance! Need `Pi.smul_apply` first: (I • f) y = I • (f y) — then smul_eq_mul. So: `simp only [Pi.smul_apply, smul_eq_mul] at e` — normalizes e fully: ∫ y, I * deriv G (x+y*I) = I * ∫ ... ✓ then `rw [← e]; exact hftc` — wait goal: I * ∫ = ΔG: from e : ∫ (I * deriv G ...) = I * ∫: I * ∫ = ∫ (I * deriv G ...) = ΔG (hftc): `rw [e] at hftc ⊢; exact hftc`?? Let me structure:
```
have h6 : I * ∫ y in z.im..w.im, deriv G (x + y * I) =
G (x + w.im * I) - G (x + z.im * I) := by
have e := intervalIntegral.integral_smul (μ := MeasureTheory.volume) (c := I)
(f := fun y : ℝ => deriv G (x + y * I)) (a := z.im) (b := w.im)
simp only [Pi.smul_apply, smul_eq_mul] at e
rw [← e]
exact hftc
```
e after simp: ∫ y in z.im..w.im, I * deriv G (x+y*I) = I * ∫ y in z.im..w.im, deriv G (x+y*I). rw [← e] on goal `I * ∫ = ΔG` → `∫ I * deriv G ... = ΔG` ✓ exact hftc ✓.
Hmm wait — does integral_smul's signature have (μ a b c f) as I guessed? `intervalIntegral.integral_smul (c) (f) : ∫ x in a..b, c • f x ∂μ = c • ∫ x in a..b, f x ∂μ` — the args (a b μ c f) implicit. Passing named args (μ := ...) (c := I) (f := ...) (a := z.im) (b := w.im) should pin it.
Let me also double check the mul_one/mul_comm fixes for hd. Apply all.
Three fixes: mul_one/mul_comm on the comp results, and the smul normalization via `Pi.smul_apply`.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiPrincipal.lean'\ns = open(p, encoding='utf-8').read()\n\ns = s.replace(\"\"\" have hcomp := h1.comp x h2\n exact hcomp\n have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) MeasureTheory.volume z.re w.re := by\"\"\",\n\"\"\" have hcomp := h1.comp x h2\n rw [mul_one] at hcomp\n exact hcomp\n have hint : IntervalIntegrable (fun x => deriv G (x + y * I)) MeasureTheory.volume z.re w.re := by\"\"\")\n\ns = s.replace(\"\"\" have hcomp := h1.comp y h2\n exact hcomp\n have hint : IntervalIntegrable (fun y : \u211d => I * deriv G (x + y * I)) MeasureTheory.volume z.im w.im := by\"\"\",\n\"\"\" have hcomp := h1.comp y h2\n rw [mul_comm] at hcomp\n exact hcomp\n have hint : IntervalIntegrable (fun y : \u211d => I * deriv G (x + y * I)) MeasureTheory.volume z.im w.im := by\"\"\")\n\ns = s.replace(\"\"\" rw [\u2190 smul_eq_mul, \u2190 intervalIntegral.integral_smul, smul_eq_mul]\n exact hftc\"\"\",\n\"\"\" have e := intervalIntegral.integral_smul (\u03bc := MeasureTheory.volume) (c := I)\n (f := fun y : \u211d => deriv G (x + y * I)) (a := z.im) (b := w.im)\n simp only [Pi.smul_apply, smul_eq_mul] at e\n rw [\u2190 e]\n exact hftc\"\"\")\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiPrincipal.lean 2>&1 | head -30",
"description": "Apply comp mul and smul fixes, recompile",
"timeout": 420000
}
thinking (3323 chars)
LiPrincipal.lean compiles clean! The FTC vanishing lemma `rectInt_deriv_eq_zero` is proved, plus the linearity and side-FTC machinery.
Now the remaining piece of ii′-1b(ii): the Acoeff/ppart definitions and the assembly `rectInt'_ppart : RectangleIntegral' (ppart n) z w = ResW1 n` (when 1 interior). Let me write that now:
```
def Acoeff (n i : ℕ) : ℂ :=
iteratedDeriv (n + 1 - i) (fun w : ℂ => (w ^ n - (w - 1) ^ n) * hLi w) 1 / (n + 1 - i)!
lemma Acoeff_one (n : ℕ) : Acoeff n 1 = ResW1 n := by
rw [Acoeff, ResW1]
have : n + 1 - 1 = n := by omega
rw [this]
/-- The principal part of J at w = 1. -/
def ppart (n : ℕ) (w : ℂ) : ℂ :=
∑ i ∈ Finset.Icc 1 (n + 1), Acoeff n i / (w - 1) ^ i
/-- The tail primitive: G(w) = −Σ_{i=2}^{n+1} A_i/((i−1)(w−1)^{i−1}). -/
def Gprim (n : ℕ) (w : ℂ) : ℂ :=
∑ i ∈ Finset.Icc 2 (n + 1), -(Acoeff n i / ((i : ℂ) - 1)) * (w - 1) ^ (-((i : ℤ) - 1))
lemma deriv_Gprim {n : ℕ} {w : ℂ} (hw : w ≠ 1) :
deriv (Gprim n) w = ∑ i ∈ Finset.Icc 2 (n + 1), Acoeff n i / (w - 1) ^ i := by
-- deriv of sum; deriv of (w−1)^{−(i−1)} = −(i−1)(w−1)^{−i}
...
lemma ppart_eq (n : ℕ) {w : ℂ} (hw : w ≠ 1) :
ppart n w = Acoeff n 1 / (w - 1) + deriv (Gprim n) w := ...
```
For deriv_Gprim: deriv of each term: f_i(w) = −(A_i/(i−1))·(w−1)^{−(i−1)} (zpow). deriv f_i = −(A_i/(i−1))·(−(i−1))(w−1)^{−(i−1)−1} = A_i·(w−1)^{−i}. Need: deriv (fun w => (w − 1) ^ (m : ℤ)) w = m·(w−1)^(m−1) — `deriv_zpow`? Let me check: `deriv_zpow (m : ℤ) (x) : deriv (fun x => x ^ m) x = m * x ^ (m - 1)`? For complex with zpow: I think `deriv_zpow` exists ✓. And (w−1)^m: composition — deriv ((w−1)^m) = m·(w−1)^{m−1}·1 ✓ via deriv_zpow + comp or directly `deriv_pow_sub...`? There might be `deriv_sub_pow_zpow`? Or compute via HasDerivAt.zpow + comp. Mechanical.
Then the final assembly:
```
theorem rectInt'_ppart {n : ℕ} {z w : ℂ}
(hre : z.re ≤ w.re) (him : z.im ≤ w.im) (h1 : Rectangle z w ∈ 𝓝 (1 : ℂ)) :
RectangleIntegral' (ppart n) z w = ResW1 n := by
-- ppart = (fun w => Acoeff n 1 / (w - 1)) + deriv (Gprim n) [EqOn off {1}, but as functions they're equal off {1}; the integral only sees the border + we can use congr]
have hdecomp : Set.EqOn (ppart n) (fun w => Acoeff n 1 / (w - 1) + deriv (Gprim n) w) (RectangleBorder z w) := by
intro s hs
have hs1 : s ≠ 1 := not_mem_rectangleBorder_of_rectangle_mem_nhds h1 hs
rw [ppart_eq _ hs1]
rw [RectangleIntegral'_congr hdecomp]
rw [RectangleIntegral'_add _ _ (integrability of A/(w−1)) (integrability of deriv Gprim)]
· rw [ResidueTheoremInRectangle hre him h1] -- gives Acoeff n 1
rw [rectInt_deriv_eq_zero ...] -- gives 0
rw [Acoeff_one, add_zero]
```
Integrabilities:
- (fun s => Acoeff n 1 / (s−1)): holomorphic off {1} ⟹ continuous on border (1 interior ⟹ border avoids 1) ⟹ RectangleBorderIntegrable via ContinuousOn.rectangleBorderIntegrable (vendored: `ContinuousOn.rectangleBorderIntegrable (hf : ContinuousOn f (Rectangle z w))` — needs continuity on the whole Rectangle (interior included — but A/(s−1) is singular at 1 INSIDE!). Hmm — the vendored `ContinuousOn.rectangleBorderNoPIntegrable` (from the agent list: exists!) — continuity on Rectangle \ {p} presumably. Let me check.
- deriv (Gprim n): also singular at 1 — same treatment.
Let me check `ContinuousOn.rectangleBorderNoPIntegrable`.
LiPrincipal.lean compiles clean. Now the final assembly of ii′-1b(ii) — checking the punctured-rectangle integrability helper.
tool: Bash
input
{
"command": "grep -n \"rectangleBorderNoPIntegrable\\|rectangleBorderIntegrable\" /d/Python/Quantum/zeta-23-lean/Zeta23/FromPNTPlus/ResidueCalcOnRectangles.lean | head -8; sed -n \"$(grep -n 'theorem ContinuousOn.rectangleBorderNoPIntegrable' /d/Python/Quantum/zeta-23-lean/Zeta23/FromPNTPlus/ResidueCalcOnRectangles.lean | head -1 | cut -d: -f1),+8p\" /d/Python/Quantum/zeta-23-lean/Zeta23/FromPNTPlus/ResidueCalcOnRectangles.lean",
"description": "Check punctured border integrability helper"
}
thinking (1660 chars)
`HolomorphicOn.rectangleBorderIntegrable'` is exactly what I need: HolomorphicOn f (Rectangle \ {p}) + Rectangle ∈ 𝓝 p ⟹ RectangleBorderIntegrable f z w.
Now write the assembly. Let me append to LiPrincipal.lean:
1. `Acoeff`, `ppart`, `Gprim` defs.
2. `deriv_Gprim`: needs deriv of zpow terms. Check `deriv_zpow`.
3. `ppart_eq` (off {1}): ppart = A_1/(w−1) + tail = A_1/(w−1) + deriv Gprim.
4. Holomorphicity of both pieces on Rectangle \ {1} (for integrability).
5. rectInt_deriv_eq_zero's hypotheses for Gprim: DifferentiableAt G at each border point (w ≠ 1 there ✓ since 1 interior) + ContinuousAt (deriv G) at border points.
6. `rectInt'_ppart` final.
For deriv_Gprim's term derivative: f_i(w) = c·(w−1)^{−(i−1)} (zpow m = −(i−1)): deriv = c·m·(w−1)^{m−1}: via deriv_zpow? Let me check the exact form. For ℂ: `deriv_zpow (m : ℤ) (x : ℂ) : deriv (fun x => x ^ m) x = m * x ^ (m - 1)`? — I believe there's `deriv_zpow`. The composition with (w−1): deriv (fun w => (w−1)^m) w = m·(w−1)^{m−1}·1 — via `deriv.comp` or a direct lemma `deriv_pow_sub...`? Alternatively use HasDerivAt.zpow + comp... Let me just compute via deriv_const_sub... or actually there's likely `deriv_fun_zpow` or handle via `(deriv_zpow m 1).comp`? Use `deriv.comp`:
deriv (fun w => (w − 1) ^ m) w: = deriv ((· ^ m) ∘ (· − 1)) w = deriv (·^m) (w−1) · deriv (·−1) w = m·(w−1)^{m−1}·1 ✓ via HasDerivAt: `(hasDerivAt_zpow m (w−1)?...` — there's `HasDerivAt.zpow (m : ℤ) (hf : HasDerivAt f f' x) : HasDerivAt (fun x => f x ^ m) (m * f x ^ (m - 1) * f') x`? Something like that exists for zpow. Then deriv via hasDerivAt.deriv.
Let me check deriv_zpow / HasDerivAt.zpow existence quickly.
Checking the zpow derivative lemma before writing the assembly.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem deriv_zpow\\|lemma deriv_zpow\" Mathlib/ --include=*.lean | head -3; grep -rn \"HasDerivAt.zpow\\|hasDerivAt_zpow\" Mathlib/Analysis/Calculus/Deriv/*.lean 2>/dev/null | head -4",
"description": "Check zpow derivative lemmas"
}
thinking (9124 chars)
`deriv_zpow (m : ℤ) (x) : deriv (fun x => x ^ m) x = m * x ^ (m - 1)` ✓ exists. For the composition (w−1)^m: use the comp or `deriv.comp`. Or directly: deriv (fun w => (w − 1) ^ m) w = deriv ((fun x => x ^ m) ∘ (fun w => w - 1)) w — via deriv.comp: deriv_zpow at (w−1) · deriv (w−1) = m·(w−1)^{m−1}·1 ✓.
Now let me write the full assembly section and append to LiPrincipal.lean.
```lean
/-! ## 3. The principal part and its integral -/
/-- The principal-part coefficients: A_i = F^{(n+1−i)}(1)/(n+1−i)!,
F(w) = (wⁿ−(w−1)ⁿ)·hLi(w). -/
def Acoeff (n i : ℕ) : ℂ :=
iteratedDeriv (n + 1 - i) (fun w : ℂ => (w ^ n - (w - 1) ^ n) * hLi w) 1 / (n + 1 - i)!
lemma Acoeff_one (n : ℕ) : Acoeff n 1 = ResW1 n := by
rw [Acoeff, ResW1, show n + 1 - 1 = n from by omega]
/-- The principal part of J at w = 1: P(w) = Σ_{i=1}^{n+1} A_i/(w−1)^i. -/
def ppart (n : ℕ) (w : ℂ) : ℂ :=
∑ i ∈ Finset.Icc 1 (n + 1), Acoeff n i / (w - 1) ^ i
/-- The tail primitive G(w) = −Σ_{i=2}^{n+1} (A_i/(i−1))·(w−1)^{−(i−1)}. -/
def Gprim (n : ℕ) (w : ℂ) : ℂ :=
∑ i ∈ Finset.Icc 2 (n + 1), -(Acoeff n i / ((i : ℂ) - 1)) * (w - 1) ^ (-((i : ℤ) - 1))
lemma deriv_Gprim {n : ℕ} {w : ℂ} (hw : w ≠ 1) :
deriv (Gprim n) w = ∑ i ∈ Finset.Icc 2 (n + 1), Acoeff n i / (w - 1) ^ i := by
rw [Gprim, deriv_sum]
apply Finset.sum_congr rfl
intro i hi
rw [Finset.mem_Icc] at hi
have hw1 : w - 1 ≠ 0 := sub_ne_zero.mpr hw
-- term: f_i(w) = -(A_i/(i−1))·(w−1)^{−(i−1)}
have hterm : deriv (fun w => -(Acoeff n i / ((i : ℂ) - 1)) * (w - 1) ^ (-((i : ℤ) - 1))) w
= Acoeff n i / (w - 1) ^ i := by
have h1 : HasDerivAt (fun w => (w - 1) ^ (-((i : ℤ) - 1)))
(((-((i : ℤ) - 1)) : ℂ) * (w - 1) ^ (-((i : ℤ) - 1) - 1)) w := by
have h := hasDerivAt_zpow (-((i : ℤ) - 1)) (w - 1) (Or.inl hw1)
-- compose with (w − 1): chain rule gives · 1
have hcomp := h.comp w (hasDerivAt_id w |>.sub_const 1)
-- hmm need the right comp form
simpa using hcomp
...
```
Hmm — deriv_zpow is for (fun x => x^m) at x; composing with (w−1): `HasDerivAt.comp` with h₂ = (·^m) over ℂ, h = (·−1): HasDerivAt ((·^m) ∘ (·−1)) (m·(w−1)^{m−1} * 1) w. Via `HasDerivAt.comp`:
```
have h1 : HasDerivAt (fun w => (w - 1) ^ (-((i : ℤ) - 1)))
((-((i : ℤ) - 1)) * (w - 1) ^ (-((i : ℤ) - 1) - 1) * 1) w := by
have h2 : HasDerivAt (fun x : ℂ => x ^ (-((i : ℤ) - 1)))
((-((i : ℤ) - 1)) * (w - 1) ^ (-((i : ℤ) - 1) - 1)) (w - 1) :=
hasDerivAt_zpow _ _ (Or.inl hw1)
have h3 : HasDerivAt (fun w : ℂ => w - 1) 1 w := by
simpa using (hasDerivAt_id w).sub_const 1
exact h2.comp w h3
```
Wait — hasDerivAt_zpow (m : ℤ) (x : 𝕜) (h : x ≠ 0 ∨ 0 ≤ m) : HasDerivAt (fun x => x ^ m) (m * x ^ (m - 1)) x ✓ — the derivative value m * x^(m−1) ✓. comp: h2.comp w h3 : HasDerivAt ((fun x => x^m) ∘ (fun w => w−1)) ((m·(w−1)^{m−1}) * 1) w ✓ — the function composition: (fun x => x^m) ∘ (fun w => w−1) = fun w => (w−1)^m ✓ defeq.
Then the full term: deriv (−(A_i/(i−1))·(w−1)^{−(i−1)}) = −(A_i/(i−1))·[−(i−1)]·(w−1)^{−(i−1)−1}·1:
with m = −(i−1) = 1−i: derivative = (1−i)·(w−1)^{(1−i)−1} = (1−i)·(w−1)^{−i}.
So term derivative = −(A_i/(i−1))·(1−i)·(w−1)^{−i} = A_i·(i−1)/(i−1)·(w−1)^{−i} = A_i·(w−1)^{−i} — and I want A_i/(w−1)^i — zpow vs pow: (w−1)^{−i} (zpow, i : ℤ) = (w−1)^{−i}... and 1/(w−1)^i = (w−1)^{−(i:ℤ)} ✓ zpow_neg... For i ≥ 2: −i ≤ −2 < 0: (w−1)^{(−(i:ℤ))} = 1/(w−1)^i ✓ via `zpow_neg` and `zpow_natCast`.
The constant multiplication: deriv (c·f) = c·deriv f ✓ `deriv_const_mul` (needs f differentiable: have it via h1.hasDerivAt.differentiableAt).
Also the negation: deriv (−c·f)... my term is `-(Acoeff n i / ((i:ℂ) − 1)) * (w−1)^m` — treat as `(-(A_i/(i−1))) * (w−1)^m`: deriv = (-(A_i/(i−1))) * (m·(w−1)^{m−1}·1) ✓ deriv_const_mul.
Then sum: deriv_sum — `deriv_sum (h : ∀ i ∈ s, DifferentiableAt ℂ (f i) x) : deriv (∑ i ∈ s, f i) x = ∑ i ∈ s, deriv (f i) x` ✓ exists.
The final equality to A_i/(w−1)^i: algebra: −(A_i/(i−1))·(1−i)·(w−1)^{−i} = A_i·(w−1)^{−i}·((i−1)/(i−1)) — with (i−1 : ℂ) ≠ 0 (i ≥ 2 ⟹ i−1 ≥ 1 ✓): field_simp + ring, then (w−1)^{−i} (zpow) = 1/(w−1)^i: `zpow_neg, zpow_natCast`: (w−1)^(−(i:ℤ)) = ((w−1)^(i:ℤ))⁻¹ = ((w−1)^i)⁻¹ ✓. So A_i·(w−1)^{−i} = A_i/((w−1)^i) ✓.
Hmm wait — the zpow exponent arithmetic: m = −((i:ℤ) − 1) = 1 − i; m − 1 = −i ✓.
Then the telescoping at the goal: A_i/(w−1)^i ✓ matches the sum.
For ppart_eq:
```
lemma ppart_eq_deriv_add {n : ℕ} {w : ℂ} (hw : w ≠ 1) :
ppart n w = Acoeff n 1 / (w - 1) + deriv (Gprim n) w := by
rw [ppart, deriv_Gprim hw]
have : Finset.Icc 1 (n + 1) = {1} ∪ Finset.Icc 2 (n + 1) := by
ext j
simp [Finset.mem_Icc]
omega
rw [this, Finset.sum_union (by simp)]
simp [pow_one]
```
Finset.sum_union needs disjoint {1} ∩ Icc 2 (n+1) = ∅ ✓ simp.
Then integrabilities + holomorphicity:
- (fun s => Acoeff n 1 / (s - 1)): HolomorphicOn on Rectangle \ {1} ✓ (rational, pole only at 1).
- deriv (Gprim n): holomorphic on Rectangle \ {1}: Gprim holomorphic there (finite sum of zpow terms ✓) ⟹ deriv holomorphic (DifferentiableOn.deriv on open set? — deriv of a holomorphic-on-open function: `DifferentiableOn.deriv (hd : DifferentiableOn ℂ f s) (ho : IsOpen s) : DifferentiableOn ℂ (deriv f) s`? I believe `DifferentiableOn.deriv` exists ✓. Rectangle \ {1} open ✓ (Rectangle closed — Rectangle \ {1} open? Rectangle is CLOSED (it's a product of closed intervals) — minus a point is NOT open! Hmm — use a larger open set: Gprim is holomorphic on ℂ \ {1} (open ✓) — DifferentiableOn.deriv on ℂ \ {1} ✓ then restrict to Rectangle \ {1} via mono. Similarly for A/(s−1).
- rectInt_deriv_eq_zero for Gprim: hG : DifferentiableAt G at every border point: border avoids 1 (1 interior ⟹ not on border via not_mem_rectangleBorder_of_rectangle_mem_nhds ✓): Gprim differentiable at w ≠ 1 ✓ (sum of differentiable terms). hGc : ContinuousAt (deriv G) at border points: deriv (Gprim n) = the tail sum (deriv_Gprim) — continuous off {1} ✓ (sum of continuous rational terms, all fine off 1).
The final theorem:
```
theorem rectInt'_ppart {n : ℕ} {z w : ℂ}
(hre : z.re ≤ w.re) (him : z.im ≤ w.im) (h1 : Rectangle z w ∈ 𝓝 (1 : ℂ)) :
RectangleIntegral' (ppart n) z w = ResW1 n := by
have h1not : (1 : ℂ) ∉ RectangleBorder z w := not_mem_rectangleBorder_of_rectangle_mem_nhds h1
have hdecomp : Set.EqOn (ppart n) (fun w => Acoeff n 1 / (w - 1) + deriv (Gprim n) w)
(RectangleBorder z w) := by
intro s hs
have hs1 : s ≠ 1 := fun heq => h1not (heq ▸ hs)
exact ppart_eq_deriv_add hs1
rw [RectangleIntegral'_congr hdecomp]
have hAint : RectangleBorderIntegrable (fun w => Acoeff n 1 / (w - 1)) z w := by
apply HolomorphicOn.rectangleBorderIntegrable' _ h1
intro s hs
have hs1 : s ≠ 1 := hs.2
exact (differentiableAt_const.div (differentiableAt_id.sub (differentiableAt_const 1)) (sub_ne_zero.mpr hs1)).differentiableWithinAt
have hGint : RectangleBorderIntegrable (deriv (Gprim n)) z w := by
apply HolomorphicOn.rectangleBorderIntegrable' _ h1
intro s hs
have hs1 : s ≠ 1 := hs.2
-- deriv of Gprim is differentiable off 1 (Gprim holomorphic on ℂ \ {1})
...
rw [RectangleIntegral'_add _ _ hAint hGint]
rw [ResidueTheoremInRectangle hre him h1]
have hzero : RectangleIntegral (deriv (Gprim n)) z w = 0 := by
apply rectInt_deriv_eq_zero
· intro s hs
have hs1 : s ≠ 1 := fun heq => h1not (heq ▸ hs)
-- Gprim differentiable at s ≠ 1
exact Gprim_differentiableAt hs1
· intro s hs
have hs1 : s ≠ 1 := fun heq => h1not (heq ▸ hs)
-- deriv Gprim continuous at s ≠ 1
rw [deriv_Gprim hs1]
-- the tail sum is continuous off 1
exact tail_continuousAt hs1
rw [RectangleIntegral', hzero]
rw [Acoeff_one]
simp
```
Wait — RectangleIntegral' f z w = (1/(2πI)) • RectangleIntegral f z w — the additivity gave RectangleIntegral' (A/(w−1) + deriv G) = RectangleIntegral' (A/(w−1)) + RectangleIntegral' (deriv G) = Acoeff + (1/(2πI))•0 = Acoeff ✓.
Let me also handle ResidueTheoremInRectangle's exact statement: `theorem ResidueTheoremInRectangle (zRe_le_wRe : z.re ≤ w.re) (zIm_le_wIm : z.im ≤ w.im) (pInRectInterior : Rectangle z w ∈ 𝓝 p) : RectangleIntegral' (fun s => c / (s - p)) z w = c` ✓ with c := Acoeff n 1, p := 1 ✓.
For Gprim differentiability + deriv continuity, define helper lemmas:
```
lemma Gprim_differentiableAt {n : ℕ} {w : ℂ} (hw : w ≠ 1) :
DifferentiableAt ℂ (Gprim n) w := by
apply DifferentiableAt.sum
intro i hi
apply DifferentiableAt.mul (differentiableAt_const _)
-- (w−1)^m differentiable at w ≠ 1 (zpow with negative exponent, base ≠ 0)
exact (differentiableAt_zpow ... ) hmm — `differentiableAt_zpow (m : ℤ) (x) (h : x ≠ 0 ∨ 0 ≤ m)`? from the grep: hasDerivAt_zpow m x H with H : x ≠ 0 ∨ 0 ≤ m ⟹ differentiableAt. For (w−1): compose.
```
And deriv_Gprim continuity: deriv (Gprim n) w = tail-sum (by deriv_Gprim) — the tail sum of rational terms, each continuous off {1} ✓ (sum of continuous functions, needs w ≠ 1 for denominators).
OK — let me write the whole section 3 and append. This is another ~150 lines. Let me write it in one go and compile.
All pieces confirmed. Writing the assembly section (Acoeff/ppart/Gprim + the integral theorem).
tool: Bash
input
{
"command": "cat >> /d/Python/Quantum/research/lean/NguyenRH1/NguyenRH1/LiPrincipal.lean << 'EOF'\n\n/-! ## 3. The principal part and its integral -/\n\n/-- The principal-part coefficients: A_i = F^{(n+1\u2212i)}(1)/(n+1\u2212i)!,\nF(w) = (w\u207f\u2212(w\u22121)\u207f)\u00b7hLi(w). -/\ndef Acoeff (n i : \u2115) : \u2102 :=\n iteratedDeriv (n + 1 - i) (fun w : \u2102 => (w ^ n - (w - 1) ^ n) * hLi w) 1 / (n + 1 - i)!\n\nlemma Acoeff_one (n : \u2115) : Acoeff n 1 = ResW1 n := by\n rw [Acoeff, ResW1, show n + 1 - 1 = n from by omega]\n\n/-- The principal part of J at w = 1: P(w) = \u03a3_{i=1}^{n+1} A_i/(w\u22121)^i. -/\ndef ppart (n : \u2115) (w : \u2102) : \u2102 :=\n \u2211 i \u2208 Finset.Icc 1 (n + 1), Acoeff n i / (w - 1) ^ i\n\n/-- The tail primitive G(w) = \u2212\u03a3_{i=2}^{n+1} (A_i/(i\u22121))\u00b7(w\u22121)^{\u2212(i\u22121)}. -/\ndef Gprim (n : \u2115) (w : \u2102) : \u2102 :=\n \u2211 i \u2208 Finset.Icc 2 (n + 1), -(Acoeff n i / ((i : \u2102) - 1)) * (w - 1) ^ (-((i : \u2124) - 1))\n\nlemma Gprim_differentiableAt {n : \u2115} {w : \u2102} (hw : w \u2260 1) :\n DifferentiableAt \u2102 (Gprim n) w := by\n rw [Gprim]\n apply DifferentiableAt.sum\n intro i hi\n apply DifferentiableAt.mul (differentiableAt_const _)\n have hw1 : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n exact (hasDerivAt_zpow _ (w - 1) (Or.inl hw1)).differentiableAt.comp w\n ((hasDerivAt_id w).sub_const 1)\n\nlemma deriv_Gprim {n : \u2115} {w : \u2102} (hw : w \u2260 1) :\n deriv (Gprim n) w = \u2211 i \u2208 Finset.Icc 2 (n + 1), Acoeff n i / (w - 1) ^ i := by\n rw [Gprim, deriv_sum (fun i hi => ?_)]\n \u00b7 apply Finset.sum_congr rfl\n intro i hi\n rw [Finset.mem_Icc] at hi\n have hw1 : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n have hi1 : ((i : \u2102) - 1) \u2260 0 := by\n have : 1 < (i : \u211d) := by exact_mod_cast (by omega : 1 < i)\n intro heq\n rw [sub_eq_zero] at heq\n have : (i : \u211d) = 1 := by exact_mod_cast heq\n linarith\n have hd : deriv (fun w => (w - 1) ^ (-((i : \u2124) - 1))) w\n = ((-((i : \u2124) - 1)) : \u2102) * (w - 1) ^ (-((i : \u2124) - 1) - 1) := by\n have h2 : HasDerivAt (fun x : \u2102 => x ^ (-((i : \u2124) - 1)))\n ((-((i : \u2124) - 1)) * (w - 1) ^ (-((i : \u2124) - 1) - 1)) (w - 1) :=\n hasDerivAt_zpow _ _ (Or.inl hw1)\n have h3 : HasDerivAt (fun w : \u2102 => w - 1) 1 w := by\n simpa using (hasDerivAt_id w).sub_const 1\n have hcomp := h2.comp w h3\n rw [Function.comp_apply, mul_one] at hcomp\n exact hcomp.deriv\n rw [deriv_const_mul _ (by\n have hw1' : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n exact (hasDerivAt_zpow _ (w - 1) (Or.inl hw1')).differentiableAt.comp w\n ((hasDerivAt_id w).sub_const 1)), hd]\n have hm : (-((i : \u2124) - 1) - 1 : \u2124) = -(i : \u2124) := by omega\n rw [hm]\n have hzi : ((-(i : \u2124)) : \u2102) = -((i : \u2102)) := by simp\n rw [hzi]\n field_simp [hw1, hi1]\n rw [zpow_neg, zpow_natCast]\n field_simp [hw1]\n ring\n \u00b7 intro i hi\n apply DifferentiableAt.mul (differentiableAt_const _)\n have hw1 : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n exact (hasDerivAt_zpow _ (w - 1) (Or.inl hw1)).differentiableAt.comp w\n ((hasDerivAt_id w).sub_const 1)\n\nlemma tail_continuousAt {n : \u2115} {w : \u2102} (hw : w \u2260 1) :\n ContinuousAt (\u2211 i \u2208 Finset.Icc 2 (n + 1), Acoeff n i / (w - 1) ^ i) w := by\n apply ContinuousAt.sum\n intro i hi\n rw [Finset.mem_Icc] at hi\n have hw1 : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n apply ContinuousAt.div (continuousAt_const)\n exact (continuousAt_id.sub continuousAt_const).pow hw1.ne' |> fun h => h.continuousAt\n \u00b7 exact pow_ne_zero _ hw1\n\nlemma ppart_eq_deriv_add {n : \u2115} {w : \u2102} (hw : w \u2260 1) :\n ppart n w = Acoeff n 1 / (w - 1) + deriv (Gprim n) w := by\n rw [ppart, deriv_Gprim hw]\n have hsplit : Finset.Icc 1 (n + 1) = {1} \u222a Finset.Icc 2 (n + 1) := by\n ext j\n simp [Finset.mem_Icc]\n omega\n rw [hsplit, Finset.sum_union (by simp)]\n simp [pow_one]\n\n/-- The principal-part integral: on any rectangle with 1 in its interior,\nRectangleIntegral' (ppart n) z w = ResW1 n. -/\ntheorem rectInt'_ppart {n : \u2115} {z w : \u2102}\n (hre : z.re \u2264 w.re) (him : z.im \u2264 w.im) (h1 : Rectangle z w \u2208 \ud835\udcdd (1 : \u2102)) :\n RectangleIntegral' (ppart n) z w = ResW1 n := by\n have h1not : (1 : \u2102) \u2209 RectangleBorder z w := not_mem_rectangleBorder_of_rectangle_mem_nhds h1\n have hdecomp : Set.EqOn (ppart n) (fun w => Acoeff n 1 / (w - 1) + deriv (Gprim n) w)\n (RectangleBorder z w) := by\n intro s hs\n have hs1 : s \u2260 1 := fun heq => h1not (heq \u25b8 hs)\n exact ppart_eq_deriv_add hs1\n rw [RectangleIntegral'_congr hdecomp]\n have hAint : RectangleBorderIntegrable (fun w => Acoeff n 1 / (w - 1)) z w := by\n apply HolomorphicOn.rectangleBorderIntegrable' _ h1\n intro s hs\n have hs1 : s \u2260 1 := hs.2\n exact (differentiableAt_const.div ((differentiableAt_id.sub (differentiableAt_const 1)))\n (sub_ne_zero.mpr hs1)).differentiableWithinAt\n have hGint : RectangleBorderIntegrable (deriv (Gprim n)) z w := by\n apply HolomorphicOn.rectangleBorderIntegrable' _ h1\n intro s hs\n have hs1 : s \u2260 1 := hs.2\n rw [deriv_Gprim hs1]\n exact (tail_continuousAt hs1).differentiableAt.continuousWithinAt\n rw [RectangleIntegral'_add _ _ hAint hGint]\n rw [ResidueTheoremInRectangle hre him h1]\n have hzero : RectangleIntegral (deriv (Gprim n)) z w = 0 := by\n apply rectInt_deriv_eq_zero\n \u00b7 intro s hs\n have hs1 : s \u2260 1 := fun heq => h1not (heq \u25b8 hs)\n exact Gprim_differentiableAt hs1\n \u00b7 intro s hs\n have hs1 : s \u2260 1 := fun heq => h1not (heq \u25b8 hs)\n rw [deriv_Gprim hs1]\n exact tail_continuousAt hs1\n rw [RectangleIntegral', hzero]\n rw [Acoeff_one]\n simp\nEOF\ncd /d/Python/Quantum/research/lean/NguyenRH1 && export PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiPrincipal.lean 2>&1 | head -40",
"description": "Append assembly section and compile",
"timeout": 420000
}
thinking (2816 chars)
Multiple issues:
1. The appended code landed OUTSIDE the namespace again (heredoc appended after `end NguyenRH1`)! Same issue as session 015. Need to remove the `end NguyenRH1` before section 3 or re-add. Fix with the python patch: remove the end before `/-! ## 3` and add it at the end.
2. `(n + 1 - i)!` parse error at 164:88 — `(n + 1 - i)!` — the factorial on a parenthesized expression with `-` — same scoped-notation issue? I added `open scoped Nat` — it should work... "unexpected token '!'; expected command" at 164:88 — col 88 — in the Acoeff def: `/ (n + 1 - i)!` — hmm, `(n + 1 - i)!` should parse... unless the issue is the `-` inside: `(n + 1 - i)!` — after `)` the `!` — postfix factorial needs NO space ✓ I wrote `(n + 1 - i)!` — hmm should be fine. Wait — maybe the error cascades from `hLi` unknown (line 164:66) — because the append landed outside the namespace where hLi lives. Fix the namespace first; most errors likely cascade from that.
3. `ContinuousAt.sum` unknown — the name: `ContinuousAt.sum`? For finite sums of continuous functions: `ContinuousAt.sum (h : ∀ i ∈ s, ContinuousAt (f i) x) : ContinuousAt (∑ i ∈ s, f i) x`? Hmm — might be `ContinuousAt.sum` doesn't exist; there's `Continuous.sum`? For continuous at a point: `ContinuousAt.sum`? Let me check — likely `ContinuousAt.sum` exists in Topology.Algebra.InfiniteSum or Continuous. If not, use `continuousAt_sum`? Hmm. Let me check quickly.
4. `differentiableAt_const.div` unknown — the pattern: `DifferentiableAt.div (hf : DifferentiableAt f x) (hg : DifferentiableAt g x) (h : g x ≠ 0)` — so it's `DifferentiableAt.div`, and for the constant numerator: `(differentiableAt_const _).div hg h`. Fix: `((differentiableAt_const (Acoeff n 1)).div (differentiableAt_id.sub (differentiableAt_const 1)) (sub_ne_zero.mpr hs1)).differentiableWithinAt`.
5. tail_continuousAt's structure: `(continuousAt_id.sub continuousAt_const).pow hw1.ne' |> fun h => h.continuousAt` — broken. Fix:
```
apply ContinuousAt.div (continuousAt_const)
· exact (continuousAt_id.sub continuousAt_const).pow _
· exact pow_ne_zero _ hw1
```
Hmm — ContinuousAt.div (hf : ContinuousAt f x) (hg : ContinuousAt g x) (h : g x ≠ 0) : ContinuousAt (f / g) x ✓ exists. And `(continuousAt_id.sub continuousAt_const).pow (n)` — ContinuousAt.pow ✓ exists.
6. The rw [deriv_Gprim hs1] inside hGint — "did not find pattern deriv (Gprim ?m) s" — deriv_Gprim's statement has {n} implicit and {w} implicit: `deriv_Gprim {n} {w} (hw : w ≠ 1)` — rw [deriv_Gprim hs1] rewrites `deriv (Gprim n) s` — should match... but wait, deriv_Gprim's LHS is `deriv (Gprim n) w` with w implicit — in hGint the goal has `deriv (Gprim n)` — should match. The error might cascade from the namespace issue. Fix namespace first.
Let me fix the namespace structure and the smaller issues.
The heredoc landed outside the namespace again — fixing structure plus the smaller issues.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiPrincipal.lean'\ns = open(p, encoding='utf-8').read()\n\n# 1. namespace: remove end before section 3, add at file end\ns = s.replace(\"end NguyenRH1\\n\\n/-! ## 3. The principal part and its integral -/\",\n \"/-! ## 3. The principal part and its integral -/\")\ns = s.rstrip() + \"\\n\\nend NguyenRH1\\n\"\n\n# 2. ContinuousAt.sum -> use explicit induction-free form\ns = s.replace(\"\"\" apply ContinuousAt.sum\n intro i hi\n rw [Finset.mem_Icc] at hi\n have hw1 : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n apply ContinuousAt.div (continuousAt_const)\n exact (continuousAt_id.sub continuousAt_const).pow hw1.ne' |> fun h => h.continuousAt\n \u00b7 exact pow_ne_zero _ hw1\"\"\",\n\"\"\" apply ContinuousAt.sum\n intro i hi\n rw [Finset.mem_Icc] at hi\n have hw1 : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n apply ContinuousAt.div (continuousAt_const)\n \u00b7 exact (continuousAt_id.sub continuousAt_const).pow _\n \u00b7 exact pow_ne_zero _ hw1\"\"\")\n\n# 3. differentiableAt_const.div fix\ns = s.replace(\"\"\" exact (differentiableAt_const.div ((differentiableAt_id.sub (differentiableAt_const 1)))\n (sub_ne_zero.mpr hs1)).differentiableWithinAt\"\"\",\n\"\"\" exact (((differentiableAt_const (Acoeff n 1)).div\n ((differentiableAt_id.sub (differentiableAt_const 1)))\n (sub_ne_zero.mpr hs1))).differentiableWithinAt\"\"\")\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiPrincipal.lean 2>&1 | head -40",
"description": "Fix namespace and remaining issues, recompile",
"timeout": 420000
}
thinking (11487 chars)
Progress — remaining issues:
1. Line 162:88: `(n + 1 - i)!` — STILL the factorial parse issue at Acoeff def. Let me look at line 162: `iteratedDeriv (n + 1 - i) (fun w : ℂ => (w ^ n - (w - 1) ^ n) * hLi w) 1 / (n + 1 - i)!` — the `!` after `)` — "unexpected token '!'; expected command". So postfix `!` after a parenthesized expression with space... I have `open scoped Nat` — the notation `n !` needs `n` to be a TERM, and `(n + 1 - i)!` — hmm — maybe the notation requires NO space but also the parser sees `(n + 1 - i)` as complete then `!` as new token — postfix notation should handle this (it's how `n!` fails but `(n+1)!` works?). In Mathlib, `(n + 1)!` is written with no space and works. My text has `(n + 1 - i)!` — should work the same... unless the issue is line 162's def Acoeff — let me look at the exact line. Maybe the earlier `open scoped Nat` was lost in my rewrites? Let me check the file header. Also error 164: the Acoeff_one rw produced `(↑n + 1 - ↑1) = ↑n.factorial` mismatch — `show n + 1 - 1 = n from by omega` rewrote `n + 1 - 1` to `n` in the goal but left `(↑n + 1 - ↑1)` (real cast?) — the factorial argument: Acoeff n 1 = iteratedDeriv (n+1−1) F 1 / (n+1−1)! — rw [show n + 1 - 1 = n] — the target `n + 1 - 1` appears in `iteratedDeriv (n + 1 - 1)` and in `(n + 1 - 1)!` — the display shows the goal became `... / (↑n + 1 - ↑1) = ... / ↑n.factorial` — the `!` in `(n+1-1)!` was elaborated as something weird — `(↑n + 1 - ↑1)` without factorial?! So the factorial parse IS broken at Acoeff's def. Fix: write `Nat.factorial (n + 1 - i)` explicitly.
2. `ContinuousAt.sum` unknown — find the right name. For sums: `ContinuousAt.sum`? — grep needed. Actually there's `ContinuousAt.sum` in Topology.Algebra.Monoid? Hmm — the standard: `ContinuousAt.sum (h : ∀ i ∈ s, ContinuousAt (f i) x) : ContinuousAt (∑ i ∈ s, f i) x`? Let me grep.
3. `deriv_sum` usage — `rw [Gprim, deriv_sum (fun i hi => ?_)]` — "Failed to rewrite using equation theorems for Gprim" — rw [Gprim] fails to unfold Gprim? Gprim is a def — rw [Gprim] should unfold via equation lemmas — the error "Failed to rewrite using equation theorems for Gprim" — maybe Gprim has implicit args or the unfold needs `Gprim.eq_def`? Hmm — rw [Gprim] usually unfolds defs... The issue might be that after the namespace fix, Gprim's def is fine, but rw [Gprim] doesn't unfold because... Let me use `unfold Gprim` or `show` — or `simp only [Gprim]`. Let me use `unfold Gprim` — hmm — or write the rw as `rw [Gprim, deriv_sum ...]` → replace with `unfold Gprim; rw [deriv_sum ...]`. Actually "Failed to rewrite using equation theorems for Gprim" typically means the def's equation lemma didn't match the goal's instance — Gprim n w vs the goal's `deriv (Gprim n) w` — the LHS of the equation is `Gprim n w` but the goal has `deriv (Gprim n) w` — the def-eq unfolds Gprim n w to the sum — should match `deriv (Gprim n) w`... Hmm — "equation theorems for Gprim" — the error is on `rw [Gprim, deriv_sum ...]` — maybe deriv_sum is the failing one? "Failed to rewrite using equation theorems for `Gprim`" — it names Gprim explicitly. Maybe deriv_sum needs the function in lambda form: deriv (fun w => ∑ i, term i w) — after unfolding Gprim, the goal is deriv (∑ i ∈ Icc 2 (n+1), fun w => ...) — deriv_sum's pattern: deriv (∑ i ∈ s, f i) x = ∑ i ∈ s, deriv (f i) x ✓ should match... The error is at line 177 (Gprim_differentiableAt's `rw [Gprim]`) and 187 (deriv_Gprim's `rw [Gprim, deriv_sum]`) — both rw [Gprim] fail. Because Gprim is defined with (n : ℕ) (w : ℂ) explicit args — the equation lemma: Gprim n w = ∑ ... — rw [Gprim] should rewrite Gprim n w... "Failed to rewrite using equation theorems" — perhaps because Gprim's definition body has `∑ i ∈ Finset.Icc 2 (n + 1), ...` and the equation lemma generated is `Gprim n w = ...` which should match... Hmm — maybe the issue: `rw [Gprim]` requires the def to be equational/reducible by equation lemmas — for a plain def it generates `Gprim.eq_1`... Actually for non-pattern-matching defs, `rw [Gprim]` uses `Gprim.def`/`Gprim.eq_def`? The standard way: `unfold Gprim` or `simp only [Gprim]`. Let me use `unfold Gprim` — wait — `unfold` works. Or `rw [show Gprim n = fun w => ∑ i ∈ Finset.Icc 2 (n + 1), ... from rfl]`. Use `unfold Gprim` — safe.
Hmm wait — actually the reason might be that rw [Gprim] is hitting the ERROR "Failed to rewrite using equation theorems for `Gprim`" — this exact error appears when the def has no equation lemmas matching — for defs with explicit arguments, rw [Gprim] needs `Gprim n w` in the goal — we have `deriv (Gprim n) w` — the pattern `Gprim n w` — is `Gprim n w` PRESENT in `deriv (Gprim n) w`? YES as a subterm. Hmm... unless Gprim's first arg n is IMPLICIT in my def? I wrote `def Gprim (n : ℕ) (w : ℂ) : ℂ` — explicit ✓. The application in goal: `Gprim n` applied to w via `deriv (Gprim n) w` — subterm `Gprim n w` ✓ present. Strange. Let me just use `unfold Gprim` — wait, actually maybe the issue is `rw [Gprim]` tries to rewrite with the equation Gprim n w = body, and the body contains `∑ i ∈ Finset.Icc 2 (n + 1), -(Acoeff n i / ((i : ℂ) - 1)) * (w - 1) ^ ...` — no problem... Let me just try `unfold Gprim` and see. Actually — the more likely cause: the previous error (line 162 factorial parse) made Acoeff ill-formed, so Gprim (which mentions Acoeff) is also ill-formed, and rw fails. Fix Acoeff's factorial first — the Gprim errors likely cascade.
4. `ContinuousAt.sum` — check name.
5. tail_continuousAt's hi : ℂ — `intro i hi; rw [Finset.mem_Icc] at hi` — hi got type ℂ?! Because `apply ContinuousAt.sum` failed and hi is garbage. Cascade.
6. hGint's `rw [deriv_Gprim hs1]` — pattern `deriv (Gprim ?m) s` not found in `DifferentiableWithinAt ℂ (deriv (Gprim n)) ... s` — the deriv (Gprim n) UNAPPLIED (as a function) — deriv_Gprim's LHS is `deriv (Gprim n) w` (applied at w) — the goal has the function `deriv (Gprim n)` unapplied at s... it's `DifferentiableWithinAt ℂ (deriv (Gprim n)) (z.Rectangle w \ {1}) s` — deriv (Gprim n) is a function ℂ → ℂ; applied at s implicitly in DifferentiableWithinAt. The rewrite `deriv (Gprim ?m) ?s` — the goal has `deriv (Gprim n)` as a bare function — the pattern with application doesn't match the unapplied function. Fix: instead of rw, use the fact directly: I want DifferentiableWithinAt (deriv (Gprim n)) ... s — since deriv (Gprim n) = the tail-sum FUNCTION (pointwise equal off {1}), and the tail-sum is continuous at s — actually differentiability of deriv at s: deriv (Gprim n) is differentiable at s (Gprim is analytic off 1 ⟹ deriv analytic) — hmm, the cleaner: show DifferentiableAt ℂ (deriv (Gprim n)) s via: Gprim differentiable on ℂ \ {1} (open) ⟹ deriv differentiable there (DifferentiableOn.deriv) ⟹ at s ✓:
```
exact ((Gprim_differentiableOn_open (n := n)).deriv (isOpen_compl_singleton)).differentiableWithinAt hs
```
Hmm — need Gprim_differentiableOn_open : DifferentiableOn ℂ (Gprim n) (Set.univ \ {1}) or (ℂ \ {1}): via Gprim_differentiableAt at every w ≠ 1: DifferentiableOn (Gprim n) {1}ᶜ: intro w hw; exact (Gprim_differentiableAt hw).differentiableWithinAt. Then DifferentiableOn.deriv (h : DifferentiableOn ℂ f s) (ho : IsOpen s) : DifferentiableOn ℂ (deriv f) s — with s = {1}ᶜ open ✓. Then .differentiableWithinAt at s ∈ {1}ᶜ ✓ (hs : s ∈ Rectangle \ {1} — need s ∈ {1}ᶜ: hs.2 ✓).
Hmm wait — but HolomorphicOn.rectangleBorderIntegrable' wants HolomorphicOn f (Rectangle \ {p}) — HolomorphicOn = DifferentiableOn. My goal inside the `intro s hs` is DifferentiableWithinAt ℂ (deriv (Gprim n)) (Rectangle \ {1}) s. With DifferentiableOn (deriv (Gprim n)) ({1}ᶜ) I get DifferentiableWithinAt at s ∈ {1}ᶜ — but the WithinAt set differs ({1}ᶜ vs Rectangle \ {1}) — DifferentiableWithinAt f s x with s ⊇ t implies DifferentiableWithinAt f t x: `(h.deriv ...).mono (Set.diff_subset_diff_right (Set.singleton_subset_iff.mpr ?))`... simpler: DifferentiableWithinAt is about the point with a set; from DifferentiableOn f {1}ᶜ at s ∈ {1}ᶜ: `(...).differentiableWithinAt (Set.mem_compl_singleton_iff.mpr hs1)` gives DifferentiableWithinAt f {1}ᶜ s — then `.mono` to Rectangle \ {1} ⊆ {1}ᶜ: `DifferentiableWithinAt.mono h (Set.diff_subset_diff_left (Set.subset_univ _))`? The set Rectangle \ {1} ⊆ {1}ᶜ ✓ via diff_subset (Set.subset_univ _). Let me:
```
have hopen : DifferentiableOn ℂ (deriv (Gprim n)) {1}ᶜ :=
(Gprim_differentiableOn_compl n).deriv isOpen_compl_singleton
exact (hopen s (Set.mem_compl_singleton_iff.mpr hs1)).mono
(Set.diff_subset_diff_right (Set.singleton_subset_iff.mpr (Set.mem_univ _)))
```
Hmm — Set.diff_subset_diff_right (h : t ⊆ s) : a \ s ⊆ a \ t — with s := {1}, t := univ?? I want Rectangle \ {1} ⊆ univ \ {1}: via Set.diff_subset_diff_right (Set.subset_univ _)?? diff_subset_diff_right (h : s ⊆ t) : a \ t ⊆ a \ s — so univ \ {1} ⊆ ... no I want Rectangle \ {1} ⊆ univ \ {1} — a := Rectangle ⊆ univ: Rectangle \ {1} ⊆ univ \ {1} via Set.diff_subset_diff_left (Set.subset_univ _) ✓ (diff_subset_diff_left : s ⊆ t → s \ r ⊆ t \ r ✓).
`.mono (Set.diff_subset_diff_left (Set.subset_univ _))` — DifferentiableWithinAt.mono : DifferentiableWithinAt f s x → t ⊆ s → DifferentiableWithinAt f t x ✓ direction: from WithinAt at {1}ᶜ to WithinAt at Rectangle\{1} ⊆ {1}ᶜ ✓.
Hmm wait — actually simpler: `DifferentiableOn.mono`: from DifferentiableOn (deriv Gprim) {1}ᶜ get DifferentiableOn (deriv Gprim) (Rectangle \ {1}) via .mono (Set.diff_subset_diff_left (Set.subset_univ _)) — then the HolomorphicOn goal is exactly DifferentiableOn (Rectangle \ {1}) — restructure hGint:
```
have hGint : RectangleBorderIntegrable (deriv (Gprim n)) z w := by
apply HolomorphicOn.rectangleBorderIntegrable' _ h1
have hopen : DifferentiableOn ℂ (deriv (Gprim n)) {1}ᶜ :=
(Gprim_differentiableOn_compl n).deriv isOpen_compl_singleton
exact hopen.mono (Set.diff_subset_diff_left (Set.subset_univ _))
```
with Gprim_differentiableOn_compl (n) : DifferentiableOn ℂ (Gprim n) {1}ᶜ:
```
lemma Gprim_differentiableOn_compl (n : ℕ) :
DifferentiableOn ℂ (Gprim n) {1}ᶜ := by
intro w hw
exact (Gprim_differentiableAt (Set.mem_compl_singleton_iff.mp hw)).differentiableWithinAt
```
And `isOpen_compl_singleton : IsOpen {x}ᶜ` ✓ exists.
And `DifferentiableOn.deriv (hd : DifferentiableOn ℂ f s) (ho : IsOpen s) : DifferentiableOn ℂ (deriv f) s` ✓ exists I believe.
7. hAint's HolomorphicOn — similar but simpler (rational function).
8. Also the hAint/hGint rw [RectangleIntegral'_add _ _ hAint hGint] — RectangleIntegral'_add's signature (f g z w) (hf hg) — `RectangleIntegral'_add _ _ hAint hGint` — the _ _ are f g? My RectangleIntegral'_add (f g : ℂ → ℂ) (z w : ℂ) (hf hg) — explicit f g z w — `RectangleIntegral'_add _ _ hAint hGint` gives only 2 underscores (f g) then hAint hGint — but z w also explicit — mismatch! `RectangleIntegral'_add _ _ _ _ hAint hGint`? — hmm — actually looking at my def: `lemma RectangleIntegral'_add (f g : ℂ → ℂ) (z w : ℂ) (hf : ...) (hg : ...)` — so RectangleIntegral'_add _ _ hAint hGint elaborates z w from the hypotheses ✓ — _ _ are f g, then z w from hf/hg ✓ should work. The error at 271:33 says hAint application mismatch — the RectangleIntegral'_add's hf expects RectangleBorderIntegrable (fun w => Acoeff n 1 / (w - 1)) z w ✓ hAint has that ✓ — hmm, the error is truncated; probably cascade.
Let me fix: Acoeff factorial (Nat.factorial explicit), Gprim unfold → `unfold`, ContinuousAt.sum name check, hGint restructure. First check ContinuousAt.sum name.
Checking the remaining API names before fixing.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/zeta-23-lean/.lake/packages/mathlib && grep -rn \"theorem ContinuousAt.sum\\|lemma ContinuousAt.sum\" Mathlib/ --include=*.lean | head -3; grep -rn \"theorem DifferentiableOn.deriv\\b\\|lemma DifferentiableOn.deriv\\b\" Mathlib/ --include=*.lean | head -3; grep -rn \"theorem isOpen_compl_singleton\" Mathlib/ --include=*.lean | head -2",
"description": "Check ContinuousAt.sum, DifferentiableOn.deriv, isOpen_compl_singleton"
}
thinking (5412 chars)
No `ContinuousAt.sum` found. I'll prove tail continuity via `ContinuousAt.add` by Finset induction, or better — use `ContinuousAt.sum` alternative: `continuousAt_sum`? Not found either. Simplest robust: Finset induction:
```
lemma tail_continuousAt {n : ℕ} {w : ℂ} (hw : w ≠ 1) :
ContinuousAt (∑ i ∈ Finset.Icc 2 (n + 1), Acoeff n i / (w - 1) ^ i) w := by
classical
refine Finset.induction (motive := fun s => ContinuousAt
(∑ i ∈ s, Acoeff n i / (w - 1) ^ i) w) ?_ ?_ (Finset.Icc 2 (n + 1))
· simp
· intro a s has hs
rw [Finset.sum_insert has]
apply ContinuousAt.add hs
· -- term continuity
have hw1 : w - 1 ≠ 0 := sub_ne_zero.mpr hw
apply ContinuousAt.div (continuousAt_const)
· exact (continuousAt_id.sub continuousAt_const).pow _
· exact pow_ne_zero _ hw1
```
Hmm — Finset.induction on (Icc 2 (n+1)) with motive — the `refine Finset.induction ?_ ?_ s` form: `Finset.induction (p : Finset α → Prop) (empty : p ∅) (insert : ∀ a s, a ∉ s → p s → p (insert a s)) : p s`? The argument order: `Finset.induction (h1 : p ∅) (h2 : ∀ ⦃a⦄ {s}, a ∉ s → p s → p (insert a s)) : p s` ✓. Let me write:
```
classical
refine Finset.induction (s := Finset.Icc 2 (n + 1)) ?_ ?_
· simp
· intro a s has hs
rw [Finset.sum_insert has]
exact ContinuousAt.add hs (term_cont _)
```
Hmm — motive inference might be tricky; alternative: `induction s using Finset.induction` — but the sum set is fixed (Icc 2 (n+1)) — induction on that Finset: `generalize` it first? Cleaner: use `Finset.induction_on`:
```
have : ∀ s : Finset ℕ, ContinuousAt (∑ i ∈ s, Acoeff n i / (w - 1) ^ i) w := by
intro s
induction s using Finset.induction with
| empty => simp
| insert has hs =>
rw [Finset.sum_insert has]
apply ContinuousAt.add hs
have hw1 : w - 1 ≠ 0 := sub_ne_zero.mpr hw
apply ContinuousAt.div (continuousAt_const)
· exact (continuousAt_id.sub continuousAt_const).pow _
· exact pow_ne_zero _ hw1
exact this _
```
Wait — ContinuousAt.div (hf) (hg) (h : g x ≠ 0) — signature check: `ContinuousAt.div (hf : ContinuousAt f x) (hg : ContinuousAt g x) (hz : g x ≠ 0) : ContinuousAt (f / g) x` ✓. And ContinuousAt.add (hf) (hg) ✓.
Hmm — but actually — the term `Acoeff n i / (w - 1) ^ i` — as a function of w: `fun w => Acoeff n i / (w - 1) ^ i` — ContinuousAt.div needs f and g as functions of w — with f := fun _ => Acoeff n i (const), g := fun w => (w−1)^i ✓.
Also `ContinuousAt.add` — signature: `ContinuousAt.add (hf : ContinuousAt f x) (hg : ContinuousAt g x) : ContinuousAt (f + g) x` ✓ — with (f + g) w = f w + g w — the sum_insert gives ∑ + term ✓ Pi.add_apply defeq.
Let me now apply all the pending fixes to LiPrincipal.lean:
1. Acoeff factorial: `Nat.factorial (n + 1 - i)` explicit.
2. Gprim unfold: `unfold Gprim` — wait, in Gprim_differentiableAt and deriv_Gprim I have `rw [Gprim]` — replace with `unfold Gprim` — hmm unfold in tactic: `unfold Gprim` should work, or `simp only [Gprim]` — simp only with the def name unfolds via equation lemmas ✓ safer. Or `rw [Gprim]`→`simp only [Gprim]`. Hmm — simp only [Gprim] uses the generated equation lemma Gprim.eq_def — should work.
3. tail_continuousAt via induction.
4. hGint restructure with Gprim_differentiableOn_compl + DifferentiableOn.deriv.
5. Acoeff_one's rw [show ...] — with Nat.factorial explicit the `show n + 1 - 1 = n` rewrite should work (target `n + 1 - 1` appears in `Nat.factorial (n + 1 - 1)` and `iteratedDeriv (n + 1 - 1)`).
For Acoeff_one, also fix: rw [Acoeff, ResW1, show n + 1 - 1 = n from by omega] — after unfolding Acoeff/ResW1 (both have the same body structure), the remaining: iteratedDeriv n F 1 / Nat.factorial (n+1−1) = iteratedDeriv n F 1 / Nat.factorial n — the show rewrites n+1−1 → n ✓ then rfl. But rw [Acoeff] — same equation-lemma issue as Gprim? Use `simp only [Acoeff, ResW1]`? — the defs are plain defs: rw [Acoeff] should unfold via equation lemma... The earlier error at 164 was the factorial parse — with Nat.factorial explicit it might work. Let me use `unfold Acoeff ResW1` or simp only. I'll use `simp only [Acoeff, ResW1, show n + 1 - 1 = n from by omega]`? — simp only with a show-term — no, simp args are lemmas: `simp only [Acoeff, ResW1]` then the arithmetic `n + 1 - 1 = n`: simp can close via omega-normalization? `simp only [Acoeff, ResW1]` unfolds both, goal: iteratedDeriv (n+1−1) F 1 / Nat.factorial (n+1−1) = iteratedDeriv n F 1 / Nat.factorial n — then `congr 1`? the args n+1−1 vs n: `congr 1` gives n+1−1 = n and Nat.factorial (n+1−1) = Nat.factorial n — both by omega/rfl... `congr 1 <;> omega`? factorial one needs congr on the argument: `congr 2`? Let me just:
```
lemma Acoeff_one (n : ℕ) : Acoeff n 1 = ResW1 n := by
simp only [Acoeff, ResW1]
congr 1
· omega
· congr 1
omega
```
Hmm — congr 1 on `iteratedDeriv (n+1−1) F 1 / Nat.factorial (n+1−1) = iteratedDeriv n F 1 / Nat.factorial n` — splits into the numerators and denominators: numerator: iteratedDeriv (n+1−1) F 1 = iteratedDeriv n F 1 — congr: n+1−1 = n ✓ omega; denominator: Nat.factorial (n+1−1) = Nat.factorial n: congr 1: n+1−1 = n ✓ omega. Let me structure:
```
simp only [Acoeff, ResW1, show n + 1 - 1 = n from by omega]
```
simp only with the show-equation as a simp rule rewrites n+1−1 → n ✓ then rfl. simp only [X, Y, heq] where heq : n + 1 - 1 = n — used as a rewrite rule ✓ works.
Let me apply all fixes.
Applying all pending fixes with explicit factorial, simp-only unfolds, induction for tail continuity, and the hGint restructure.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiPrincipal.lean'\ns = open(p, encoding='utf-8').read()\n\n# 1. Acoeff: explicit Nat.factorial\ns = s.replace(\"\"\"def Acoeff (n i : \u2115) : \u2102 :=\n iteratedDeriv (n + 1 - i) (fun w : \u2102 => (w ^ n - (w - 1) ^ n) * hLi w) 1 / (n + 1 - i)!\"\"\",\n\"\"\"def Acoeff (n i : \u2115) : \u2102 :=\n iteratedDeriv (n + 1 - i) (fun w : \u2102 => (w ^ n - (w - 1) ^ n) * hLi w) 1 /\n Nat.factorial (n + 1 - i)\"\"\")\n\n# 2. Acoeff_one\ns = s.replace(\"\"\"lemma Acoeff_one (n : \u2115) : Acoeff n 1 = ResW1 n := by\n rw [Acoeff, ResW1, show n + 1 - 1 = n from by omega]\"\"\",\n\"\"\"lemma Acoeff_one (n : \u2115) : Acoeff n 1 = ResW1 n := by\n simp only [Acoeff, ResW1, show n + 1 - 1 = n from by omega]\"\"\")\n\n# 3. Gprim unfolds\ns = s.replace(\"\"\" rw [Gprim]\n apply DifferentiableAt.sum\"\"\",\n\"\"\" simp only [Gprim]\n apply DifferentiableAt.sum\"\"\")\ns = s.replace(\"\"\" rw [Gprim, deriv_sum (fun i hi => ?_)]\"\"\",\n\"\"\" simp only [Gprim]\n rw [deriv_sum (fun i hi => ?_)]\"\"\")\n\n# 4. tail_continuousAt via induction\ns = s.replace(\"\"\"lemma tail_continuousAt {n : \u2115} {w : \u2102} (hw : w \u2260 1) :\n ContinuousAt (\u2211 i \u2208 Finset.Icc 2 (n + 1), Acoeff n i / (w - 1) ^ i) w := by\n apply ContinuousAt.sum\n intro i hi\n rw [Finset.mem_Icc] at hi\n have hw1 : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n apply ContinuousAt.div (continuousAt_const)\n \u00b7 exact (continuousAt_id.sub continuousAt_const).pow _\n \u00b7 exact pow_ne_zero _ hw1\"\"\",\n\"\"\"lemma tail_continuousAt {n : \u2115} {w : \u2102} (hw : w \u2260 1) :\n ContinuousAt (\u2211 i \u2208 Finset.Icc 2 (n + 1), Acoeff n i / (w - 1) ^ i) w := by\n have hterm : \u2200 i : \u2115, ContinuousAt (fun w => Acoeff n i / (w - 1) ^ i) w := by\n intro i\n have hw1 : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n apply ContinuousAt.div (continuousAt_const)\n \u00b7 exact (continuousAt_id.sub continuousAt_const).pow _\n \u00b7 exact pow_ne_zero _ hw1\n have : \u2200 s : Finset \u2115, ContinuousAt (\u2211 i \u2208 s, Acoeff n i / (w - 1) ^ i) w := by\n intro s\n induction s using Finset.induction with\n | empty => simp\n | insert has hs =>\n rename_i a s\n rw [Finset.sum_insert has]\n exact ContinuousAt.add hs (hterm a)\n exact this _\"\"\")\n\n# 5. hGint restructure\ns = s.replace(\"\"\" have hGint : RectangleBorderIntegrable (deriv (Gprim n)) z w := by\n apply HolomorphicOn.rectangleBorderIntegrable' _ h1\n intro s hs\n have hs1 : s \u2260 1 := hs.2\n rw [deriv_Gprim hs1]\n exact (tail_continuousAt hs1).differentiableAt.continuousWithinAt\"\"\",\n\"\"\" have hGint : RectangleBorderIntegrable (deriv (Gprim n)) z w := by\n apply HolomorphicOn.rectangleBorderIntegrable' _ h1\n have hopen : DifferentiableOn \u2102 (deriv (Gprim n)) {1}\u1d9c := by\n have hd : DifferentiableOn \u2102 (Gprim n) {1}\u1d9c := by\n intro s hs\n exact (Gprim_differentiableAt (Set.mem_compl_singleton_iff.mp hs)).differentiableWithinAt\n exact hd.deriv isOpen_compl_singleton\n exact hopen.mono (Set.diff_subset_diff_left (Set.subset_univ _))\"\"\")\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiPrincipal.lean 2>&1 | head -40",
"description": "Apply assembly fixes and recompile",
"timeout": 420000
}
thinking (10715 chars)
I see the HDiv error source: in `hnum.div hden (pow_ne_zero _ hw1)` — `hnum.div` — ContinuousAt.div — the dot-projection: hnum : ContinuousAt (fun w => Acoeff n i) w — `.div hden (pow_ne_zero _ hw1)` — ContinuousAt.div (hf) (hg) (hz : g x ≠ 0) : ContinuousAt (f / g) x — the result (f/g) — Pi division: HDiv (ℂ → ?) — the ERROR `HDiv ℂ ℂ (ℂ → ?m.5)` — hmm — ContinuousAt.div's result: `ContinuousAt (f / g) x` where (f / g) : α → β with pointwise division — instance `Pi.div` — the division f/g of FUNCTIONS — the goal (after `exact`) is the hterm statement `ContinuousAt (fun w => Acoeff n i / (w - 1) ^ i) w` — Lean must unify `(fun w => Acoeff n i) / (fun w => (w−1)^i)` with `fun w => Acoeff n i / (w−1)^i` — Pi.div_apply defeq ✓ — but the ERROR is at 229:46 which is... line 229 = `exact hnum.div hden (pow_ne_zero _ hw1)`?? — let me count: 229 is `have hden : ContinuousAt (fun w => (w - 1) ^ i) w :=` region or the `(continuousAt_id.sub continuousAt_const).pow _` line (229:46 is the `.pow _` position). `.pow _` — ContinuousAt.pow (h) (n) — with `_` — the HDiv error at that position?? no...
Actually — the errors at 229:46 and 237:48 mention `HDiv ℂ ℂ (ℂ → ?m.209 s)` — `?m.209 s` — a function applied to s! In the induction case: `ContinuousAt.add hs (hterm a)` — hs : ContinuousAt (∑ i ∈ s, ...) — wait — ContinuousAt.add (hf) (hg) : ContinuousAt (f + g) x — the goal (after rw [Finset.sum_insert has]) is `ContinuousAt (∑ i ∈ insert a s, ...) w` which rw turned into `ContinuousAt (∑ i ∈ s, ... + Acoeff n a / (w−1)^a) w`?? — Finset.sum_insert : ∑ i ∈ insert a s, f i = f a + ∑ i ∈ s, f i ✓ — so goal: `ContinuousAt (Acoeff n a / (w−1)^a + ∑ i ∈ s, Acoeff n i / (w−1)^i) w` — ContinuousAt.add hs (hterm a) : ContinuousAt ((∑-function) + (term-function)) — via Pi.add — matches the goal up to add order ✓ should work...
The HDiv error `ℂ → ?m.209 s` — something is divided by a FUNCTION. Where? `Acoeff n i / (w - 1) ^ i` — WAIT. I bet the issue is `(w - 1) ^ i` — if `i` here is NOT the natural number exponent but got elaborated as... no. Hmm, `Acoeff n i / (w - 1) ^ i` — Lean parses this as `HDiv.hDiv (Acoeff n i) ((w - 1) ^ i)` — HDiv ℂ ℂ — fine...
Unless — `Acoeff n i` is not ℂ! Acoeff def: `Acoeff (n i : ℕ) : ℂ := iteratedDeriv (n + 1 - i) ... 1 / Nat.factorial (n + 1 - i)` — hmm wait — the elaboration of `Acoeff n i` requires Acoeff to be fully elaborated — if Acoeff's def has an ERROR (line 178/188 simp failures are in DIFFERENT lemmas — Gprim_differentiableAt/deriv_Gprim), Acoeff itself might be fine... The errors at 178/188 are `unfold Gprim` + `apply DifferentiableAt.sum` / `rw [deriv_sum ...]` — those are the NEXT lemmas. Acoeff compiled (no error at 162 now after Nat.factorial fix — the error list no longer shows 162).
So the HDiv error is genuinely in tail_continuousAt. `HDiv ℂ ℂ (ℂ → ?m.209 s)` — the `?m.209 s` — an application of a metavariable to s — in the `insert` case, `rename_i a s` renamed s — the goal after `rw [Finset.sum_insert has]`: `ContinuousAt (Acoeff n a / (w - 1) ^ a + ∑ i ∈ s, Acoeff n i / (w - 1) ^ i) w` — and `ContinuousAt.add hs (hterm a)` — ContinuousAt.add : ContinuousAt (f + g) x with (f + g) via Pi.add — Pi.add's instance HDiv?? no, Pi.add is HAdd. The HDiv error — hmm — `ContinuousAt.add` might not exist! Check: `ContinuousAt.add (hf : ContinuousAt f x) (hg : ContinuousAt g x) : ContinuousAt (f + g) x` ✓ exists I'm sure.
OK let me just look at line numbers precisely: 229:46 and 237:48. Line 229 in the current file — the `have hden` line or `.pow _`. 237 = `exact ContinuousAt.add hs (hterm a)`. The HDiv error at 237:48 = the `hterm a` position — hterm a : ContinuousAt (fun w => Acoeff n a / (w - 1) ^ a) w — the HDiv ℂ ℂ (ℂ → ?m.209 s) — `?m.209 s` — s is the Finset! `Acoeff n i / (w - 1) ^ i` — WAIT. I see it: in hterm's statement I wrote `fun w => Acoeff n i / (w - 1) ^ i` — Lean might parse `Acoeff n i / (w - 1) ^ i` as `(Acoeff n i / (w - 1)) ^ i`?? — no, ^ binds tighter... UNLESS the elaboration made `(w - 1) ^ i` into `HPow.hPow (w-1) i` ✓ fine.
Hold on — `?m.209 s` — s applied — the sum `∑ i ∈ s, Acoeff n i / (w - 1) ^ i` — the summand is a FUNCTION of i (with w FIXED — this is a sum over ℂ values, not functions!). The sum `∑ i ∈ s, Acoeff n i / (w - 1) ^ i` is a COMPLEX NUMBER (sum of complex terms) ✓ — the ContinuousAt is of a CONSTANT function?? NO — tail_continuousAt's statement: `ContinuousAt (∑ i ∈ Finset.Icc 2 (n + 1), Acoeff n i / (w - 1) ^ i) w` — the sum is a fixed complex number and ContinuousAt of a constant — THAT'S NOT WHAT I WANT! The tail sum as a function of w: I need `fun w => ∑ i, Acoeff n i / (w - 1) ^ i`!! In rectInt_deriv_eq_zero's hGc hypothesis I need ContinuousAt (deriv (Gprim n)) s — with deriv_Gprim: deriv (Gprim n) w = ∑ i, Acoeff n i / (w - 1) ^ i — as functions of w. But tail_continuousAt's statement lacks the `fun w =>`!! The goal `ContinuousAt (∑ i ∈ s, Acoeff n i / (w - 1) ^ i) w` — the sum over i of (Acoeff n i / (w−1)^i) — this IS a function of w implicitly?? NO — `∑ i ∈ s, Acoeff n i / (w - 1) ^ i` with w : ℂ a VARIABLE — the sum's VALUE depends on w — so the expression IS a function of w (the lambda is implicit in the proposition). ContinuousAt (expr-involving-w) w — Lean elaborates ContinuousAt f w with f := fun w => expr ✓ — that's how it works (the `this : ∀ s : Finset ℕ, ContinuousAt (∑ i ∈ s, Acoeff n i / (w - 1) ^ i) w` — with w free — Lean generalizes f := fun w => ∑ i ∈ s, ... ✓). So the HDiv error is elsewhere... `HDiv ℂ ℂ (ℂ → ?m.209 s)` — the unifier, when matching `ContinuousAt (∑ i ∈ s, Acoeff n i / (w - 1) ^ i) w` against `ContinuousAt ?f w` with ?f a metavariable — it must abstract w — higher-order pattern unification — it found `Acoeff n i / (w - 1) ^ i` and tried to make ?f := fun w => ... — the HDiv error suggests the division's operands got mistyped: `Acoeff n i` : ℂ and `(w - 1) ^ i` : ℂ — HDiv ℂ ℂ ✓ — but the error says HDiv ℂ ℂ (ℂ → ?m.209 s) — the DIVISOR is `ℂ → ?m.209 s` — a function of type ℂ → (something applied to s). So `(w - 1) ^ i` elaborated as a function ℂ → ?m.209 s?? — with i replaced by a metavariable applied to s! — `?m.209 s` — YES — in the induction's insert case, the `i` in the sum body became `?m.209 s` — because my `this : ∀ s : Finset ℕ, ContinuousAt (∑ i ∈ s, Acoeff n i / (w - 1) ^ i) w` — the `i` in `(w - 1) ^ i` is the BOUND sum variable i ∈ s ✓ — but the elaborator... hmm.
Actually wait — the error at 229:46 is in `hden : ContinuousAt (fun w => (w - 1) ^ i) w := (continuousAt_id.sub continuousAt_const).pow _` — the `.pow _` — ContinuousAt.pow (hf) (n : ℕ) : ContinuousAt (f ^ n) x — the function `f ^ n` — Pi.pow — `(fun w => w − 1) ^ i` — Pi.pow instance: `(fun w => w − 1) ^ i` with i : ℕ ✓ — Pi.pow : Pow (α → β) ℕ (fun _ => Pow β) — HDiv ℂ ℂ (ℂ → ?m.5) — NO that's HDiv not HPow... The hnum.div hden line (229?) — `exact hnum.div hden (pow_ne_zero _ hw1)` — ContinuousAt.div's result (f/g) — Pi.div — HDiv (ℂ→?) — the error HDiv ℂ ℂ (ℂ → ?m.5) — the DIVIDEND is ℂ, divisor ℂ, result ℂ → ?m.5 — THREE different types in HDiv?? HDiv takes α β γ (one type + output): HDiv ℂ ℂ (ℂ → ?m.5) means dividing ℂ by ℂ to get a ℂ → ?m.5 function?! That's the instance synthesis failing to find HDiv ℂ ℂ (ℂ → ?m.5) — because the EXPECTED result of `hnum.div hden _` is the hterm goal `ContinuousAt (fun w => Acoeff n i / (w - 1) ^ i) w` — ContinuousAt F w with F := fun w => Acoeff n i / (w−1)^i — and hnum.div hden gives ContinuousAt ((fun w => Acoeff n i) / (fun w => (w−1)^i)) w — F vs that: unify `fun w => Acoeff n i / (w−1)^i` with `(fun w => Acoeff n i) / (fun w => (w−1)^i)` — by Pi.div_apply: LHS-of-Pi.div at w: (f/g) w = f w / g w = Acoeff n i / (w−1)^i ✓ — the unifier has to synthesize the division `Acoeff n i / (w - 1) ^ i` where it needs HDiv ℂ ℂ ℂ — but the error shows HDiv ℂ ℂ (ℂ → ?m.5) — the divisor `(w - 1) ^ i` — with i FREE — in the unification, i became ?m.5 applied?? — `?m.5` at 229 and `?m.209 s` at 237 — in 237 (the induction insert case), the goal after rw [Finset.sum_insert has] has the term `Acoeff n a / (w - 1) ^ a` — with a renamed... `?m.209 s` — the unifier created a metavariable applied to s. This is the classic "metavariable in the goal from a bad statement" — the hterm statement `∀ i : ℕ, ContinuousAt (fun w => Acoeff n i / (w - 1) ^ i) w` — when applied `hterm a`, gives ContinuousAt (fun w => Acoeff n a / (w−1)^a) w ✓ fine...
I'm going in circles with the text display. The root issue is likely my hterm's `ContinuousAt (fun w => Acoeff n i / (w - 1) ^ i) w` vs the `this`'s `ContinuousAt (∑ i ∈ s, Acoeff n i / (w - 1) ^ i) w` — in `this`, the sum is over complex values ✓ with w the outer variable — Lean elaborates `ContinuousAt (∑ i ∈ s, BODY) w` with f := fun w => ∑ i ∈ s, BODY ✓ — BUT the elaborator must figure out that w in BODY is the SAME w as the point — it does via the lambda... Actually NO — `ContinuousAt (∑ i ∈ s, Acoeff n i / (w - 1) ^ i) w` — here the whole first argument is an EXPRESSION containing w — Lean treats it as `ContinuousAt (fun w => ∑ i ∈ s, Acoeff n i / (w-1)^i) w`? NO — Lean does NOT automatically lambda-abstract! The first arg to ContinuousAt is just an expression of type ℂ?? — ContinuousAt (f : α → β) (x : α) — the first arg must be a FUNCTION. `∑ i ∈ s, Acoeff n i / (w - 1) ^ i` is a ℂ value, not a function! So Lean coerces/unifies it as fun w => ... via eta-expansion during unification with ContinuousAt's signature — and THAT's where the HDiv ℂ ℂ (ℂ → ?m) comes from: Lean is trying to make the ℂ expression into a function ℂ → ? — by eta-expansion, treating the whole `Acoeff n i / (w-1)^i` — with i metavariabled...
RIGHT — the fix: make the function explicit everywhere: `ContinuousAt (fun w => ∑ i ∈ s, Acoeff n i / (w - 1) ^ i) w`. Let me fix tail_continuousAt's statements:
```
lemma tail_continuousAt {n : ℕ} {w : ℂ} (hw : w ≠ 1) :
ContinuousAt (fun w => ∑ i ∈ Finset.Icc 2 (n + 1), Acoeff n i / (w - 1) ^ i) w := by
have hterm : ∀ i : ℕ, ContinuousAt (fun w => Acoeff n i / (w - 1) ^ i) w := ...
have : ∀ s : Finset ℕ, ContinuousAt (fun w => ∑ i ∈ s, Acoeff n i / (w - 1) ^ i) w := by
intro s
induction s using Finset.induction with
| empty => simp
| insert has hs =>
rename_i a s
rw [Finset.sum_insert has]
exact ContinuousAt.add hs (hterm a)
exact this _
```
The insert case goal: ContinuousAt (fun w => Acoeff n a / (w−1)^a + ∑ i ∈ s, ...) w — ContinuousAt.add hs (hterm a) : ContinuousAt ((fun w => ∑...) + (fun w => term)) — Pi.add — matches via Pi.add_apply ✓.
Same for tail_continuousAt's main statement — add `fun w =>`. AND the Gprim eta issues (lines 179/189): use `show` with the explicit family form.
Let me apply all these.
Root cause found: the `ContinuousAt` statements need explicit `fun w =>` lambdas. Fixing along with the eta-form `show` for the sum differentiability.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiPrincipal.lean'\ns = open(p, encoding='utf-8').read()\n\n# 1. Gprim_differentiableAt: show family form\ns = s.replace(\"\"\" unfold Gprim\n apply DifferentiableAt.sum\n intro i hi\n apply DifferentiableAt.mul (differentiableAt_const _)\"\"\",\n\"\"\" unfold Gprim\n show DifferentiableAt \u2102 (\u2211 i \u2208 Finset.Icc 2 (n + 1),\n fun w : \u2102 => -(Acoeff n i / (\u2191i - 1)) * (w - 1) ^ (-(\u2191i - 1))) w\n apply DifferentiableAt.sum\n intro i hi\n apply DifferentiableAt.mul (differentiableAt_const _)\"\"\")\n\n# 2. deriv_Gprim: show family form\ns = s.replace(\"\"\" unfold Gprim\n rw [deriv_sum (fun i hi => ?_)]\"\"\",\n\"\"\" show deriv (\u2211 i \u2208 Finset.Icc 2 (n + 1),\n fun w : \u2102 => -(Acoeff n i / (\u2191i - 1)) * (w - 1) ^ (-(\u2191i - 1))) w = _\n rw [deriv_sum (fun i hi => ?_)]\"\"\")\n\n# 3. tail_continuousAt: explicit fun w =>\ns = s.replace(\"\"\"lemma tail_continuousAt {n : \u2115} {w : \u2102} (hw : w \u2260 1) :\n ContinuousAt (\u2211 i \u2208 Finset.Icc 2 (n + 1), Acoeff n i / (w - 1) ^ i) w := by\"\"\",\n\"\"\"lemma tail_continuousAt {n : \u2115} {w : \u2102} (hw : w \u2260 1) :\n ContinuousAt (fun w => \u2211 i \u2208 Finset.Icc 2 (n + 1), Acoeff n i / (w - 1) ^ i) w := by\"\"\")\ns = s.replace(\"\"\" have : \u2200 s : Finset \u2115, ContinuousAt (\u2211 i \u2208 s, Acoeff n i / (w - 1) ^ i) w := by\"\"\",\n\"\"\" have : \u2200 s : Finset \u2115, ContinuousAt (fun w => \u2211 i \u2208 s, Acoeff n i / (w - 1) ^ i) w := by\"\"\")\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiPrincipal.lean 2>&1 | head -40",
"description": "Fix lambda abstraction issues, recompile",
"timeout": 420000
}
thinking (6300 chars)
Progress but still issues:
1. `Neg ℕ` — in my `show` I wrote `-(↑i - 1)` where ↑i : ℤ?? — the `show` I wrote has `fun w : ℂ => -(Acoeff n i / (↑i - 1)) * (w - 1) ^ (-(↑i - 1))` — the exponents: `-(↑i - 1)` — the ↑i got elaborated as ℕ (the Gprim def's `(-((i : ℤ) - 1))` — in my show I wrote `(-(↑i - 1))` — the ↑i is... i : ℕ, `↑i` with target ℤ from the zpow — but the `-(↑i - 1)` — the `1` and `-` might elaborate in ℕ! In the Gprim def I wrote `(w - 1) ^ (-((i : ℤ) - 1))` — explicit (i : ℤ). In my show I wrote `(-(↑i - 1))` without the type ascription — elaborates in ℕ (Neg ℕ fails). Fix: use `(-((i : ℤ) - 1))` exactly as in Gprim's def.
2. The `show` defeq failure: target `DifferentiableAt ℂ (fun w => ∑ i, f i w) w` vs my show `DifferentiableAt ℂ (∑ i, fun w => f i w) w` — NOT definitionally equal (the sum is over functions vs the lambda outside). Finset.sum_apply : (∑ i ∈ s, f i) x = ∑ i ∈ s, f i x — as functions: (fun w => ∑ i, f i w) vs (∑ i, fun w => f i w) — these ARE equal by Finset.sum_apply pointwise, but as function TERMS they differ — `show` needs defeq — funext-level, not defeq. So `show` fails. Instead: rewrite the goal first with `simp only [Finset.sum_apply]`? — the goal `DifferentiableAt ℂ (fun w => ∑ i, f i w) w` — simp only [Finset.sum_apply] rewrites `(∑ i, f i) w` → `∑ i, f i w` — the goal already has the applied form... Hmm — the issue: after `unfold Gprim`, the goal is `DifferentiableAt ℂ (fun w => ∑ i ∈ Icc 2 (n+1), f i w) w`?? NO — Gprim n w = ∑ i, f i w — the goal is DifferentiableAt ℂ (Gprim n) w — unfold Gprim gives DifferentiableAt ℂ (fun w => ∑ i ∈ ..., f i w) w? — unfold Gprim in the GOAL `DifferentiableAt ℂ (Gprim n) w`: Gprim n is a FUNCTION ℂ → ℂ; unfold gives `DifferentiableAt ℂ (fun w => ∑ i ∈ ..., f i w) w`?? — Gprim n = fun w => ∑ i ∈ ..., (fun w => ...) — wait Gprim's def: `Gprim (n : ℕ) (w : ℂ) : ℂ := ∑ i ∈ ..., -(A_i/(i−1)) * (w−1)^...` — so Gprim n = fun w => ∑ i, term i w — after unfold, goal: DifferentiableAt ℂ (fun w => ∑ i, term i w) w. And DifferentiableAt.sum expects `DifferentiableAt 𝕜 (∑ i ∈ u, A i) x` where A i : E → F — unify `∑ i ∈ u, ?A i` with `fun w => ∑ i, term i w` — eta: ?A i := fun w => term i w ✓ — the unifier FAILED earlier because of the form... The robust way: `apply DifferentiableAt.sum _ (fun i hi => ?_)`? no — the issue is matching `∑ i ∈ u, A i` with `fun w => ∑ i, f i w` — higher-order pattern: `∑ i ∈ u, A i` (a function) vs `fun w => ∑ i, f i w` — unifier sets A i := fun w => f i w ✓ should work via eta... it didn't. Use `Finset.sum_apply` to convert the goal's lambda into the sum-of-functions form FIRST:
```
unfold Gprim
rw [show (fun w : ℂ => ∑ i ∈ Finset.Icc 2 (n + 1), -(Acoeff n i / (↑i - 1)) * (w - 1) ^ (-((i : ℤ) - 1))) =
∑ i ∈ Finset.Icc 2 (n + 1), (fun w : ℂ => -(Acoeff n i / (↑i - 1)) * (w - 1) ^ (-((i : ℤ) - 1))) from by
funext w
simp [Finset.sum_apply]]
apply DifferentiableAt.sum
intro i hi
...
```
`Finset.sum_apply : (∑ i ∈ s, f i) x = ∑ i ∈ s, f i x` — funext: (fun w => ∑ i, f i w) = (∑ i, fun w => f i w)? — funext w: goal (fun w => ∑ i, f i w) w = (∑ i, fun w => f i w) w — LHS beta → ∑ i, f i w; RHS → ∑ i, (fun w => f i w) w = ∑ i, f i w ✓ — simp [Finset.sum_apply] normalizes ✓.
Hmm — actually wait — is Gprim n itself (as a function) already in the "sum of functions" form? `Gprim n` unfolds to `fun w => ∑ i ∈ ..., -(Acoeff n i / (↑i-1)) * (w-1)^...` — the body is ∑ i, (term with w) — so as a function it's `fun w => ∑ i, term i w` — to apply DifferentiableAt.sum I need it as `∑ i, (fun w => term i w)` — same thing via sum_apply. OK.
3. tail empty case: `ContinuousAt (fun w => 0) w` — after simp at empty: goal `ContinuousAt (fun w => ∑ i ∈ ∅, ...) w` = ContinuousAt (fun w => 0) w — `simp` reduced to that but didn't close: `continuousAt_const` — add it: `| empty => simp [continuousAt_const]`? — `simp` should close ContinuousAt (fun w => 0) w via continuousAt_const — it didn't. Use `exact continuousAt_const`.
4. `Finset.sum_insert has` — the `has` got type ℕ (rename_i a s renamed things: `has` is now the a ∉ s proof? The error: `has` has type ℕ — the rename_i a s renamed the WRONG variables: in `Finset.induction`, the insert case binders are (a : α) (s : Finset α) (has : a ∉ s) (hs : p s) — my `| insert has hs =>` pattern: has := a (the element!), hs := s — WRONG order. The case pattern: `| insert a s has hs` — wait the induction's insert case: `∀ ⦃a : α⦄ {s : Finset α}, a ∉ s → p s → p (insert a s)` — binders: a, s, has, hs — pattern `| insert has hs =>` binds has := a, hs := s?? — with two names for four binders, Lean assigns has := a, hs := s, and the remaining two get inaccessible names ✓ that's why `has` was ℕ. Fix: `| insert a s has hs =>` and use has for ∉ and hs for the IH:
```
| insert a s has hs =>
rw [Finset.sum_insert has]
exact ContinuousAt.add hs (hterm a)
```
And remove rename_i.
5. `Set.sdiff_subset_sdiff_left (Set.subset_univ ?m)` — gives `?m \ ?r ⊆ univ \ ?r` — I want Rectangle \ {1} ⊆ {1}ᶜ — {1}ᶜ = univ \ {1} ✓ — so I need sdiff_subset_sdiff_left (h : Rectangle ⊆ univ) : Rectangle \ {1} ⊆ univ \ {1} ✓ — the expected type `z.Rectangle w \ {1} ⊆ {1}ᶜ` — {1}ᶜ vs univ \ {1} — sdiff notation: {1}ᶜ is compl, univ \ {1} is sdiff — same set, different head — convert: `Set.sdiff_subset_sdiff_left (Set.subset_univ _)` produces `z.Rectangle w \ {1} ⊆ Set.univ \ {1}` — need `⊆ {1}ᶜ` — univ \ {1} = {1}ᶜ defeq? `Set.compl_eq_univ_diff`? — use `show z.Rectangle w \ {1} ⊆ {1}ᶜ; exact ...`? Or `.mono` with the univ-diff version — DifferentiableOn.mono expects `z.Rectangle w \ {1} ⊆ {1}ᶜ` — give: `Set.subset_univ _ |> Set.sdiff_subset_sdiff_left` produces univ\{1} — hmm — write it as: `(Set.sdiff_subset_sdiff_left (Set.subset_univ _))` with expected type via `show`:
```
exact hopen.mono (t := z.Rectangle w \ {1}) (by
intro s hs
exact ⟨Set.mem_univ _, hs.2⟩)
```
Cleaner: prove the subset by hand: Rectangle \ {1} ⊆ {1}ᶜ: intro s hs; exact hs.2 — hs : s ∈ Rectangle \ {1} — hs.2 : s ∉ {1} — {1}ᶜ membership: s ∈ {1}ᶜ ⟺ s ∉ {1} ✓ `exact hs.2`. So:
```
exact hopen.mono (by intro s hs; exact hs.2)
```
`DifferentiableOn.mono (h : DifferentiableOn f t) (hs : s ⊆ t) : DifferentiableOn f s` — hopen.mono (subset-proof) ✓.
Let me apply all these fixes.
Several structural fixes needed. Applying them now.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && python - << 'PYEOF'\np = 'NguyenRH1/LiPrincipal.lean'\ns = open(p, encoding='utf-8').read()\n\n# 1. Gprim_differentiableAt: proper function-form conversion\ns = s.replace(\"\"\" unfold Gprim\n show DifferentiableAt \u2102 (\u2211 i \u2208 Finset.Icc 2 (n + 1),\n fun w : \u2102 => -(Acoeff n i / (\u2191i - 1)) * (w - 1) ^ (-(\u2191i - 1))) w\n apply DifferentiableAt.sum\n intro i hi\n apply DifferentiableAt.mul (differentiableAt_const _)\"\"\",\n\"\"\" unfold Gprim\n rw [show (fun w : \u2102 => \u2211 i \u2208 Finset.Icc 2 (n + 1),\n -(Acoeff n i / (\u2191i - 1)) * (w - 1) ^ (-((i : \u2124) - 1))) =\n \u2211 i \u2208 Finset.Icc 2 (n + 1),\n (fun w : \u2102 => -(Acoeff n i / (\u2191i - 1)) * (w - 1) ^ (-((i : \u2124) - 1))) from by\n funext w\n simp [Finset.sum_apply]]\n apply DifferentiableAt.sum\n intro i hi\n apply DifferentiableAt.mul (differentiableAt_const _)\"\"\")\n\n# 2. deriv_Gprim: same conversion\ns = s.replace(\"\"\" show deriv (\u2211 i \u2208 Finset.Icc 2 (n + 1),\n fun w : \u2102 => -(Acoeff n i / (\u2191i - 1)) * (w - 1) ^ (-(\u2191i - 1))) w = _\n rw [deriv_sum (fun i hi => ?_)]\"\"\",\n\"\"\" unfold Gprim\n rw [show (fun w : \u2102 => \u2211 i \u2208 Finset.Icc 2 (n + 1),\n -(Acoeff n i / (\u2191i - 1)) * (w - 1) ^ (-((i : \u2124) - 1))) =\n \u2211 i \u2208 Finset.Icc 2 (n + 1),\n (fun w : \u2102 => -(Acoeff n i / (\u2191i - 1)) * (w - 1) ^ (-((i : \u2124) - 1))) from by\n funext w\n simp [Finset.sum_apply]]\n rw [deriv_sum (fun i hi => ?_)]\"\"\")\n\n# 3. tail induction fixes\ns = s.replace(\"\"\" induction s using Finset.induction with\n | empty => simp\n | insert has hs =>\n rename_i a s\n rw [Finset.sum_insert has]\n exact ContinuousAt.add hs (hterm a)\n exact this _\"\"\",\n\"\"\" induction s using Finset.induction with\n | empty => exact continuousAt_const\n | insert a s has hs =>\n rw [Finset.sum_insert has]\n exact ContinuousAt.add hs (hterm a)\n exact this _\"\"\")\n\n# 4. subset by hand\ns = s.replace(\"exact hopen.mono (Set.sdiff_subset_sdiff_left (Set.subset_univ _))\",\n \"exact hopen.mono (by intro s hs; exact hs.2)\")\n\nopen(p, 'w', encoding='utf-8').write(s)\nprint(\"patched\")\nPYEOF\nexport PATH=\"$HOME/.elan/bin:$PATH\" && lake env lean NguyenRH1/LiPrincipal.lean 2>&1 | head -40",
"description": "Apply structural fixes and recompile",
"timeout": 420000
}
thinking (3523 chars)
Now I can fix precisely:
1. Lines 189/224/237 (the `.differentiableAt.comp w ((hasDerivAt_id w).sub_const 1)`):
The issue is `DifferentiableAt.comp` argument structure. Correct form: `DifferentiableAt.comp (x) (hg : DifferentiableAt 𝕜 g (f x)) (hf : DifferentiableAt 𝕜 f x)`. So:
```
exact ((hasDerivAt_zpow (-((i : ℤ) - 1)) (w - 1) (Or.inl hw1)).differentiableAt).comp w
(((hasDerivAt_id w).sub_const 1).differentiableAt)
```
with explicit zpow argument. And the function forms: hg : DifferentiableAt (fun x => x^m) (w−1) — hf : DifferentiableAt (fun x => id x − 1) w — the composition: (fun x => x^m) ∘ (fun x => id x − 1) = fun x => (id x − 1)^m = fun x => (x−1)^m ✓ — but is `id x − 1` defeq `x − 1` ✓ (id_apply) — and the GOAL's function `(w - 1) ^ m` as a function of w ✓ — the comp result: DifferentiableAt ((fun x => x^m) ∘ (fun x => id x − 1)) w — goal: DifferentiableAt (fun w => (w−1)^m) w — defeq via comp_apply + id ✓ — might need simpa: `simpa using (...)`. Let me use:
```
exact (((hasDerivAt_zpow (-((i : ℤ) - 1)) (w - 1) (Or.inl hw1)).differentiableAt).comp w
(((hasDerivAt_id w).sub_const 1).differentiableAt))
```
and if unification struggles, add simpa.
2. Line 216: `hasDerivAt_zpow _ _ (Or.inl hw1)` — give m explicitly: `hasDerivAt_zpow (-((i : ℤ) - 1)) (w - 1) (Or.inl hw1)` ✓.
3. Line 229: `rw [hzi]` — hzi : ((-(i : ℤ)) : ℂ) = -((i : ℂ)) — the pattern `-↑↑i` — hzi's LHS is `((-(i:ℤ)) : ℂ)` — the goal after rw [hm] has `(w - 1) ^ (-(i : ℤ))` — the exponent is `-(i:ℤ)` (ℤ-negation, not cast) — hzi is about casting −(i:ℤ) to ℂ — the goal's zpow exponent `-(i:ℤ)` : ℤ — hzi's LHS `((-(i:ℤ)) : ℂ)` — that pattern requires the CAST of -(i:ℤ) — in the goal the exponent is INSIDE zpow (stays ℤ) — no cast to rewrite! My hzi was meant for the coefficient `(-((i:ℤ)−1)) : ℂ` — the derivative coefficient. Hmm — let me re-examine: after rw [hd] and deriv_const_mul, the goal is:
-(A_i/(i−1)) * ((-((i:ℤ)−1)) * (w−1)^(-(i:ℤ))) = A_i / (w−1)^i — the coefficient `-((i:ℤ)−1)` cast to ℂ. The `hm` rewrote the EXPONENT `-((i:ℤ)−1)−1 = -(i:ℤ)` ✓. Now the coefficient `((-((i:ℤ)−1)) : ℂ)` — I want to simplify it to `-(↑i−1)` (as a complex number): `(-((i:ℤ)−1) : ℤ)` cast to ℂ = −((i:ℂ)−1): `Int.cast_neg`, `Int.cast_sub`, `Int.cast_one`: `simp [Int.cast_neg, Int.cast_sub]`:
```
rw [hm]
simp only [Int.cast_neg, Int.cast_sub, Int.cast_one]
field_simp [hw1, hi1]
...
```
Let me restructure that part: after rw [hm], goal: −(A_i/(i−1)) · (((-((i:ℤ)−1)):ℂ) · (w−1)^(−(i:ℤ))) = A_i/(w−1)^i. Note (-((i:ℤ)−1) : ℤ) = (1 − i : ℤ): cast to ℂ = 1 − ↑i (Int.cast_sub/neg/one). And −(A_i/(i−1)) · ((1−↑i)·X) = −A_i·(1−↑i)/(↑i−1)·X = A_i·(↑i−1)/(↑i−1)·X = A_i·X — with X = (w−1)^(−(i:ℤ)) = (w−1)^(−i) (zpow_neg: (−(i:ℤ)) = −i... (w−1)^(-(i:ℤ)) — `zpow_natCast` won't directly give the /(w−1)^i (pow) form: (w−1)^(−(i:ℤ)) = ((w−1)^(i:ℤ))⁻¹ = ((w−1)^i)⁻¹ ✓ zpow_neg then zpow_natCast (i:ℤ cast from ℕ ✓).
So: field_simp [hw1, hi1] with the coefficient normalized:
```
rw [hm]
have hc : ((-((i : ℤ) - 1)) : ℂ) = 1 - (i : ℂ) := by
rw [show (-((i : ℤ) - 1) : ℤ) = 1 - (i : ℤ) from by omega]
simp [Int.cast_sub, Int.cast_one]
rw [hc]
field_simp [hw1, hi1]
rw [zpow_neg, zpow_natCast]
field_simp [hw1]
ring
```
The field_simp should clear denominators (i−1, (w−1)^i) and then ring closes: −(A_i/(i−1))·((1−i)·(w−1)^{−i}) = A_i/(w−1)^i ⟺ −A_i(1−i)(w−1)^{−i}(i−1)(w−1)^i = A_i(i−1) ⟺ A_i(i−1) = A_i(i−1) ✓.
Let me apply these three fixes to the exact lines.
Applying precise fixes to the three broken spots.
tool: Edit
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiPrincipal.lean",
"old_string": " apply DifferentiableAt.sum\n intro i hi\n apply DifferentiableAt.mul (differentiableAt_const _)\n have hw1 : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n exact (hasDerivAt_zpow _ (w - 1) (Or.inl hw1)).differentiableAt.comp w\n ((hasDerivAt_id w).sub_const 1)\n\nlemma deriv_Gprim {n : \u2115} {w : \u2102} (hw : w \u2260 1) :",
"new_string": " apply DifferentiableAt.sum\n intro i hi\n apply DifferentiableAt.mul (differentiableAt_const _)\n have hw1 : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n exact (((hasDerivAt_zpow (-((i : \u2124) - 1)) (w - 1) (Or.inl hw1)).differentiableAt).comp w\n (((hasDerivAt_id w).sub_const 1).differentiableAt))\n\nlemma deriv_Gprim {n : \u2115} {w : \u2102} (hw : w \u2260 1) :"
}
thinking (8904 chars)
The cast dance is the issue: `-((i : ℤ) - 1)` displays as `-(↑i - 1)` with ↑i : ℤ — and the derivative coefficient is `↑(-(↑i - 1))` (cast of the INTEGER to ℂ) vs my hd statement's `(-((i : ℤ) - 1)) : ℂ` — these differ in display but... the error at 216:8 says expected `-(↑↑i - 1) * (w - 1) ^ (...)` — DOUBLE cast ↑↑i — the derivative value in hasDerivAt_zpow's result: `↑(m : ℤ)` where m = −(↑i−1) — so the coefficient is `↑(-(↑i - 1))` (cast of ℤ to ℂ) — and my hd statement wrote `((-((i : ℤ) - 1)) : ℂ)` — displayed as `-(↑↑i - 1)`?? — the double-cast: `↑(↑i)` — ↑i is ℕ→ℤ, then ↑↑i is ℤ→ℂ — so `(-((i:ℤ)−1)) : ℂ` displays as `-(↑↑i − 1)` where 1 : ℂ — while hasDerivAt_zpow's derivative is `↑(-(↑i − 1))` displayed as... the mismatch: `↑(-(↑i - 1)) * ...` vs `-(↑↑i - 1) * ...` — one has the whole integer cast, the other has ↑↑i − 1 (cast of i then subtract 1 in ℂ). These are EQUAL but not syntactically — the hasDerivAt_zpow I applied produced its own form, but my h2's stated type has the other form. Fix: make h2's stated type match hasDerivAt_zpow's OUTPUT form exactly: `hasDerivAt_zpow (-((i : ℤ) - 1)) (w - 1) (Or.inl hw1)` produces `HasDerivAt (fun x => x ^ (-(↑i - 1))) (↑(-(↑i - 1)) * (w - 1) ^ (-(↑i - 1) - 1)) (w - 1)` — note `↑(-(↑i - 1))` (whole integer cast). So h2's statement should be:
```
have h2 : HasDerivAt (fun x : ℂ => x ^ (-((i : ℤ) - 1)))
((↑(-((i : ℤ) - 1)) : ℂ) * (w - 1) ^ (-((i : ℤ) - 1) - 1)) (w - 1) :=
hasDerivAt_zpow (-((i : ℤ) - 1)) (w - 1) (Or.inl hw1)
```
Then hcomp : HasDerivAt ((·^m) ∘ (·−1)) (↑(-(↑i−1)) * (w−1)^(m−1) * 1) w — the goal: deriv (fun w => (w−1)^m) w = ((-((i:ℤ)−1)) : ℂ) * (w−1)^(m−1) — with the coefficient form `((-((i:ℤ)−1)) : ℂ)` vs `↑(-(↑i−1))` — same term, different notation — after the Function.comp_apply + mul_one rewrites, hcomp.deriv : deriv ((·^m) ∘ (·−1)) w = ↑(-(↑i−1)) * (w−1)^(m−1) — the GOAL has coefficient `(-((i:ℤ)−1)) : ℂ` — vs hcomp's `↑(-(↑i−1))` — SAME (both are "cast of the integer −(i−1) to ℂ") — just displayed differently. Should unify by defeq/rfl... The error at 220:10: `rw [Function.comp_apply, mul_one] at hcomp` — Function.comp_apply pattern `(?m ∘ ?m) ?m` — the hcomp's function is `((fun x => x ^ m) ∘ fun w => w - 1)` — comp_apply should match `(f ∘ g) x`... but hcomp's HasDerivAt has the function UNAPPLIED (as a whole function in HasDerivAt's first slot) — comp_apply needs an application. Use `simp only [Function.comp_apply, mul_one] at hcomp`? — comp_apply as simp rewrites `(f ∘ g) x` occurrences — the function argument of HasDerivAt is `(fun x => x^m) ∘ (fun w => w−1)` — as a bare function — no application to rewrite. The HasDerivAt.unfold? Instead use `HasDerivAt.comp`'s result directly via hcomp.deriv with the goal form: hcomp : HasDerivAt ((fun x => x^m) ∘ (fun w => w−1)) D w — hcomp.deriv : deriv ((fun x => x^m) ∘ (fun w => w−1)) w = D — the goal: deriv (fun w => (w−1)^m) w = D' — the functions (fun x => x^m) ∘ (fun w => w−1) vs (fun w => (w−1)^m) — defeq (comp_apply + eta): `exact hcomp.deriv` should work if D matches. D = ↑(-(↑i−1)) * (w−1)^(m−1) * 1 — with mul_one not applied — hcomp has `... * 1` at the end (from comp's h₂' * h' = D * 1): rw [mul_one] at hcomp fixes ✓ then exact hcomp.deriv — the coefficient ↑(-(↑i−1)) vs goal's ((-((i:ℤ)−1)) : ℂ) — defeq same ✓ exact should close.
The error at 220 says Function.comp_apply pattern not found in `HasDerivAt ((fun x => x ^ m) ∘ fun w => w - 1) (...) w` — right, no application. Fix: drop Function.comp_apply, just `rw [mul_one] at hcomp; exact hcomp.deriv`.
Line 229: `rw [show (-((i : ℤ) - 1) : ℤ) = 1 - (i : ℤ) from by omega]` — the pattern `-(↑i - 1)` not found in `-(↑↑i - 1) = 1 - ↑i` — the hc statement's LHS `((-((i : ℤ) - 1)) : ℂ)` — displayed as `-(↑↑i - 1)` — my show's LHS `(-((i : ℤ) - 1) : ℤ)` — with the ℤ-negation — these don't match syntactically: hc's LHS is `(↑(-(↑i − 1)) : ℂ)` (whole cast) vs my show pattern `(-((i:ℤ)−1) : ℤ)` — different! The hc statement should be about the CASTED value: `((-((i : ℤ) - 1) : ℤ) : ℂ) = 1 - (i : ℂ)` — i.e., ↑(−(↑i−1)) = 1 − ↑i. My show's LHS `(-((i : ℤ) - 1) : ℤ)` = −(↑i−1) : ℤ — and hc's LHS is the CAST of that to ℂ. The rewrite `rw [show (-((i : ℤ) - 1) : ℤ) = 1 - (i : ℤ) from by omega]` — I want to rewrite the INTEGER inside the cast: the cast is `((X : ℤ) : ℂ)` with X = −(↑i−1) — rewrite X → (1 − ↑i : ℤ): the pattern in hc's LHS is `(↑X : ℂ)` with X = `-(↑i - 1)`... The display `-(↑↑i - 1)` — hmm — that reads as −(↑↑i − 1) : ℂ — i.e., the negation OUTSIDE and ↑↑i − 1 inside — so hc's LHS is `-((↑(↑i)) - 1)`?? — meaning the cast got distributed: ↑(-(↑i−1)) was elaborated/simplified to -(↑↑i − 1)?? — Lean's coercion simp normal form: `↑(-(↑i − 1))` → `-(↑↑i − 1)` (pushing casts outward). So the actual term is `-(↑↑i - 1) : ℂ` (negation of (↑↑i − 1)). My show pattern `(-((i:ℤ)−1) : ℤ)` doesn't appear. Fix: state hc differently:
```
have hc : (-((i : ℤ) - 1) : ℂ) = 1 - (i : ℂ) := by
simp [Int.cast_sub, Int.cast_one]
rw [hc]
```
hc : (↑(-(↑i − 1)) : ℂ) = 1 − ↑i — proof: simp [Int.cast_sub, Int.cast_one] — LHS: ↑(−(↑i−1)) → −(↑↑i − 1)... simp should normalize both sides to the same: LHS −(↑↑i−1) = −↑↑i + 1; RHS 1 − ↑i: are these equal?? −(↑↑i − 1) = 1 − ↑↑i ✓ (as complex: −(x−1) = 1−x ✓) — simp/ring:
```
have hc : (-((i : ℤ) - 1) : ℂ) = 1 - (i : ℂ) := by
push_cast
ring
rw [hc]
```
push_cast normalizes the LHS to −↑↑i + 1 or 1 − ↑↑i; then ring closes 1−↑↑i = 1−↑i (both ↑i : ℂ same cast ✓).
And the earlier hd statement's coefficient: I wrote `((-((i : ℤ) - 1)) : ℂ) * (w - 1) ^ (...)` — after all these, hcomp.deriv should match by defeq (the cast forms are defeq-equal by push_cast normalization, but exact's defeq check goes through instance unfolding — might work). If not, I'll state hd with the normalized coefficient `-(↑i - 1 : ℂ)` from the start... Simplest: change hd's coefficient to `((1 : ℂ) - (i : ℂ))`-free form — keep `((-((i : ℤ) - 1)) : ℂ)` and let the downstream `rw [hc]` handle it — hc rewrites `(-((i:ℤ)−1) : ℂ)` — but the DISPLAYED term is `-(↑↑i−1)` — hc's LHS `(-((i:ℤ)−1) : ℂ)` — after push_cast in hc's PROOF the statement remains `↑(-(↑i−1)) = 1−↑i` — rewriting it in the goal requires the goal to contain `↑(-(↑i−1))` — the goal has `-(↑↑i−1)` (normalized form) — MISMATCH again. Ugh. The robust path: state hd's coefficient AS `(-(↑i - 1) : ℂ)` — i.e., the complex-number negation of (↑i − 1) — and prove the hasDerivAt result matches via push_cast normalization of hcomp.deriv's coefficient. Let me restructure hd:
```
have hd : deriv (fun w => (w - 1) ^ (-((i : ℤ) - 1))) w
= ((-(↑i - 1)) : ℂ) * (w - 1) ^ (-((i : ℤ) - 1) - 1) := by
have h2 := hasDerivAt_zpow (-((i : ℤ) - 1)) (w - 1) (Or.inl hw1)
have h3 : HasDerivAt (fun w : ℂ => w - 1) 1 w := by
simpa using (hasDerivAt_id w).sub_const 1
have hcomp := h2.comp w h3
rw [mul_one] at hcomp
have hd' := hcomp.deriv
push_cast at hd' ⊢
exact hd'
```
Hmm — push_cast at hd' ⊢ — normalizes both to the same form? push_cast on hd' : ↑(−(↑i−1))·... → −(↑↑i−1)·... and goal `(-(↑i−1) : ℂ)·...` — `-(↑i − 1)` with ↑i : ℂ — push_cast normalizes ↑↑i − 1 and ↑i − 1 differently?? (−(↑↑i − 1) : ℂ) vs (−(↑i − 1) : ℂ) — the first is −(x − 1) with x = ↑↑i, the second −(y) with y = ↑i − 1 — push_cast: ↑(↑i) = ↑i (one cast ✓ same). −(↑↑i − 1) = −(↑i − 1) ✓ syntactically after cast fusion ✓. OK — but wait, my hd's coefficient written `(-(↑i - 1) : ℂ)` — that's the complex negation applied to (↑i − 1) — is that the same as the goal's expected form downstream? In the final algebra I want the coefficient to cancel with −(A_i/(i−1)): −(A_i/(i−1)) · ((−(↑i−1))·X) = A_i·(↑i−1)/(↑i−1)·X = A_i·X ✓ via field_simp [hi1] + ring ✓. So let me set hd's coefficient to `(-(↑i - 1) : ℂ)` where ↑i : ℂ — write it as `(-((i : ℂ) - 1) : ℂ)` to be unambiguous... honestly at this point the cleanest is to avoid the coefficient naming entirely: prove hd with the coefficient AS IT COMES from hasDerivAt_zpow (i.e. `↑(-(↑i − 1))`), and in the final algebra, normalize with push_cast before field_simp. Let me restructure the whole term-derivative computation more robustly — actually let me just make hd's statement use EXACTLY the hasDerivAt_zpow output coefficient form, then in the final step push_cast + field_simp + ring:
hd : deriv (fun w => (w - 1) ^ (-((i : ℤ) - 1))) w
= ((↑(-((i : ℤ) - 1))) : ℂ) * (w - 1) ^ (-((i : ℤ) - 1) - 1)
with proof: hcomp.deriv after mul_one — then in the final: rw [deriv_const_mul ..., hd]; then push_cast; field_simp [hw1, hi1]; ring.
The `↑(-((i : ℤ) - 1))` written in Lean: `((-((i : ℤ) - 1) : ℤ) : ℂ)`? — hmm, `↑(-((i:ℤ)−1))` — write `((-((i : ℤ) - 1) : ℤ) : ℂ)` — explicit both casts. Then hcomp.deriv's coefficient is exactly that ✓ exact hcomp.deriv closes after mul_one ✓.
Let me rewrite lines 212–233 accordingly.
Let me rewrite the problematic derivative block with exact cast forms.
tool: Edit ok
input
{
"file_path": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiPrincipal.lean",
"old_string": " have hd : deriv (fun w => (w - 1) ^ (-((i : \u2124) - 1))) w\n = ((-((i : \u2124) - 1)) : \u2102) * (w - 1) ^ (-((i : \u2124) - 1) - 1) := by\n have h2 : HasDerivAt (fun x : \u2102 => x ^ (-((i : \u2124) - 1)))\n ((-((i : \u2124) - 1)) * (w - 1) ^ (-((i : \u2124) - 1) - 1)) (w - 1) :=\n hasDerivAt_zpow (-((i : \u2124) - 1)) (w - 1) (Or.inl hw1)\n have h3 : HasDerivAt (fun w : \u2102 => w - 1) 1 w := by\n simpa using (hasDerivAt_id w).sub_const 1\n have hcomp := h2.comp w h3\n rw [Function.comp_apply, mul_one] at hcomp\n exact hcomp.deriv\n rw [deriv_const_mul _ (by\n have hw1' : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n exact (((hasDerivAt_zpow (-((i : \u2124) - 1)) (w - 1) (Or.inl hw1')).differentiableAt).comp w\n (((hasDerivAt_id w).sub_const 1).differentiableAt))), hd]\n have hm : (-((i : \u2124) - 1) - 1 : \u2124) = -(i : \u2124) := by omega\n rw [hm]\n have hc : ((-((i : \u2124) - 1)) : \u2102) = 1 - (i : \u2102) := by\n rw [show (-((i : \u2124) - 1) : \u2124) = 1 - (i : \u2124) from by omega]\n simp [Int.cast_sub, Int.cast_one]\n rw [hc]\n field_simp [hw1, hi1]\n rw [zpow_neg, zpow_natCast]\n field_simp [hw1]\n ring",
"new_string": " have hd : deriv (fun w => (w - 1) ^ (-((i : \u2124) - 1))) w\n = ((-((i : \u2124) - 1) : \u2124) : \u2102) * (w - 1) ^ (-((i : \u2124) - 1) - 1) := by\n have h2 : HasDerivAt (fun x : \u2102 => x ^ (-((i : \u2124) - 1)))\n (((-((i : \u2124) - 1) : \u2124) : \u2102) * (w - 1) ^ (-((i : \u2124) - 1) - 1)) (w - 1) :=\n hasDerivAt_zpow (-((i : \u2124) - 1)) (w - 1) (Or.inl hw1)\n have h3 : HasDerivAt (fun w : \u2102 => w - 1) 1 w := by\n simpa using (hasDerivAt_id w).sub_const 1\n have hcomp := h2.comp w h3\n rw [mul_one] at hcomp\n exact hcomp.deriv\n rw [deriv_const_mul _ (by\n have hw1' : w - 1 \u2260 0 := sub_ne_zero.mpr hw\n exact (((hasDerivAt_zpow (-((i : \u2124) - 1)) (w - 1) (Or.inl hw1')).differentiableAt).comp w\n (((hasDerivAt_id w).sub_const 1).differentiableAt))), hd]\n have hm : (-((i : \u2124) - 1) - 1 : \u2124) = -(i : \u2124) := by omega\n rw [hm]\n push_cast\n field_simp [hw1, hi1]\n rw [zpow_neg, zpow_natCast]\n field_simp [hw1]\n ring"
}
result 2026-08-21 22:21:18Z → 2026-08-26 06:29:12Z
{
"filePath": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\NguyenRH1\\LiDogLeg.lean",
"oldString": " rw [intervalIntegral.integral_eq_sub_of_hasDerivAt hF hint]\n have h1 : (0 : \u211d) \u2264 Real.exp (-c * XR) / c := by positivity\n have e : Real.exp (-c * 3) = Real.exp (-3 * c) := by\n congr 1\n ring\n rw [e]\n linarith [h1]",
"newString": " rw [intervalIntegral.integral_eq_sub_of_hasDerivAt hF hint, e, sub_le_iff_le_add]\n have h1 : (0 : \u211d) \u2264 Real.exp (-c * XR) := (Real.exp_pos _).le\n have h2 : -Real.exp (-c * XR) / c \u2264 0 := by\n apply div_nonpos_of_nonpos_of_nonneg _ hc.le\n linarith [h1]\n linarith [h2]",
"originalFile": "/-\nNguyenRH1/LiDogLeg.lean \u2014 ii\u2032-6-DL-1 (D-074, session 040): the zero-free\ndog-leg deformation of the Lagarias horizontal right tail.\n\nTHE CONTENT (D-074 \u00a73.1\u20133.2): on the dog-leg rectangle [3, X_R]\u00d7[T, U]\n(T > 0), the Lagarias integrand Jlag n s = (s/(s\u22121))\u207f\u22121 \u00b7 (\u2212\u03b6\u2032/\u03b6(s)) is\nholomorphic UNCONDITIONALLY (s \u2260 1 since im > 0; \u03b6 s \u2260 0 for re s \u2265 3 > 1\nby Mathlib's Euler-product nonvanishing `riemannZeta_ne_zero_of_one_lt_re`\n\u2014 NO perimeter hypothesis, no zero-avoidance at U). Cauchy's theorem\n(`HolomorphicOn.vanishesOnRectangle`) then gives the EXACT deformation\nidentity\n H(3\u2192X_R, T) = H(3\u2192X_R, U) \u2212 V(X_R, T\u2192U) + V(3, T\u2192U)\n(the upper right tail = the high horizontal \u2212 the right drop + the left\nlift), plus the Jlag conjugation identity for the lower-side transfer.\n\nThis is the repair of Finding F-D (D-072): the broken low-path envelope\nis ABANDONED (not bounded) \u2014 the magnitude bound comes later from the\nthree dog-leg pieces, all in the unconditionally zero-free region.\n-/\nimport Mathlib\nimport NguyenRH1.LiSides\nimport NguyenRH1.LiTightR\nimport NguyenRH1.LiBasePoints\n\nopen Zeta23 Complex Filter Topology\nopen scoped Nat\n\nnoncomputable section\n\nnamespace NguyenRH1\n\n/-! ## 1. Dog-leg analyticity (D-074 \u00a73.1; no perimeter) -/\n\n/-- The dog-leg corners (same real-part/imaginary-part form as rectZ/rectW). -/\ndef dogZ (T : \u211d) : \u2102 := ((3 : \u211d) : \u2102) + (T : \u211d) * Complex.I\ndef dogW (XR U : \u211d) : \u2102 := ((XR : \u211d) : \u2102) + (U : \u211d) * Complex.I\n\nlemma dogZ_re (T : \u211d) : (dogZ T).re = 3 := by simp [dogZ]\nlemma dogZ_im (T : \u211d) : (dogZ T).im = T := by simp [dogZ]\nlemma dogW_re (XR U : \u211d) : (dogW XR U).re = XR := by simp [dogW]\nlemma dogW_im (XR U : \u211d) : (dogW XR U).im = U := by simp [dogW]\n\n/-- Jlag is differentiable at every point with 3 \u2264 re, 0 < im:\n\u03b6 is zero-free for 1 < re (Mathlib `riemannZeta_ne_zero_of_one_lt_re`,\nUNCONDITIONAL \u2014 the Euler-product region) and s \u2260 1 (im \u2260 0).\nNO perimeter hypothesis. -/\ntheorem Jlag_differentiableAt_dogleg {n : \u2115} {s : \u2102}\n (hre : 3 \u2264 s.re) (him : 0 < s.im) :\n DifferentiableAt \u2102 (Jlag n) s := by\n apply Jlag_differentiableAt\n \u00b7 rintro rfl\n simp at him\n \u00b7 exact riemannZeta_ne_zero_of_one_lt_re (by linarith)\n\n/-- Jlag is holomorphic on the whole dog-leg rectangle\n[3, X_R]\u00d7[T, U] (T > 0). -/\ntheorem holomorphicOn_Jlag_dogleg {n : \u2115} {T U XR : \u211d}\n (hT : 0 < T) (hTU : T \u2264 U) (hXR : 3 \u2264 XR) :\n HolomorphicOn (Jlag n) (Rectangle (dogZ T) (dogW XR U)) := by\n intro s hs\n rw [Rectangle, Complex.mem_reProdIm, dogZ_re, dogW_re, dogZ_im, dogW_im] at hs\n rw [Set.uIcc_of_le hXR, Set.uIcc_of_le hTU] at hs\n exact (Jlag_differentiableAt_dogleg hs.1.1 (by linarith [hs.2.1])).differentiableWithinAt\n\n/-- **The dog-leg rectangle integral vanishes** (Cauchy; the region is\nunconditionally zero-free \u2014 the residue sum is EMPTY, no perimeter). -/\ntheorem rectangleIntegral_Jlag_dogleg_eq_zero {n : \u2115} {T U XR : \u211d}\n (hT : 0 < T) (hTU : T \u2264 U) (hXR : 3 \u2264 XR) :\n RectangleIntegral (Jlag n) (dogZ T) (dogW XR U) = 0 :=\n (holomorphicOn_Jlag_dogleg hT hTU hXR).vanishesOnRectangle subset_rfl\n\n/-- The (2\u03c0i)\u207b\u00b9-normalized form (API symmetry with rectInt'_Jlag). -/\ntheorem rectangleIntegral'_Jlag_dogleg_eq_zero {n : \u2115} {T U XR : \u211d}\n (hT : 0 < T) (hTU : T \u2264 U) (hXR : 3 \u2264 XR) :\n RectangleIntegral' (Jlag n) (dogZ T) (dogW XR U) = 0 := by\n rw [RectangleIntegral', rectangleIntegral_Jlag_dogleg_eq_zero hT hTU hXR,\n smul_zero]\n\n/-- **THE EXACT DOG-LEG DEFORMATION IDENTITY** (D-074 \u00a73.2 (\u2605), the\ncapstone for ii\u2032-6-c): the low right-horizontal equals the high\nhorizontal minus the right drop plus the left lift. Orientations: all\nH-integrals left-to-right, all V-integrals upward (the main contour's\ntop side is their reversal, handled at the fold site). -/\ntheorem upper_right_horizontal_eq_dogleg {n : \u2115} {T U XR : \u211d}\n (hT : 0 < T) (hTU : T \u2264 U) (hXR : 3 \u2264 XR) :\n HIntegral (Jlag n) 3 XR T =\n HIntegral (Jlag n) 3 XR U - VIntegral (Jlag n) XR T U +\n VIntegral (Jlag n) 3 T U := by\n have h0 := rectangleIntegral_Jlag_dogleg_eq_zero (n := n) hT hTU hXR\n unfold RectangleIntegral at h0\n rw [dogZ_re, dogZ_im, dogW_re, dogW_im] at h0\n linear_combination h0\n\n/-! ## 2. The conjugation identity (for the lower-side transfer, DL-5) -/\n\n/-- kFun is conjugation-symmetric (real-coefficient rational function). -/\ntheorem kFun_conj (n : \u2115) (s : \u2102) :\n kFun n ((starRingEnd \u2102) s) = (starRingEnd \u2102) (kFun n s) := by\n unfold kFun\n simp [map_sub, map_pow, map_one]\n\n/-- **Jlag is conjugation-symmetric** (from `riemannZeta_conj` +\n`iteratedDeriv_riemannZeta_conj`): Jlag n (s\u0304) = conj (Jlag n s).\nNeeded for the lower-horizontal transfer (DL-5). -/\ntheorem Jlag_conj (n : \u2115) {s : \u2102} (hs : s \u2260 1) :\n Jlag n ((starRingEnd \u2102) s) = (starRingEnd \u2102) (Jlag n s) := by\n have h1 : deriv riemannZeta ((starRingEnd \u2102) s) =\n (starRingEnd \u2102) (deriv riemannZeta s) := by\n have h := iteratedDeriv_riemannZeta_conj 1 hs\n rwa [iteratedDeriv_one] at h\n unfold Jlag\n rw [kFun_conj, _root_.riemannZeta_conj, h1]\n simp only [map_mul, map_neg, map_div\u2080]\n\n/-! ## 3. The left-lift bound (DL-2, D-074 \u00a73.3 V_left) -/\n\n/-- **Kernel on the lift**: \u2016kFun n (3+it)\u2016 \u2264 e^{5/2}+1 for n \u2264 t\u00b2\n(D-074 \u00a76: |(3+it)/(2+it)|\u00b2 = (9+t\u00b2)/(4+t\u00b2) = 1 + 5/(4+t\u00b2), whose n-th\npower is \u2264 e^{5n/(2(4+t\u00b2))} \u2264 e^{5/2}). -/\ntheorem kFun_three_add_it_norm_le_exp_five_halves_add_one {n : \u2115} {t : \u211d}\n (hT : (n : \u211d) \u2264 t ^ 2) :\n \u2016kFun n ((3 : \u211d) + t * Complex.I)\u2016 \u2264 Real.exp (5 / 2) + 1 := by\n rcases Nat.eq_zero_or_pos n with hn | hn\n \u00b7 subst hn\n simp only [kFun, pow_zero, sub_self, norm_zero]\n positivity\n \u00b7 have hnR : (1 : \u211d) \u2264 (n : \u211d) := by exact_mod_cast hn\n have ht2 : (0 : \u211d) < 4 + t ^ 2 := by positivity\n have hn4t2 : (n : \u211d) \u2264 4 + t ^ 2 := by linarith [hT]\n have hQpos : (0 : \u211d) \u2264 (9 + t ^ 2) / (4 + t ^ 2) := by positivity\n have hQle : (9 + t ^ 2) / (4 + t ^ 2) \u2264 Real.exp (5 / (n : \u211d)) := by\n have h1 : (9 + t ^ 2) / (4 + t ^ 2) = 1 + 5 / (4 + t ^ 2) := by\n field_simp [ht2.ne']\n ring\n rw [h1]\n have h2 : 5 / (4 + t ^ 2) \u2264 5 / (n : \u211d) :=\n (div_le_div_iff_of_pos_left (by norm_num) ht2 (by positivity)).mpr hn4t2\n have h3 := Real.add_one_le_exp (5 / (n : \u211d))\n linarith\n have hQn : ((9 + t ^ 2) / (4 + t ^ 2)) ^ n \u2264 Real.exp 5 := by\n calc ((9 + t ^ 2) / (4 + t ^ 2)) ^ n \u2264 (Real.exp (5 / (n : \u211d))) ^ n :=\n pow_le_pow_left\u2080 hQpos hQle n\n _ = Real.exp 5 := by\n rw [\u2190 Real.exp_nat_mul]\n congr 1\n have hn0 : (n : \u211d) \u2260 0 := by exact_mod_cast hn.ne'\n field_simp [hn0]\n have hns3 : Complex.normSq ((3 : \u211d) + t * Complex.I) = 9 + t ^ 2 := by\n simp [Complex.normSq_apply]\n ring\n have hns2 : Complex.normSq ((2 : \u211d) + t * Complex.I) = 4 + t ^ 2 := by\n simp [Complex.normSq_apply]\n ring\n have hnormA : \u2016((3 : \u211d) + t * Complex.I)\u2016 = Real.sqrt (9 + t ^ 2) := by\n have h1 : \u2016((3 : \u211d) + t * Complex.I)\u2016 =\n Real.sqrt (Complex.normSq ((3 : \u211d) + t * Complex.I)) := by\n rw [Complex.normSq_eq_norm_sq, Real.sqrt_sq (norm_nonneg _)]\n rw [h1, hns3]\n have hnormB : \u2016((2 : \u211d) + t * Complex.I)\u2016 = Real.sqrt (4 + t ^ 2) := by\n have h1 : \u2016((2 : \u211d) + t * Complex.I)\u2016 =\n Real.sqrt (Complex.normSq ((2 : \u211d) + t * Complex.I)) := by\n rw [Complex.normSq_eq_norm_sq, Real.sqrt_sq (norm_nonneg _)]\n rw [h1, hns2]\n have hnorm : \u2016((3 : \u211d) + t * Complex.I) / ((2 : \u211d) + t * Complex.I)\u2016 =\n Real.sqrt ((9 + t ^ 2) / (4 + t ^ 2)) := by\n rw [norm_div, hnormA, hnormB,\n \u2190 Real.sqrt_div (by positivity : (0 : \u211d) \u2264 9 + t ^ 2)]\n have hs1 : ((3 : \u211d) + t * Complex.I) - 1 = (2 : \u211d) + t * Complex.I := by\n push_cast\n ring\n unfold kFun\n rw [hs1]\n calc \u2016(((3 : \u211d) + t * Complex.I) / ((2 : \u211d) + t * Complex.I)) ^ n - 1\u2016\n \u2264 \u2016(((3 : \u211d) + t * Complex.I) / ((2 : \u211d) + t * Complex.I)) ^ n\u2016 + \u2016(1 : \u2102)\u2016 :=\n norm_sub_le _ _\n _ = (Real.sqrt ((9 + t ^ 2) / (4 + t ^ 2))) ^ n + 1 := by\n rw [norm_pow, hnorm, norm_one]\n _ \u2264 Real.exp (5 / 2) + 1 := by\n have h4 : (Real.sqrt ((9 + t ^ 2) / (4 + t ^ 2))) ^ n \u2264 Real.exp (5 / 2) := by\n have hx0 : (0 : \u211d) \u2264 Real.sqrt ((9 + t ^ 2) / (4 + t ^ 2)) :=\n Real.sqrt_nonneg _\n have hx : (0 : \u211d) \u2264 (Real.sqrt ((9 + t ^ 2) / (4 + t ^ 2))) ^ n :=\n pow_nonneg hx0 n\n have h5 : ((Real.sqrt ((9 + t ^ 2) / (4 + t ^ 2))) ^ n) ^ 2 \u2264 Real.exp 5 := by\n have e : ((Real.sqrt ((9 + t ^ 2) / (4 + t ^ 2))) ^ n) ^ 2 =\n ((9 + t ^ 2) / (4 + t ^ 2)) ^ n := by\n rw [\u2190 pow_mul, mul_comm n 2, pow_mul, Real.sq_sqrt hQpos]\n rw [e]\n exact hQn\n have h8 : (Real.sqrt ((9 + t ^ 2) / (4 + t ^ 2))) ^ n =\n Real.sqrt (((Real.sqrt ((9 + t ^ 2) / (4 + t ^ 2))) ^ n) ^ 2) := by\n rw [Real.sqrt_sq hx]\n rw [h8]\n calc Real.sqrt (((Real.sqrt ((9 + t ^ 2) / (4 + t ^ 2))) ^ n) ^ 2)\n \u2264 Real.sqrt (Real.exp 5) := Real.sqrt_le_sqrt h5\n _ = Real.exp (5 / 2) := (Real.exp_half 5).symm\n linarith [h4]\n\n/-- The Dirichlet majorant at s = 3 (summable since 3 > 1). -/\ndef dirichletC3 : \u211d :=\n \u2211' n : \u2115, \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) (3 : \u2102) n\u2016\n\n/-- Termwise 3-vs-2 comparison for the \u039b L-series: \u039b(n)/n\u00b3 \u2264 (1/2)\u00b7\u039b(n)/n\u00b2. -/\nlemma norm_term_vonMangoldt_three_le_half (n : \u2115) :\n \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) (3 : \u2102) n\u2016 \u2264\n (1 / 2) * \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) (2 : \u2102) n\u2016 := by\n have h3re : ((3 : \u2102).re) = 3 := rfl\n have h2re : ((2 : \u2102).re) = 2 := rfl\n simp only [LSeries.norm_term_eq, h3re, h2re]\n split\n \u00b7 norm_num\n \u00b7 next hn =>\n rcases eq_or_ne n 1 with rfl | hn1\n \u00b7 simp [ArithmeticFunction.vonMangoldt_apply_one]\n \u00b7 have hn2 : 2 \u2264 n := by omega\n have h\u039b : \u2016(ArithmeticFunction.vonMangoldt n : \u2102)\u2016 =\n ArithmeticFunction.vonMangoldt n :=\n Complex.norm_of_nonneg ArithmeticFunction.vonMangoldt_nonneg\n rw [h\u039b]\n have e : ArithmeticFunction.vonMangoldt n / (n : \u211d) ^ (3 : \u211d) =\n (1 / (n : \u211d)) * (ArithmeticFunction.vonMangoldt n / (n : \u211d) ^ (2 : \u211d)) := by\n rw [show (3 : \u211d) = 2 + 1 by norm_num,\n Real.rpow_add (by positivity : (0 : \u211d) < (n : \u211d)), Real.rpow_one]\n field_simp [show (n : \u211d) \u2260 0 by positivity]\n have h12 : (1 : \u211d) / (n : \u211d) \u2264 1 / 2 :=\n one_div_le_one_div_of_le (by norm_num : (0 : \u211d) < 2)\n (by exact_mod_cast hn2 : (2 : \u211d) \u2264 (n : \u211d))\n have hpos : (0 : \u211d) \u2264 ArithmeticFunction.vonMangoldt n / (n : \u211d) ^ (2 : \u211d) :=\n div_nonneg ArithmeticFunction.vonMangoldt_nonneg\n (Real.rpow_nonneg (by positivity : (0 : \u211d) \u2264 (n : \u211d)) _)\n calc ArithmeticFunction.vonMangoldt n / (n : \u211d) ^ (3 : \u211d)\n = (1 / (n : \u211d)) * (ArithmeticFunction.vonMangoldt n / (n : \u211d) ^ (2 : \u211d)) := e\n _ \u2264 (1 / 2) * (ArithmeticFunction.vonMangoldt n / (n : \u211d) ^ (2 : \u211d)) :=\n mul_le_mul_of_nonneg_right h12 hpos\n\n/-- dirichletC3 \u2264 1/2 (the termwise comparison + dirichletC2 \u2264 1) \u2014\nthe certified C_zeta3 = 0.5 of D-074 \u00a74. (A tighter 0.17 build is\npossible via a 6-prime partial sum + antitone-integral tail; the fold\nis indifferent to the constant, so the cheap certified 0.5 is charged.) -/\nlemma dirichletC3_le_half : dirichletC3 \u2264 1 / 2 := by\n have hsum3 : Summable (fun n : \u2115 =>\n \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) (3 : \u2102) n\u2016) := by\n rw [summable_norm_iff]\n exact ArithmeticFunction.LSeriesSummable_vonMangoldt (by norm_num)\n have hsum2 : Summable (fun n : \u2115 =>\n \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) (2 : \u2102) n\u2016) := by\n rw [summable_norm_iff]\n exact ArithmeticFunction.LSeriesSummable_vonMangoldt (by norm_num)\n calc dirichletC3\n = \u2211' n : \u2115, \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) (3 : \u2102) n\u2016 := rfl\n _ \u2264 \u2211' n : \u2115, (1 / 2) *\n \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) (2 : \u2102) n\u2016 :=\n Summable.tsum_le_tsum (fun n => norm_term_vonMangoldt_three_le_half n) hsum3\n (hsum2.mul_left (1 / 2))\n _ = (1 / 2) * dirichletC2 := by rw [dirichletC2, tsum_mul_left]\n _ \u2264 1 / 2 := by linarith [dirichletC2_le_one]\n\n/-- \u2016\u03b6\u2032/\u03b6 s\u2016 \u2264 dirichletC3 for re s \u2265 3 (the s = 3 clone of the\nDirichlet-series majorant). -/\nlemma norm_logDeriv_zeta_le_dirichletC3 {s : \u2102} (hs : 3 \u2264 s.re) :\n \u2016logDeriv riemannZeta s\u2016 \u2264 dirichletC3 := by\n have hs1 : (1 : \u211d) < s.re := by linarith\n have h1 : -logDeriv riemannZeta s\n = LSeries (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) s := by\n have h2 := ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div hs1\n rw [logDeriv, Pi.div_apply, h2]\n ring\n have hsum3 : Summable (fun n : \u2115 =>\n \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) (3 : \u2102) n\u2016) := by\n rw [summable_norm_iff]\n exact ArithmeticFunction.LSeriesSummable_vonMangoldt (by norm_num)\n have hsumS : Summable (fun n : \u2115 =>\n \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) s n\u2016) := by\n rw [summable_norm_iff]\n exact ArithmeticFunction.LSeriesSummable_vonMangoldt hs1\n have hle : \u2016LSeries (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) s\u2016\n \u2264 dirichletC3 := by\n show \u2016\u2211' n : \u2115, LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) s n\u2016 \u2264 _\n calc \u2016\u2211' n : \u2115, LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) s n\u2016\n \u2264 \u2211' n : \u2115, \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) s n\u2016 :=\n norm_tsum_le_tsum_norm hsumS\n _ \u2264 \u2211' n : \u2115, \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) (3 : \u2102) n\u2016 :=\n Summable.tsum_le_tsum (fun n => LSeries.norm_term_le_of_re_le_re _ (by\n simp\n exact hs) n) hsumS hsum3\n _ = dirichletC3 := rfl\n calc \u2016logDeriv riemannZeta s\u2016\n = \u2016LSeries (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) s\u2016 := by\n rw [\u2190 h1, norm_neg]\n _ \u2264 dirichletC3 := hle\n\n/-- \u2016\u03b6\u2032/\u03b6 s\u2016 \u2264 1/2 for re s \u2265 3 (the charged C_zeta3 = 0.5). -/\nlemma norm_logDeriv_zeta_le_half {s : \u2102} (hs : 3 \u2264 s.re) :\n \u2016logDeriv riemannZeta s\u2016 \u2264 1 / 2 :=\n (norm_logDeriv_zeta_le_dirichletC3 hs).trans dirichletC3_le_half\n\n/-- **The left-lift bound** (D-074 \u00a73.3 V_left): for 0 < T \u2264 U and\nn \u2264 T\u00b2, \u2016VIntegral (Jlag n) 3 T U\u2016 \u2264 (U \u2212 T)\u00b7(e^{5/2}+1)/2. The kernel\n\u2264 e^{5/2}+1 (the 1+5/(4+t\u00b2) computation), the zeta factor \u2264 1/2\n(certified, no perimeter). -/\ntheorem vIntegral_Jlag_three_norm_le {n : \u2115} {T U : \u211d}\n (hT0 : (0 : \u211d) < T) (hTU : T \u2264 U) (hTn : (n : \u211d) \u2264 T ^ 2) :\n \u2016VIntegral (Jlag n) 3 T U\u2016 \u2264 (U - T) * (Real.exp (5 / 2) + 1) / 2 := by\n have hnorm : \u2016VIntegral (Jlag n) 3 T U\u2016 =\n \u2016\u222b t in T..U, Jlag n ((3 : \u211d) + t * Complex.I)\u2016 := by\n unfold VIntegral\n rw [norm_smul, Complex.norm_I, one_mul]\n rw [hnorm]\n have hbound : \u2200 t \u2208 Set.Ioc T U,\n \u2016Jlag n ((3 : \u211d) + t * Complex.I)\u2016 \u2264 (Real.exp (5 / 2) + 1) * (1 / 2) := by\n intro t ht\n have htT : T < t := ht.1\n have ht2 : (n : \u211d) \u2264 t ^ 2 := by nlinarith [hTn, hT0]\n have hre : (3 : \u211d) \u2264 ((3 : \u211d) + t * Complex.I).re := by simp\n have h1 := kFun_three_add_it_norm_le_exp_five_halves_add_one ht2\n have h2 := norm_logDeriv_zeta_le_half (s := (3 : \u211d) + t * Complex.I) hre\n have hnorm3 : \u2016Jlag n ((3 : \u211d) + t * Complex.I)\u2016 =\n \u2016kFun n ((3 : \u211d) + t * Complex.I)\u2016 *\n \u2016logDeriv riemannZeta ((3 : \u211d) + t * Complex.I)\u2016 := by\n show \u2016kFun n ((3 : \u211d) + t * Complex.I) *\n (-logDeriv riemannZeta ((3 : \u211d) + t * Complex.I))\u2016 = _\n rw [norm_mul, norm_neg]\n rw [hnorm3]\n exact mul_le_mul h1 h2 (norm_nonneg _) (by positivity)\n have hint : \u2016\u222b t in T..U, Jlag n ((3 : \u211d) + t * Complex.I)\u2016 \u2264\n ((Real.exp (5 / 2) + 1) * (1 / 2)) * |U - T| := by\n apply intervalIntegral.norm_integral_le_of_norm_le_const\n intro t ht\n rw [Set.uIoc_of_le hTU] at ht\n exact hbound t ht\n have habs : |U - T| = U - T := abs_of_nonneg (by linarith)\n rw [habs] at hint\n calc \u2016\u222b t in T..U, Jlag n ((3 : \u211d) + t * Complex.I)\u2016\n \u2264 ((Real.exp (5 / 2) + 1) * (1 / 2)) * (U - T) := hint\n _ = (U - T) * (Real.exp (5 / 2) + 1) / 2 := by ring\n\n/-! ## 4. The high-horizontal stepping (DL-3, D-074 \u00a77 + D-073 \u00a74) -/\n\n/-- Termwise \u03c3-vs-2 comparison for the \u039b L-series (the (6.10) halving):\n\u039b(m)/m^\u03c3 \u2264 2^{\u2212(\u03c3\u22122)}\u00b7\u039b(m)/m\u00b2 for \u03c3 \u2265 2. -/\nlemma norm_term_vonMangoldt_le_two_pow {\u03c3 t : \u211d} (h\u03c3 : 2 \u2264 \u03c3) (m : \u2115) :\n \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102))\n ((\u03c3 : \u211d) + t * Complex.I) m\u2016 \u2264\n (2 : \u211d) ^ (-(\u03c3 - 2)) * \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) (2 : \u2102) m\u2016 := by\n have h\u03c3re : ((\u03c3 : \u211d) + t * Complex.I).re = \u03c3 := by simp\n have h2re : ((2 : \u2102).re) = 2 := rfl\n simp only [LSeries.norm_term_eq, h\u03c3re, h2re]\n split\n \u00b7 norm_num\n \u00b7 next hm =>\n have h\u039b : \u2016(ArithmeticFunction.vonMangoldt m : \u2102)\u2016 =\n ArithmeticFunction.vonMangoldt m :=\n Complex.norm_of_nonneg ArithmeticFunction.vonMangoldt_nonneg\n rw [h\u039b]\n rcases eq_or_ne m 1 with rfl | hm1\n \u00b7 simp [ArithmeticFunction.vonMangoldt_apply_one]\n \u00b7 have hm2 : 2 \u2264 m := by omega\n have e : ArithmeticFunction.vonMangoldt m / (m : \u211d) ^ \u03c3 =\n (1 / (m : \u211d) ^ (\u03c3 - 2)) * (ArithmeticFunction.vonMangoldt m / (m : \u211d) ^ (2 : \u211d)) := by\n rw [show (\u03c3 : \u211d) = (\u03c3 - 2) + 2 by ring,\n Real.rpow_add (by positivity : (0 : \u211d) < (m : \u211d))]\n field_simp [show (m : \u211d) \u2260 0 by positivity]\n ring_nf\n rw [e]\n have hle : (1 : \u211d) / (m : \u211d) ^ (\u03c3 - 2) \u2264 (2 : \u211d) ^ (-(\u03c3 - 2)) := by\n rw [Real.rpow_neg (by norm_num : (0 : \u211d) \u2264 2), \u2190 one_div]\n apply one_div_le_one_div_of_le (Real.rpow_pos_of_pos (by norm_num : (0 : \u211d) < 2) _)\n exact Real.rpow_le_rpow (by norm_num : (0 : \u211d) \u2264 2)\n (by exact_mod_cast hm2 : (2 : \u211d) \u2264 (m : \u211d)) (by linarith : (0 : \u211d) \u2264 \u03c3 - 2)\n have hpos : (0 : \u211d) \u2264 ArithmeticFunction.vonMangoldt m / (m : \u211d) ^ (2 : \u211d) :=\n div_nonneg ArithmeticFunction.vonMangoldt_nonneg\n (Real.rpow_nonneg (by positivity : (0 : \u211d) \u2264 (m : \u211d)) _)\n exact mul_le_mul_of_nonneg_right hle hpos\n\n/-- \u2016\u03b6\u2032/\u03b6(\u03c3+it)\u2016 \u2264 2^{\u2212(\u03c3\u22122)}\u00b7dirichletC2 for \u03c3 \u2265 2 (the (6.10)\nhalving in LSeries form; dirichletC2 \u2264 1 makes the tail free). -/\nlemma norm_logDeriv_zeta_le_two_pow {\u03c3 t : \u211d} (h\u03c3 : 2 \u2264 \u03c3) :\n \u2016logDeriv riemannZeta ((\u03c3 : \u211d) + t * Complex.I)\u2016 \u2264\n (2 : \u211d) ^ (-(\u03c3 - 2)) * dirichletC2 := by\n have hs1 : (1 : \u211d) < ((\u03c3 : \u211d) + t * Complex.I).re := by simp; linarith\n have h1 : -logDeriv riemannZeta ((\u03c3 : \u211d) + t * Complex.I)\n = LSeries (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) ((\u03c3 : \u211d) + t * Complex.I) := by\n have h2 := ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div hs1\n rw [logDeriv, Pi.div_apply, h2]\n ring\n have hsum2 : Summable (fun n : \u2115 =>\n \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) (2 : \u2102) n\u2016) := by\n rw [summable_norm_iff]\n exact ArithmeticFunction.LSeriesSummable_vonMangoldt (by norm_num)\n have hsumS : Summable (fun n : \u2115 =>\n \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102))\n ((\u03c3 : \u211d) + t * Complex.I) n\u2016) := by\n rw [summable_norm_iff]\n exact ArithmeticFunction.LSeriesSummable_vonMangoldt hs1\n have hle : \u2016LSeries (fun n => (ArithmeticFunction.vonMangoldt n : \u2102))\n ((\u03c3 : \u211d) + t * Complex.I)\u2016 \u2264 (2 : \u211d) ^ (-(\u03c3 - 2)) * dirichletC2 := by\n show \u2016\u2211' n : \u2115, LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102))\n ((\u03c3 : \u211d) + t * Complex.I) n\u2016 \u2264 _\n calc \u2016\u2211' n : \u2115, LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102))\n ((\u03c3 : \u211d) + t * Complex.I) n\u2016\n \u2264 \u2211' n : \u2115, \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102))\n ((\u03c3 : \u211d) + t * Complex.I) n\u2016 :=\n norm_tsum_le_tsum_norm hsumS\n _ \u2264 \u2211' n : \u2115, (2 : \u211d) ^ (-(\u03c3 - 2)) *\n \u2016LSeries.term (fun n => (ArithmeticFunction.vonMangoldt n : \u2102)) (2 : \u2102) n\u2016 :=\n Summable.tsum_le_tsum (fun n => norm_term_vonMangoldt_le_two_pow h\u03c3 n) hsumS\n (hsum2.mul_left _)\n _ = (2 : \u211d) ^ (-(\u03c3 - 2)) * dirichletC2 := by rw [dirichletC2, tsum_mul_left]\n calc \u2016logDeriv riemannZeta ((\u03c3 : \u211d) + t * Complex.I)\u2016\n = \u2016LSeries (fun n => (ArithmeticFunction.vonMangoldt n : \u2102))\n ((\u03c3 : \u211d) + t * Complex.I)\u2016 := by\n rw [\u2190 h1, norm_neg]\n _ \u2264 (2 : \u211d) ^ (-(\u03c3 - 2)) * dirichletC2 := hle\n\n/-- **Kernel envelope** (D-074 \u00a77, the single-exponential form that\nreplaces the unit-step geometric series): \u2016(1+1/((\u03c3\u22121)+iU))\u207f\u2016 \u2264\ne^{(4/9)\u03c3} for \u03c3 \u2265 3 and n \u2264 (4/9)U\u00b2. From the (6.11) core\n\u20161+1/s\u2016 \u2264 1+(re s+1)/normSq s \u2264 1+\u03c3/U\u00b2. -/\ntheorem one_add_div_pow_norm_le_exp_four_ninths {n : \u2115} {\u03c3 U : \u211d}\n (h\u03c3 : 3 \u2264 \u03c3) (hU : 0 < U) (hnU : (n : \u211d) \u2264 (4 / 9) * U ^ 2) :\n \u2016(1 + 1/(((\u03c3 : \u211d) - 1) + U * Complex.I))\u2016 ^ n \u2264 Real.exp ((4 / 9) * \u03c3) := by\n have hs0 : (((\u03c3 : \u211d) - 1) + U * Complex.I) \u2260 0 := by\n intro h\n have him : (((\u03c3 : \u211d) - 1) + U * Complex.I).im = 0 := by rw [h]; simp\n simp at him\n linarith\n have hle := norm_one_add_one_div_le hs0\n have hre : (((\u03c3 : \u211d) - 1) + U * Complex.I).re + 1 = \u03c3 := by\n simp [Complex.add_re, Complex.ofReal_re, Complex.mul_re, Complex.I_re, Complex.I_im,\n Complex.sub_re, Complex.one_re]\n have hns : Complex.normSq (((\u03c3 : \u211d) - 1) + U * Complex.I) = (\u03c3 - 1) ^ 2 + U ^ 2 := by\n simp [Complex.normSq_apply]\n ring\n have hstep : ((((\u03c3 : \u211d) - 1) + U * Complex.I).re + 1) /\n Complex.normSq (((\u03c3 : \u211d) - 1) + U * Complex.I) \u2264 \u03c3 / U ^ 2 := by\n rw [hre, hns]\n have hU2 : (0 : \u211d) < U ^ 2 := by positivity\n have h1 : (0 : \u211d) \u2264 (\u03c3 - 1) ^ 2 := sq_nonneg _\n exact (div_le_div_iff_of_pos_left (by linarith : (0 : \u211d) < \u03c3)\n (by positivity) hU2).mpr (by linarith [h1])\n have hstep1 : 1 + ((((\u03c3 : \u211d) - 1) + U * Complex.I).re + 1) /\n Complex.normSq (((\u03c3 : \u211d) - 1) + U * Complex.I) \u2264 1 + \u03c3 / U ^ 2 := by\n linarith [hstep]\n have hpow1 : \u2016(1 + 1/(((\u03c3 : \u211d) - 1) + U * Complex.I))\u2016 ^ n \u2264 (1 + \u03c3 / U ^ 2) ^ n :=\n pow_le_pow_left\u2080 (norm_nonneg _) (hle.trans hstep1) n\n have hpow2 : (1 + \u03c3 / U ^ 2) ^ n \u2264 Real.exp ((n : \u211d) * (\u03c3 / U ^ 2)) := by\n calc (1 + \u03c3 / U ^ 2) ^ n \u2264 (Real.exp (\u03c3 / U ^ 2)) ^ n := by\n have h := Real.add_one_le_exp (\u03c3 / U ^ 2)\n exact pow_le_pow_left\u2080 (by positivity) (by linarith) n\n _ = Real.exp ((n : \u211d) * (\u03c3 / U ^ 2)) := (Real.exp_nat_mul (\u03c3 / U ^ 2) n).symm\n have hexp : (n : \u211d) * (\u03c3 / U ^ 2) \u2264 (4 / 9) * \u03c3 := by\n have hU2 : (0 : \u211d) < U ^ 2 := by positivity\n have h\u03c30 : (0 : \u211d) < \u03c3 := by linarith\n have h1 : (n : \u211d) / U ^ 2 \u2264 4 / 9 := by\n have h2 := div_le_div_of_nonneg_right hnU hU2.le\n rwa [mul_div_cancel_right\u2080 _ hU2.ne'] at h2\n rw [show (n : \u211d) * (\u03c3 / U ^ 2) = ((n : \u211d) / U ^ 2) * \u03c3 by ring]\n exact mul_le_mul_of_nonneg_right h1 h\u03c30.le\n calc \u2016(1 + 1/(((\u03c3 : \u211d) - 1) + U * Complex.I))\u2016 ^ n\n \u2264 Real.exp ((n : \u211d) * (\u03c3 / U ^ 2)) := hpow1.trans hpow2\n _ \u2264 Real.exp ((4 / 9) * \u03c3) := Real.exp_le_exp.mpr hexp\n\n/-! ## 5. The product envelope and the integral assembly (DL-3c/d) -/\n\n/-- **The product envelope** (D-074 \u00a77): for \u03c3 \u2265 3, 0 < t, n \u2264 (4/9)t\u00b2,\n\u2016Jlag n (\u03c3+it)\u2016 \u2264 (4\u00b7e^{\u2212c\u03c3} + 4\u00b72^{\u2212\u03c3})\u00b7dirichletC2, c = log 2 \u2212 4/9.\nThe kernel envelope (e^{(4/9)\u03c3}) times the zeta halving (2^{\u2212(\u03c3\u22122)})\ncollapses to the single exponential 4\u00b7e^{\u2212c\u03c3}: no geometric series. -/\ntheorem Jlag_dogleg_norm_le_envelope {n : \u2115} {\u03c3 t : \u211d}\n (h\u03c3 : 3 \u2264 \u03c3) (ht : 0 < t) (hnU : (n : \u211d) \u2264 (4 / 9) * t ^ 2) :\n \u2016Jlag n ((\u03c3 : \u211d) + t * Complex.I)\u2016 \u2264\n (4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) + 4 * (2 : \u211d) ^ (-\u03c3)) * dirichletC2 := by\n have hw1 : ((\u03c3 : \u211d) + t * Complex.I) - 1 = ((\u03c3 : \u211d) - 1) + t * Complex.I := by\n push_cast\n ring\n have hs1ne : (((\u03c3 : \u211d) - 1) + t * Complex.I) \u2260 0 := by\n intro h\n have him : (((\u03c3 : \u211d) - 1) + t * Complex.I).im = 0 := by rw [h]; simp\n simp at him\n linarith\n have hwid : ((\u03c3 : \u211d) + t * Complex.I) / (((\u03c3 : \u211d) + t * Complex.I) - 1) =\n 1 + 1 / (((\u03c3 : \u211d) - 1) + t * Complex.I) := by\n rw [hw1]\n field_simp [hs1ne]\n ring\n have hker := one_add_div_pow_norm_le_exp_four_ninths h\u03c3 ht hnU\n have hzeta := norm_logDeriv_zeta_le_two_pow (show (2 : \u211d) \u2264 \u03c3 by linarith) (t := t)\n have hk : \u2016kFun n ((\u03c3 : \u211d) + t * Complex.I)\u2016 \u2264 Real.exp ((4 / 9) * \u03c3) + 1 := by\n unfold kFun\n rw [hwid]\n calc \u2016(1 + 1 / (((\u03c3 : \u211d) - 1) + t * Complex.I)) ^ n - 1\u2016\n \u2264 \u2016(1 + 1 / (((\u03c3 : \u211d) - 1) + t * Complex.I)) ^ n\u2016 + \u2016(1 : \u2102)\u2016 := norm_sub_le _ _\n _ = \u2016(1 + 1 / (((\u03c3 : \u211d) - 1) + t * Complex.I))\u2016 ^ n + 1 := by rw [norm_pow, norm_one]\n _ \u2264 Real.exp ((4 / 9) * \u03c3) + 1 := by linarith [hker]\n have hprod : \u2016Jlag n ((\u03c3 : \u211d) + t * Complex.I)\u2016 \u2264\n (Real.exp ((4 / 9) * \u03c3) + 1) * ((2 : \u211d) ^ (-(\u03c3 - 2)) * dirichletC2) := by\n have hn3 : \u2016Jlag n ((\u03c3 : \u211d) + t * Complex.I)\u2016 =\n \u2016kFun n ((\u03c3 : \u211d) + t * Complex.I)\u2016 *\n \u2016logDeriv riemannZeta ((\u03c3 : \u211d) + t * Complex.I)\u2016 := by\n show \u2016kFun n ((\u03c3 : \u211d) + t * Complex.I) *\n (-logDeriv riemannZeta ((\u03c3 : \u211d) + t * Complex.I))\u2016 = _\n rw [norm_mul, norm_neg]\n rw [hn3]\n exact mul_le_mul hk hzeta (norm_nonneg _)\n (add_nonneg (Real.exp_nonneg _) (by norm_num))\n have h2b : (2 : \u211d) ^ (-\u03c3) = Real.exp (-(Real.log 2) * \u03c3) := by\n rw [Real.rpow_def_of_pos (by norm_num : (0 : \u211d) < 2)]\n congr 1\n ring\n have h22 : (2 : \u211d) ^ (2 : \u211d) = 4 := by\n rw [Real.rpow_two]\n norm_num\n have h2a : (2 : \u211d) ^ (-(\u03c3 - 2)) = 4 * (2 : \u211d) ^ (-\u03c3) := by\n rw [show (-(\u03c3 - 2)) = -\u03c3 + 2 by ring, Real.rpow_add (by norm_num : (0 : \u211d) < 2), h2b, h22]\n ring\n have hexp_alg : Real.exp ((4 / 9) * \u03c3) * Real.exp (-(Real.log 2) * \u03c3) =\n Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) := by\n rw [\u2190 Real.exp_add]\n congr 1\n ring\n have halg : (Real.exp ((4 / 9) * \u03c3) + 1) * ((2 : \u211d) ^ (-(\u03c3 - 2))) =\n 4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) + 4 * (2 : \u211d) ^ (-\u03c3) := by\n rw [h2a, h2b]\n calc (Real.exp ((4 / 9) * \u03c3) + 1) * (4 * Real.exp (-(Real.log 2) * \u03c3))\n = 4 * (Real.exp ((4 / 9) * \u03c3) * Real.exp (-(Real.log 2) * \u03c3)) +\n 4 * Real.exp (-(Real.log 2) * \u03c3) := by ring\n _ = 4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) + 4 * Real.exp (-(Real.log 2) * \u03c3) := by\n rw [hexp_alg]\n calc \u2016Jlag n ((\u03c3 : \u211d) + t * Complex.I)\u2016\n \u2264 (Real.exp ((4 / 9) * \u03c3) + 1) * ((2 : \u211d) ^ (-(\u03c3 - 2)) * dirichletC2) := hprod\n _ = dirichletC2 * ((Real.exp ((4 / 9) * \u03c3) + 1) * (2 : \u211d) ^ (-(\u03c3 - 2))) := by ring\n _ = dirichletC2 * (4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) + 4 * (2 : \u211d) ^ (-\u03c3)) := by\n rw [halg]\n\n/-- The FTC-bound \u222b\u2083^XR e^{\u2212c\u03c3}d\u03c3 \u2264 e^{\u22123c}/c for c > 0. -/\nlemma integral_exp_neg_le {c XR : \u211d} (hc : 0 < c) (_hXR : 3 \u2264 XR) :\n \u222b \u03c3 in (3 : \u211d)..XR, Real.exp (-c * \u03c3) \u2264 Real.exp (-3 * c) / c := by\n have hF : \u2200 x \u2208 Set.uIcc (3 : \u211d) XR,\n HasDerivAt (fun \u03c3 => -Real.exp (-c * \u03c3) / c) (Real.exp (-c * x)) x := by\n intro x hx\n have h2 : HasDerivAt (fun \u03c3 => Real.exp (-c * \u03c3)) (Real.exp (-c * x) * (-c)) x := by\n have h := ((hasDerivAt_id' x).const_mul (-c)).exp\n rwa [mul_one] at h\n have h3 := h2.const_mul (-1 / c)\n rw [show (-1 / c) * (Real.exp (-c * x) * (-c)) = Real.exp (-c * x) by\n field_simp [hc.ne']] at h3\n have h5 : (fun \u03c3 => (-1 / c) * Real.exp (-c * \u03c3)) =\n (fun \u03c3 => -Real.exp (-c * \u03c3) / c) := by\n funext \u03c3\n field_simp [hc.ne']\n rw [h5] at h3\n exact h3\n have hint : IntervalIntegrable (fun \u03c3 => Real.exp (-c * \u03c3)) MeasureTheory.volume 3 XR := by\n apply ContinuousOn.intervalIntegrable\n exact (Real.continuous_exp.comp (continuous_const.mul continuous_id)).continuousOn\n rw [intervalIntegral.integral_eq_sub_of_hasDerivAt hF hint]\n have h1 : (0 : \u211d) \u2264 Real.exp (-c * XR) / c := by positivity\n have e : Real.exp (-c * 3) = Real.exp (-3 * c) := by\n congr 1\n ring\n rw [e]\n linarith [h1]\n\n/-- The certified exponent-decay constant c = log 2 \u2212 4/9 \u2265 0.2487. -/\nlemma cdog_gt : (0.2487 : \u211d) \u2264 Real.log 2 - 4 / 9 := by\n have h := Real.log_two_gt_d9\n norm_num at h\n linarith\n\n/-- The certified e^{4/3} \u2264 3.8073 (the (1\u2212x/16)\u207b\u00b9\u2076 route + d9 e). -/\nlemma exp_four_thirds_le : Real.exp (4 / 3) \u2264 (3.8073 : \u211d) := by\n have he13 : Real.exp (1 / 3) \u2264 (1.4006 : \u211d) :=\n le_trans (exp_le_inv_sub_sixteen (by norm_num) (by norm_num)) (by norm_num)\n rw [show (4 / 3 : \u211d) = 1 + 1 / 3 by norm_num, Real.exp_add]\n calc Real.exp 1 * Real.exp (1 / 3) \u2264 2.7182818286 * 1.4006 :=\n mul_le_mul Real.exp_one_lt_d9.le he13 (Real.exp_pos _).le (by norm_num)\n _ \u2264 3.8073 := by norm_num\n\n/-- **THE HIGH-HORIZONTAL BOUND** (D-074 \u00a77 capstone; D-073 Cor 4.2's\nR(1.5) in single-exponential-envelope form): for 0 < U, n \u2264 (4/9)U\u00b2\n(i.e. U \u2265 (3/2)\u221an) and 3 \u2264 XR, \u2016HIntegral (Jlag n) 3 XR U\u2016 \u2264 8.38\n(charged; the true value \u2264 1.2 at n = 10\u2075, E-034 V5). Charged with\ndirichletC2 \u2264 1 \u2014 the tight R(1.5) = 5.94 would need a dirichletC2 \u2264\n0.57 build (documented as the tightening path; the fold is\nindifferent: \u0394 \u2248 +2.4 per side). -/\ntheorem hIntegral_Jlag_dogleg_norm_le {n : \u2115} {U XR : \u211d}\n (hU : 0 < U) (hnU : (n : \u211d) \u2264 (4 / 9) * U ^ 2) (hXR : 3 \u2264 XR) :\n \u2016HIntegral (Jlag n) 3 XR U\u2016 \u2264 (8.38 : \u211d) := by\n have hc : (0 : \u211d) < Real.log 2 - 4 / 9 := by\n have h := cdog_gt\n linarith\n have hpt : \u2200 \u03c3 \u2208 Set.Ioc 3 XR,\n \u2016Jlag n ((\u03c3 : \u211d) + U * Complex.I)\u2016 \u2264\n (4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) + 4 * (2 : \u211d) ^ (-\u03c3)) * dirichletC2 :=\n fun \u03c3 h\u03c3 => Jlag_dogleg_norm_le_envelope (by linarith [h\u03c3.1]) hU hnU\n have hcontA : Continuous (fun \u03c3 : \u211d => Real.exp (-(Real.log 2 - 4 / 9) * \u03c3)) :=\n Real.continuous_exp.comp (continuous_const.mul continuous_id)\n have hcontB : Continuous (fun \u03c3 : \u211d => (2 : \u211d) ^ (-\u03c3)) := by\n have h1 : Continuous (fun \u03c3 : \u211d => Real.exp (-(Real.log 2) * \u03c3)) :=\n Real.continuous_exp.comp (continuous_const.mul continuous_id)\n have h2 : (fun \u03c3 : \u211d => (2 : \u211d) ^ (-\u03c3)) =\n (fun \u03c3 : \u211d => Real.exp (-(Real.log 2) * \u03c3)) := by\n funext \u03c3\n rw [Real.rpow_def_of_pos (by norm_num : (0 : \u211d) < 2)]\n congr 1\n ring\n rw [h2]\n exact h1\n have hIntA : IntervalIntegrable (fun \u03c3 : \u211d => 4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3))\n MeasureTheory.volume 3 XR := by\n apply ContinuousOn.intervalIntegrable\n exact (hcontA.const_mul 4).continuousOn\n have hIntB : IntervalIntegrable (fun \u03c3 : \u211d => 4 * (2 : \u211d) ^ (-\u03c3)) MeasureTheory.volume 3 XR := by\n apply ContinuousOn.intervalIntegrable\n exact (hcontB.const_mul 4).continuousOn\n have hIntG : IntervalIntegrable (fun \u03c3 : \u211d =>\n (4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) + 4 * (2 : \u211d) ^ (-\u03c3)) * dirichletC2)\n MeasureTheory.volume 3 XR := by\n have h := (hIntA.add hIntB).const_mul dirichletC2\n convert h using 1\n ext \u03c3\n ring\n -- step 1: \u2016H\u2016 \u2264 \u222b envelope\n have h1 : \u2016HIntegral (Jlag n) 3 XR U\u2016 \u2264\n \u222b \u03c3 in (3 : \u211d)..XR,\n (4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) + 4 * (2 : \u211d) ^ (-\u03c3)) * dirichletC2 := by\n unfold HIntegral\n apply intervalIntegral.norm_integral_le_of_norm_le hXR _ hIntG\n exact Filter.Eventually.of_forall (fun \u03c3 h\u03c3 => hpt \u03c3 h\u03c3)\n -- step 2: \u222b envelope = dirichletC2\u00b7(4\u222be^{\u2212c\u03c3} + 4\u222b2^{\u2212\u03c3})\n have h2 : \u222b \u03c3 in (3 : \u211d)..XR,\n (4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) + 4 * (2 : \u211d) ^ (-\u03c3)) * dirichletC2\n = dirichletC2 * (\u222b \u03c3 in (3 : \u211d)..XR, 4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) +\n \u222b \u03c3 in (3 : \u211d)..XR, 4 * (2 : \u211d) ^ (-\u03c3)) := by\n rw [intervalIntegral.integral_const_mul, intervalIntegral.integral_add hIntA hIntB]\n -- step 3: the two integral bounds\n have h3a : \u222b \u03c3 in (3 : \u211d)..XR, 4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) \u2264\n Real.exp (4 / 3) / (2 * (Real.log 2 - 4 / 9)) := by\n rw [intervalIntegral.integral_const_mul]\n have h := integral_exp_neg_le hc hXR\n have he3c : Real.exp (-3 * (Real.log 2 - 4 / 9)) = Real.exp (4 / 3) / 8 := by\n have h3l2 : Real.exp (-(3 * Real.log 2)) = 1 / 8 := by\n have e1 : -(3 * Real.log 2) = Real.log (1 / 8) := by\n rw [show ((1 : \u211d) / 8) = (2 ^ 3 : \u211d)\u207b\u00b9 by norm_num, Real.log_inv, Real.log_pow]\n push_cast\n ring\n rw [e1, Real.exp_log (by norm_num : (0 : \u211d) < 1 / 8)]\n calc Real.exp (-3 * (Real.log 2 - 4 / 9))\n = Real.exp ((4 / 3) + -(3 * Real.log 2)) := by congr 1; ring\n _ = Real.exp (4 / 3) * Real.exp (-(3 * Real.log 2)) := by rw [Real.exp_add]\n _ = Real.exp (4 / 3) / 8 := by rw [h3l2]; ring\n rw [he3c] at h\n calc 4 * (Real.exp (-3 * (Real.log 2 - 4 / 9)) / (Real.log 2 - 4 / 9))\n = 4 * ((Real.exp (4 / 3) / 8) / (Real.log 2 - 4 / 9)) := by rw [he3c]\n _ = Real.exp (4 / 3) / (2 * (Real.log 2 - 4 / 9)) := by\n field_simp [hc.ne']\n ring\n have h3b : \u222b \u03c3 in (3 : \u211d)..XR, 4 * (2 : \u211d) ^ (-\u03c3) \u2264 1 / (2 * Real.log 2) := by\n have h2e : (fun \u03c3 : \u211d => (2 : \u211d) ^ (-\u03c3)) =\n (fun \u03c3 : \u211d => Real.exp (-(Real.log 2) * \u03c3)) := by\n funext \u03c3\n rw [Real.rpow_def_of_pos (by norm_num : (0 : \u211d) < 2)]\n congr 1\n ring\n rw [h2e, intervalIntegral.integral_const_mul]\n have h := integral_exp_neg_le (Real.log_pos (by norm_num : (1 : \u211d) < 2)) hXR\n have h3l2 : Real.exp (-3 * Real.log 2) = 1 / 8 := by\n have e1 : (-3 * Real.log 2) = Real.log (1 / 8) := by\n rw [show ((1 : \u211d) / 8) = (2 ^ 3 : \u211d)\u207b\u00b9 by norm_num, Real.log_inv, Real.log_pow]\n push_cast\n ring\n rw [e1, Real.exp_log (by norm_num : (0 : \u211d) < 1 / 8)]\n rw [h3l2] at h\n calc 4 * \u222b \u03c3 in (3 : \u211d)..XR, Real.exp (-(Real.log 2) * \u03c3)\n \u2264 4 * ((1 / 8) / Real.log 2) := mul_le_mul_of_nonneg_left h (by norm_num)\n _ = 1 / (2 * Real.log 2) := by\n field_simp [Real.log_pos (by norm_num : (1 : \u211d) < 2)].ne'\n ring\n -- step 4: the certified assembly\n have hlog2 : (0.6931471803 : \u211d) \u2264 Real.log 2 := Real.log_two_gt_d9\n have h48 : Real.exp (4 / 3) / (2 * (Real.log 2 - 4 / 9)) \u2264 (7.6545 : \u211d) := by\n have hcge := cdog_gt\n have h1 : Real.exp (4 / 3) / (2 * (Real.log 2 - 4 / 9)) \u2264 3.8073 / (2 * 0.2487) :=\n div_le_div exp_four_thirds_le (by linarith) (by norm_num) (by positivity)\n calc Real.exp (4 / 3) / (2 * (Real.log 2 - 4 / 9))\n \u2264 3.8073 / (2 * 0.2487) := h1\n _ \u2264 7.6545 := by norm_num\n have h72 : 1 / (2 * Real.log 2) \u2264 (0.7214 : \u211d) := by\n have h1 : 1 / (2 * Real.log 2) \u2264 1 / (2 * 0.6931471803) :=\n one_div_le_one_div_of_le (by positivity) (by linarith)\n calc 1 / (2 * Real.log 2) \u2264 1 / (2 * 0.6931471803) := h1\n _ \u2264 0.7214 := by norm_num\n have hC2 : dirichletC2 \u2264 1 := dirichletC2_le_one\n have hsum : dirichletC2 * (\u222b \u03c3 in (3 : \u211d)..XR, 4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) +\n \u222b \u03c3 in (3 : \u211d)..XR, 4 * (2 : \u211d) ^ (-\u03c3)) \u2264 (8.38 : \u211d) := by\n have hA0 : (0 : \u211d) \u2264 Real.exp (4 / 3) / (2 * (Real.log 2 - 4 / 9)) := by positivity\n have hB0 : (0 : \u211d) \u2264 1 / (2 * Real.log 2) := by positivity\n calc dirichletC2 * (\u222b \u03c3 in (3 : \u211d)..XR, 4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) +\n \u222b \u03c3 in (3 : \u211d)..XR, 4 * (2 : \u211d) ^ (-\u03c3))\n \u2264 1 * (Real.exp (4 / 3) / (2 * (Real.log 2 - 4 / 9)) + 1 / (2 * Real.log 2)) := by\n apply mul_le_mul hC2 (add_le_add h3a h3b) (by positivity) (by norm_num)\n _ = Real.exp (4 / 3) / (2 * (Real.log 2 - 4 / 9)) + 1 / (2 * Real.log 2) := by ring\n _ \u2264 7.6545 + 0.7214 := add_le_add h48 h72\n _ \u2264 8.38 := by norm_num\n calc \u2016HIntegral (Jlag n) 3 XR U\u2016\n \u2264 \u222b \u03c3 in (3 : \u211d)..XR,\n (4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) + 4 * (2 : \u211d) ^ (-\u03c3)) * dirichletC2 := h1\n _ = dirichletC2 * (\u222b \u03c3 in (3 : \u211d)..XR, 4 * Real.exp (-(Real.log 2 - 4 / 9) * \u03c3) +\n \u222b \u03c3 in (3 : \u211d)..XR, 4 * (2 : \u211d) ^ (-\u03c3)) := h2\n _ \u2264 8.38 := hsum\n\nend NguyenRH1\n\nend\n",
"structuredPatch": [
{
"oldStart": 553,
"oldLines": 13,
"newStart": 553,
"newLines": 12,
"lines": [
" have hint : IntervalIntegrable (fun \u03c3 => Real.exp (-c * \u03c3)) MeasureTheory.volume 3 XR := by",
" apply ContinuousOn.intervalIntegrable",
" exact (Real.continuous_exp.comp (continuous_const.mul continuous_id)).continuousOn",
"- rw [intervalIntegral.integral_eq_sub_of_hasDerivAt hF hint]",
"- have h1 : (0 : \u211d) \u2264 Real.exp (-c * XR) / c := by positivity",
"- have e : Real.exp (-c * 3) = Real.exp (-3 * c) := by",
"- congr 1",
"- ring",
"- rw [e]",
"- linarith [h1]",
"+ rw [intervalIntegral.integral_eq_sub_of_hasDerivAt hF hint, e, sub_le_iff_le_add]",
"+ have h1 : (0 : \u211d) \u2264 Real.exp (-c * XR) := (Real.exp_pos _).le",
"+ have h2 : -Real.exp (-c * XR) / c \u2264 0 := by",
"+ apply div_nonpos_of_nonpos_of_nonneg _ hc.le",
"+ linarith [h1]",
"+ linarith [h2]",
" ",
" /-- The certified exponent-decay constant c = log 2 \u2212 4/9 \u2265 0.2487. -/",
" lemma cdog_gt : (0.2487 : \u211d) \u2264 Real.log 2 - 4 / 9 := by"
]
}
],
"userModified": false,
"replaceAll": false
}
thinking (651 chars)
LiPrincipal.lean compiles clean! The entire ii′-1b(ii) is proved:
- `rectInt_deriv_eq_zero` (FTC vanishing)
- `Acoeff`, `ppart`, `Gprim`
- `deriv_Gprim`, `tail_continuousAt`, `ppart_eq_deriv_add`
- `rectInt'_ppart` : RectangleIntegral' (ppart n) z w = ResW1 n (when 1 interior)
Let me build the module and run the axiom audit, then commit this sub-stage progress (crash-safe), then decide whether to continue with ii′-1b(iii) or close the session.
Given the session's length (many hours of Lean iteration), the natural checkpoint: ii′-1b(i) + (ii) complete — commit. (iii) is the final rectangle residue assembly — a good chunk for the next session.
LiPrincipal.lean compiles clean — ii′-1b(ii) complete. Building the module and auditing, then committing this checkpoint.
tool: Bash
input
{
"command": "cd /d/Python/Quantum/research/lean/NguyenRH1 && export PATH=\"$HOME/.elan/bin:$PATH\" && lake build NguyenRH1.LiPrincipal 2>&1 | tail -3 && cat > PrintAxioms.lean << 'EOF'\n/- Session 016 axiom audit: ii\u2032-1b(ii) new declarations. -/\nimport Mathlib\nimport NguyenRH1.LiPrincipal\n\nopen NguyenRH1\n\n#print axioms rectInt'_ppart\n#print axioms rectInt_deriv_eq_zero\n#print axioms deriv_Gprim\n#print axioms Acoeff_one\nEOF\nlake env lean PrintAxioms.lean 2>&1 | head -6",
"description": "Build LiPrincipal and audit axioms",
"timeout": 600000
}
thinking (1704 chars)
Committed. Now — session 016 has delivered ii′-1b(i) and (ii). The remaining piece of ii′-1b is (iii): the full rectangle residue theorem for J. Given the session has been very long (many Lean iterations), let me check the time/pacing. The user is on telegram and said "let's go" — I should keep working as long as productive, but this is a natural milestone. Let me assess what (iii) needs and decide whether to continue or wrap with a clean status update.
ii′-1b(iii) plan (from the design):
- R := J − P: holomorphic on Rectangle \ (zeros ∪ {−2}) with simple poles at zeros (residues mult·k_n(ρ−1) = mult·(1−(ρ/(ρ−1))ⁿ)) and at −2 (residue 1−(2/3)ⁿ).
- The order-at-1 computation (R = G near 1, where G = [F − Tayl_n F]/(w−1)^{n+1} analytic).
- residueTheorem_finset (vendored Zeta23.Analytic.RectangleLogDeriv) for R.
- Assemble: sides = ∮J = ∮P + ∮R = ResW1 + Σ_residues.
That's another substantial file (300+ lines, with the order computation being the trickiest part). Given how long this session has run, and per the pacing rules (§8.5 BREAK PROMPT — approaching long work should pause and check with the user), this is a good point to close session 016 cleanly with the milestone committed, give the user the status, and let them decide to continue.
Actually — the user said "let's go" from telegram and I should keep momentum but also be honest about session boundaries. The session protocol (§8.4) wants clean end-states. I have a clean committed milestone (ii′-1b(i)+(ii)). Let me wrap with the journal + STATE update for session 016, then report.
Let me do the session-016 closure: journal, STATE, NGUYEN checklist update (ii′-1b partially done — mark (i)/(ii)), db registration, commit.
A natural milestone: ii′-1b(i) + (ii) complete and committed. Let me close session 016 cleanly with the archive updates.
tool: Write ok
input
{
"file_path": "D:\\Python\\Quantum\\research\\journal\\session-016.md",
"content": "# Session 016 \u2014 2026-08-21 \u2014 Tier ii\u2032 sub-stage ii\u2032-1b (i)+(ii) COMPLETE\n\n## Directive\nContinue tier ii\u2032 per D-064: sub-stage ii\u2032-1b (R1 residue machinery).\n\n## Work done\n**ii\u2032-1b(i) COMPLETE (commit 1c35d31)** \u2014 LiResidue.lean:\n- `zetaA = (w\u22121)\u00b7\u03b6(w)` extended by 1 at 1: analytic (removable\n singularity via Mathlib `riemannZeta_residue_one` +\n RemovableSingularity.lean's `differentiableOn_update_limUnder_of_bddAbove`).\n- `hLi = 1 \u2212 (w\u22121)\u00b7(zetaA\u2032/zetaA)`: analytic at 1, value 1, agrees with\n (w\u22121)(\u2212\u03b6\u2032/\u03b6) on a punctured neighborhood of 1 (`hLi_eq_near_one`,\n via riemannZeta_residue_one.eventually_ne).\n- `lcoeff k := iteratedDeriv (k+1) hLi 1 / (k+1)!` \u2014 operational\n Laurent coefficients of \u2212\u03b6\u2032/\u03b6 at 1.\n- `A_iter`: iterated derivatives of A(w) = w\u207f\u2212(w\u22121)\u207f at 1\n (descFactorial for i < n, 0 for i = n; via iteratedDeriv_pow +\n iteratedDeriv_comp_sub_const).\n- **`ResW1_eq_sum`**: the w=1 residue of the Lagarias-kernel integrand\n equals \u03a3_{j=1}^n C(n,j)\u00b7lcoeff(j\u22121) \u2014 via iteratedDeriv_mul\n (Leibniz), as designed (D-064 R1) and verified numerically (session 014).\n\n**ii\u2032-1b(ii) COMPLETE (commit 973fe66)** \u2014 LiPrincipal.lean:\n- `rectInt_deriv_eq_zero`: RectangleIntegral (deriv G) = 0 when G is\n differentiable on the border \u2014 per-side FTC with the mixed-field chain\n rule (HasDerivAt.comp in the \u211d\u2192\u2102\u2192\u2102 algebra tower), border MapsTo from\n vendored Rectangle.lean.\n- `RectangleIntegral'_add` linearity.\n- `Acoeff/ppart/Gprim`; `deriv_Gprim` (termwise: hasDerivAt_zpow + comp);\n `tail_continuousAt` (Finset induction); `ppart_eq_deriv_add`.\n- **`rectInt'_ppart`**: RectangleIntegral' (ppart n) z w = ResW1 n on\n any rectangle with 1 interior \u2014 A_1 term by the vendored\n `ResidueTheoremInRectangle`, i \u2265 2 tail vanishes by the primitive FTC.\n\nBoth axiom-audited: 3 standard axioms only.\n\n## Lean notes (hard-won this session, additions to the handoff list)\n- Factorial `n !` is SCOPED notation \u2014 needs `open scoped Nat`.\n- `conj` is scope-locked (ComplexConjugate) \u2014 use `starRingEnd \u2102`.\n- Parametrized lambdas over \u211d into \u2102 need explicit `(x : \u211d)` annotations\n (else x elaborates at \u2102 and every downstream unify fails).\n- `HasDerivAt.comp` handles mixed fields via NormedAlgebra/IsScalarTower.\n- `ContinuousLinearMap.hasDerivAt : HasDerivAt e (e 1) x` (ofRealCLM).\n- `intervalIntegral.integral_eq_sub_of_hasDerivAt` (FTC-2) with explicit\n (f := ...) (f' := ...) args \u2014 unification is brittle otherwise.\n- `ContinuousAt` of expressions containing the point variable: write the\n `fun w =>` lambda EXPLICITLY (Lean's eta-unification misfires).\n- Finset.sum_apply / funext for sum-of-functions \u2194 lambda-of-sums.\n- Finset.sum_bij arg order: (i, hi, i_inj, i_surj, h).\n- differentiableOn_update_limUnder_of_bddAbove (removable singularity);\n Tendsto.eventually_ne; DifferentiableOn.deriv (CauchyIntegral.lean).\n\n## State at stop\nii\u2032-1b(i)+(ii) complete. Remaining for ii\u2032-1b: (iii) the full rectangle\nresidue theorem for J \u2014 R = J \u2212 P holomorphic off {zeros \u222a {\u22122}}\n(order \u2265 0 at 1 via Taylor-remainder), simple poles at zeros (residue\nmult\u00b7(1\u2212(\u03c1/(\u03c1\u22121))\u207f)) and at \u22122 (residue 1\u2212(2/3)\u207f), via vendored\n`residueTheorem_finset` (Zeta23.Analytic.RectangleLogDeriv), then\nassemble sides = ResW1 + \u03a3 + triv.\nNext session: ii\u2032-1b(iii).\n"
}
result 2026-08-21 22:28:49Z → 2026-08-22 06:36:48Z
{
"type": "update",
"filePath": "D:\\Python\\Quantum\\research\\lean\\NguyenRH1\\PrintAxioms.lean",
"content": "/- Session 020 axiom audit: ii\u2032-3a piece (A) part 1 new declarations. -/\nimport Mathlib\nimport NguyenRH1.LiArchimedean\n\nopen NguyenRH1\n\n#print axioms logDeriv_Gamma\u211d_one\n#print axioms logDeriv_Gamma\u211d_one_add\n#print axioms pi_cpow_neg_half_eq_exp\n#print axioms log_four_pi\n",
"structuredPatch": [
{
"oldStart": 1,
"oldLines": 13,
"newStart": 1,
"newLines": 11,
"lines": [
"-/- Session 019 axiom audit: ii\u2032-3a piece (B) new declarations. -/",
"+/- Session 020 axiom audit: ii\u2032-3a piece (A) part 1 new declarations. -/",
" import Mathlib",
"-import NguyenRH1.LiZetaCoeff",
"+import NguyenRH1.LiArchimedean",
" ",
" open NguyenRH1",
" ",
"-#print axioms iteratedDeriv_hLiExt",
"-#print axioms hLiExt_analyticAt_zero",
"-#print axioms hLiExt_mul_id",
"-#print axioms hLiExt_tendsto",
"-#print axioms iteratedDeriv_hLi_one_add",
"-#print axioms hLiExt_eq_near_zero",
"+#print axioms logDeriv_Gamma\u211d_one",
"+#print axioms logDeriv_Gamma\u211d_one_add",
"+#print axioms pi_cpow_neg_half_eq_exp",
"+#print axioms log_four_pi",
" "
]
}
],
"originalFile": "/- Session 019 axiom audit: ii\u2032-3a piece (B) new declarations. -/\nimport Mathlib\nimport NguyenRH1.LiZetaCoeff\n\nopen NguyenRH1\n\n#print axioms iteratedDeriv_hLiExt\n#print axioms hLiExt_analyticAt_zero\n#print axioms hLiExt_mul_id\n#print axioms hLiExt_tendsto\n#print axioms iteratedDeriv_hLi_one_add\n#print axioms hLiExt_eq_near_zero\n",
"autoRead": false
}
Session 016 complete. Status for you:
## ii′-1b(i) + (ii) — DONE and committed (axiom-clean)
**LiResidue.lean** (commit 1c35d31):
- `zetaA = (w−1)·ζ(w)` with the pole filled in — proved **analytic at w=1** (removable singularity via Mathlib's machinery).
- `hLi` — the analytic-at-1 form of `(w−1)(−ζ′/ζ)`, value 1.
- `lcoeff k` — the Laurent coefficients of −ζ′/ζ at 1, defined operationally.
- **`ResW1_eq_sum`**: the w=1 residue of the Lagarias-kernel integrand = **Σ_{j=1}^n C(n,j)·lcoeff(j−1)**, proved via Leibniz (`iteratedDeriv_mul`) — exactly the identity we verified numerically in session 014.
**LiPrincipal.lean** (commit 973fe66):
- **`rectInt_deriv_eq_zero`**: the rectangle integral of a derivative vanishes (per-side FTC, mixed-field chain rule).
- **`rectInt'_ppart`**: the principal part **integrates to ResW1 n** on any rectangle with 1 in its interior (A₁ term by the vendored rectangle residue theorem; the i ≥ 2 tail vanishes by the primitive argument).
Both modules: **3 standard axioms only**, full build green.
## Overall tier ii′ progress
- ii′-0 ✔ (design + 2 discoveries) · ii′-1a ✔ (liCoeff defect repaired) · **ii′-1b: (i)✔ (ii)✔**, (iii) remaining
- Remaining map: ii′-1b(iii) → ii′-2 → ii′-3 (long pole) → ii′-4 → ii′-5 → ii′-6 → ii′-7
## Next (session 017): ii′-1b(iii)
The final residue piece: R = J − ppart shown holomorphic off {zeros ∪ {−2}} (Taylor-remainder order computation at w=1), simple poles at zeros with residue `mult·(1−(ρ/(ρ−1))ⁿ)`, assembly `sides(T) = ResW1 + Σ zeros + triv` via the vendored `residueTheorem_finset`.
Everything is committed and crash-safe (21c7497). Paper A remains frozen/submittable. Say "go" to continue.
I don’t want to continue now, maybe later. Save our project. But before we go, let me know where we stand with new stage in the research
thinking (323 chars)
The user wants to stop. Everything is already committed (21c7497). They want a clear summary of where the research stands with the new stage (tier ii′). Let me give a concise, complete status summary — the project is saved, and here's the state. No new work needed. Just confirm everything is committed and give the status.
Everything is saved — all work committed to git (latest: 21c7497), nothing lives only in conversation. Here's the complete picture of where we stand.
## The new stage: tier ii′ — closing the Lean contour bound before submission
**The goal.** Upgrade Paper A's finite-height Li theorem (λₙ > 0 for n ≤ (3×10¹²−1)² ≈ 9×10²⁴) from "Lean-verified *assuming* the contour bound `SfBoundProp`" to "Lean-verified with the contour bound **proved inside Lean**". Perimeter that stays declared (honest, per D-062): Platt–Trudgian RH-to-3×10¹², finite Li verification to 5×10⁵, Trudgian's N(T)/S(T), M₀.
**Protection:** Paper A is frozen and submission-ready at all times — every sub-stage ends committed; nothing moves until the final sub-stage ii′-7.
## Progress so far (3 of ~9 sub-stages done)
| Sub-stage | Status | What it delivered |
|---|---|---|
| **ii′-0** (session 014) | ✔ | Design D-064 + **two discoveries**: (1) the `liCoeff` encoding was *false as written* (junk sum — the audit question you asked caught it); (2) the crux identity **S_f = Res₁ exactly**, making the assembly tail-free |
| **ii′-1a** (session 015) | ✔ | The defect **repaired**: `liCoeff` now uses the correct paired sum, summability *proved*; `LiVerifiedUpTo`/`SfBoundProp` are now true statements, not vacuous |
| **ii′-1b** (sessions 016–17) | **2/3 done** | (i) the w=1 residue value: **ResW1 = Σⱼ C(n,j)·lcoeff(j−1)** proved by Leibniz; (ii) the principal part integrates to the residue (**rectInt'_ppart**); (iii) the full rectangle residue theorem for J — *next* |
All new Lean code: full build green, **only the 3 standard axioms** everywhere (audited live each session).
## What's next
1. **ii′-1b(iii)** — rectangle residue theorem for J (poles at zeros + trivial zero −2; assembly `sides = ResW1 + Σ zeros + triv`).
2. **ii′-2** — the two elementary binomial swaps (λₙ and S_∞ into binomial form).
3. **ii′-3** — the long pole: the Lagarias (4.10) Laurent relation (EF-reuse first, Hadamard fallback).
4. **ii′-4/5/6/7** — zero-avoiding T + kernel bounds, the R-bound, final assembly, closure + paper Appendix B update.
Estimate: ~9–16 sessions total; we've done the design and the first machinery tiers on schedule.
## State of the mission
- **Paper A**: submission-ready *right now* if you change your mind — and *stronger* than before, because the formal claims are no longer vacuous (the liCoeff fix).
- **Archive**: STATE.md has the exact resume point ("Session 017: ii′-1b(iii)"); journal-014/015/016 have full narratives; NGUYEN.md Phase 5B checklist tracks all 9 sub-stages.
Whenever you're ready, just say continue — the resume point is set.
What is the e cost of the current session
thinking (885 chars)
The user asks "What is the e cost of the current session" — likely a typo for "the cost". They're asking about the cost of the current session. But I don't have access to billing/cost information — I'm an agent in this CLI environment; I can't see token usage, dollar costs, or API billing. I should answer honestly: I can't see session costs. What I CAN offer: the session's work metrics (sessions 014–016 spanned the tier ii′ start, ~2 sub-stages worth of Lean iterations, commits, lines of code). Maybe clarify what they mean — API cost vs effort. I could give an estimate of the work done in this session (session 016 was the big one: LiResidue.lean ~270 lines, LiPrincipal.lean ~320 lines, many compile iterations).
The user might be asking about API/token cost for this conversation. I genuinely don't have that data. Be honest and brief. Offer the measurable proxies I do have.
I can't see billing or token-usage data — that information lives in your API account/dashboard, not in my environment. If you mean the API cost of this conversation, I have no way to measure it.
What I can tell you about this session's measurable footprint:
- **Timeframe**: sessions 014–016 (today, 2026-08-21) — design + 2 Lean sub-stages.
- **Code produced**: ~930 lines of new Lean (LiSkeleton §1 ~340, LiResidue.lean ~270, LiPrincipal.lean ~320), all compiled and axiom-audited.
- **Lean compile iterations**: roughly 25–30 edit-build cycles this session (the two new files needed ~15 iterations between them — residue/FTC machinery is API-heavy).
- **Commits**: 8 (e56cb66, 7a395b2, be1ffb2, 1c35d31, 973fe66, 21c7497 + docs).
- **Compute**: mostly interactive `lake env lean` single-file checks (~15–40s each) plus 3 full package builds (~1–3 min each) — modest CPU usage on your Ryzen.
If you want actual API costs, check your provider's usage dashboard. If you meant something else by "e cost" (effort? remaining estimated cost of the project?), tell me and I'll answer that instead.
Run ‘/cost project’
thinking (215 chars)
As expected, `cost` isn't a shell command. The `/cost` is a slash command of the Nguyen CLI itself — it must be typed by the user directly into the CLI prompt, not executed by me. Let me tell the user how to run it.
`/cost` is a **slash command of the Nguyen CLI itself** — it's not a shell command I can run for you. You need to type it directly into the CLI prompt:
```
/cost
```
(or `/cost project` if that variant exists in your version).
Slash commands (`/help`, `/cost`, `/fast`, etc.) are handled by the CLI before they reach me, so they don't come through my tool interface. Type it yourself at the prompt and the usage/cost report will display for you.
For what it's worth, if you're tracking spend: this session was heavier than average — ~25–30 Lean compile iterations with large Mathlib imports is token-intensive work. Future sessions of the same kind (ii′-1b(iii), ii′-2/3/5) will be similar; the design/planning sessions (ii′-0 style) are much lighter.
So far how successful are we so far with the new project
thinking (595 chars)
The user asks for an assessment of how successful the tier ii′ project is so far. Let me give an honest, measured assessment: what the goal is, what's been achieved, confidence level, risks ahead, and how it compares to expectations. Be honest — not cheerleading. The project is going well: design held up, two sub-stages done, defect found and fixed early (a real win), crux identity simplified the work, machinery built on schedule. Remaining risks: ii′-3 (the (4.10) Laurent relation — the long pole), ii′-5 (R-bound). Estimate where we are: ~3 of 9 sub-stages, on schedule for 9–16 sessions.
Honest assessment of tier ii′ so far:
## Scorecard: genuinely strong
**By the numbers:** 3 of 9 sub-stages complete in 3 sessions, against a 9–16 session estimate. On or ahead of schedule, zero blowups.
**The wins that matter most:**
1. **Your audit question caught a real defect.** The `liCoeff` encoding was silently vacuous — `LiVerifiedUpTo`/`SfBoundProp` were *false as written*, so the session-012 "machine-verified" theorem had unfulfillable hypotheses. If we'd submitted without tier ii′, a careful referee digging into the Lean could have found that. Now it's fixed *and* the hypotheses are true statements. That alone justifies doing this before submission.
2. **The mathematics cooperated.** The crux identity (Sf = Res₁ exactly) eliminated the scariest planned sub-task — the variable-order pole meeting the archimedean sum collapsed into a Leibniz computation + the (4.10) relation. The tail-free assembly means the final bound has fewer moving parts than D-062 feared.
3. **Every planned dependency checked out clean.** Rectangle residue theorem vendored and sorry-free; Zeta23's zero-summability proved; Borel–Carathéodory/Jensen/digamma present. No "missing Mathlib" surprises so far.
4. **Quality is holding.** Full builds green, only the 3 standard axioms everywhere, audit run after each sub-stage.
## Honest risks remaining
- **ii′-3 (the (4.10) Laurent relation)** is the make-or-break item — the only sub-stage with real mathematical uncertainty. If the EF-reuse route (β2) doesn't fit, we fall back to building Hadamard (+1–2 sessions).
- **ii′-5 (the R-bound)** is the second-biggest chunk; machinery exists but it's 2–3 sessions of grinding.
- Everything else (ii′-1b(iii), ii′-2, ii′-4, ii′-6, ii′-7) is engineering with known routes.
## Bottom line
We're roughly **25–30% through, on schedule, with the two scariest unknowns (encoding defect, crux identity) already resolved in our favor**. Success probability I'd put at **~85–90%** to fully close `SfBoundProp` as designed. The failure mode is benign: if ii′-3 stalls, Paper A submits as-is with the hypothesis declared (and now correctly encoded) — no downside risk to the paper.
Next session picks up at ii′-1b(iii) whenever you're ready.