← Session 18 — Lean tier (ii): finite-height proof + certified base points
thinking (33460 chars)
Both research derivations — not malware.
Now I have the complete picture:
**B(n) structure (D-037/D-056/D-057):**
- B(n) = 2N(T) + 4T[(2/3)C₀(T) + A log(T+2) + B₀] + 40M₀ + 2(e⁴+1)[7H(T) + 3.3] + I_I + 1, T = √n + 1
- Majorized version B̃(n): C₀ → Ĉ₀ = 0.433 log(t+2) + 0.886 loglog(t+2) + 2.9; N(T) → F + S_b...
Wait — the Lean marginTilde has "2 * F T" with abstract F. In D-057's component expansion: "2F(T) → #1, #2 (mod constants); 2S_b(T) → #3, #4". So the full N-majorant is F(T) + S_b(T) where F(T) = (T/2π)log(T/2πe) + 7/8 (Trudgian's smooth N) and S_b(T) = 0.137 log T + 0.443 log log T + 1.588.
In the Lean file, marginTilde's F is the ENTIRE N-count majorant (whatever majorizes Ncount 0 T), with hψ : ψ[F] < 0 as hypothesis. The D-057 §6 note says: "The Lean theorem is parameterized over F (the majorant and its ψ-condition hψ are hypotheses, discharged elsewhere for the explicit Trudgian majorant)".
So for the assembly, F_assembly(T) := F_Tru(T) + S_b(T) where:
- F_Tru(T) = (T/2π)·log(T/(2πe)) + 7/8
- S_b(T) = 0.137·log T + 0.443·log log T + 1.588
Hmm wait, need to be careful about domains: S_b bound holds for T ≥ e (Trudgian), log log T needs T > 1. For T = √n+1 with n ≥ 20: T ≥ 5.47 > e ✓.
And hmaj : ∀ T, (Ncount 0 T : ℝ) ≤ F_assembly T — Trudgian 2014 Thm 1. Hmm, but for small T (T < e)? Ncount 0 T = number of zeros with 0 < Im ≤ T presumably. Trudgian's bound |S(T)| ≤ ... holds for T ≥ e. For T < e... F(T) = (T/2π)log(T/2πe) + 7/8 is negative for small T! (T/2π)log(T/2πe) at T=1: (1/2π)·log(1/(2πe)) ≈ 0.159·(−2.84) ≈ −0.45, +7/8 = 0.42; + S_b... log 1 = 0, log log 1 = log 0 = junk! So F_assembly as written is ill-defined/junky for small T in Lean (log log 1 = log 0 = 0 in Lean's junk convention — actually Real.log 0 = 0, so log log 1 = 0, fine as junk but the bound Ncount ≤ F might be FALSE for small T if F is small/negative).
Where is hmaj USED? In the eventual proof of SfBound — for T = √n + 1 with n ≥ N₀ = 80000, T ≥ 283.8 ≫ e. So hmaj is only needed for T ≥ some large value. To keep the assembly clean, state hmaj as: ∀ T ≥ (some threshold), Ncount 0 T ≤ F T. Actually in marginTilde_convex, hmaj is stated ∀ T. Is hmaj USED in marginTilde_convex? Looking at the proof... it takes hmaj as a hypothesis but I don't see it used in the proof body! Let me check... scanning the proof: it uses hF (ContDiff), hψ (ψ[F] < 0). hmaj appears unused in the convexity proof itself! It's there because marginTilde is meant to majorize the true margin — the majorant property matters for the ASSEMBLY (margin ≥ marginTilde), not for convexity. Indeed: margin(n) = S(n) − B(n) + 1 ≥ S(n) − B̃(n) + 1 = marginTilde F n requires N(T) ≤ F(T) (so that 2N ≤ 2F) and C₀ ≤ Ĉ₀ etc.
OK so now the design crystallizes. Let me define everything with abstract F (as marginTilde already does), and structure the assembly as:
**Definitions:**
1. `sInftyLower (n : ℝ) : ℝ := (1/2)*n*log n + (lagariasC1 − γ/2)*n − 4` — extract from sInfty_lower_bound.
2. `Bn (F : ℝ → ℝ) (n : ℝ) : ℝ := 2*F(√n+1) + 4(√n+1)((2/3)C0hat(√n+1) + 10.5 log(√n+1+2) + 48) + 40*1.3352 + 2(e⁴+1)(7 Hhat(√n+1) + 3.3) + IIMaj n + 1` — matching marginTilde exactly.
3. `margin_eq : marginTilde F n = sInftyLower n − Bn F n + 1` — by ring (like marginTilde_eq_expanded).
4. `Sf (n : ℕ) : ℝ := SInfty n + 1 − (liCoeff n).re` — BL Thm 2 as definition of the finite part (honesty note: BL Thm 2 says this equals the prime-side sum; the contour bound is proved for the prime-side sum).
Hmm wait — actually, is that the right sign? λ_n = S_∞(n) − S_f(n) + 1 ⟹ S_f = S_∞ + 1 − λ_n. ✓.
But hold on: is λ_n real? LiVerifiedUpTo states 0 < (liCoeff n).re. λ_n is real by conjugate symmetry (noted in the file). Sf as defined is real by construction (taking .re). Fine.
5. `SfBoundProp (F) : Prop := ∀ n : ℕ, 80000 ≤ n → (n:ℝ) ≤ (3*10^12 − 1)^2 → |Sf n| ≤ Bn F n` — hmm, range: SfBound needed only for n in [N₀, N₁]. For n < N₀, hfinite covers. Should SfBound range over [1, N₁] or [N₀, N₁]? The contour bound works for n ≥ 20-ish (needs n large enough for various pieces; actually the B(n) bound is valid for all n ≥ some small threshold — the zero-avoidance and kernel bounds don't need large n; but B ≥ |S_f| worst-case... it's claimed valid broadly). For the assembly, only [N₀, N₁] is consumed. Honest + minimal: state ∀ n with 1 ≤ n and n ≤ N₁. The eventual proof will use n ≥ 20 or so for some pieces but that's fine (stronger statement covers). Hmm — is |S_f n| ≤ B n even TRUE for small n? |S_f(1)| = small; B(1) = big positive number. B(n) is large positive for all n ≥ 1 (all terms positive: F(T)... F(T) for T = √1+1 = 2: F_Tru(2) = (2/2π)log(2/2πe)+7/8 = 0.318·log(0.117)+0.875 = 0.318·(−2.145)+0.875 = 0.19; S_b(2) = 0.137·0.69 + 0.443·log(0.69) + 1.588 = 0.095 + 0.443·(−0.371)+1.588 = 1.52. So 2F ≈ 3.4; other terms positive. So B(1) ≥ ~10 or so. |S_f(1)| =? S_f(1) = Σ_p... λ_1 = 0.0230957 (Keiper). S_∞(1) = (1−a₁)·1 − 1 + Σ h⁺... = small. S_f(1) = S_∞(1) + 1 − λ_1. Should be fine but why risk it: the D-037 bound derivation assumes n in certain ranges? "T ∈ [√n, √n+1] chosen zero-avoiding" works for any n ≥ 1; |k_n| bounds fine. I think |S_f n| ≤ B n holds for all 1 ≤ n ≤ N₁. But to be SAFE and minimal, restrict SfBound to N₀ ≤ n ≤ N₁ — that's all the assembly uses, and it's the honest claim (the bound was DESIGNED for the margin range). Actually hmm, simpler for triage: state it for the range consumed. I'll go with 1 ≤ n ≤ N₁ since the pieces are uniform... no wait. Let me just use the range the assembly needs: N₀ ≤ n. No — think about the eventual discharge: proving SfBound for n ≥ N₀ = 80000 means T ≥ 283, all Trudgian bounds in range, M₀ fine, etc. All the delicate small-n cases vanish. That's actually BETTER for the eventual proof. Decision: SfBound range = N₀ ≤ n ≤ N₁, i.e. `∀ n : ℕ, 80000 ≤ n → (n:ℝ) ≤ N₁ → |Sf n| ≤ Bn F n`.
Hmm, but then hfinite needs to cover n < 80000, i.e. n ≤ 79999. LiVerifiedUpTo (5×10⁵) covers n ≤ 5×10⁵ ⊇ n ≤ 79999 ✓.
6. The explicit F: `FTrud (T : ℝ) : ℝ := (T/(2π))·log(T/(2π·e)) + 7/8 + 0.137·log T + 0.443·log log T + 1.588`. Hmm — wait. Should the assembly instantiate FTrud now, or keep F abstract?
Per the notes: "state lambda_pos_finite_height with the finite-part bound as an explicit named hypothesis (SfBound : ∀ n, |S_f n| ≤ B n), and discharge the full assembly conditional on it."
The single named hypothesis = SfBound. If F stays abstract, then hψ, hF, hbase, hbase′ are ALSO hypotheses → not "one named hypothesis". So instantiate F = FTrud and discharge:
- hF: ContDiff ℝ 2 FTrud — elementary (Mathlib: log, div, const). T > 0 needed... ContDiff on all of ℝ is FALSE for FTrud (log T at T ≤ 0 junk but ContDiff requires actual smoothness; log is not differentiable at 0; T/(2π)·log(T/(2πe)) smooth only on T > 0... as a function ℝ → ℝ with junk values, ContDiff ℝ 2 FTrud is false globally!). But marginTilde_convex requires `ContDiff ℝ 2 F` GLOBALLY (hF : ContDiff ℝ 2 F). Problem!
Options: (a) weaken marginTilde_convex to ContDiffOn (Set.Ioi 0) or Ioi 1... The proof uses hF via contDiffOn_mFblock: hF.contDiffOn.comp contDiffOn_sqrt_shift (mapsTo_univ) — it maps Ioi 20 into Ioi (−1) via √m+1 ≥ 5.47. So F only needs ContDiffOn (Ioi (−1)) or even Ioi 1. The chain_rule_sqrt_shift used for vF uses chain_rule_sqrt_shift F hF — the GLOBAL version. But chain_rule_sqrt_shift_on (the localized variant, PROVED) only needs ContDiffOn (Ioi (−1))! So I can refactor: marginTilde_convex with hF : ContDiffOn ℝ 2 F (Set.Ioi (-1)) and hψ range T ≥ √20+1 (already). The vF step would use chain_rule_sqrt_shift_on. And contDiffOn_mFblock needs F ContDiffOn (Ioi (−1)) composed with √m+1 mapping Ioi 20 → Ioi (−1) — mapsTo_sqrt_shift exists ✓.
That's a small refactor of marginTilde_convex: change hF : ContDiff ℝ 2 F → ContDiffOn ℝ 2 F (Set.Ioi (-1)), and vF: chain_rule_sqrt_shift F hF → chain_rule_sqrt_shift_on F hF; contDiffOn_mFblock: hF.contDiffOn.comp → hF.comp; continuousOn_marginExpanded: hF.continuous.continuousOn → hF.continuousOn. Manageable.
Then FTrud's ContDiffOn (Ioi (−1)): pieces T·log(T/(2πe)) = (1/2π)(T log T − T log(2πe))... log T for T > −1... log is smooth on (0,∞); on Ioi (−1) log T hits T ∈ (−1, 0] — NOT smooth. Hmm! FTrud uses log T and log log T — smooth only for T > 1 (log log needs log T > 0 ⟹ T > 1). So FTrud is ContDiffOn (Ioi 1) at best. T = √n+1 for n > 20 gives T > √20+1 ≈ 5.47 > 1 ✓. So localize F to Ioi 1? Then mapsTo: √m+1 for m > 20 lands in Ioi (√20+1) ⊆ Ioi 1 ✓. And chain_rule_sqrt_shift_on needs ContDiffOn (Ioi (−1)) — generalize to (Ioi c) with c < √20+1... The lemma chain_rule_sqrt_shift_on as stated: ContDiffOn ℝ 2 φ (Set.Ioi (-1)) → ... at n > 0, uses √n+1 > −1... actually uses hmem : Ioi (−1) ∈ 𝓝 (√m+1) since √m+1 ≥ 1 > −1. A version with Ioi 1: needs √m+1 > 1 ⟺ m > 0 ✓. So chain_rule_sqrt_shift_on' with ContDiffOn ℝ 2 φ (Set.Ioi 1).
Hmm, this is getting into real refactor territory. Alternative: keep marginTilde_convex AS IS (global ContDiff F) and define FTrud with junk-safe smooth extensions... NO — cleaner alternative: don't instantiate F in the margin theorem; instead structure the assembly as TWO theorems:
**Theorem A (assembly, abstract F):**
```
theorem lambda_pos_finite_height_aux
(hfinite : LiVerifiedUpTo (5*10^5))
(F : ℝ → ℝ) (hF : ContDiffOn ℝ 2 F (Set.Ioi 1)) -- or global ContDiff
(hψ : ∀ T ≥ √20+1, ψ[F](T) < 0)
(hbase : 0 < marginTilde F 80000)
(hbase' : 0 < deriv (marginTilde F) 80000)
(hSf : SfBoundProp F) :
∀ n, 1 ≤ n → (n:ℝ) ≤ N₁ → 0 < (liCoeff n).re
```
All hypotheses here are honest named items. But that's 6 hypotheses, not 1.
**Theorem B (instantiated):** prove hF, hψ, hbase, hbase′ for FTrud, leaving:
```
theorem lambda_pos_finite_height
(hRH : RHUpTo (3*10^12)) (hfinite : LiVerifiedUpTo (5*10^5))
(hSf : SfBoundProp FTrud) :
∀ n, 1 ≤ n → (n:ℝ) ≤ N₁ → 0 < (liCoeff n).re
```
hψ for FTrud: ψ[F+S_b] = (1/2π)ψ[T log T] + ... via ψ-linearity. ψ is linear in φ: ψ[c₁φ₁ + c₂φ₂] = c₁ψ[φ₁] + c₂ψ[φ₂] (needs deriv linearity lemmas — deriv_add, deriv_const_mul for deriv and deriv² — we HAVE deriv2_add, deriv2_const_mul! and psiOf is deriv(deriv φ) − deriv φ/(T−1) — linear given differentiability). So prove psiOf_add, psiOf_const_mul, psiOf_const (ψ[K] = 0... ψ[K] = 0 − 0/(T−1) = 0 ✓; note deriv const = 0). Then ψ[FTrud] = (1/2π)ψ[T log T] + (1/2π)(1−log(2πe))·ψ[T]... wait let me expand FTrud into blocks:
FTrud(T) = (T/2π)·log(T/(2πe)) + 7/8 + 0.137·log T + 0.443·log log T + 1.588
= (1/2π)·T·log T − (log(2πe)/2π)·T + (7/8 + 1.588) + 0.137·log T + 0.443·log log T
Blocks: T·log T (#1), T (#2), const, log T (#3), log log T (#4) — exactly D-057's rows #1–#4! "2F(T) → #1, #2 (mod constants); 2S_b(T) → #3, #4". So I need psiOf for blocks #1–#4 (unshifted versions):
- #1: ψ[T log T] = 1/T − (log T + 1)/(T−1) < 0 (D-057 row 1 sign: ⟺ −1 < T log T ✓)
- #2: ψ[T] = −1/(T−1) < 0 — HAVE (psiOf_id)
- #3: ψ[log T] = −1/T² − 1/(T(T−1)) < 0
- #4: ψ[log log T] = −(log T+1)/(T log T)² − 1/(T log T (T−1)) < 0
- const: ψ = 0
All provable with existing machinery (hasDerivAt patterns from the file). Weights: 1/(2π) > 0, −log(2πe)/(2π) < 0 (!). Uh oh — the coefficient of T is NEGATIVE: F(T) = (T/2π)log(T/2πe) + 7/8 = (1/2π)T log T − (log(2π)/2π + 1/2π... log(2πe) = log 2π + 1)·T/(2π)... so coefficient of T is −(log(2π)+1)/(2π) < 0. ψ[T] = −1/(T−1) < 0, times negative weight gives POSITIVE contribution. But the total: ψ[F] = (1/2π)[1/T − (log T+1)/(T−1)] − ((log 2π + 1)/2π)·(−1/(T−1)) + ... = (1/2π)[1/T − (log T + 1)/(T−1) + (log 2π + 1)/(T−1)] = (1/2π)[1/T − (log T − log 2π)/(T−1)] = (1/2π)[1/T − log(T/2π)/(T−1)]. For T ≥ 5.47: log(T/2π) = log(0.87) < 0 at T=5.47... interesting, could be positive ψ?! Direct: ψ[F_Tru] where F_Tru = (T/2π)log(T/2πe)+7/8: F′ = (1/2π)(log(T/2πe) + 1) = (1/2π)log(T/2π), F″ = 1/(2πT). ψ = 1/(2πT) − (1/2π)log(T/2π)/(T−1) = (1/2π)[1/T − log(T/2π)/(T−1)]. At T = 5.47: 1/T = 0.183; log(5.47/6.283) = log(0.8707) = −0.1386; −(−0.1386)/(4.47) = +0.031. ψ = (1/2π)(0.183+0.031) = 0.034 > 0!!!
F_Tru's ψ is POSITIVE at small T?! That would break the convexity! But wait — D-057's table row #1 is T log T (not F_Tru). The component expansion says "2F(T) → #1, #2 (mod constants)" — i.e. 2F(T) = (T/π)log(T/2πe) + 7/4 = (1/π)[T log T − (log 2πe) T] + 7/4. Rows: #1 T log T with ψ < 0; #2 T with ψ = −1/(T−1) < 0 but weight −(log 2πe)/π < 0 → contribution to margiñ″ is −w·ψ/(4n)... wait signs: margiñ″ = 1/(2n) − Σ wᵢψᵢ/(4n) − IIMaj″. The B̃ terms enter with MINUS: each B̃-component wᵢ·blockᵢ (wᵢ > 0) contributes −wᵢψᵢ/(4n) to margiñ″. For convexity need margiñ″ > 0, i.e. 1/(2n) − Σwᵢψᵢ/(4n) − IIMaj″ > 0. Blocks with ψᵢ < 0 HELP (positive contribution). Row #2 T with NEGATIVE weight −log(2πe)·... hold on: (T/π)log(T/2πe) = (1/π)T log T − (log(2πe)/π)T. The second term has negative coefficient in B̃. Then in margiñ″: −[−(log 2πe/π)]·ψ[T]/(4n) = +(log 2πe/π)·(−1/(T−1))/(4n) < 0 — HURTS.
So is marginTilde actually convex with the TRUE Trudgian F?? Let me sanity check numerically: F_Tru(T), T = √n+1. The claim "margin convex" was E-029-verified and marginTilde_convex PROVED for abstract F with hψ : ψ[F] < 0. If ψ[F_Tru + S_b] > 0 somewhere, then the Lean hypothesis hψ would be FALSE for the explicit Trudgian majorant — a real problem!
Let me compute ψ of the FULL majorant M(T) = F_Tru(T) + S_b(T) at T = 5.47:
F_Tru: F′ = (1/2π)log(T/2π), F″ = 1/(2πT).
S_b: 0.137 log T + 0.443 log log T + 1.588: S_b′ = 0.137/T + 0.443/(T log T); S_b″ = −0.137/T² − 0.443(log T + 1)/(T log T)².
At T = 5.4721: log T = 1.6995, log log T = 0.5300.
F″ = 1/(2π·5.4721) = 0.02909. F′ = (1/2π)·log(0.8707) = 0.15915·(−0.13857) = −0.022054. ψ_F = 0.02909 − (−0.022054)/4.4721 = 0.02909 + 0.004932 = 0.034023.
S_b″ = −0.137/29.94 − 0.443·(2.6995)/(5.4721·1.6995)² = −0.004575 − 0.443·2.6995/86.47 = −0.004575 − 0.013830 = −0.018405.
S_b′ = 0.137/5.4721 + 0.443/(5.4721·1.6995) = 0.025036 + 0.047638 = 0.072674.
ψ_Sb = −0.018405 − 0.072674/4.4721 = −0.018405 − 0.016251 = −0.034656.
ψ_M = 0.034023 − 0.034656 = −0.0006 < 0. PHEW. Barely negative at T₀, and more negative as T grows (ψ_F → 0⁺? as T→∞: 1/T vs log(T/2π)/(T−1): for T > 2π·e^{(T−1)/T}... log(T/2π)/(T−1) vs 1/T: T log(T/2π) vs T−1: at T = 100: 100·log(15.9) = 276.8 > 99 ✓ so ψ_F < 0 for T ≥ ~17? Let me check T = 20: 1/20 = 0.05; log(20/2π)/19 = log(3.183)/19 = 1.1576/19 = 0.0609 > 0.05 ⟹ ψ_F(20) < 0. T = 15: 0.0667 vs log(2.387)/14 = 0.870/14 = 0.0622 < 0.0667 ⟹ ψ_F(15) > 0. T = 17: 0.0588 vs log(2.7056)/16 = 0.9955/16 = 0.0622 ⟹ <0? 0.0588 < 0.0622 ⟹ ψ_F(17) < 0. So ψ_F turns negative around T ≈ 16, and ψ_Sb < 0 always. So ψ_M < 0 everywhere on the range (needs the combination, since ψ_F > 0 on [5.47, ~16]).
So the correct explicit majorant for Lean is M(T) := F_Tru(T) + S_b(T) — the FULL N(T) majorant — and hψ for it requires the combination argument (not blockwise sign, since the T log T block is positive-ψ on part of the range!). Hmm — wait, D-057's table row #1 says ψ[T log T] < 0 "⟺ −1 < T log T ✓" — TRUE: ψ[T log T] = 1/T − (log T + 1)/(T−1) < 0 ⟺ (T−1) < T(log T + 1) ⟺ −1 < T log T ✓ always. But the NEGATIVE-weight T term: −(log 2πe)/π·T with ψ[T] < 0 gives positive contribution... Let me recompute the SUM as D-057 does: rows #1 + #2 with weights w₁ = 1/π (from 2F: (1/π)T log T) and w₂ = −log(2πe)/π < 0 — D-057's §2 says "B̃ is a positive combination of the blocks below" — but #2 appears with both positive (4T·(2/3)·2.9, 4T·B₀) and negative (−log(2πe)/π from 2F) weights?! NET weight of T: from 4T[(2/3)Ĉ₀ + A log + B₀]: (8/3)·2.9 + 4·48 = 7.73 + 192 = 199.7; from 2F: −log(2πe)/π = −2.8379/3.1416·... log(2πe) = 1.8379+1 = wait log(2π) = 1.83788, log(2πe) = 2.83788. 2F(T) = (T/π)(log T − log 2πe)... hmm 2F(T) = 2·(T/2π)log(T/2πe) + 7/4 = (T/π)log T − (2.83788/π)T + 7/4 = (T/π)log T − 0.90327·T + 7/4. So net T weight: 199.7 − 0.90 = 198.8 > 0 ✓. D-057's "positive combination" refers to the NET expansion — the 2F's negative T-weight is absorbed by the huge positive T-weight from 4T·B₀. OK! So the 11-block table works on the NET expansion, all weights positive.
But in the LEAN file, marginTilde_convex keeps F ABSTRACT (hψ atomic) — D-057 §6: "The Lean theorem is parameterized over F... those rows never appear: the 2F(T) term is handled atomically via hψ." So the Lean hψ hypothesis is: ψ[F] < 0 where F is the whole N-majorant. For the instantiation F := F_Tru + S_b (M above), ψ[M] = ψ_F + ψ_Sb; ψ_F > 0 on [5.47, 16] but |ψ_Sb| > ψ_F there (checked numerically at 5.47: −0.0006 total; need a proof for the whole interval [5.47, 16]).
Hmm OK. So instantiating F := M requires proving ψ[M](T) < 0 for T ≥ √20+1, which on [5.47, 16] needs the cross-cancellation ψ_Sb < −ψ_F. That's a real-analytic inequality — provable by elementary means (rational/log bounds on a compact interval — could use monotonicity splitting + pointwise numeric bounds at a few anchor points with derivative control; or find a slicker sign argument).
Slicker: ψ[M] = 1/(2πT) − (1/2π)log(T/2π)/(T−1) + S_b″ − S_b′/(T−1). Ugh. Alternative: prove ψ[M] < 0 by showing ψ[M] is increasing-ish... or bound: ψ_F ≤ 1/(2πT) + (1/2π)·max(0, −log(T/2π))/(T−1)... On T ∈ [5.47, 2π]: log(T/2π) ≤ 0 so ψ_F = 1/(2πT) + |log(T/2π)|/(2π(T−1)) ≤ 1/(2πT) + log(2π/5.47... hmm log(2π/T) ≤ log(2π/5.4721) = 0.1386 for T ∈ [5.47, 2π]. And ψ_Sb ≤ −0.137/T² − 0.443(logT+1)/(T logT)² − [0.137/T + 0.443/(T log T)]/(T−1). All terms… this is a finite-interval verification. Doable but fiddly in Lean.
Alternatively choose a SLIGHTLY larger majorant that's blockwise clean! We get to CHOOSE F (any majorant of N works, at the cost of margin). E.g., replace F_Tru by something with provably negative ψ blockwise: F_alt(T) = (1/2π)·T·log T + 7/8 (drop the −(log 2πe)/2π·T term — but then F_alt ≥ F_Tru? F_Tru = (1/2π)T log T − ((log 2π + 1)/2π)T + 7/8. F_alt − F_Tru = ((log 2π + 1)/2π)T > 0 ✓ so F_alt + S_b ≥ F_Tru + S_b ≥ N ✓ majorant preserved. ψ[F_alt] = (1/2π)ψ[T log T] < 0 ✓ blockwise! And the margin cost: B increases by 2·((log 2π+1)/2π)T ≈ 0.903·T ≈ 0.903√n — margin(N₁) has √n·log n·(1/2 − ...) slack; margiñ(80000) = 16020 vs extra 0.903·(√80000+1) ≈ 256 — margiñ drops to ~15764, still > 0; margiñ′ drops by ~0.903/(2√n)·... ≈ 0.0016 — still > 0. The crossover N₀ moves slightly; E-028's N₀ = 75451 had margin 2.4 — adding 0.9√n ≈ 250 at n = 80000... wait margin at crossover 75451 was 2.4; the extra 0.9·T ≈ 0.9·275.7 ≈ 248 pushes crossover up by Δn where margin′·Δn = 248, margin′ ≈ 3.7 → Δn ≈ 67. N₀ ≈ 75520. Adopted N₀ = 80000 has margin 16020 − 248 ≈ 15772 > 0 ✓. Totally fine!
Even cleaner: F_alt(T) := (1/2π)·T·log T + S_b(T) + 7/8 — all blocks with provable ψ signs:
- T·log T: ψ < 0 (row #1) ✓ (weight 1/2π > 0)
- log T: ψ < 0 (row #3, weight 0.137) ✓
- log log T: ψ < 0 (row #4, weight 0.443) ✓
- const 7/8 + 1.588: ψ = 0 ✓
All four are the UNSHIFTED blocks. Need psiOf lemmas for T·log T, log T, log log T, const. Provable with existing machinery (Real.hasDerivAt_log etc.). And N(T) ≤ F_alt(T) is the Trudgian perimeter hypothesis (stated: Ncount 0 T ≤ F_alt T for T ≥ √20+1... plus honestly it's F_Tru + S_b that's Trudgian; F_alt ≥ that by the dropped term — but as a HYPOTHESIS we just state Ncount ≤ F_alt directly, noting in the docstring it's Trudgian 2014 + the dropped-term slack).
Hmm wait — actually hold on. Does hmaj even appear in the assembly theorem? Earlier analysis: hmaj is used in the eventual SfBound proof, NOT in the margin assembly. The margin assembly uses: marginTilde convex (hF, hψ) + base points + marginTilde = slower − Bn + 1 + SfBound + sInfty_lower_bound. Where does the majorant property N ≤ F enter? It enters SfBound's proof: |zeros sum| ≤ 2N(T) ≤ 2F(T). So in the ASSEMBLY theorem (conditional on SfBound), hmaj doesn't appear. ✓ So the assembly theorem:
```
theorem lambda_pos_finite_height
(hRH : RHUpTo (3 * 10 ^ 12)) -- perimeter (consumed by SfBound's proof; unused here)
(hfinite : LiVerifiedUpTo (5 * 10 ^ 5)) -- perimeter
(hSf : SfBoundProp) : -- THE named analytic hypothesis
∀ n : ℕ, 1 ≤ n → (n : ℝ) ≤ (3 * 10 ^ 12 - 1 : ℝ) ^ 2 → 0 < (liCoeff n).re
```
with SfBoundProp referencing the explicit Bn (with F_alt baked in or abstract F?). Decision: bake in the explicit majorant — SfBound should be fully concrete: `∀ n, 80000 ≤ n → (n:ℝ) ≤ N₁ → |Sf n| ≤ BnExplicit n`. Then BnExplicit := Bn F_alt. And marginTilde F_alt.
Assembly proof (given hSf, hfinite):
- intro n hn1 hnN1
- by_cases n ≤ 80000: hfinite n hn1 (le_trans h (by norm_num)) — wait LiVerifiedUpTo (5*10^5) needs n ≤ 5*10^5: 80000 ≤ 500000 ✓. Gives 0 < (liCoeff n).re ✓.
- else: 80000 < n, so 80001 ≤ n (Nat), n ≥ 20 ✓.
- h20 : 20 ≤ (n:ℝ)
- hkey: (liCoeff n).re = SInfty n − Sf n + 1 (from Sf def: Sf n = SInfty n + 1 − (liCoeff n).re ⟹ ring)
- (liCoeff n).re ≥ sInftyLower n − |Sf n| + 1... let me be careful: SInfty n ≥ sInftyLower n (sInfty_lower_bound, needs n ≥ 20 ✓ — the theorem is stated for ℕ: sInfty_lower_bound (n : ℕ) (hn : 20 ≤ n) : ... ≤ SInfty n ✓). −Sf n ≥ −|Sf n| ✓ (neg_le_abs... actually Sf n ≤ |Sf n| so −|Sf n| ≤ −Sf n... wait we need lower bound on λ = S_∞ − S_f + 1 ≥ slower − |S_f| + 1 ✓ since −S_f ≥ −|S_f| and S_∞ ≥ slower).
- |Sf n| ≤ BnExplicit n (hSf n (80001 ≥ 80000) hnN1) — note BnExplicit takes (n : ℝ) or ℕ? Bn F n with n : ℝ (marginTilde takes ℝ). Cast: hSf stated with ((n : ℝ)) — fine.
- So λ.re ≥ sInftyLower n − BnExplicit n + 1 = marginTilde F_alt n (ring lemma).
- marginTilde F_alt n > 0: convexity argument:
- marginTilde_convex F_alt hF hmaj hψ : ConvexOn ℝ (Ici 20) (marginTilde F_alt) — WAIT, marginTilde_convex's hF is global ContDiff ℝ 2 F. F_alt = (1/2π)T log T + 0.137 log T + 0.443 log log T + const — NOT globally C² (singularities at T = 0, 1). So I DO need the ContDiffOn refactor of marginTilde_convex. OK, decided: refactor marginTilde_convex (and marginTilde continuity/ContDiffOn lemmas + vF chain-rule step) from `ContDiff ℝ 2 F` to `ContDiffOn ℝ 2 F (Set.Ioi 1)`. Check each use of hF in marginTilde_convex:
- contDiffOn_mFblock F hF : hF.contDiffOn.comp contDiffOn_sqrt_shift (mapsTo_univ) → with ContDiffOn: hF.comp contDiffOn_sqrt_shift (mapsTo into Ioi 1: need mapsTo_sqrt_shift₁ : MapsTo (√·+1) (Ioi 20) (Ioi 1) — √m+1 > √20+1 > 1 ✓ easy).
- vF: chain_rule_sqrt_shift F hF n hn0 → chain_rule_sqrt_shift_on currently needs ContDiffOn (Ioi (−1)). Generalize chain_rule_sqrt_shift_on to any c < 1? The proof uses hmem: Ioi (−1) ∈ 𝓝 (√m+1) since √m+1 ≥ 1 > −1. For Ioi 1: √m+1 > 1 ⟺ m > 0 ✓ but needs Set.Ioi 1 ∈ 𝓝 (√m+1): √m+1 > 1 strictly for m > 0 ✓ Ioi_mem_nhds. So a version chain_rule_sqrt_shift_on₁ with (Ioi 1). Rather than proliferating, generalize chain_rule_sqrt_shift_on to parameter c with h : c < 1? The proof structure: hmem m hm : Ioi c ∈ 𝓝 (√m+1) needs √m+1 > c ⟸ 1 > c (since √m ≥ 0... wait need √m+1 > c: √m ≥ 0 ⟹ √m+1 ≥ 1 > c ✓). So parameterize: chain_rule_sqrt_shift_on (φ) (hφ : ContDiffOn ℝ 2 φ (Set.Ioi c)) (hc : c < 1) (n) (hn : 0 < n). The existing one (c = −1) is used for blocks (log-shifted blocks need Ioi (−1)). Keep existing as-is; add the general one? Or refactor existing call sites... Existing call sites use contDiffOn_TL1 etc. (Ioi (−1)). If I generalize the lemma to take c, call sites pass c = −1, hc = by norm_num. That's clean: modify chain_rule_sqrt_shift_on signature, update ~9 call sites in marginTilde_convex (add (by norm_num : (-1:ℝ) < 1)), and vF uses c = 1. Hmm wait, actually simpler: keep chain_rule_sqrt_shift_on unchanged; for F_alt use hF : ContDiffOn ℝ 2 F_alt (Set.Ioi (−1))? F_alt on Ioi (−1): log T for T ∈ (−1, 0] — Real.log is junk (0) for T ≤ 0 and NOT differentiable there (as a function ℝ→ℝ it's actually differentiable at T < 0! Real.log of negative = log|x|? NO — Real.log x = Real.log |x|? In Mathlib, Real.log x = log |x|... let me recall: Mathlib's Real.log is defined as Complex... Real.log x = Real.log (|x|)? Actually `Real.log x = Complex.log (x : ℂ) |>.re`? Hmm — Mathlib: Real.log x := Real.exp partial inverse... Real.log x = if x = 0 then 0 else ... Actually Real.log in Mathlib: `Real.log x = Complex.log x |>.re`? The key facts: Real.log is differentiable on ℝ \ {0}? There's Real.hasDerivAt_log (hx : x ≠ 0)! Yes — Mathlib's Real.log = log|x| basically (Real.log_neg_eq_log : log (−x) = log x). So log IS smooth on ℝ \ {0}, and ContDiffOn ℝ 2 Real.log (Ioi (−1))?? At x = 0 ∈ Ioi (−1): log 0 = 0 (junk), not continuous even. So ContDiffOn ℝ n Real.log (Ioi (−1)) is FALSE (0 ∈ Ioi (−1), log not differentiable at 0: Real.hasDerivAt_log needs x ≠ 0; at 0 the function is... log x = log|x| near 0⁻ goes to −∞ — not even continuous at 0). So F_alt is NOT ContDiffOn (Ioi (−1)). Must use Ioi 0 or Ioi 1. log log T needs T > 1 (log T > 0) — actually log log T as ℝ function: smooth where log T ≠ 0 AND T ≠ 0, i.e. T ∈ (−∞,0)∪(0,1)∪(1,∞)... on (0,1): log T < 0, log log T = log|log T| smooth there too! But our domain: Ioi 1 is the clean choice (√20+1 ≈ 5.47 > 1 ✓ mapsTo fine).
So: refactor marginTilde_convex to take hF : ContDiffOn ℝ 2 F (Set.Ioi 1), with vF via a new chain_rule_sqrt_shift_at₁ or generalized. Also continuousOn_marginExpanded uses hF.continuous.continuousOn.comp hT (mapsTo_univ) on Ici 20: F needs ContinuousOn (Ici-image = [√20+1, ∞)) — ContDiffOn (Ioi 1).continuousOn comp works with mapsTo (Ici 20 → Ioi 1: √m+1 ≥ √20+1 > 1 ✓).
OK the refactor is contained. Good.
- base points: hbase : 0 < marginTilde F_alt 80000, hbase′ : 0 < deriv (marginTilde F_alt) 80000. These are explicit numeric evaluations — PROVABLE in principle. For THIS session, they could be left as hypotheses of the aux theorem and discharged later (they're "computational perimeter" — single-point evaluations, E-028/E-029-verified). The notes say the endpoint is "verified modulo one named analytic hypothesis + the computational perimeter" — base-point evaluations ARE computational perimeter items. But they're provable-from-Mathlib numerics (unlike Platt–Trudgian). Ideal: prove them. Realistic this session: keep as hypotheses hbase/hbase′ feeding the aux theorem, with the main theorem... hmm, if main theorem takes hbase/hbase′ as hypotheses, then it's 4 hypotheses. To get to "one named analytic hypothesis + perimeter", discharge hbase/hbase′ via numeric proofs. That's a chunk of tight numeric work (margiñ(80000) = 16020 — HUGE margin, so crude bounds suffice! margiñ′ = 3.7 — margin small-ish but still O(1); crude interval bounds with error < 1 suffice. Both very doable with rational squeezes: need log(80000), log(T+2) at T = √80000+1 ≈ 283.84, etc. With margin 16020, we need lower bound pieces to ~10% accuracy — EASY with norm_num-scale bounds. For deriv: 3.7, need accuracy ~0.5 — the derivative has an explicit closed form (deriv of marginExpanded pieces — all available via hasDerivAt machinery). Feasible but a solid chunk of work.)
Given the scope, sub-stage breakdown for session 012:
- 12.1: Refactor (ContDiffOn), defs (sInftyLower, Bn, Sf, SfBoundProp, F_alt), margin identity (ring), convex-pos lemma, assembly theorem aux (abstract F + hbase/hbase′ hypotheses) — COMPILES.
- 12.2: psiOf blocks #1/#3/#4 + const + linearity; ψ[F_alt] < 0 proof; instantiate F_alt; discharge hF (ContDiffOn Ioi 1).
- 12.3: base-point numerics (margiñ(80000) > 0, margiñ′(80000) > 0) in Lean.
- 12.4: triage documentation (D-062: what's inside SfBound — Mathlib-tractable vs Trudgian-class; perimeter decision), journal, STATE, db, commit, paper appendix update.
That's ambitious for one session but sub-stages are committable. Actually the notes said "achievable in a few sessions" — don't rush. Let me aim for 12.1 + 12.2 today, possibly 12.3.
Wait — one more design question: SfBoundProp range and the hfinite split. N₀ = 80000. In Lean: case split at n ≤ 80000 vs n ≥ 80001.
hfinite : LiVerifiedUpTo (5*10^5): ∀ n, 1 ≤ n → n ≤ 5*10^5 → 0 < (liCoeff n).re. Note 5*10^5 as ℕ literal: 500000 ✓.
SfBoundProp: ∀ n : ℕ, 80001 ≤ n → (n:ℝ) ≤ (3*10^12 − 1)^2 → |Sf n| ≤ Bn F_alt (n:ℝ). Hmm — or 80000 ≤ n to be round? The overlap: hfinite covers ≤ 80000 (via ≤ 5×10⁵); hSf covers ≥ 80001. Clean complementary. Or make hSf start at 80000 and split at < 80000 / ≥ 80000. Either fine. I'll use N₀ = 80000 in hSf (80000 ≤ n) and split hfinite side at n < 80000 (n ≤ 79999 ≤ 5×10⁵ ✓). Slightly cleaner: SfBound from N₀, matching D-037's "adopted N₀ := 80 000".
Also should SfBoundProp quantify (n : ℝ) or ℕ? Sf n is on ℕ (SInfty n, liCoeff n take ℕ). Bn takes ℝ. State: ∀ n : ℕ, 80000 ≤ n → (n:ℝ) ≤ N₁ → |Sf n| ≤ Bn (n:ℝ). ✓
N₁ = (3*10^12 − 1)^2 as ℝ. In the theorem statement it already appears as ((3 * 10 ^ 12 - 1 : ℝ) ^ 2). Keep consistent.
Another subtlety: `liCoeff` uses tsum of a possibly-non-summable family (junk 0 if not summable). The honesty note covers it — summability is inside SfBound's eventual content effectively (S_f finite ⟺ ...). Fine — skeleton design choice inherited.
Also `Ncount` — used in hmaj of marginTilde_convex. If hmaj is unused in marginTilde_convex's proof... it IS in the signature. For the refactored theorem I can DROP hmaj from marginTilde_convex (it's not used in the proof!)? Careful: is it really unused? Scanning the proof body of marginTilde_convex... hmaj appears only in the signature. The convexity proof never uses the majorant property. Dropping it changes the theorem's meaning not at all (convexity of marginTilde F doesn't need F to majorize anything). But hmaj documents intent. Lean linter: unused variable warning (already present in session 011? — the file compiled, so warnings are tolerated). KEEP hmaj to avoid churn? If it's already there and compiling, keep. Actually wait — if I'm refactoring hF anyway, touching the signature, keep hmaj as is. Fine.
Hmm, wait — actually let me reconsider: is hmaj really unused? `marginTilde_convex (F : ℝ → ℝ) (hF : ContDiff ℝ 2 F) (hmaj : ∀ T : ℝ, (Ncount 0 T : ℝ) ≤ F T) (hψ : ...)`. Body: uses hF (via contDiffOn_mFblock F hF, hCDFc, chain_rule_sqrt_shift F hF), hψ (hψn). hmaj: NOT used. Ncount: from Zeta23 (open Zeta23). OK keep.
Now the convex-pos lemma. Statement: if f convex on Ici 20 (real), C² interior..., f(N₀) > 0, f′(N₀) > 0 (deriv at N₀ exists), then f(x) > 0 for x ≥ N₀. Proof: for x > N₀: by ConvexOn, deriv is monotone on interior (Mathlib: ConvexOn.monotoneOn_deriv : ConvexOn ℝ S f → MonotoneOn (deriv f) (interior S)). f C² on Ioi 20 ⟹ deriv f differentiable... monotoneOn_deriv needs ConvexOn only? Let me recall Mathlib: `ConvexOn.monotoneOn_deriv (hf : ConvexOn ℝ s f) : MonotoneOn (deriv f) (interior s)`. I believe it exists (uses slope monotonicity + differentiable... hmm, it might need no differentiability — deriv junk... Actually I recall `ConvexOn.monotoneOn_deriv` exists in Mathlib.Analysis.Convex.Deriv or ...Specific... yes: ConvexOn.monotoneOn_deriv : ConvexOn ℝ s f → MonotoneOn (deriv f) (interior s). I'm fairly confident it exists.)
Then: for x > N₀ (N₀ ≥ 20, interior since N₀ > 20): f(x) − f(N₀) = ∫ or MVT: exists_deriv_eq_slope (f continuous on [N₀, x], differentiable on (N₀, x)): ∃ ξ ∈ (N₀, x), f′(ξ) = (f(x)−f(N₀))/(x−N₀). ξ ∈ interior Ici 20 = Ioi 20 ✓ (ξ > N₀ ≥ 20... need ξ > 20: ξ > N₀ = 80000 > 20 ✓). monotoneOn_deriv: N₀ ≤ ξ, both in interior ⟹ f′(N₀) ≤ f′(ξ). So (f(x)−f(N₀))/(x−N₀) = f′(ξ) ≥ f′(N₀) > 0 ⟹ f(x) ≥ f(N₀) + f′(N₀)(x−N₀) > 0 ✓.
MVT in Mathlib: `exists_deriv_eq_slope (f : ℝ → ℝ) (hfc : ContinuousOn f (Set.Icc a b)) (hff' : DifferentiableOn ℝ f (Set.Ioo a b)) (hab : a < b) : ∃ c ∈ Set.Ioo a b, deriv f c = (f b − f a)/(b − a)`. ✓ That's the tool.
So lemma:
```
theorem pos_of_convex_base {f : ℝ → ℝ} (hconv : ConvexOn ℝ (Set.Ici 20) f)
(hfc : ContinuousOn f (Set.Ici 20)) -- implied by convexity? ConvexOn → ContinuousOn interior; on closed set need assumption. We have continuousOn_marginExpanded.
(hfd : DifferentiableOn ℝ f (Set.Ioi 20)) -- from ContDiffOn
(N₀ x : ℝ) (hN : 20 ≤ N₀) (hx : N₀ ≤ x) -- need N₀ > 20 for interior? interior Ici 20 = Ioi 20; N₀ = 80000 > 20 ✓. State with 20 < N₀.
(h0 : 0 < f N₀) (h0' : 0 < deriv f N₀) : 0 < f x
```
Case x = N₀: h0. Case N₀ < x: MVT argument. monotoneOn_deriv needs N₀, ξ ∈ interior (Ici 20) = Ioi 20: N₀ > 20 ✓ (80000), ξ > N₀ ✓.
Good. Now the deriv of marginTilde at 80000: hbase′ needs deriv (marginTilde F_alt) 80000 — computed via the hasDerivAt machinery? For 12.3. The explicit derivative formula: deriv of marginExpanded pieces — we have HasDerivAt for each piece (hasDerivAt_marginS, chain-rule first derivatives...). vF-style first-derivative: deriv (fun n => F(√n+1)) n = F′(√n+1)/(2√n) — needs F′ explicit for F_alt: F_alt′ = (1/2π)(log T + 1) + 0.137/T + 0.443/(T log T). Then margiñ′(80000) = (1/2)(log n + 1) + (C₁−γ/2) − [2F′(T)/(2√n) + ...] — a mess but each piece has closed form; evaluate numerically with rational bounds. It's real work but mechanical.
Scope check for session 012: 12.1 (refactor + defs + assembly aux) + 12.2 (ψ blocks + F_alt instantiation). 12.3 (base points) maybe. 12.4 (triage doc + session protocol). Let me get moving — start with 12.1.
First, check Zeta23.Statement for Ncount/IsNontrivialZero (need for signatures) — quick grep. Also check the lakefile/lean-toolchain for NguyenRH1 and how to build (from STATE.md: iterate with `lake env lean NguyenRH1/LiSkeleton.lean` from package dir, elan at ~/.elan/bin).
Let me look at the Zeta23 statement file quickly.
Both derivations are project research files — not malware. I now have the full picture. Key design facts extracted:
**Assembly chain (D-037 §2):** `λ_n = S_∞(n) − S_f(n) + 1` (BL Thm 2), `λ_n ≥ S_∞^lower(n) − B(n) + 1 = margin(n)`; margin convex (D-057, Lean tier (i) done) + base point at N₀ = 80 000 (E-028: margiñ = 16 020, margiñ′ = 3.7) ⟹ positivity on [N₀, N₁]; n < N₀ by `LiVerifiedUpTo 5×10⁵`.
**Critical design detail (D-057 §2):** the true Trudgian majorant F(T) = (T/2π)log(T/2πe)+7/8 has ψ > 0 on part of the range (negative-weight T term) — D-057's table only works on the *net* expansion. For the Lean instantiation I'll use a slightly larger blockwise-clean majorant: `F_alt(T) = (1/2π)T·log T + 0.137·log T + 0.443·log log T + 7/8 + 1.588` (drops the negative-weight −((log 2π+1)/2π)T term ⟹ still a valid majorant; margin cost ≈ 0.9√n ≈ 256 at N₀ vs margin 16 020 — negligible). All four blocks have provably negative ψ (D-057 rows #1/#3/#4).
Let me check the Zeta23 types and the Lean build setup.
tool: Bash
input
{
"command": "grep -n \"Ncount\\|def IsNontrivialZero\\|zeroMult\" D:/Python/Quantum/research/lean/zeta-23-lean/Zeta23/Statement.lean 2>/dev/null | head -20; echo ---; cat D:/Python/Quantum/research/lean/NguyenRH1/lean-toolchain; echo ---; ls D:/Python/Quantum/research/lean/NguyenRH1/",
"description": "Check Zeta23 types and NguyenRH1 package layout"
}
raw content_json (database row)
[{"type":"thinking","thinking":"Both research derivations — not malware. \n\nNow I have the complete picture:\n\n**B(n) structure (D-037/D-056/D-057):**\n- B(n) = 2N(T) + 4T[(2/3)C₀(T) + A log(T+2) + B₀] + 40M₀ + 2(e⁴+1)[7H(T) + 3.3] + I_I + 1, T = √n + 1\n- Majorized version B̃(n): C₀ → Ĉ₀ = 0.433 log(t+2) + 0.886 loglog(t+2) + 2.9; N(T) → F + S_b... \n\nWait — the Lean marginTilde has \"2 * F T\" with abstract F. In D-057's component expansion: \"2F(T) → #1, #2 (mod constants); 2S_b(T) → #3, #4\". So the full N-majorant is F(T) + S_b(T) where F(T) = (T/2π)log(T/2πe) + 7/8 (Trudgian's smooth N) and S_b(T) = 0.137 log T + 0.443 log log T + 1.588.\n\nIn the Lean file, marginTilde's F is the ENTIRE N-count majorant (whatever majorizes Ncount 0 T), with hψ : ψ[F] < 0 as hypothesis. The D-057 §6 note says: \"The Lean theorem is parameterized over F (the majorant and its ψ-condition hψ are hypotheses, discharged elsewhere for the explicit Trudgian majorant)\".\n\nSo for the assembly, F_assembly(T) := F_Tru(T) + S_b(T) where:\n- F_Tru(T) = (T/2π)·log(T/(2πe)) + 7/8\n- S_b(T) = 0.137·log T + 0.443·log log T + 1.588\n\nHmm wait, need to be careful about domains: S_b bound holds for T ≥ e (Trudgian), log log T needs T > 1. For T = √n+1 with n ≥ 20: T ≥ 5.47 > e ✓.\n\nAnd hmaj : ∀ T, (Ncount 0 T : ℝ) ≤ F_assembly T — Trudgian 2014 Thm 1. Hmm, but for small T (T < e)? Ncount 0 T = number of zeros with 0 < Im ≤ T presumably. Trudgian's bound |S(T)| ≤ ... holds for T ≥ e. For T < e... F(T) = (T/2π)log(T/2πe) + 7/8 is negative for small T! (T/2π)log(T/2πe) at T=1: (1/2π)·log(1/(2πe)) ≈ 0.159·(−2.84) ≈ −0.45, +7/8 = 0.42; + S_b... log 1 = 0, log log 1 = log 0 = junk! So F_assembly as written is ill-defined/junky for small T in Lean (log log 1 = log 0 = 0 in Lean's junk convention — actually Real.log 0 = 0, so log log 1 = 0, fine as junk but the bound Ncount ≤ F might be FALSE for small T if F is small/negative).\n\nWhere is hmaj USED? In the eventual proof of SfBound — for T = √n + 1 with n ≥ N₀ = 80000, T ≥ 283.8 ≫ e. So hmaj is only needed for T ≥ some large value. To keep the assembly clean, state hmaj as: ∀ T ≥ (some threshold), Ncount 0 T ≤ F T. Actually in marginTilde_convex, hmaj is stated ∀ T. Is hmaj USED in marginTilde_convex? Looking at the proof... it takes hmaj as a hypothesis but I don't see it used in the proof body! Let me check... scanning the proof: it uses hF (ContDiff), hψ (ψ[F] < 0). hmaj appears unused in the convexity proof itself! It's there because marginTilde is meant to majorize the true margin — the majorant property matters for the ASSEMBLY (margin ≥ marginTilde), not for convexity. Indeed: margin(n) = S(n) − B(n) + 1 ≥ S(n) − B̃(n) + 1 = marginTilde F n requires N(T) ≤ F(T) (so that 2N ≤ 2F) and C₀ ≤ Ĉ₀ etc.\n\nOK so now the design crystallizes. Let me define everything with abstract F (as marginTilde already does), and structure the assembly as:\n\n**Definitions:**\n1. `sInftyLower (n : ℝ) : ℝ := (1/2)*n*log n + (lagariasC1 − γ/2)*n − 4` — extract from sInfty_lower_bound.\n2. `Bn (F : ℝ → ℝ) (n : ℝ) : ℝ := 2*F(√n+1) + 4(√n+1)((2/3)C0hat(√n+1) + 10.5 log(√n+1+2) + 48) + 40*1.3352 + 2(e⁴+1)(7 Hhat(√n+1) + 3.3) + IIMaj n + 1` — matching marginTilde exactly.\n3. `margin_eq : marginTilde F n = sInftyLower n − Bn F n + 1` — by ring (like marginTilde_eq_expanded).\n4. `Sf (n : ℕ) : ℝ := SInfty n + 1 − (liCoeff n).re` — BL Thm 2 as definition of the finite part (honesty note: BL Thm 2 says this equals the prime-side sum; the contour bound is proved for the prime-side sum).\n\nHmm wait — actually, is that the right sign? λ_n = S_∞(n) − S_f(n) + 1 ⟹ S_f = S_∞ + 1 − λ_n. ✓.\n\nBut hold on: is λ_n real? LiVerifiedUpTo states 0 < (liCoeff n).re. λ_n is real by conjugate symmetry (noted in the file). Sf as defined is real by construction (taking .re). Fine.\n\n5. `SfBoundProp (F) : Prop := ∀ n : ℕ, 80000 ≤ n → (n:ℝ) ≤ (3*10^12 − 1)^2 → |Sf n| ≤ Bn F n` — hmm, range: SfBound needed only for n in [N₀, N₁]. For n < N₀, hfinite covers. Should SfBound range over [1, N₁] or [N₀, N₁]? The contour bound works for n ≥ 20-ish (needs n large enough for various pieces; actually the B(n) bound is valid for all n ≥ some small threshold — the zero-avoidance and kernel bounds don't need large n; but B ≥ |S_f| worst-case... it's claimed valid broadly). For the assembly, only [N₀, N₁] is consumed. Honest + minimal: state ∀ n with 1 ≤ n and n ≤ N₁. The eventual proof will use n ≥ 20 or so for some pieces but that's fine (stronger statement covers). Hmm — is |S_f n| ≤ B n even TRUE for small n? |S_f(1)| = small; B(1) = big positive number. B(n) is large positive for all n ≥ 1 (all terms positive: F(T)... F(T) for T = √1+1 = 2: F_Tru(2) = (2/2π)log(2/2πe)+7/8 = 0.318·log(0.117)+0.875 = 0.318·(−2.145)+0.875 = 0.19; S_b(2) = 0.137·0.69 + 0.443·log(0.69) + 1.588 = 0.095 + 0.443·(−0.371)+1.588 = 1.52. So 2F ≈ 3.4; other terms positive. So B(1) ≥ ~10 or so. |S_f(1)| =? S_f(1) = Σ_p... λ_1 = 0.0230957 (Keiper). S_∞(1) = (1−a₁)·1 − 1 + Σ h⁺... = small. S_f(1) = S_∞(1) + 1 − λ_1. Should be fine but why risk it: the D-037 bound derivation assumes n in certain ranges? \"T ∈ [√n, √n+1] chosen zero-avoiding\" works for any n ≥ 1; |k_n| bounds fine. I think |S_f n| ≤ B n holds for all 1 ≤ n ≤ N₁. But to be SAFE and minimal, restrict SfBound to N₀ ≤ n ≤ N₁ — that's all the assembly uses, and it's the honest claim (the bound was DESIGNED for the margin range). Actually hmm, simpler for triage: state it for the range consumed. I'll go with 1 ≤ n ≤ N₁ since the pieces are uniform... no wait. Let me just use the range the assembly needs: N₀ ≤ n. No — think about the eventual discharge: proving SfBound for n ≥ N₀ = 80000 means T ≥ 283, all Trudgian bounds in range, M₀ fine, etc. All the delicate small-n cases vanish. That's actually BETTER for the eventual proof. Decision: SfBound range = N₀ ≤ n ≤ N₁, i.e. `∀ n : ℕ, 80000 ≤ n → (n:ℝ) ≤ N₁ → |Sf n| ≤ Bn F n`.\n\nHmm, but then hfinite needs to cover n < 80000, i.e. n ≤ 79999. LiVerifiedUpTo (5×10⁵) covers n ≤ 5×10⁵ ⊇ n ≤ 79999 ✓.\n\n6. The explicit F: `FTrud (T : ℝ) : ℝ := (T/(2π))·log(T/(2π·e)) + 7/8 + 0.137·log T + 0.443·log log T + 1.588`. Hmm — wait. Should the assembly instantiate FTrud now, or keep F abstract? \n\nPer the notes: \"state lambda_pos_finite_height with the finite-part bound as an explicit named hypothesis (SfBound : ∀ n, |S_f n| ≤ B n), and discharge the full assembly conditional on it.\"\n\nThe single named hypothesis = SfBound. If F stays abstract, then hψ, hF, hbase, hbase′ are ALSO hypotheses → not \"one named hypothesis\". So instantiate F = FTrud and discharge:\n- hF: ContDiff ℝ 2 FTrud — elementary (Mathlib: log, div, const). T > 0 needed... ContDiff on all of ℝ is FALSE for FTrud (log T at T ≤ 0 junk but ContDiff requires actual smoothness; log is not differentiable at 0; T/(2π)·log(T/(2πe)) smooth only on T > 0... as a function ℝ → ℝ with junk values, ContDiff ℝ 2 FTrud is false globally!). But marginTilde_convex requires `ContDiff ℝ 2 F` GLOBALLY (hF : ContDiff ℝ 2 F). Problem!\n\nOptions: (a) weaken marginTilde_convex to ContDiffOn (Set.Ioi 0) or Ioi 1... The proof uses hF via contDiffOn_mFblock: hF.contDiffOn.comp contDiffOn_sqrt_shift (mapsTo_univ) — it maps Ioi 20 into Ioi (−1) via √m+1 ≥ 5.47. So F only needs ContDiffOn (Ioi (−1)) or even Ioi 1. The chain_rule_sqrt_shift used for vF uses chain_rule_sqrt_shift F hF — the GLOBAL version. But chain_rule_sqrt_shift_on (the localized variant, PROVED) only needs ContDiffOn (Ioi (−1))! So I can refactor: marginTilde_convex with hF : ContDiffOn ℝ 2 F (Set.Ioi (-1)) and hψ range T ≥ √20+1 (already). The vF step would use chain_rule_sqrt_shift_on. And contDiffOn_mFblock needs F ContDiffOn (Ioi (−1)) composed with √m+1 mapping Ioi 20 → Ioi (−1) — mapsTo_sqrt_shift exists ✓.\n\nThat's a small refactor of marginTilde_convex: change hF : ContDiff ℝ 2 F → ContDiffOn ℝ 2 F (Set.Ioi (-1)), and vF: chain_rule_sqrt_shift F hF → chain_rule_sqrt_shift_on F hF; contDiffOn_mFblock: hF.contDiffOn.comp → hF.comp; continuousOn_marginExpanded: hF.continuous.continuousOn → hF.continuousOn. Manageable.\n\nThen FTrud's ContDiffOn (Ioi (−1)): pieces T·log(T/(2πe)) = (1/2π)(T log T − T log(2πe))... log T for T > −1... log is smooth on (0,∞); on Ioi (−1) log T hits T ∈ (−1, 0] — NOT smooth. Hmm! FTrud uses log T and log log T — smooth only for T > 1 (log log needs log T > 0 ⟹ T > 1). So FTrud is ContDiffOn (Ioi 1) at best. T = √n+1 for n > 20 gives T > √20+1 ≈ 5.47 > 1 ✓. So localize F to Ioi 1? Then mapsTo: √m+1 for m > 20 lands in Ioi (√20+1) ⊆ Ioi 1 ✓. And chain_rule_sqrt_shift_on needs ContDiffOn (Ioi (−1)) — generalize to (Ioi c) with c < √20+1... The lemma chain_rule_sqrt_shift_on as stated: ContDiffOn ℝ 2 φ (Set.Ioi (-1)) → ... at n > 0, uses √n+1 > −1... actually uses hmem : Ioi (−1) ∈ 𝓝 (√m+1) since √m+1 ≥ 1 > −1. A version with Ioi 1: needs √m+1 > 1 ⟺ m > 0 ✓. So chain_rule_sqrt_shift_on' with ContDiffOn ℝ 2 φ (Set.Ioi 1). \n\nHmm, this is getting into real refactor territory. Alternative: keep marginTilde_convex AS IS (global ContDiff F) and define FTrud with junk-safe smooth extensions... NO — cleaner alternative: don't instantiate F in the margin theorem; instead structure the assembly as TWO theorems:\n\n**Theorem A (assembly, abstract F):** \n```\ntheorem lambda_pos_finite_height_aux\n (hfinite : LiVerifiedUpTo (5*10^5))\n (F : ℝ → ℝ) (hF : ContDiffOn ℝ 2 F (Set.Ioi 1)) -- or global ContDiff\n (hψ : ∀ T ≥ √20+1, ψ[F](T) < 0)\n (hbase : 0 < marginTilde F 80000)\n (hbase' : 0 < deriv (marginTilde F) 80000)\n (hSf : SfBoundProp F) :\n ∀ n, 1 ≤ n → (n:ℝ) ≤ N₁ → 0 < (liCoeff n).re\n```\nAll hypotheses here are honest named items. But that's 6 hypotheses, not 1.\n\n**Theorem B (instantiated):** prove hF, hψ, hbase, hbase′ for FTrud, leaving:\n```\ntheorem lambda_pos_finite_height\n (hRH : RHUpTo (3*10^12)) (hfinite : LiVerifiedUpTo (5*10^5))\n (hSf : SfBoundProp FTrud) :\n ∀ n, 1 ≤ n → (n:ℝ) ≤ N₁ → 0 < (liCoeff n).re\n```\n\nhψ for FTrud: ψ[F+S_b] = (1/2π)ψ[T log T] + ... via ψ-linearity. ψ is linear in φ: ψ[c₁φ₁ + c₂φ₂] = c₁ψ[φ₁] + c₂ψ[φ₂] (needs deriv linearity lemmas — deriv_add, deriv_const_mul for deriv and deriv² — we HAVE deriv2_add, deriv2_const_mul! and psiOf is deriv(deriv φ) − deriv φ/(T−1) — linear given differentiability). So prove psiOf_add, psiOf_const_mul, psiOf_const (ψ[K] = 0... ψ[K] = 0 − 0/(T−1) = 0 ✓; note deriv const = 0). Then ψ[FTrud] = (1/2π)ψ[T log T] + (1/2π)(1−log(2πe))·ψ[T]... wait let me expand FTrud into blocks:\n\nFTrud(T) = (T/2π)·log(T/(2πe)) + 7/8 + 0.137·log T + 0.443·log log T + 1.588\n= (1/2π)·T·log T − (log(2πe)/2π)·T + (7/8 + 1.588) + 0.137·log T + 0.443·log log T\n\nBlocks: T·log T (#1), T (#2), const, log T (#3), log log T (#4) — exactly D-057's rows #1–#4! \"2F(T) → #1, #2 (mod constants); 2S_b(T) → #3, #4\". So I need psiOf for blocks #1–#4 (unshifted versions):\n- #1: ψ[T log T] = 1/T − (log T + 1)/(T−1) < 0 (D-057 row 1 sign: ⟺ −1 < T log T ✓)\n- #2: ψ[T] = −1/(T−1) < 0 — HAVE (psiOf_id)\n- #3: ψ[log T] = −1/T² − 1/(T(T−1)) < 0\n- #4: ψ[log log T] = −(log T+1)/(T log T)² − 1/(T log T (T−1)) < 0\n- const: ψ = 0\n\nAll provable with existing machinery (hasDerivAt patterns from the file). Weights: 1/(2π) > 0, −log(2πe)/(2π) < 0 (!). Uh oh — the coefficient of T is NEGATIVE: F(T) = (T/2π)log(T/2πe) + 7/8 = (1/2π)T log T − (log(2π)/2π + 1/2π... log(2πe) = log 2π + 1)·T/(2π)... so coefficient of T is −(log(2π)+1)/(2π) < 0. ψ[T] = −1/(T−1) < 0, times negative weight gives POSITIVE contribution. But the total: ψ[F] = (1/2π)[1/T − (log T+1)/(T−1)] − ((log 2π + 1)/2π)·(−1/(T−1)) + ... = (1/2π)[1/T − (log T + 1)/(T−1) + (log 2π + 1)/(T−1)] = (1/2π)[1/T − (log T − log 2π)/(T−1)] = (1/2π)[1/T − log(T/2π)/(T−1)]. For T ≥ 5.47: log(T/2π) = log(0.87) < 0 at T=5.47... interesting, could be positive ψ?! Direct: ψ[F_Tru] where F_Tru = (T/2π)log(T/2πe)+7/8: F′ = (1/2π)(log(T/2πe) + 1) = (1/2π)log(T/2π), F″ = 1/(2πT). ψ = 1/(2πT) − (1/2π)log(T/2π)/(T−1) = (1/2π)[1/T − log(T/2π)/(T−1)]. At T = 5.47: 1/T = 0.183; log(5.47/6.283) = log(0.8707) = −0.1386; −(−0.1386)/(4.47) = +0.031. ψ = (1/2π)(0.183+0.031) = 0.034 > 0!!! \n\nF_Tru's ψ is POSITIVE at small T?! That would break the convexity! But wait — D-057's table row #1 is T log T (not F_Tru). The component expansion says \"2F(T) → #1, #2 (mod constants)\" — i.e. 2F(T) = (T/π)log(T/2πe) + 7/4 = (1/π)[T log T − (log 2πe) T] + 7/4. Rows: #1 T log T with ψ < 0; #2 T with ψ = −1/(T−1) < 0 but weight −(log 2πe)/π < 0 → contribution to margiñ″ is −w·ψ/(4n)... wait signs: margiñ″ = 1/(2n) − Σ wᵢψᵢ/(4n) − IIMaj″. The B̃ terms enter with MINUS: each B̃-component wᵢ·blockᵢ (wᵢ > 0) contributes −wᵢψᵢ/(4n) to margiñ″. For convexity need margiñ″ > 0, i.e. 1/(2n) − Σwᵢψᵢ/(4n) − IIMaj″ > 0. Blocks with ψᵢ < 0 HELP (positive contribution). Row #2 T with NEGATIVE weight −log(2πe)·... hold on: (T/π)log(T/2πe) = (1/π)T log T − (log(2πe)/π)T. The second term has negative coefficient in B̃. Then in margiñ″: −[−(log 2πe/π)]·ψ[T]/(4n) = +(log 2πe/π)·(−1/(T−1))/(4n) < 0 — HURTS.\n\nSo is marginTilde actually convex with the TRUE Trudgian F?? Let me sanity check numerically: F_Tru(T), T = √n+1. The claim \"margin convex\" was E-029-verified and marginTilde_convex PROVED for abstract F with hψ : ψ[F] < 0. If ψ[F_Tru + S_b] > 0 somewhere, then the Lean hypothesis hψ would be FALSE for the explicit Trudgian majorant — a real problem!\n\nLet me compute ψ of the FULL majorant M(T) = F_Tru(T) + S_b(T) at T = 5.47:\nF_Tru: F′ = (1/2π)log(T/2π), F″ = 1/(2πT).\nS_b: 0.137 log T + 0.443 log log T + 1.588: S_b′ = 0.137/T + 0.443/(T log T); S_b″ = −0.137/T² − 0.443(log T + 1)/(T log T)².\nAt T = 5.4721: log T = 1.6995, log log T = 0.5300.\nF″ = 1/(2π·5.4721) = 0.02909. F′ = (1/2π)·log(0.8707) = 0.15915·(−0.13857) = −0.022054. ψ_F = 0.02909 − (−0.022054)/4.4721 = 0.02909 + 0.004932 = 0.034023.\nS_b″ = −0.137/29.94 − 0.443·(2.6995)/(5.4721·1.6995)² = −0.004575 − 0.443·2.6995/86.47 = −0.004575 − 0.013830 = −0.018405.\nS_b′ = 0.137/5.4721 + 0.443/(5.4721·1.6995) = 0.025036 + 0.047638 = 0.072674.\nψ_Sb = −0.018405 − 0.072674/4.4721 = −0.018405 − 0.016251 = −0.034656.\nψ_M = 0.034023 − 0.034656 = −0.0006 < 0. PHEW. Barely negative at T₀, and more negative as T grows (ψ_F → 0⁺? as T→∞: 1/T vs log(T/2π)/(T−1): for T > 2π·e^{(T−1)/T}... log(T/2π)/(T−1) vs 1/T: T log(T/2π) vs T−1: at T = 100: 100·log(15.9) = 276.8 > 99 ✓ so ψ_F < 0 for T ≥ ~17? Let me check T = 20: 1/20 = 0.05; log(20/2π)/19 = log(3.183)/19 = 1.1576/19 = 0.0609 > 0.05 ⟹ ψ_F(20) < 0. T = 15: 0.0667 vs log(2.387)/14 = 0.870/14 = 0.0622 < 0.0667 ⟹ ψ_F(15) > 0. T = 17: 0.0588 vs log(2.7056)/16 = 0.9955/16 = 0.0622 ⟹ <0? 0.0588 < 0.0622 ⟹ ψ_F(17) < 0. So ψ_F turns negative around T ≈ 16, and ψ_Sb < 0 always. So ψ_M < 0 everywhere on the range (needs the combination, since ψ_F > 0 on [5.47, ~16]).\n\nSo the correct explicit majorant for Lean is M(T) := F_Tru(T) + S_b(T) — the FULL N(T) majorant — and hψ for it requires the combination argument (not blockwise sign, since the T log T block is positive-ψ on part of the range!). Hmm — wait, D-057's table row #1 says ψ[T log T] < 0 \"⟺ −1 < T log T ✓\" — TRUE: ψ[T log T] = 1/T − (log T + 1)/(T−1) < 0 ⟺ (T−1) < T(log T + 1) ⟺ −1 < T log T ✓ always. But the NEGATIVE-weight T term: −(log 2πe)/π·T with ψ[T] < 0 gives positive contribution... Let me recompute the SUM as D-057 does: rows #1 + #2 with weights w₁ = 1/π (from 2F: (1/π)T log T) and w₂ = −log(2πe)/π < 0 — D-057's §2 says \"B̃ is a positive combination of the blocks below\" — but #2 appears with both positive (4T·(2/3)·2.9, 4T·B₀) and negative (−log(2πe)/π from 2F) weights?! NET weight of T: from 4T[(2/3)Ĉ₀ + A log + B₀]: (8/3)·2.9 + 4·48 = 7.73 + 192 = 199.7; from 2F: −log(2πe)/π = −2.8379/3.1416·... log(2πe) = 1.8379+1 = wait log(2π) = 1.83788, log(2πe) = 2.83788. 2F(T) = (T/π)(log T − log 2πe)... hmm 2F(T) = 2·(T/2π)log(T/2πe) + 7/4 = (T/π)log T − (2.83788/π)T + 7/4 = (T/π)log T − 0.90327·T + 7/4. So net T weight: 199.7 − 0.90 = 198.8 > 0 ✓. D-057's \"positive combination\" refers to the NET expansion — the 2F's negative T-weight is absorbed by the huge positive T-weight from 4T·B₀. OK! So the 11-block table works on the NET expansion, all weights positive. \n\nBut in the LEAN file, marginTilde_convex keeps F ABSTRACT (hψ atomic) — D-057 §6: \"The Lean theorem is parameterized over F... those rows never appear: the 2F(T) term is handled atomically via hψ.\" So the Lean hψ hypothesis is: ψ[F] < 0 where F is the whole N-majorant. For the instantiation F := F_Tru + S_b (M above), ψ[M] = ψ_F + ψ_Sb; ψ_F > 0 on [5.47, 16] but |ψ_Sb| > ψ_F there (checked numerically at 5.47: −0.0006 total; need a proof for the whole interval [5.47, 16]).\n\nHmm OK. So instantiating F := M requires proving ψ[M](T) < 0 for T ≥ √20+1, which on [5.47, 16] needs the cross-cancellation ψ_Sb < −ψ_F. That's a real-analytic inequality — provable by elementary means (rational/log bounds on a compact interval — could use monotonicity splitting + pointwise numeric bounds at a few anchor points with derivative control; or find a slicker sign argument).\n\nSlicker: ψ[M] = 1/(2πT) − (1/2π)log(T/2π)/(T−1) + S_b″ − S_b′/(T−1). Ugh. Alternative: prove ψ[M] < 0 by showing ψ[M] is increasing-ish... or bound: ψ_F ≤ 1/(2πT) + (1/2π)·max(0, −log(T/2π))/(T−1)... On T ∈ [5.47, 2π]: log(T/2π) ≤ 0 so ψ_F = 1/(2πT) + |log(T/2π)|/(2π(T−1)) ≤ 1/(2πT) + log(2π/5.47... hmm log(2π/T) ≤ log(2π/5.4721) = 0.1386 for T ∈ [5.47, 2π]. And ψ_Sb ≤ −0.137/T² − 0.443(logT+1)/(T logT)² − [0.137/T + 0.443/(T log T)]/(T−1). All terms… this is a finite-interval verification. Doable but fiddly in Lean.\n\nAlternatively choose a SLIGHTLY larger majorant that's blockwise clean! We get to CHOOSE F (any majorant of N works, at the cost of margin). E.g., replace F_Tru by something with provably negative ψ blockwise: F_alt(T) = (1/2π)·T·log T + 7/8 (drop the −(log 2πe)/2π·T term — but then F_alt ≥ F_Tru? F_Tru = (1/2π)T log T − ((log 2π + 1)/2π)T + 7/8. F_alt − F_Tru = ((log 2π + 1)/2π)T > 0 ✓ so F_alt + S_b ≥ F_Tru + S_b ≥ N ✓ majorant preserved. ψ[F_alt] = (1/2π)ψ[T log T] < 0 ✓ blockwise! And the margin cost: B increases by 2·((log 2π+1)/2π)T ≈ 0.903·T ≈ 0.903√n — margin(N₁) has √n·log n·(1/2 − ...) slack; margiñ(80000) = 16020 vs extra 0.903·(√80000+1) ≈ 256 — margiñ drops to ~15764, still > 0; margiñ′ drops by ~0.903/(2√n)·... ≈ 0.0016 — still > 0. The crossover N₀ moves slightly; E-028's N₀ = 75451 had margin 2.4 — adding 0.9√n ≈ 250 at n = 80000... wait margin at crossover 75451 was 2.4; the extra 0.9·T ≈ 0.9·275.7 ≈ 248 pushes crossover up by Δn where margin′·Δn = 248, margin′ ≈ 3.7 → Δn ≈ 67. N₀ ≈ 75520. Adopted N₀ = 80000 has margin 16020 − 248 ≈ 15772 > 0 ✓. Totally fine!\n\nEven cleaner: F_alt(T) := (1/2π)·T·log T + S_b(T) + 7/8 — all blocks with provable ψ signs:\n- T·log T: ψ < 0 (row #1) ✓ (weight 1/2π > 0)\n- log T: ψ < 0 (row #3, weight 0.137) ✓\n- log log T: ψ < 0 (row #4, weight 0.443) ✓\n- const 7/8 + 1.588: ψ = 0 ✓\n\nAll four are the UNSHIFTED blocks. Need psiOf lemmas for T·log T, log T, log log T, const. Provable with existing machinery (Real.hasDerivAt_log etc.). And N(T) ≤ F_alt(T) is the Trudgian perimeter hypothesis (stated: Ncount 0 T ≤ F_alt T for T ≥ √20+1... plus honestly it's F_Tru + S_b that's Trudgian; F_alt ≥ that by the dropped term — but as a HYPOTHESIS we just state Ncount ≤ F_alt directly, noting in the docstring it's Trudgian 2014 + the dropped-term slack).\n\nHmm wait — actually hold on. Does hmaj even appear in the assembly theorem? Earlier analysis: hmaj is used in the eventual SfBound proof, NOT in the margin assembly. The margin assembly uses: marginTilde convex (hF, hψ) + base points + marginTilde = slower − Bn + 1 + SfBound + sInfty_lower_bound. Where does the majorant property N ≤ F enter? It enters SfBound's proof: |zeros sum| ≤ 2N(T) ≤ 2F(T). So in the ASSEMBLY theorem (conditional on SfBound), hmaj doesn't appear. ✓ So the assembly theorem:\n\n```\ntheorem lambda_pos_finite_height\n (hRH : RHUpTo (3 * 10 ^ 12)) -- perimeter (consumed by SfBound's proof; unused here)\n (hfinite : LiVerifiedUpTo (5 * 10 ^ 5)) -- perimeter\n (hSf : SfBoundProp) : -- THE named analytic hypothesis\n ∀ n : ℕ, 1 ≤ n → (n : ℝ) ≤ (3 * 10 ^ 12 - 1 : ℝ) ^ 2 → 0 < (liCoeff n).re\n```\n\nwith SfBoundProp referencing the explicit Bn (with F_alt baked in or abstract F?). Decision: bake in the explicit majorant — SfBound should be fully concrete: `∀ n, 80000 ≤ n → (n:ℝ) ≤ N₁ → |Sf n| ≤ BnExplicit n`. Then BnExplicit := Bn F_alt. And marginTilde F_alt.\n\nAssembly proof (given hSf, hfinite):\n- intro n hn1 hnN1\n- by_cases n ≤ 80000: hfinite n hn1 (le_trans h (by norm_num)) — wait LiVerifiedUpTo (5*10^5) needs n ≤ 5*10^5: 80000 ≤ 500000 ✓. Gives 0 < (liCoeff n).re ✓.\n- else: 80000 < n, so 80001 ≤ n (Nat), n ≥ 20 ✓.\n - h20 : 20 ≤ (n:ℝ)\n - hkey: (liCoeff n).re = SInfty n − Sf n + 1 (from Sf def: Sf n = SInfty n + 1 − (liCoeff n).re ⟹ ring)\n - (liCoeff n).re ≥ sInftyLower n − |Sf n| + 1... let me be careful: SInfty n ≥ sInftyLower n (sInfty_lower_bound, needs n ≥ 20 ✓ — the theorem is stated for ℕ: sInfty_lower_bound (n : ℕ) (hn : 20 ≤ n) : ... ≤ SInfty n ✓). −Sf n ≥ −|Sf n| ✓ (neg_le_abs... actually Sf n ≤ |Sf n| so −|Sf n| ≤ −Sf n... wait we need lower bound on λ = S_∞ − S_f + 1 ≥ slower − |S_f| + 1 ✓ since −S_f ≥ −|S_f| and S_∞ ≥ slower).\n - |Sf n| ≤ BnExplicit n (hSf n (80001 ≥ 80000) hnN1) — note BnExplicit takes (n : ℝ) or ℕ? Bn F n with n : ℝ (marginTilde takes ℝ). Cast: hSf stated with ((n : ℝ)) — fine.\n - So λ.re ≥ sInftyLower n − BnExplicit n + 1 = marginTilde F_alt n (ring lemma).\n - marginTilde F_alt n > 0: convexity argument:\n - marginTilde_convex F_alt hF hmaj hψ : ConvexOn ℝ (Ici 20) (marginTilde F_alt) — WAIT, marginTilde_convex's hF is global ContDiff ℝ 2 F. F_alt = (1/2π)T log T + 0.137 log T + 0.443 log log T + const — NOT globally C² (singularities at T = 0, 1). So I DO need the ContDiffOn refactor of marginTilde_convex. OK, decided: refactor marginTilde_convex (and marginTilde continuity/ContDiffOn lemmas + vF chain-rule step) from `ContDiff ℝ 2 F` to `ContDiffOn ℝ 2 F (Set.Ioi 1)`. Check each use of hF in marginTilde_convex:\n - contDiffOn_mFblock F hF : hF.contDiffOn.comp contDiffOn_sqrt_shift (mapsTo_univ) → with ContDiffOn: hF.comp contDiffOn_sqrt_shift (mapsTo into Ioi 1: need mapsTo_sqrt_shift₁ : MapsTo (√·+1) (Ioi 20) (Ioi 1) — √m+1 > √20+1 > 1 ✓ easy).\n - vF: chain_rule_sqrt_shift F hF n hn0 → chain_rule_sqrt_shift_on currently needs ContDiffOn (Ioi (−1)). Generalize chain_rule_sqrt_shift_on to any c < 1? The proof uses hmem: Ioi (−1) ∈ 𝓝 (√m+1) since √m+1 ≥ 1 > −1. For Ioi 1: √m+1 > 1 ⟺ m > 0 ✓ but needs Set.Ioi 1 ∈ 𝓝 (√m+1): √m+1 > 1 strictly for m > 0 ✓ Ioi_mem_nhds. So a version chain_rule_sqrt_shift_on₁ with (Ioi 1). Rather than proliferating, generalize chain_rule_sqrt_shift_on to parameter c with h : c < 1? The proof structure: hmem m hm : Ioi c ∈ 𝓝 (√m+1) needs √m+1 > c ⟸ 1 > c (since √m ≥ 0... wait need √m+1 > c: √m ≥ 0 ⟹ √m+1 ≥ 1 > c ✓). So parameterize: chain_rule_sqrt_shift_on (φ) (hφ : ContDiffOn ℝ 2 φ (Set.Ioi c)) (hc : c < 1) (n) (hn : 0 < n). The existing one (c = −1) is used for blocks (log-shifted blocks need Ioi (−1)). Keep existing as-is; add the general one? Or refactor existing call sites... Existing call sites use contDiffOn_TL1 etc. (Ioi (−1)). If I generalize the lemma to take c, call sites pass c = −1, hc = by norm_num. That's clean: modify chain_rule_sqrt_shift_on signature, update ~9 call sites in marginTilde_convex (add (by norm_num : (-1:ℝ) < 1)), and vF uses c = 1. Hmm wait, actually simpler: keep chain_rule_sqrt_shift_on unchanged; for F_alt use hF : ContDiffOn ℝ 2 F_alt (Set.Ioi (−1))? F_alt on Ioi (−1): log T for T ∈ (−1, 0] — Real.log is junk (0) for T ≤ 0 and NOT differentiable there (as a function ℝ→ℝ it's actually differentiable at T < 0! Real.log of negative = log|x|? NO — Real.log x = Real.log |x|? In Mathlib, Real.log x = log |x|... let me recall: Mathlib's Real.log is defined as Complex... Real.log x = Real.log (|x|)? Actually `Real.log x = Complex.log (x : ℂ) |>.re`? Hmm — Mathlib: Real.log x := Real.exp partial inverse... Real.log x = if x = 0 then 0 else ... Actually Real.log in Mathlib: `Real.log x = Complex.log x |>.re`? The key facts: Real.log is differentiable on ℝ \\ {0}? There's Real.hasDerivAt_log (hx : x ≠ 0)! Yes — Mathlib's Real.log = log|x| basically (Real.log_neg_eq_log : log (−x) = log x). So log IS smooth on ℝ \\ {0}, and ContDiffOn ℝ 2 Real.log (Ioi (−1))?? At x = 0 ∈ Ioi (−1): log 0 = 0 (junk), not continuous even. So ContDiffOn ℝ n Real.log (Ioi (−1)) is FALSE (0 ∈ Ioi (−1), log not differentiable at 0: Real.hasDerivAt_log needs x ≠ 0; at 0 the function is... log x = log|x| near 0⁻ goes to −∞ — not even continuous at 0). So F_alt is NOT ContDiffOn (Ioi (−1)). Must use Ioi 0 or Ioi 1. log log T needs T > 1 (log T > 0) — actually log log T as ℝ function: smooth where log T ≠ 0 AND T ≠ 0, i.e. T ∈ (−∞,0)∪(0,1)∪(1,∞)... on (0,1): log T < 0, log log T = log|log T| smooth there too! But our domain: Ioi 1 is the clean choice (√20+1 ≈ 5.47 > 1 ✓ mapsTo fine).\n \n So: refactor marginTilde_convex to take hF : ContDiffOn ℝ 2 F (Set.Ioi 1), with vF via a new chain_rule_sqrt_shift_at₁ or generalized. Also continuousOn_marginExpanded uses hF.continuous.continuousOn.comp hT (mapsTo_univ) on Ici 20: F needs ContinuousOn (Ici-image = [√20+1, ∞)) — ContDiffOn (Ioi 1).continuousOn comp works with mapsTo (Ici 20 → Ioi 1: √m+1 ≥ √20+1 > 1 ✓).\n\n OK the refactor is contained. Good.\n\n - base points: hbase : 0 < marginTilde F_alt 80000, hbase′ : 0 < deriv (marginTilde F_alt) 80000. These are explicit numeric evaluations — PROVABLE in principle. For THIS session, they could be left as hypotheses of the aux theorem and discharged later (they're \"computational perimeter\" — single-point evaluations, E-028/E-029-verified). The notes say the endpoint is \"verified modulo one named analytic hypothesis + the computational perimeter\" — base-point evaluations ARE computational perimeter items. But they're provable-from-Mathlib numerics (unlike Platt–Trudgian). Ideal: prove them. Realistic this session: keep as hypotheses hbase/hbase′ feeding the aux theorem, with the main theorem... hmm, if main theorem takes hbase/hbase′ as hypotheses, then it's 4 hypotheses. To get to \"one named analytic hypothesis + perimeter\", discharge hbase/hbase′ via numeric proofs. That's a chunk of tight numeric work (margiñ(80000) = 16020 — HUGE margin, so crude bounds suffice! margiñ′ = 3.7 — margin small-ish but still O(1); crude interval bounds with error < 1 suffice. Both very doable with rational squeezes: need log(80000), log(T+2) at T = √80000+1 ≈ 283.84, etc. With margin 16020, we need lower bound pieces to ~10% accuracy — EASY with norm_num-scale bounds. For deriv: 3.7, need accuracy ~0.5 — the derivative has an explicit closed form (deriv of marginExpanded pieces — all available via hasDerivAt machinery). Feasible but a solid chunk of work.)\n\n Given the scope, sub-stage breakdown for session 012:\n - 12.1: Refactor (ContDiffOn), defs (sInftyLower, Bn, Sf, SfBoundProp, F_alt), margin identity (ring), convex-pos lemma, assembly theorem aux (abstract F + hbase/hbase′ hypotheses) — COMPILES.\n - 12.2: psiOf blocks #1/#3/#4 + const + linearity; ψ[F_alt] < 0 proof; instantiate F_alt; discharge hF (ContDiffOn Ioi 1).\n - 12.3: base-point numerics (margiñ(80000) > 0, margiñ′(80000) > 0) in Lean.\n - 12.4: triage documentation (D-062: what's inside SfBound — Mathlib-tractable vs Trudgian-class; perimeter decision), journal, STATE, db, commit, paper appendix update.\n\n That's ambitious for one session but sub-stages are committable. Actually the notes said \"achievable in a few sessions\" — don't rush. Let me aim for 12.1 + 12.2 today, possibly 12.3.\n\nWait — one more design question: SfBoundProp range and the hfinite split. N₀ = 80000. In Lean: case split at n ≤ 80000 vs n ≥ 80001.\n\nhfinite : LiVerifiedUpTo (5*10^5): ∀ n, 1 ≤ n → n ≤ 5*10^5 → 0 < (liCoeff n).re. Note 5*10^5 as ℕ literal: 500000 ✓.\n\nSfBoundProp: ∀ n : ℕ, 80001 ≤ n → (n:ℝ) ≤ (3*10^12 − 1)^2 → |Sf n| ≤ Bn F_alt (n:ℝ). Hmm — or 80000 ≤ n to be round? The overlap: hfinite covers ≤ 80000 (via ≤ 5×10⁵); hSf covers ≥ 80001. Clean complementary. Or make hSf start at 80000 and split at < 80000 / ≥ 80000. Either fine. I'll use N₀ = 80000 in hSf (80000 ≤ n) and split hfinite side at n < 80000 (n ≤ 79999 ≤ 5×10⁵ ✓). Slightly cleaner: SfBound from N₀, matching D-037's \"adopted N₀ := 80 000\".\n\nAlso should SfBoundProp quantify (n : ℝ) or ℕ? Sf n is on ℕ (SInfty n, liCoeff n take ℕ). Bn takes ℝ. State: ∀ n : ℕ, 80000 ≤ n → (n:ℝ) ≤ N₁ → |Sf n| ≤ Bn (n:ℝ). ✓\n\nN₁ = (3*10^12 − 1)^2 as ℝ. In the theorem statement it already appears as ((3 * 10 ^ 12 - 1 : ℝ) ^ 2). Keep consistent.\n\nAnother subtlety: `liCoeff` uses tsum of a possibly-non-summable family (junk 0 if not summable). The honesty note covers it — summability is inside SfBound's eventual content effectively (S_f finite ⟺ ...). Fine — skeleton design choice inherited.\n\nAlso `Ncount` — used in hmaj of marginTilde_convex. If hmaj is unused in marginTilde_convex's proof... it IS in the signature. For the refactored theorem I can DROP hmaj from marginTilde_convex (it's not used in the proof!)? Careful: is it really unused? Scanning the proof body of marginTilde_convex... hmaj appears only in the signature. The convexity proof never uses the majorant property. Dropping it changes the theorem's meaning not at all (convexity of marginTilde F doesn't need F to majorize anything). But hmaj documents intent. Lean linter: unused variable warning (already present in session 011? — the file compiled, so warnings are tolerated). KEEP hmaj to avoid churn? If it's already there and compiling, keep. Actually wait — if I'm refactoring hF anyway, touching the signature, keep hmaj as is. Fine.\n\nHmm, wait — actually let me reconsider: is hmaj really unused? `marginTilde_convex (F : ℝ → ℝ) (hF : ContDiff ℝ 2 F) (hmaj : ∀ T : ℝ, (Ncount 0 T : ℝ) ≤ F T) (hψ : ...)`. Body: uses hF (via contDiffOn_mFblock F hF, hCDFc, chain_rule_sqrt_shift F hF), hψ (hψn). hmaj: NOT used. Ncount: from Zeta23 (open Zeta23). OK keep.\n\nNow the convex-pos lemma. Statement: if f convex on Ici 20 (real), C² interior..., f(N₀) > 0, f′(N₀) > 0 (deriv at N₀ exists), then f(x) > 0 for x ≥ N₀. Proof: for x > N₀: by ConvexOn, deriv is monotone on interior (Mathlib: ConvexOn.monotoneOn_deriv : ConvexOn ℝ S f → MonotoneOn (deriv f) (interior S)). f C² on Ioi 20 ⟹ deriv f differentiable... monotoneOn_deriv needs ConvexOn only? Let me recall Mathlib: `ConvexOn.monotoneOn_deriv (hf : ConvexOn ℝ s f) : MonotoneOn (deriv f) (interior s)`. I believe it exists (uses slope monotonicity + differentiable... hmm, it might need no differentiability — deriv junk... Actually I recall `ConvexOn.monotoneOn_deriv` exists in Mathlib.Analysis.Convex.Deriv or ...Specific... yes: ConvexOn.monotoneOn_deriv : ConvexOn ℝ s f → MonotoneOn (deriv f) (interior s). I'm fairly confident it exists.)\n\nThen: for x > N₀ (N₀ ≥ 20, interior since N₀ > 20): f(x) − f(N₀) = ∫ or MVT: exists_deriv_eq_slope (f continuous on [N₀, x], differentiable on (N₀, x)): ∃ ξ ∈ (N₀, x), f′(ξ) = (f(x)−f(N₀))/(x−N₀). ξ ∈ interior Ici 20 = Ioi 20 ✓ (ξ > N₀ ≥ 20... need ξ > 20: ξ > N₀ = 80000 > 20 ✓). monotoneOn_deriv: N₀ ≤ ξ, both in interior ⟹ f′(N₀) ≤ f′(ξ). So (f(x)−f(N₀))/(x−N₀) = f′(ξ) ≥ f′(N₀) > 0 ⟹ f(x) ≥ f(N₀) + f′(N₀)(x−N₀) > 0 ✓. \n\nMVT in Mathlib: `exists_deriv_eq_slope (f : ℝ → ℝ) (hfc : ContinuousOn f (Set.Icc a b)) (hff' : DifferentiableOn ℝ f (Set.Ioo a b)) (hab : a < b) : ∃ c ∈ Set.Ioo a b, deriv f c = (f b − f a)/(b − a)`. ✓ That's the tool.\n\nSo lemma:\n```\ntheorem pos_of_convex_base {f : ℝ → ℝ} (hconv : ConvexOn ℝ (Set.Ici 20) f)\n (hfc : ContinuousOn f (Set.Ici 20)) -- implied by convexity? ConvexOn → ContinuousOn interior; on closed set need assumption. We have continuousOn_marginExpanded.\n (hfd : DifferentiableOn ℝ f (Set.Ioi 20)) -- from ContDiffOn\n (N₀ x : ℝ) (hN : 20 ≤ N₀) (hx : N₀ ≤ x) -- need N₀ > 20 for interior? interior Ici 20 = Ioi 20; N₀ = 80000 > 20 ✓. State with 20 < N₀.\n (h0 : 0 < f N₀) (h0' : 0 < deriv f N₀) : 0 < f x\n```\nCase x = N₀: h0. Case N₀ < x: MVT argument. monotoneOn_deriv needs N₀, ξ ∈ interior (Ici 20) = Ioi 20: N₀ > 20 ✓ (80000), ξ > N₀ ✓.\n\nGood. Now the deriv of marginTilde at 80000: hbase′ needs deriv (marginTilde F_alt) 80000 — computed via the hasDerivAt machinery? For 12.3. The explicit derivative formula: deriv of marginExpanded pieces — we have HasDerivAt for each piece (hasDerivAt_marginS, chain-rule first derivatives...). vF-style first-derivative: deriv (fun n => F(√n+1)) n = F′(√n+1)/(2√n) — needs F′ explicit for F_alt: F_alt′ = (1/2π)(log T + 1) + 0.137/T + 0.443/(T log T). Then margiñ′(80000) = (1/2)(log n + 1) + (C₁−γ/2) − [2F′(T)/(2√n) + ...] — a mess but each piece has closed form; evaluate numerically with rational bounds. It's real work but mechanical.\n\nScope check for session 012: 12.1 (refactor + defs + assembly aux) + 12.2 (ψ blocks + F_alt instantiation). 12.3 (base points) maybe. 12.4 (triage doc + session protocol). Let me get moving — start with 12.1.\n\nFirst, check Zeta23.Statement for Ncount/IsNontrivialZero (need for signatures) — quick grep. Also check the lakefile/lean-toolchain for NguyenRH1 and how to build (from STATE.md: iterate with `lake env lean NguyenRH1/LiSkeleton.lean` from package dir, elan at ~/.elan/bin).\n\nLet me look at the Zeta23 statement file quickly.","signature":""},{"type":"text","text":"Both derivations are project research files — not malware. I now have the full picture. Key design facts extracted:\n\n**Assembly chain (D-037 §2):** `λ_n = S_∞(n) − S_f(n) + 1` (BL Thm 2), `λ_n ≥ S_∞^lower(n) − B(n) + 1 = margin(n)`; margin convex (D-057, Lean tier (i) done) + base point at N₀ = 80 000 (E-028: margiñ = 16 020, margiñ′ = 3.7) ⟹ positivity on [N₀, N₁]; n < N₀ by `LiVerifiedUpTo 5×10⁵`.\n\n**Critical design detail (D-057 §2):** the true Trudgian majorant F(T) = (T/2π)log(T/2πe)+7/8 has ψ > 0 on part of the range (negative-weight T term) — D-057's table only works on the *net* expansion. For the Lean instantiation I'll use a slightly larger blockwise-clean majorant: `F_alt(T) = (1/2π)T·log T + 0.137·log T + 0.443·log log T + 7/8 + 1.588` (drops the negative-weight −((log 2π+1)/2π)T term ⟹ still a valid majorant; margin cost ≈ 0.9√n ≈ 256 at N₀ vs margin 16 020 — negligible). All four blocks have provably negative ψ (D-057 rows #1/#3/#4).\n\nLet me check the Zeta23 types and the Lean build setup."},{"type":"tool_use","id":"Bash_16","name":"Bash","input":{"command":"grep -n \"Ncount\\|def IsNontrivialZero\\|zeroMult\" D:/Python/Quantum/research/lean/zeta-23-lean/Zeta23/Statement.lean 2>/dev/null | head -20; echo ---; cat D:/Python/Quantum/research/lean/NguyenRH1/lean-toolchain; echo ---; ls D:/Python/Quantum/research/lean/NguyenRH1/","description":"Check Zeta23 types and NguyenRH1 package layout"},"extra_content":null}]