diff --git a/formal/D2_SCHUR.md b/formal/D2_SCHUR.md new file mode 100644 index 000000000..fd7921da9 --- /dev/null +++ b/formal/D2_SCHUR.md @@ -0,0 +1,101 @@ +# D2 Schur and endpoint positivity: exact formal scope + +**Scientific effect NONE.** Dylan Roy — delegated AI work. Actual author OpenAI / +GPT-6 Astra Pro, session `lean-d2-schur-expansion-20261005`. This is a continuation +of that provider's informal derivation, not a nonauthor or blind review. +Alignment remains PENDING_INDEPENDENT_REVIEW; source progress is not an observed +kernel run. No source record, scientific register, prize or Boolean is advanced. + +## Exact source interface + +At Math- commit `ec61d0a4e1d7c29554c0af93fca983092327b618`, consume +`reviews/side24_d2_certified_small_L_claude_20261005/NOTE.md` section2, +Git blob `852f7403a8a06a1ef061e363df9502ae16f7a341`, SHA256 +`407828facb8dde26a036a08a5b3978eb74d6d8a508c68e2758c291e16e911588`. +The exact Schur cancellation and endpoint observation were recorded separately +in Math-#302 comment6005199919. That mutable comment is attribution/context; +the complete formulas and Lean definitions here are the bound proof input. + +The variables are arbitrary real scalars `m2`, `m4`, `m6`, `q`. The intended +interpretation is raw one-coordinate spectral moments and +`q=cos(theta)^2*sin(theta)^2`. The interpretation is NOT constructed in Lean. +The source covariance uses the raw spectral Gram of quadratic monomials, NOT +centered spectral covariance and NOT conditioning on the field height. + +Set `k4=m4-3*m2^2`. Definitions in D2Schur.lean are + +``` +alpha = m4 - 2*k4*q +gamma = m2^2 + 2*k4*q +D = m2^2*m4 + k4*(m4+m2^2)*q +N = m2^2*(m4^2-m2^4) +S = alpha - (gamma^3+(2*gamma+alpha)*k4^2*q*(1-4*q))/D +Delta = m6-m4^2/m2 +T = (1-4*q)*Delta + 4*q*(Delta+9*m2*(m4-m2^2))/4 +``` + +The first14 declarations prove identities/inequalities of these expressions. +The last2 are positive reference and singular-boundary controls. No additional +rejection-run count is claimed for those2 ordinary audited declarations. + +## Declaration-by-declaration mapping + +| Declaration | Statement and hypotheses | +|---|---| +| d2_schur_numerator | `alpha*D-gamma^3-(2gamma+alpha)*k4^2*q*(1-4q)=N`; no denominator hypothesis | +| d2_det_axis | `D(0)=m2^2*m4` | +| d2_det_diagonal | `D(1/4)=(m4-m2^2)*(m4+3m2^2)/4` | +| d2_det_interpolation | D is the convex interpolation of those endpoints when q is in the intended interval; the equality holds for every real q | +| d2_schur_ratio | `S=N/D` requires `D!=0` | +| d2_numerator_pos | `N>0` from `m2>0` and `m4>m2^2` | +| d2_det_pos | `D>0` from those moment conditions and `0<=q<=1/4` | +| d2_schur_pos | `S>0` under the same conditions | +| d2_det_le_endpoint_max | D at `0<=q<=1/4` is at most the larger endpoint, without moment positivity hypotheses | +| d2_schur_endpoint_lower | `N/max(D(0),D(1/4))<=S` under strict moment conditions and the q interval | +| d2_tau_cumulant_eq | The original sixth/fourth cumulant formula equals T, with `m2!=0` | +| d2_tau_axis | `T(0)=Delta` | +| d2_tau_diagonal | `T(1/4)=(Delta+9*m2*(m4-m2^2))/4` | +| d2_tau_pos | T is positive from `m2>0`, `m4>m2^2`, `Delta>0`, `0<=q<=1/4` | +| d2_gaussian_control | At `m2=1,m4=3,m6=15`, `D=3`, `S=8/3`, `T=6`, for every real q | +| d2_degenerate_control | At `m2=m4=m6=1,q=1/4`, D=0, S=2 but N/D=0; axis T=0. The unguarded quotient identity and strict positivity at the moment boundary are false | + +The positive lower-bound value follows from N>0 and positive endpoint maximum; +this is not a computation of its value for any period. Empty/nonreal/negative +moment inputs are not silently treated as probability laws. The mathematical +proofs are for arbitrary reals satisfying the written hypotheses; rational +Python controls are only falsification and implementation checks. + +## Integration and verification + +The existing47 theorem proof files, gate.py, pinned Lean4.34.1, mathlib commit +`d13f23b723b8a846827a245b89c10fc7d3f11612`, dependencies, old rejection controls, +original archives and historical alignment records remain unchanged. +The new16 targets extend the exact inventory to63. The predecessor weight test +checks its original slice40:47 instead of claiming to be the terminal suffix; +this new test checks the exact remaining suffix and exact total63. No old +weight inequality or test case is removed. The executable gate still requires +all declared sources/hashes and transitive axiom reports and all5 real negative +controls. The full type log remains part of the execution evidence. + +``` +python -B -S -m unittest discover -s formal/tests -v +python -B -O -S -m unittest discover -s formal/tests -v +python -B -S formal/gate.py +python -B -S formal/gate.py --execute +``` + +A source-only result does not run Lean. This author environment has no Lean +installation and cannot resolve GitHub DNS. Hosted build/recheck/axiom/negative +execution on the actual candidate is therefore required before a kernel claim. +Nonauthor exact-scope review is also required, independently of execution. + +## Explicit exclusions and preserved obligations + +Not formalized: construction or covariance identification of the random field; +actual matrix inverse/Schur complement or Gram rotation; derivation/realizability +of the moment assumptions; `q`'s trigonometric representation; finite-L tails; +interval arithmetic or quadrature; coefficient formula(15.2), Gamma normalization +or lifetime laws; higher dimensions; persistence matching; CapI4 transport; +any whole-package independent alignment or the earlier #281 lineage issue. +The source-bound numerical implementation remains unchanged. These algebraic +companions may assist its future review but do not retroactively validate it. diff --git a/formal/README.md b/formal/README.md index e4e0fa6ee..47d3ebba4 100644 --- a/formal/README.md +++ b/formal/README.md @@ -14,7 +14,7 @@ cd .. python formal/gate.py --execute ``` -The source-only command does not run Lean. The execute command fails unless the pinned project builds, `leanchecker` rechecks the package, all 47 declarations have transitive axiom reports restricted to propext/Classical.choice/Quot.sound, and five executable negative controls are rejected. It writes logs and a receipt in `.lake/formal-evidence/`; the workflow uploads them even on failure. A receipt from arbitrary input is not trusted evidence: use the successful read-only workflow and checked Git commit. +The source-only command does not run Lean. The execute command fails unless the pinned project builds, `leanchecker` rechecks the package, all 63 declarations have transitive axiom reports restricted to propext/Classical.choice/Quot.sound, and five executable negative controls are rejected. It writes logs and a receipt in `.lake/formal-evidence/`; the workflow uploads them even on failure. A receipt from arbitrary input is not trusted evidence: use the successful read-only workflow and checked Git commit. Sources: [scope](SCOPE.md), [glossary](GLOSSARY.md), [manifest](manifest.json), [blueprint source](blueprint/src/content.tex). The original GP-FOR-192 bytes are preserved under originals/*.lean.txt; separately named V2 companions carry the documented compiler-only repairs in [COMPATIBILITY.md](COMPATIBILITY.md). No historical Status.lean or claimed status is imported. [Alignment contract](SCOPE.md#review-contract) remains distinct from kernel evidence. @@ -47,3 +47,7 @@ The additive [WeightPerturbation](WEIGHT_PERTURBATION.md) supplies seven declara Read the current source-bound PR and exact head first; main #95 is historical rollout context. A non-OpenAI alignment reviewer should inspect all assumptions, the source correspondence and the explicit nonclaims. An independent engineering reviewer should attack omitted targets, imports carrying custom axioms, stale scope/hash/review records and altered toolchains. A probability formalizer should next identify the constructed weighted law with the concrete typed Palm model and discharge its same-law moment/lower-normalizer interface. Do not import GP214's upper bound as the lower bound. The MeasureBridge source is supplied but has no self-awarded kernel or alignment status. Coordinate before editing; a review request is not a claim that a reviewer is active. Blueprint declaration links are checked against the target inventory and compiled declarations, not by semantic equivalence. The full plasTeX/LaTeX website is not installed in this pilot. Optional independent checkers or AI proof generators may be added with pinned versions/budgets; their availability and execution must be separately recorded. Never treat AlphaProof as an assumed publicly callable CI service or a generator's success as an independent alignment review. + +## D2 Schur and endpoint positivity + +The additive [D2Schur](D2_SCHUR.md) supplies sixteen real-algebra declarations: exact Schur cancellation, determinant endpoint interpolation, positive conditional-expression bounds, cubic-variance cumulant conversion, and reference/singular controls. The earlier47 Lean proof bytes and the gate remain unchanged. The total inventory is63. Moment realizability, Gaussian/Palm identification and coefficient quadrature are not formalized by these conditional expressions; independent alignment remains pending. diff --git a/formal/ResearchFormalCoreR1.lean b/formal/ResearchFormalCoreR1.lean index 0cd5a62af..7e484d7d5 100644 --- a/formal/ResearchFormalCoreR1.lean +++ b/formal/ResearchFormalCoreR1.lean @@ -5,3 +5,4 @@ import ResearchFormalCoreR1.WeightedLaw import ResearchFormalCoreR1.MomentTail import ResearchFormalCoreR1.MomentGenerality import ResearchFormalCoreR1.WeightPerturbation +import ResearchFormalCoreR1.D2Schur diff --git a/formal/ResearchFormalCoreR1/D2Schur.lean b/formal/ResearchFormalCoreR1/D2Schur.lean new file mode 100644 index 000000000..b95460c0d --- /dev/null +++ b/formal/ResearchFormalCoreR1/D2Schur.lean @@ -0,0 +1,169 @@ +import Mathlib.Data.Real.Basic +import Mathlib.Tactic + +/-! +# Algebraic d=2 Schur and positivity companion + +Dylan Roy — delegated AI work. Actual author: OpenAI / GPT-6 Astra Pro. +Source: Math-#302 NOTE section 2 and additive identity comment 6005199919. +These are real algebraic expressions with explicit hypotheses, not a +construction of the Gaussian field or a proof of the coefficient integral. +-/ + +namespace ResearchFormalCoreR1 + +noncomputable def d2Alpha (m2 m4 q : ℝ) : ℝ := + m4 - 2 * (m4 - 3 * m2 ^ 2) * q + +noncomputable def d2Gamma (m2 m4 q : ℝ) : ℝ := + m2 ^ 2 + 2 * (m4 - 3 * m2 ^ 2) * q + +noncomputable def d2DetV (m2 m4 q : ℝ) : ℝ := + m2 ^ 2 * m4 + (m4 - 3 * m2 ^ 2) * (m4 + m2 ^ 2) * q + +noncomputable def d2Numerator (m2 m4 : ℝ) : ℝ := + m2 ^ 2 * (m4 ^ 2 - m2 ^ 4) + +noncomputable def d2Schur (m2 m4 q : ℝ) : ℝ := + d2Alpha m2 m4 q - + (d2Gamma m2 m4 q ^ 3 + + (2 * d2Gamma m2 m4 q + d2Alpha m2 m4 q) * + (m4 - 3 * m2 ^ 2) ^ 2 * q * (1 - 4 * q)) / d2DetV m2 m4 q + +noncomputable def d2Delta (m2 m4 m6 : ℝ) : ℝ := m6 - m4 ^ 2 / m2 + +noncomputable def d2Tau (m2 m4 m6 q : ℝ) : ℝ := + (1 - 4 * q) * d2Delta m2 m4 m6 + + 4 * q * ((d2Delta m2 m4 m6 + 9 * m2 * (m4 - m2 ^ 2)) / 4) + +/-- Exact polynomial cancellation; it does not divide by the pin determinant. -/ +theorem d2_schur_numerator (m2 m4 q : ℝ) : + d2Alpha m2 m4 q * d2DetV m2 m4 q - d2Gamma m2 m4 q ^ 3 - + (2 * d2Gamma m2 m4 q + d2Alpha m2 m4 q) * + (m4 - 3 * m2 ^ 2) ^ 2 * q * (1 - 4 * q) = d2Numerator m2 m4 := by + unfold d2Alpha d2Gamma d2DetV d2Numerator + ring + +theorem d2_det_axis (m2 m4 : ℝ) : d2DetV m2 m4 0 = m2 ^ 2 * m4 := by + simp [d2DetV] + +theorem d2_det_diagonal (m2 m4 : ℝ) : + d2DetV m2 m4 (1 / 4) = (m4 - m2 ^ 2) * (m4 + 3 * m2 ^ 2) / 4 := by + unfold d2DetV + ring + +theorem d2_det_interpolation (m2 m4 q : ℝ) : + d2DetV m2 m4 q = (1 - 4 * q) * (m2 ^ 2 * m4) + + 4 * q * ((m4 - m2 ^ 2) * (m4 + 3 * m2 ^ 2) / 4) := by + unfold d2DetV + ring + +/-- The nonzero hypothesis is essential even with Lean's total division. -/ +theorem d2_schur_ratio (m2 m4 q : ℝ) (hD : d2DetV m2 m4 q ≠ 0) : + d2Schur m2 m4 q = d2Numerator m2 m4 / d2DetV m2 m4 q := by + have h := d2_schur_numerator m2 m4 q + unfold d2Schur + apply (eq_div_iff hD).2 + rw [sub_mul, div_mul_cancel₀ _ hD] + linarith + +theorem d2_numerator_pos (m2 m4 : ℝ) (hm2 : 0 < m2) (hm4 : m2 ^ 2 < m4) : + 0 < d2Numerator m2 m4 := by + have hx : 0 < m2 ^ 2 := sq_pos_of_pos hm2 + have hv : 0 < m4 - m2 ^ 2 := sub_pos.mpr hm4 + have hs : 0 < m4 + m2 ^ 2 := by linarith + have he : d2Numerator m2 m4 = m2 ^ 2 * (m4 - m2 ^ 2) * (m4 + m2 ^ 2) := by + unfold d2Numerator + ring + rw [he] + exact mul_pos (mul_pos hx hv) hs + +theorem d2_det_pos (m2 m4 q : ℝ) (hm2 : 0 < m2) (hm4 : m2 ^ 2 < m4) + (hq0 : 0 ≤ q) (hq1 : q ≤ 1 / 4) : 0 < d2DetV m2 m4 q := by + have hx : 0 < m2 ^ 2 := sq_pos_of_pos hm2 + have hm4pos : 0 < m4 := lt_trans hx hm4 + have ha : 0 < m2 ^ 2 * m4 := mul_pos hx hm4pos + have hv : 0 < m4 - m2 ^ 2 := sub_pos.mpr hm4 + have hs : 0 < m4 + 3 * m2 ^ 2 := by positivity + have hb : 0 < (m4 - m2 ^ 2) * (m4 + 3 * m2 ^ 2) / 4 := by positivity + rw [d2_det_interpolation] + by_cases hq : q = 0 + · simpa [hq] using ha + · have hqp : 0 < q := lt_of_le_of_ne hq0 (Ne.symm hq) + have hw : 0 ≤ 1 - 4 * q := by linarith + exact add_pos_of_nonneg_of_pos (mul_nonneg hw ha.le) (mul_pos (by positivity) hb) + +theorem d2_schur_pos (m2 m4 q : ℝ) (hm2 : 0 < m2) (hm4 : m2 ^ 2 < m4) + (hq0 : 0 ≤ q) (hq1 : q ≤ 1 / 4) : 0 < d2Schur m2 m4 q := by + have hD := d2_det_pos m2 m4 q hm2 hm4 hq0 hq1 + rw [d2_schur_ratio m2 m4 q (ne_of_gt hD)] + exact div_pos (d2_numerator_pos m2 m4 hm2 hm4) hD + +theorem d2_det_le_endpoint_max (m2 m4 q : ℝ) (hq0 : 0 ≤ q) (hq1 : q ≤ 1 / 4) : + d2DetV m2 m4 q ≤ + max (m2 ^ 2 * m4) ((m4 - m2 ^ 2) * (m4 + 3 * m2 ^ 2) / 4) := by + have hw : 0 ≤ 1 - 4 * q := by linarith + have hv : 0 ≤ 4 * q := by positivity + rw [d2_det_interpolation] + calc + _ ≤ (1 - 4 * q) * max (m2 ^ 2 * m4) ((m4 - m2 ^ 2) * (m4 + 3 * m2 ^ 2) / 4) + + 4 * q * max (m2 ^ 2 * m4) ((m4 - m2 ^ 2) * (m4 + 3 * m2 ^ 2) / 4) := + add_le_add (mul_le_mul_of_nonneg_left (le_max_left _ _) hw) + (mul_le_mul_of_nonneg_left (le_max_right _ _) hv) + _ = _ := by ring + +/-- A uniform positive lower bound on q in [0,1/4], with moment premises explicit. -/ +theorem d2_schur_endpoint_lower (m2 m4 q : ℝ) (hm2 : 0 < m2) (hm4 : m2 ^ 2 < m4) + (hq0 : 0 ≤ q) (hq1 : q ≤ 1 / 4) : + d2Numerator m2 m4 / + max (m2 ^ 2 * m4) ((m4 - m2 ^ 2) * (m4 + 3 * m2 ^ 2) / 4) ≤ + d2Schur m2 m4 q := by + have hD := d2_det_pos m2 m4 q hm2 hm4 hq0 hq1 + have hbound := d2_det_le_endpoint_max m2 m4 q hq0 hq1 + have hM := lt_of_lt_of_le hD hbound + rw [d2_schur_ratio m2 m4 q (ne_of_gt hD)] + exact (div_le_div_iff₀ hM hD).2 + (mul_le_mul_of_nonneg_left hbound (d2_numerator_pos m2 m4 hm2 hm4).le) + +theorem d2_tau_cumulant_eq (m2 m4 m6 q : ℝ) (hm2 : m2 ≠ 0) : + 6 * m2 ^ 3 + 9 * m2 * (m4 - 3 * m2 ^ 2) * (1 - 2 * q) + + (m6 - 15 * m4 * m2 + 30 * m2 ^ 3 - (m4 - 3 * m2 ^ 2) ^ 2 / m2) * + (1 - 3 * q) = d2Tau m2 m4 m6 q := by + unfold d2Tau d2Delta + field_simp [hm2] + <;> ring + +theorem d2_tau_axis (m2 m4 m6 : ℝ) : d2Tau m2 m4 m6 0 = d2Delta m2 m4 m6 := by + simp [d2Tau] + +theorem d2_tau_diagonal (m2 m4 m6 : ℝ) : + d2Tau m2 m4 m6 (1 / 4) = + (d2Delta m2 m4 m6 + 9 * m2 * (m4 - m2 ^ 2)) / 4 := by + unfold d2Tau + ring + +theorem d2_tau_pos (m2 m4 m6 q : ℝ) (hm2 : 0 < m2) (hm4 : m2 ^ 2 < m4) + (hDelta : 0 < d2Delta m2 m4 m6) (hq0 : 0 ≤ q) (hq1 : q ≤ 1 / 4) : + 0 < d2Tau m2 m4 m6 q := by + have hv : 0 < m4 - m2 ^ 2 := sub_pos.mpr hm4 + have hb : 0 < (d2Delta m2 m4 m6 + 9 * m2 * (m4 - m2 ^ 2)) / 4 := by positivity + unfold d2Tau + by_cases hq : q = 0 + · simpa [hq] using hDelta + · have hqp : 0 < q := lt_of_le_of_ne hq0 (Ne.symm hq) + have hw : 0 ≤ 1 - 4 * q := by linarith + exact add_pos_of_nonneg_of_pos (mul_nonneg hw hDelta.le) (mul_pos (by positivity) hb) + +/-- Gaussian-reference algebra, for all real q, not a probabilistic identification. -/ +theorem d2_gaussian_control (q : ℝ) : + d2DetV 1 3 q = 3 ∧ d2Schur 1 3 q = 8 / 3 ∧ d2Tau 1 3 15 q = 6 := by + norm_num [d2DetV, d2Schur, d2Alpha, d2Gamma, d2Tau, d2Delta] + <;> ring + +/-- At a singular moment boundary the unguarded quotient identity is false. -/ +theorem d2_degenerate_control : + d2DetV 1 1 (1 / 4) = 0 ∧ d2Schur 1 1 (1 / 4) = 2 ∧ + d2Numerator 1 1 / d2DetV 1 1 (1 / 4) = 0 ∧ d2Tau 1 1 1 0 = 0 := by + norm_num [d2DetV, d2Schur, d2Alpha, d2Gamma, d2Numerator, d2Tau, d2Delta] + +end ResearchFormalCoreR1 diff --git a/formal/SCOPE.md b/formal/SCOPE.md index f8b7c74b7..24ef1d7e6 100644 --- a/formal/SCOPE.md +++ b/formal/SCOPE.md @@ -99,6 +99,26 @@ proof bytes, the gate, dependency pins and historical review records remain unchanged. The prior withheld lineage does not become accepted through this extension or through successful execution; a new scoped review is required. +## Additive D2 Schur and endpoint positivity (sixteen further declarations) + +The total is now 63 theorem targets. [D2_SCHUR.md](D2_SCHUR.md) gives the +hash-bound declaration-by-declaration mapping. D2Schur.lean proves exact +polynomial Schur cancellation, its quotient form only for a nonzero denominator, +affine determinant endpoint identities, positivity and an endpoint-based lower +bound from explicit strict moment and q-interval hypotheses, and the cubic +variance cumulant conversion with positive-mixture consequences. Two ordinary +audited declarations retain the Gaussian-reference and singular-moment controls. +They are not two additional rejection runs. + +Earlier47 Lean proof bytes, gate.py, dependencies, the original5 executable +negative controls and historical reviews remain unchanged. The old weight test +continues to check its exact40:47 slice; the new test checks the exact16-target +suffix and total63. No realizability of the raw moments, actual matrix/field +identification, trigonometric parametrization, interval arithmetic, coefficient +quadrature or persistence theorem is supplied. The informal numerical packet +is unchanged. Kernel execution and a new source-specific alignment review remain +distinct; older withheld lineage and all wider scientific obligations survive. + ## Review contract The source manifest is an evidence sidecar, not another scientific register. A trusted successful workflow establishes kernel evidence only for these target declarations and their displayed hypotheses, relative to Lean's kernel/standard foundations/toolchain. Independent review must compare each Lean statement and definition to this scope note and the source actually cited. Review author, provider, family and agent must be explicit. Validate an authenticated record with `python formal/gate.py --alignment review.json`; then the existing controlling gate must decide whether its wider requirements are met. The validator does not authenticate a review merely because a JSON string names a reviewer. diff --git a/formal/blueprint/src/content.tex b/formal/blueprint/src/content.tex index 50a971584..2afd3e89a 100644 --- a/formal/blueprint/src/content.tex +++ b/formal/blueprint/src/content.tex @@ -56,3 +56,17 @@ \section{Same-law measure-theoretic bridge} \end{lemma} \begin{proof}Bound the numerator, derive a positive normalizer, and use the unchanged scalar quotient theorem.\end{proof} + + +\section{D2 Schur algebra and endpoint positivity} +\begin{lemma}[Endpoint lower bound for the conditional expression] +\label{lem:d2-schur} +\lean{ResearchFormalCoreR1.d2_schur_endpoint_lower} +For the expressions defined in D2Schur, assume $m_2>0$, $m_4>m_2^2$ +and $0\le q\le1/4$. Put $N=m_2^2(m_4^2-m_2^4)$ and +$D(q)=m_2^2m_4+(m_4-3m_2^2)(m_4+m_2^2)q$. +Then $N/\max\{D(0),D(1/4)\}\le S(q)$, and $S(q)>0$. +The scalar-to-Gaussian covariance identification is not formalized here. +\end{lemma} +\begin{proof}Cancel the Schur numerator, bound the positive affine denominator +by its endpoint maximum, and reverse that comparison upon reciprocation.\end{proof} diff --git a/formal/manifest.json b/formal/manifest.json index 45c10dde0..5aa2c31af 100644 --- a/formal/manifest.json +++ b/formal/manifest.json @@ -26,7 +26,8 @@ "ResearchFormalCoreR1/WeightedLaw.lean", "ResearchFormalCoreR1/MomentTail.lean", "ResearchFormalCoreR1/MomentGenerality.lean", - "ResearchFormalCoreR1/WeightPerturbation.lean" + "ResearchFormalCoreR1/WeightPerturbation.lean", + "ResearchFormalCoreR1/D2Schur.lean" ], "targets": [ "ResearchFormalCoreR1.ec005_fold_gap", @@ -75,18 +76,34 @@ "ResearchFormalCoreR1.weightPerturbation_event_integral_bounds", "ResearchFormalCoreR1.weightPerturbation_quotient_bound", "ResearchFormalCoreR1.weightedLaw_event_perturbation", - "ResearchFormalCoreR1.weightedLaw_event_perturbation_r2" + "ResearchFormalCoreR1.weightedLaw_event_perturbation_r2", + "ResearchFormalCoreR1.d2_schur_numerator", + "ResearchFormalCoreR1.d2_det_axis", + "ResearchFormalCoreR1.d2_det_diagonal", + "ResearchFormalCoreR1.d2_det_interpolation", + "ResearchFormalCoreR1.d2_schur_ratio", + "ResearchFormalCoreR1.d2_numerator_pos", + "ResearchFormalCoreR1.d2_det_pos", + "ResearchFormalCoreR1.d2_schur_pos", + "ResearchFormalCoreR1.d2_det_le_endpoint_max", + "ResearchFormalCoreR1.d2_schur_endpoint_lower", + "ResearchFormalCoreR1.d2_tau_cumulant_eq", + "ResearchFormalCoreR1.d2_tau_axis", + "ResearchFormalCoreR1.d2_tau_diagonal", + "ResearchFormalCoreR1.d2_tau_pos", + "ResearchFormalCoreR1.d2_gaussian_control", + "ResearchFormalCoreR1.d2_degenerate_control" ], "files": { ".gitignore": "b34af236d1df9e39ed4f98fca51702530ce76bdee4e1a69512f6caed933c3374", "COMPATIBILITY.md": "33721aad32f82131a6956a06b58c5bc41f5d28f26efe840a99a4d51ad60cf247", "GLOSSARY.md": "6bdda2ce054915efc26e8db462dbe8fd9d0c1db30e02328857bebc6568e05ce9", - "README.md": "35e3a29206c592947ff7ff44e2ee6eb796ca9791937adbe3eb03bfa0ed6aa1bf", + "README.md": "52c4829c23c5caa8142b4c8d7152766b92cb966b1cb8213ff5210e6fa4ef080e", "ResearchFormalCoreR1/AlgebraV2.lean": "4480708263c40a2f7f03f12ef7e15f0eb4f8193c2dccbb253921a7ec251863c3", "ResearchFormalCoreR1/ProbabilityCompanionsV2.lean": "338452a0c2ba24d016059354d543cc995b8cb29c9d4a41d98bb93499f5f8cb8f", - "ResearchFormalCoreR1.lean": "e648c41573b1ddc4e12af2ef1e3d3bff0d2c923f01b63e75186735f10eb35860", - "SCOPE.md": "36e0714bcb79a158a6e50ff5b1e5e772939800ba023d865944901e4e7ae34838", - "blueprint/src/content.tex": "e00ee78344ed27c097bccb8c6360f6bb86a223ab06319a407de2dd0104fd2e28", + "ResearchFormalCoreR1.lean": "c55cc116ff3ffbffdb692226e215450a5d2e85b60d27b1b04d529b87bdef38f8", + "SCOPE.md": "8fa7e879e23742aba77df8687659ca9dcfd13a19e0add6192229c2f80629b3cb", + "blueprint/src/content.tex": "0c976e8e4a5e69a443e93796c8f6cbf91bf73c224448c4256de72a041e04161f", "evidence/initial-build-failure.log": "43393d2e2b3148a2453e3092a1ff04e257dbd4a6dc97eb2853a8bc0451002591", "gate.py": "958b149ea3a4ce735644a2079f817b5deddf5dc0d5ca347904ad09db6ad47d68", "lake-manifest.json": "d63753befccc21923783a5085148e3ff028d97134ea52f5a08bd87ecf1b0b043", @@ -112,7 +129,10 @@ "LINEAGE_VALIDATION.md": "bba9d0a859f1ba45670fe122e4e72ae1094a2226de98aa814d838b0baaf61815", "ResearchFormalCoreR1/WeightPerturbation.lean": "50ce15709a133da12a0b4333cc653d26c5fd8a412976c975a7c2f3b25ed5c00f", "WEIGHT_PERTURBATION.md": "0ac969b86f5b2cc4e84b4bb61790c7497164b923dc5f3fc5be99195b75b1b212", - "tests/test_weight_perturbation.py": "a83f272236a2d315d20561b862c952963b825c24baef42972f368eba11a897d7", - "evidence/weight-perturbation-initial-build-failure.log": "2abe4ec4bcfa4de282e7983ffebb225af21308c60b84083a1696bcced31b9c7c" + "tests/test_weight_perturbation.py": "e5400fec9d7a0cfeb7669689375184a04e8748fed6c28f58d51cfe1529fbc75b", + "evidence/weight-perturbation-initial-build-failure.log": "2abe4ec4bcfa4de282e7983ffebb225af21308c60b84083a1696bcced31b9c7c", + "D2_SCHUR.md": "c25f4add4c92479ae0f6dfaac43fc9be7a71766f050a79acbc2c72acf47ef4d3", + "ResearchFormalCoreR1/D2Schur.lean": "d3fb3ed7b4043227f1d5a06e208de9d94eb413c067e9d0f8802388407c9e15b9", + "tests/test_d2_schur.py": "3463a1865809735ee59d0042d2a9049eb4c2cad7beb4f01ca173475c33cb1589" } } diff --git a/formal/tests/test_d2_schur.py b/formal/tests/test_d2_schur.py new file mode 100644 index 000000000..2801b961b --- /dev/null +++ b/formal/tests/test_d2_schur.py @@ -0,0 +1,137 @@ +"""Source wiring and exact finite controls; these do not execute Lean.""" +from fractions import Fraction as F +import hashlib +import itertools +import json +from pathlib import Path +import re +import unittest + +ROOT = Path(__file__).resolve().parents[1] +MODULE = 'ResearchFormalCoreR1/D2Schur.lean' +NAMES = [ + 'd2_schur_numerator', 'd2_det_axis', 'd2_det_diagonal', + 'd2_det_interpolation', 'd2_schur_ratio', 'd2_numerator_pos', + 'd2_det_pos', 'd2_schur_pos', 'd2_det_le_endpoint_max', + 'd2_schur_endpoint_lower', 'd2_tau_cumulant_eq', 'd2_tau_axis', + 'd2_tau_diagonal', 'd2_tau_pos', 'd2_gaussian_control', + 'd2_degenerate_control', +] + + +def det3(a): + return sum(((-1 if (i, j, k) in ((0, 2, 1), (1, 0, 2), (2, 1, 0)) else 1) + * a[0][i]*a[1][j]*a[2][k] + for i,j,k in itertools.permutations(range(3))), F(0)) + + +class D2SchurTests(unittest.TestCase): + def source(self): + self.assertTrue((ROOT/MODULE).is_file(), 'D2Schur Lean implementation absent') + return (ROOT/MODULE).read_text() + + def test_exact_declarations(self): + self.assertEqual(re.findall(r'^theorem\s+([A-Za-z_][A-Za-z0-9_]*)', self.source(), re.M), NAMES) + + def test_no_proof_holes_or_native_shortcut(self): + text = self.source() + for forbidden in ('sorry', 'admit', 'native_decide', 'axiom ', 'unsafe '): + self.assertNotIn(forbidden, text) + self.assertIn('(hD : d2DetV m2 m4 q ≠ 0)', text) + self.assertIn('(hm4 : m2 ^ 2 < m4)', text) + self.assertIn('(hDelta : 0 < d2Delta m2 m4 m6)', text) + + def test_manifest_exact_extension(self): + self.assertTrue((ROOT/'manifest.json').is_file(), 'manifest absent') + m = json.loads((ROOT/'manifest.json').read_text()) + self.assertEqual(m['targets'][47:], ['ResearchFormalCoreR1.'+n for n in NAMES]) + self.assertEqual(len(m['targets']), 63) + self.assertEqual(m['source_modules'][-1], MODULE) + self.assertEqual(m['alignment_status'], 'PENDING_INDEPENDENT_REVIEW') + self.assertEqual(m['scientific_effect'], 'NONE') + for path in (MODULE, 'D2_SCHUR.md', 'tests/test_d2_schur.py'): + self.assertEqual(hashlib.sha256((ROOT/path).read_bytes()).hexdigest(), m['files'][path]) + self.assertEqual(m['files']['gate.py'], + '958b149ea3a4ce735644a2079f817b5deddf5dc0d5ca347904ad09db6ad47d68') + self.assertEqual(m['files']['ResearchFormalCoreR1/WeightPerturbation.lean'], + '50ce15709a133da12a0b4333cc653d26c5fd8a412976c975a7c2f3b25ed5c00f') + + def test_import_and_blueprint_wiring(self): + self.assertTrue((ROOT/'ResearchFormalCoreR1.lean').is_file(), 'root absent') + self.assertIn('import ResearchFormalCoreR1.D2Schur\n', (ROOT/'ResearchFormalCoreR1.lean').read_text()) + text = (ROOT/'blueprint/src/content.tex').read_text() + self.assertIn(r'\lean{ResearchFormalCoreR1.d2_schur_endpoint_lower}', text) + self.assertNotIn(r'\leanok', text) + + def test_independent_spectral_gram_rotations(self): + laws = [((F(1), F(1)),), + ((F(0), F(1,2)), (F(1), F(1,2))), + ((F(1), F(1,2)), (F(2), F(1,2))), + ((F(0), F(1,3)), (F(1), F(1,3)), (F(3), F(1,3))), + ((F(1,2), F(2,3)), (F(5,2), F(1,3)))] + count = 0 + for radial in laws: + atoms = [(sign*r, p/2) for r,p in radial for sign in (-1,1)] + moment = lambda n: sum((p*x**n for x,p in atoms), F(0)) + m2,m4,m6 = (moment(n) for n in (2,4,6)) + for t in (F(0), F(1,5), F(1,3), F(1,2), F(2,3), F(1), F(2)): + c,s=(1-t*t)/(1+t*t), 2*t/(1+t*t) + q=c*c*s*s; k=m4-3*m2*m2 + gram=[[F(0) for _ in range(3)] for _ in range(3)] + for (x,px),(y,py) in itertools.product(atoms, repeat=2): + u,w=c*x+s*y,-s*x+c*y + vals=(u*u,u*w,w*w) + for i,j in itertools.product(range(3),repeat=2): + gram[i][j] += px*py*vals[i]*vals[j] + D=gram[0][0]*gram[1][1]-gram[0][1]**2 + formula=m2*m2*m4+k*(m4+m2*m2)*q + numerator=m2*m2*(m4*m4-m2**4) + self.assertEqual(D,formula) + self.assertEqual(det3(gram),numerator) + if D>0: + cross=(gram[0][2],gram[1][2]) + schur=gram[2][2]-(gram[1][1]*cross[0]**2-2*gram[0][1]*cross[0]*cross[1]+gram[0][0]*cross[1]**2)/D + self.assertEqual(schur,numerator/D) + count+=1 + self.assertEqual(count,35) + + def test_all_endpoint_inequalities_on_rational_controls(self): + count=0 + for m2 in (F(1,3),F(1),F(2)): + for excess,delta in itertools.product((F(1,7),F(1),F(4)),repeat=2): + m4=m2*m2+excess; m6=m4*m4/m2+delta + A=m2*m2*m4; B=(m4-m2*m2)*(m4+3*m2*m2)/4 + N=m2*m2*(m4*m4-m2**4) + for q in (F(0),F(1,32),F(1,8),F(7,32),F(1,4)): + D=A+(m4-3*m2*m2)*(m4+m2*m2)*q + T=delta+q*(9*m2*excess-3*delta) + self.assertEqual(D,(1-4*q)*A+4*q*B) + self.assertGreater(D,0); self.assertGreater(T,0) + self.assertLessEqual(D,max(A,B)) + self.assertLessEqual(N/max(A,B),N/D) + count+=1 + self.assertEqual(count,135) + + def test_gaussian_reference_and_required_denominator_guard(self): + for q in (F(0),F(1,8),F(1,4)): + self.assertEqual(F(1)**2*(F(3)**2-F(1)**4)/3,F(8,3)) + m2=m4=F(1); q=F(1,4); k=m4-3*m2*m2 + alpha=m4-2*k*q; gamma=m2*m2+2*k*q + D=m2*m2*m4+k*(m4+m2*m2)*q + self.assertEqual((D,alpha,gamma),(F(0),F(2),F(0))) + # Lean's total division gives 0/0=0; at this singular input the + # subtractive expression is 2 but the numerator/determinant ratio is 0. + self.assertNotEqual(alpha,F(0)) + + def test_wrong_sign_and_missing_soft_factor_are_detected(self): + m2,m4,q=F(1),F(2),F(1,8) + D=m2*m2*m4+(m4-3*m2*m2)*(m4+m2*m2)*q + wrong=m2*m2*m4-(m4-3*m2*m2)*(m4+m2*m2)*q + self.assertNotEqual(D,wrong) + N=m2*m2*(m4*m4-m2**4) + self.assertNotEqual(N,m2*m2*m4*m4) + self.assertEqual((m4-m2*m2)*(m4+3*m2*m2)/4,F(5,4)) + + +if __name__=='__main__': + unittest.main() diff --git a/formal/tests/test_weight_perturbation.py b/formal/tests/test_weight_perturbation.py index f411c2450..d3b6c1cc5 100644 --- a/formal/tests/test_weight_perturbation.py +++ b/formal/tests/test_weight_perturbation.py @@ -46,8 +46,8 @@ def test_module_and_exact_declarations(self): def test_exact_extension_inventory(self): m = json.loads((ROOT/'manifest.json').read_text()) - self.assertEqual(m['targets'][40:], ['ResearchFormalCoreR1.'+n for n in NAMES]) - self.assertEqual(len(m['targets']), 47) + self.assertEqual(m['targets'][40:47], ['ResearchFormalCoreR1.'+n for n in NAMES]) + self.assertGreaterEqual(len(m['targets']), 47) self.assertIn(MODULE, m['source_modules']) def test_source_scope_and_tests_are_bound(self):