feat(MagicFunction): Schwartzness of the eight-dimensional integrals Iⱼ and Jⱼ via smooth cutoff - #433
Conversation
… Iⱼ'/Jⱼ' The one-dimensional integrals Iⱼ' and Jⱼ' are not Schwartz as stated (they grow exponentially as x → -∞), so the previous smooth'/decay' obligations were unprovable. Following the smooth-transition-function strategy: * Add SchwartzMap.ofNonnegDecay (ForMathlib/RadialSchwartz/SmoothCutoff): a function ℝ → E that is smooth on (a, ∞) for some a < 0 and has Schwartz-type decay on [0, ∞) becomes a genuine Schwartz function after multiplication by Real.smoothTransition (1 - 2 * x / a), which vanishes on (-∞, a/2] and is 1 on [0, ∞). Fully proved (no sorries). * Add exists_smooth_cutoff, the statement of PR #316 (Matt Cushman), obtained from mathlib's Real.smoothTransition. * Redefine SchwartzIntegrals.Iⱼ' (resp. Jⱼ') as the cutoff of RealIntegrals.Iⱼ' with a = -2 (transition on [-1, 0], as in PR #316; resp. a = -1 for Jⱼ', since ψS only gives convergence on (-1, ∞)). * Replace the false decay'/smooth' obligations with provable ones: decay on [0, ∞) only, and ContDiffOn (Ioi (-2)) (resp. Ioi (-1)) for the sixth integral; the Iⱼ'_bounding estimates supply the zeroth-order cases. * Prove Iⱼ_coe/Jⱼ_coe/a_coe/b_coe: the eight-dimensional Schwartz functions are *equal* to the radial functions RadialFunctions.Iⱼ/Jⱼ/a/b, since the cutoff is invisible after composing with ‖·‖ ^ 2 ≥ 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PgeJjuvzNGKAeHZy9gxUn
…ule exposure Verified against a full source build of the project (3453 jobs, success): * move module docstrings before `@[expose] public section` (style linter) * make the two lemmas used in `ofNonnegDecay`'s fields public (the module system rejects private references in exposed definition bodies) * `le_or_lt` → `le_or_gt`, `show` → `change`, line-width fixes `SchwartzMap.ofNonnegDecay`, `exists_smooth_cutoff` and the apply lemmas check with standard axioms only; `a_coe`/`b_coe` depend on `sorryAx` only through the restated smoothness/decay hypotheses, as intended. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PgeJjuvzNGKAeHZy9gxUn
🔍 Independent Review — Round 1Overall. The structural core of this PR is genuinely good. Verification I ran. 1. Faithfulness to the ask✅ The essential fix is correct and is the heart of the task. Pre-PR, ✅ The 🟡 should-fix (defensible) — the analytic content is entirely deferred, and 🟡 should-fix — 2. Idiomaticity & Mathlib quality✅ 🟡 should-fix — make the two glue lemmas 🟢 nice-to-have — add the basic @[simp] theorem ofNonnegDecay_apply (…) :
ofNonnegDecay f a ha hf hdecay x = smoothTransition (1 - 2 * x / a) • f x := rflWith it, the two conditional lemmas become 🟢 nice-to-have — the name Naming is otherwise on-convention: 3. Efficiency✅ The two proofs are near-minimal for what they are. 🟢 nice-to-have — the middle split point is 4. Clarity, conciseness, cleanliness, modularity✅ Excellent module docstrings and separation of concerns. The top-of-file docs explain why the 1-D functions fail to be Schwartz and how the cutoff repairs it (module docstrings may carry strategy — this is the right place for it). Putting the reusable bridge in 🟢 nice-to-have — one docstring wraps mid-phrase ( What's done well (summary)
Severity ranking
Nice work on the hard part — the bridge is the right abstraction and it's solid. Generated by Claude Code |
…eaner decay split, private helpers * Add `@[simp] SchwartzMap.ofNonnegDecay_apply` (the `rfl` unfolding lemma) and route the two `*_apply_of_*` lemmas through it. * `decay_transition_smul`: split ℝ at the transition endpoints `a/2` and `0` (instead of `1`), aligning the compact case with the transition interval `[a/2, 0]` and dropping the arbitrary constant; bound becomes `|a| ^ k * C₁`. * Keep the four pointwise transition facts `private`; document why the two substantive lemmas (`contDiff_transition_smul`, `decay_transition_smul`) must stay `public` (they are the proof fields of the `@[expose]`d `ofNonnegDecay`). * Soften the decay docstrings in a/b Schwartz to not overstate that `Iⱼ'_bounding` is already wired into the (still `sorry`) decay lemmas, and reflow an over-long docstring line. Verified: `lake build` of all three files clean (only `sorry` warnings remain); `#print axioms` on the SmoothCutoff declarations is `[propext, Classical.choice, Quot.sound]`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PgeJjuvzNGKAeHZy9gxUn
Response to Round 1 reviewThanks for the careful, verified review. Addressed in Should-fix
Nice-to-have
Rebuilt clean (only the intended Generated by Claude Code |
🔍 Independent Review — Round 2Overall. I reviewed the current HEAD ( Verification I ran. 1. Faithfulness to the ask✅ The restated 1-D statements are mathematically TRUE — I checked each independently.
This is the crux and it's right: the pre-PR obligations were false (smoothness/decay on all of 🟡 should-fix (defensible scope) — the 23 analytic 2. Idiomaticity & Mathlib quality✅ ✅ The public/private split is not just acceptable but minimal — I confirm the author's Round-1 resolution. Exposing 🟢 nice-to-have — avoid 3. Efficiency✅ Both substantive proofs are near-minimal. 4. Clarity, conciseness, cleanliness, modularity✅ Docstrings and modularity are a strength. The reusable bridge lives in 🟢 nice-to-have — Done well
Severity ranking
Solid work — the bridge is the correct abstraction and the corrected 1-D statements are the right foundation for the follow-up. Independent Round-2 review generated by Claude Code Generated by Claude Code |
…d-2 review) Add an on-declaration note that `exists_smooth_cutoff` is a standalone existence result recording the PR #316 connection and is not used by `ofNonnegDecay` (which builds the rescaled transition directly). The reviewer's other nit — renaming `lt_or_ge`/`le_or_gt` to `lt_or_le`/`le_or_lt` — does not apply to the pinned mathlib (v4.30.0): those names do not exist there, and `lt_or_ge`/`le_or_gt` are already the clean-orientation lemmas (`a < b ∨ b ≤ a` / `a ≤ b ∨ b < a`). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PgeJjuvzNGKAeHZy9gxUn
Response to Round 2 reviewThanks — and I appreciate the independent confirmation that the restated 1-D statements are mathematically true and that the Should-fix — track the 23 analytic Nice-to-have (b) — flag Nice-to-have (a) — Rebuilt clean; axioms unchanged. Generated by Claude Code |
🔍 Independent Review — Round 3Overall. I reviewed the current HEAD ( 1. Faithfulness to the ask ✅ (confirmed, nothing new)The 2. Idiomaticity & Mathlib quality🟠 should-fix (NEW) — e.g. Concrete fix: delete the ✅ 3. Efficiency ✅Both substantive proofs are near-minimal ( 4. Clarity, cleanliness, modularity ✅Module docstrings are accurate — I checked the transition spellings: 🟢 nice-to-have — Done well
Severity ranking
Genuinely solid PR; the one new item is cosmetic simp-hygiene, not correctness. Independent Round-3 review generated by Claude Code Generated by Claude Code |
`SchwartzMap` has no `apply` simps-projection, so `@[simps!]` descended into `ℂ = {re, im}` and
generated 8 unused, non-idiomatic global `@[simp]` lemmas (`a'_toFun_re`, `a_toFun_im`, …) that
expose `toFun` and split the eigenfunctions into real/imaginary parts. Nothing in the repo
references them (by name or via `simp`), and the intended API is the hand-written `a_coe`/`b_coe`
and `*_apply_of_nonneg`. Removed the four attributes.
Verified: full `lake build` succeeds (3453 jobs) — no downstream breakage from dropping the
generated simp lemmas.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PgeJjuvzNGKAeHZy9gxUn
Response to Round 3 reviewNice catch — this is a real issue the first two rounds missed. Fixed in Should-fix — I did the downstream rebuild you flagged as untested: full Nice-to-have — Thanks for digging past the earlier rounds rather than re-confirming them. Generated by Claude Code |
🔍 Independent Review — Round 4Overall. I reviewed the current HEAD independently, with no assumptions carried over from the earlier rounds, and rebuilt the core clean ( Independent re-verification (correctness)
1. Faithfulness ✅Confirmed, nothing new. The 2. Idiomaticity & mathlib quality🟢 nice-to-have (NEW) — 🟢 nice-to-have (NEW) — the decay predicate is spelled out verbatim three times ( Otherwise 3. Efficiency ✅Both substantive proofs are near-minimal ( 4. Clarity, cleanliness, modularity ✅Docstrings are accurate (checked above), file placement is good (bridge in Done well
Severity ranking
Genuinely clean PR. The remaining items are cosmetic; the core is solid. Independent Round-4 review generated by Claude Code Generated by Claude Code |
… (round-4 review) `exists_smooth_cutoff` sat in the root namespace — mild global-namespace pollution for a `ForMathlib`-style file. It is a fact about real functions built from `Real.smoothTransition`, so `Real.exists_smooth_cutoff` is the idiomatic home. The declaration is unused, so the move is safe; updated the module docstring reference accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PgeJjuvzNGKAeHZy9gxUn
Response to Round 4 reviewThanks for the independent hand-derivation of the transition facts, the case-splits, and the Nice-to-have 1 — Nice-to-have 2 — DRY the
If the maintainers would prefer the abstraction (e.g. if this decay notion recurs elsewhere in the project), I'm happy to introduce Standing item unchanged: the analytic 1-D Generated by Claude Code |
🔍 Independent Review — Round 5Overall. I reviewed the current HEAD from scratch, with no assumptions carried from Rounds 1–4, and independently re-verified the mathematics and the mechanical claims. The Verification I ran (this round, from scratch).
2. Idiomaticity & Mathlib quality🟠 should-fix (NEW) —
Mathlib's orientation convention (and this repo's own theorem Real.exists_smooth_cutoff :
∃ f : ℝ → ℝ, ContDiff ℝ ∞ f ∧ (∀ x : ℝ, x ≤ -1 → f x = 0) ∧ ∀ x : ℝ, 0 ≤ x → f x = 1 :=(the proof 🟢 nice-to-have (NEW) — Otherwise 1. Faithfulness ✅Confirmed independently, nothing new. The restated 1-D obligations are true where the pre-PR globals were false; the 23 analytic 3. Efficiency ✅Both substantive proofs are near-minimal ( 4. Clarity, cleanliness, modularity ✅Docstrings accurate (I re-checked the Done well
Severity ranking
Genuinely clean PR; the two new items are cosmetic/style, not correctness. Independent Round-5 review generated by Claude Code Generated by Claude Code |
…und-5 review) * Re-orient all `≥` in statements to `≤` per the project's inequality-orientation convention: `Real.exists_smooth_cutoff`'s `x ≥ 0 → f x = 1` becomes `0 ≤ x → f x = 1`, and the `∀ x ≥ (0 : ℝ), …` decay predicate (in `ofNonnegDecay`, `decay_transition_smul`, and the 12 `Iⱼ'`/`Jⱼ'` decay lemmas) becomes `∀ x, (0 : ℝ) ≤ x → …`. (Defeq, so no proof changes.) * Drop the unused `Filter` from `open Real Set Filter` in SmoothCutoff. Verified: `lake build` of all three files clean (only intended `sorry`s). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PgeJjuvzNGKAeHZy9gxUn
Response to Round 5 reviewThanks for reviewing from scratch and re-deriving the transition facts, case-splits, and Should-fix —
Nice-to-have — unused All three files rebuild clean (only the intended analytic Generated by Claude Code |
|
To be superseded by #444 (see docstring). |
(This is an experimental PR: I wanted to see if Claude could do this in a good way by launching and interacting with independent review agents along the way. This will be done in a much better way in #444.)
Schwartzness of the eight-dimensional integrals
IⱼandJⱼThe one-dimensional integrals
RealIntegrals.Iⱼ',Jⱼ' : ℝ → ℂare not Schwartz functions as currently stated: they grow exponentially asx → -∞, and the sixth integrals are not even given by convergent integrals far to the left of the origin. The previoussmooth'/decay'obligations ina/Schwartz.leanandb/Schwartz.leanwere therefore unprovable. Since the eight-dimensional integrals are obtained by composing with‖·‖² ≥ 0, only the behaviour on[0, ∞)matters — so we multiply by a smooth transition function (STF) that is1on[0, ∞)and vanishes far to the left, and compose that with‖·‖².What this PR does
1. New:
ForMathlib/RadialSchwartz/SmoothCutoff.lean— fully proved, no sorriesexists_smooth_cutoff:∃ f : ℝ → ℝ, ContDiff ℝ ∞ f ∧ (∀ x ≤ -1, f x = 0) ∧ ∀ x ≥ 0, f x = 1— this is precisely the statement of Existence of smooth cutoff function #316 (@mattcushman), obtained here in one term from mathlib'sReal.smoothTransition. I could not make this PR depend on Existence of smooth cutoff function #316 in the git sense: its base branchschwartzness-dimensionsshares no merge base with currentmain(the history was rewritten; 143 files / 12k+ lines and an older toolchain apart), so the statement is included and credited instead. If Existence of smooth cutoff function #316 is rebased and merged first, this lemma can be dropped in favour of it.SchwartzMap.ofNonnegDecay (f : ℝ → E) (a : ℝ) (ha : a < 0) (hf : ContDiffOn ℝ ∞ f (Ioi a)) (hdecay : …) : 𝓢(ℝ, E)— the Schwartz functionx ↦ Real.smoothTransition (1 - 2x/a) • f x, given smoothness offon(a, ∞)and Schwartz-type decay on[0, ∞)only. The transition vanishes on(-∞, a/2]and is1on[0, ∞). Fora = -2the cutoff is exactlysmoothTransition (x + 1), i.e. the STF of Existence of smooth cutoff function #316 transitioning on[-1, 0].ofNonnegDecay_apply_of_nonneg/ofNonnegDecay_apply_of_le_half: it agrees withfon[0, ∞)and vanishes belowa/2.#print axioms: all three check with[propext, Classical.choice, Quot.sound]— nosorryAx.2.
a/Schwartz.lean:SchwartzIntegrals.Iⱼ' := ofNonnegDecay RealIntegrals.Iⱼ' (-2) …Iⱼ'_decay_nonneg(decay of all derivatives on[0, ∞)); the zeroth-order cases are supplied (up to integrating the bound) by the existingIntegralEstimates.Iⱼ'_bounding. TheI₃'transfer trick of feat(Schwartz): proveI₃'_decay'#339 also ports verbatim to these restated bounds.I₆'_smooth'(false: the integral only converges forx > -2, bynorm_φ₀_le) is replaced byI₆'_smoothOn : ContDiffOn ℝ ∞ I₆' (Ioi (-2)).I₁'…I₅'_smooth'are kept unchanged (compact contours; the existing conditional proof ofI₃'_smooth'survives untouched).Iⱼ_coe : ⇑Iⱼ = RadialFunctions.Iⱼanda_coe : ⇑a = RadialFunctions.a— the eight-dimensional Schwartz functions are equal to the radial functions, because the cutoff is invisible after composing with‖·‖² ≥ 0(via the existingschwartzMap_multidimensional_of_schwartzMap_real, i.e.SchwartzMap.compCLMwith‖·‖²).a'_eq_sum_RealIntegrals(false as a global function equality under any correct definition) is replaced bya'_apply_of_nonneg;a_eq_sum_integrals_SchwartzIntegralsremainsrfl, anda_eq_sum_integrals_RadialFunctionskeeps its statement with a two-line proof.3.
b/Schwartz.lean: same treatment forJⱼ/b, witha = -1The blueprint's bound
‖ψS z‖ ≤ C e^{-π Im z}(lemma:psi-bound) only guarantees convergence ofJ₆'on(-1, ∞), so a transition on[-1, 0]cannot work on theb-side; instead the cutoff transitions on[-1/2, 0]. This is the only asymmetry with thea-side, and is whyofNonnegDecayis parametrised by the thresholda.Status of the remaining hypotheses
The 23 remaining sorries (11 on the
a-side, 12 on theb-side) are exactly the corrected one-dimensional smoothness/decay statements — all now believed provable (Leibniz rule + theIntegralEstimatesbounds, blueprint Prop. 7.8 /prop:b-schwartz). Everything built on top of them — the Schwartz structures, the equalities withRadialFunctions.Iⱼ/Jⱼ/a/b, and all downstream files (Eigenfunction,SpecialValues,g/Basic) — is fully verified: the sorry count is unchanged, but the statements are now true and the architecture sound.Verification
lake buildsucceeds (3453 jobs), including all downstream consumers, with no new warnings from the touched files (style linters clean).#print axioms a_coe/b_coe:sorryAxenters only through the restated hypotheses above.🤖 Generated with Claude Code
https://claude.ai/code/session_017PgeJjuvzNGKAeHZy9gxUn
Generated by Claude Code