Skip to content

feat(Analysis/Polynomial): certified Sturm chains from a PRS certificate - #42559

Open
AMcRoberts wants to merge 5 commits into
leanprover-community:masterfrom
AMcRoberts:sturm-certificate
Open

feat(Analysis/Polynomial): certified Sturm chains from a PRS certificate#42559
AMcRoberts wants to merge 5 commits into
leanprover-community:masterfrom
AMcRoberts:sturm-certificate

Conversation

@AMcRoberts

Copy link
Copy Markdown

Stacked on #42558 — this branch is sturm-abstract plus one more commit,
so the diff will include both PRs' changes until #42558 merges. Only the
second commit (SturmCertificate.lean + its test file) belongs to this PR;
please review that commit specifically until #42558 lands, at which point
this diff will shrink to just this PR's content.


CertifiedSturmChain packages the algebraic data a Euclidean or
pseudo-remainder-sequence construction naturally produces (a positive-scaled
recurrence at each step, a nonzero-constant Bézout identity between p and
its derivative, and a nonzero-constant terminal element) and proves it
satisfies IsSturmSequence (#42558), so a concrete PRS chain can drive
Sturm's root-count theorem directly without re-deriving the sign semantics
per instance.

This development was produced independently from the classical sources
cited in the module's own ## References section, without consulting the
formalisation cited by #42558.

We introduce Sturm sequences for real polynomials and prove Sturm's
theorem: the number of sign variations of the sequence decreases by
exactly the number of distinct roots crossed on a half-open interval.
The development follows the structure of Manuel Eberl's AFP entry
*A Formalisation of Sturm's Theorem* (2014); see the module's own
References section.
@github-actions github-actions Bot added the new-contributor This PR was made by a contributor with at most 5 merged PRs. Welcome to the community! label Aug 8, 2026
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

Welcome new contributor!

Thank you for contributing to Mathlib! If you haven't done so already, please review our contribution guidelines, as well as the style guide and naming conventions. In particular, we kindly remind contributors that we have guidelines regarding the use of AI when making pull requests.

We use a review queue to manage reviews. If your PR does not appear there, it is probably because it is not successfully building (i.e., it doesn't have a green checkmark), has the awaiting-author tag, or another reason described in the Lifecycle of a PR. The review dashboard has a dedicated webpage which shows whether your PR is on the review queue, and (if not), why.

If you haven't already done so, please come to https://leanprover.zulipchat.com/, introduce yourself, and mention your new PR.

Thank you again for joining our community.

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

PR summary a229300f32

Import changes for modified files

No significant changes to the import graph

Import changes for all files
Files Import difference
Mathlib.Analysis.Polynomial.Sturm (new file) 1673
Mathlib.Analysis.Polynomial.SturmCertificate (new file) 1941

Declarations diff (regex)

+ CertifiedSturmChain
+ CertifiedSturmChain.count_roots_between
+ CertifiedSturmChain.toIsSturmSequence
+ IsQuasiSturmSequence
+ IsQuasiSturmSequence.tail
+ IsSturmSequence
+ IsSturmSequence.count_roots_between
+ IsSturmSequence.count_roots_between_empty
+ IsSturmSequence.exists_left_drop
+ IsSturmSequence.p_zero
+ bezout_nonzero_constant_no_common_real_root
+ constant_of_eventually_locally_constant_Icc
+ constant_terminal_sign
+ destutter'_append
+ eventually_ne_zero_nhdsWithin
+ exists_delta_of_eventually_nhdsWithin_compl
+ finite_exists_min
+ getLastD_congr
+ ne_zero_of_sign_eq
+ positive_scaled_recurrence_sign_reversal
+ signList_eventually_eq
+ signList_eventually_eq'
+ sign_eval_eventually_eq
+ simple_root_derivative_punctured_sign
+ splitSturmVariations
+ splitSturmVariationsTotal
+ splitSturmVariationsTotalAt
+ splitSturmVariationsTotalAt_eq
+ splitSturmVariationsTotalAt_eventually_const
+ splitSturmVariationsTotalAt_self
+ sturmTestCertified
+ sturmTestChain
+ sturmTestP
+ sturmVariations
+ sturmVariations_core_triple
+ sturmVariations_distrib
+ sturmVariations_eventually_const
+ sturmVariations_eventually_const_of_all_ne
+ sturmVariations_nil
+ sturmVariations_pair_eventually_eq
+ sturmVariations_singleton
+ sturmVariations_sturm_triple

You can run this locally as follows
## from your `mathlib4` directory:
git clone https://github.com/leanprover-community/mathlib-ci.git ../mathlib-ci

## summary with just the declaration names:
../mathlib-ci/scripts/pr_summary/declarations_diff.sh <optional_commit>

## more verbose report:
../mathlib-ci/scripts/pr_summary/declarations_diff.sh long <optional_commit>

The doc-module for scripts/pr_summary/declarations_diff.sh in the mathlib-ci repository contains some details about this script.

Declarations diff (Lean)

Lean-aware diff — post-build, computed from the Lean environment (commit a229300).

  • +66 new declarations
  • −0 removed declarations
+Polynomial.CertifiedSturmChain
+Polynomial.CertifiedSturmChain.bezout
+Polynomial.CertifiedSturmChain.casesOn
+Polynomial.CertifiedSturmChain.count_roots_between
+Polynomial.CertifiedSturmChain.head_eq_p
+Polynomial.CertifiedSturmChain.length_ge_two
+Polynomial.CertifiedSturmChain.mk
+Polynomial.CertifiedSturmChain.ne_nil
+Polynomial.CertifiedSturmChain.rec
+Polynomial.CertifiedSturmChain.recOn
+Polynomial.CertifiedSturmChain.recurrence
+Polynomial.CertifiedSturmChain.second_eq_derivative
+Polynomial.CertifiedSturmChain.second_mem
+Polynomial.CertifiedSturmChain.terminal_constant
+Polynomial.CertifiedSturmChain.toIsSturmSequence
+Polynomial.IsQuasiSturmSequence
+Polynomial.IsQuasiSturmSequence.casesOn
+Polynomial.IsQuasiSturmSequence.last_sign_const
+Polynomial.IsQuasiSturmSequence.mk
+Polynomial.IsQuasiSturmSequence.ne_nil
+Polynomial.IsQuasiSturmSequence.rec
+Polynomial.IsQuasiSturmSequence.recOn
+Polynomial.IsQuasiSturmSequence.signs
+Polynomial.IsQuasiSturmSequence.tail
+Polynomial.IsSturmSequence
+Polynomial.IsSturmSequence.casesOn
+Polynomial.IsSturmSequence.count_roots_between
+Polynomial.IsSturmSequence.count_roots_between_empty
+Polynomial.IsSturmSequence.deriv_sign
+Polynomial.IsSturmSequence.exists_left_drop
+Polynomial.IsSturmSequence.head_eq_p
+Polynomial.IsSturmSequence.length_ge_two
+Polynomial.IsSturmSequence.mk
+Polynomial.IsSturmSequence.p_zero
+Polynomial.IsSturmSequence.rec
+Polynomial.IsSturmSequence.recOn
+Polynomial.IsSturmSequence.squarefree_pair
+Polynomial.IsSturmSequence.toIsQuasiSturmSequence
+Polynomial.bezout_nonzero_constant_no_common_real_root
+Polynomial.constant_of_eventually_locally_constant_Icc
+Polynomial.constant_terminal_sign
+Polynomial.eventually_ne_zero_nhdsWithin
+Polynomial.exists_delta_of_eventually_nhdsWithin_compl
+Polynomial.ne_zero_of_sign_eq
+Polynomial.positive_scaled_recurrence_sign_reversal
+Polynomial.signList_eventually_eq
+Polynomial.signList_eventually_eq'
+Polynomial.sign_eval_eventually_eq
+Polynomial.simple_root_derivative_punctured_sign
+Polynomial.splitSturmVariations
+Polynomial.splitSturmVariations.eq_def
+Polynomial.splitSturmVariations.induct
+Polynomial.splitSturmVariationsTotal
+Polynomial.splitSturmVariationsTotalAt
+Polynomial.splitSturmVariationsTotalAt_eq
+Polynomial.splitSturmVariationsTotalAt_eventually_const
+Polynomial.splitSturmVariationsTotalAt_self
+Polynomial.sturmVariations
+Polynomial.sturmVariations_core_triple
+Polynomial.sturmVariations_distrib
+Polynomial.sturmVariations_eventually_const
+Polynomial.sturmVariations_eventually_const_of_all_ne
+Polynomial.sturmVariations_nil
+Polynomial.sturmVariations_pair_eventually_eq
+Polynomial.sturmVariations_singleton
+Polynomial.sturmVariations_sturm_triple

No changes to strong technical debt.

Increase in weak tech debt: (relative, absolute) = (2.00, 0.00)
Current number Change Type (weak)
5051 2 exposed public sections

Current commit a229300f32
Reference commit 87adeaebd3

This script lives in the mathlib-ci repository. To run it locally, from your mathlib4 directory:

git clone https://github.com/leanprover-community/mathlib-ci.git ../mathlib-ci
../mathlib-ci/scripts/reporting/technical-debt-metrics.sh pr_summary
  • The relative value is the weighted sum of the differences with weight given by the inverse of the current value of the statistic.
  • The absolute value is the relative value divided by the total sum of the inverses of the current values (i.e. the weighted average of the differences).

@github-actions github-actions Bot added the t-analysis Analysis (normed *, calculus) label Aug 8, 2026
…rd_msgs)

Three real CI failures found and fixed:
- PR title had a capitalized subject; mathlib's title linter requires
  a lowercase first word.
- references.bib's new eberl2014sturm entry was in the wrong
  alphabetical position (bibtool's canonical sort wants it before
  Echenique2005, not after EinsiedlerWard2017) and left a stray blank
  line; applied the exact diff CI's own bibtool check computed.
- MathlibTest/Sturm.lean used bare #check without #guard_msgs, so its
  info-level output was flagged as an unexpected build failure; wrapped
  each #check with #guard_msgs and the exact expected output.
CertifiedSturmChain packages the algebraic data a Euclidean or
pseudo-remainder-sequence construction naturally produces (a
positive-scaled recurrence at each step, a nonzero-constant Bezout
identity between p and its derivative, and a nonzero-constant
terminal element) and proves it satisfies IsSturmSequence, so a
concrete PRS chain can drive Sturm's root-count theorem directly.

This development was produced independently from the classical
sources cited in the module's own References section, without
consulting the formalisation cited by the abstract theorem this
depends on (leanprover-community#42558).
…, guard_msgs)

Two real CI failures found and fixed, same root causes as the
sturm-abstract branch's own fix commit:
- references.bib's eisermann2012sturm entry left a stray double
  blank line before Eisenbud1995; bibtool's canonical form wants one.
- MathlibTest/SturmCertificate.lean used bare #check without
  #guard_msgs, so its info-level output was flagged as an unexpected
  build failure; wrapped each #check with #guard_msgs and the exact
  expected output.
…pacing

eisermann2012sturm had drifted back before Eisenbud1995 instead of after
it, pebayRojasThompson2022's author field lost its bibtool line-wrap, and
a stray blank line before perfect1969matroid crept back in from upstream
drift. Re-ran bibtool's canonical pass to restore all three.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-contributor This PR was made by a contributor with at most 5 merged PRs. Welcome to the community! t-analysis Analysis (normed *, calculus)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant