Current task: —

← Session 21 — Tier ii′ planning + launch: close SfBoundProp in Lean (D-064)

#938 assistant 2026-08-21 20:57:36.023 UTC · 1711→4171 tok open ⤢
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"
}
raw content_json (database row)
[{"type":"thinking","thinking":"All confirmed. Now let me write LiResidue.lean Part 1 (zetaA + hLi + lcoeff + ResW1). This is a big file. Let me write it carefully.\n\nKey pieces:\n1. zetaA def + apply/one lemmas.\n2. zetaA_analyticAt_one:\n   - s := Metric.ball 1 2 (a nhd of 1).\n   - DifferentiableOn (fun w => (w−1)*ζ w) (ball 1 2 \\ {1}): differentiableAt at w ≠ 1: (w−1) differentiable, ζ differentiable at w ≠ 1 (differentiableAt_riemannZeta) ✓ product.\n   - 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.\n   - Then differentiableOn_update_limUnder_of_bddAbove (hc : ball 1 2 ∈ 𝓝 1) hd hb : DifferentiableOn (update f 1 (limUnder (𝓝[≠]1) f)) (ball 1 2).\n   - 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).\n   - 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 ✓).\n   - 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.\n\n3. hLi := fun w => 1 - (w - 1) * (deriv zetaA w / zetaA w).\n   - 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 ✓.\n   - hLi_one : hLi 1 = 1: hLi 1 = 1 − (1−1)·(...) = 1 − 0 = 1 ✓ simp.\n   - hLi_eq {w : ℂ} (hw : w ≠ 1) : hLi w = (w - 1) * (-(deriv riemannZeta w) / riemannZeta w):\n     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 ✓).\n     zetaA w = (w−1)·ζ w (hw, update_of_ne).\n     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.\n     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.\n\n4. lcoeff k := iteratedDeriv (k + 1) hLi 1 / (k + 1)! — def.\n5. ResW1 n := iteratedDeriv n (fun w => (w^n - (w - 1)^n) * hLi w) 1 / n ! — def.\n6. ResW1_eq_sum : ResW1 n = Σ_{j=1}^n (n.choose j : ℂ) * lcoeff (j - 1):\n   - 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.\n   - 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.\n   - iteratedDeriv_mul: F^{(n)}(1) = Σ_{i=0}^n C(n,i)·A^{(i)}(1)·h^{(n−i)}(1).\n   - 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):\n     iteratedDeriv i (wⁿ) 1 = descFac n i·1^(n−i) = descFac n i (simp [iteratedDeriv_pow]).\n     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 ✓.\n     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).\n     The subtraction: iteratedDeriv i (f − g) 1 = iteratedDeriv i f 1 − iteratedDeriv i g 1 — `iteratedDeriv_sub`? should exist (linear map).\n   - 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).\n   - 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).\n   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) ✓).\n   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.\n   - 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.\n\nLet me grep for the factorial identities quickly, then write Part 1.","signature":""},{"type":"text","text":"All machinery confirmed. Let me check the factorial identities needed for the coefficient algebra, then write LiResidue.lean Part 1."},{"type":"tool_use","id":"Bash_190","name":"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"},"extra_content":null}]