Skip to content

Retire unreachable symbolic compatibility ranges - #73

Merged
ChrisRackauckas merged 1 commit into
SciML:mainfrom
ChrisRackauckas-Claude:agent/fsp-symbolic-public-floors
Jul 22, 2026
Merged

Retire unreachable symbolic compatibility ranges#73
ChrisRackauckas merged 1 commit into
SciML:mainfrom
ChrisRackauckas-Claude:agent/fsp-symbolic-public-floors

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member

Ignore this PR until it has been reviewed by @ChrisRackauckas.

Summary

  • retire symbolic compatibility ranges that are unreachable under the package's simultaneous ModelingToolkitBase dependency
  • replace non-public or re-export-only symbolic access with APIs exported by their declaring packages
  • preserve the documented build_ratefuncs return contract while compiling rate functions through public Symbolics.build_function
  • add regression coverage for the compatibility floors, symbolic parameter names, generated rate expressions/callables, and transient RHS/matrix equivalence

Why these floors

ModelingToolkitBase 1 already requires SymbolicUtils 4.6+ and Symbolics 7.1.1+.
Consequently, the old SymbolicUtils 1/2/3 and Symbolics 5/6 declarations were
dead ranges rather than usable transition support. Catalyst 15 is also
incompatible with ModelingToolkitBase 1 because its Symbolics constraint stops
at major 6.

The SciML downgrade workflow selected the direct floors recorded here:

  • Catalyst 16.2
  • ModelingToolkitBase 1.17
  • SciMLBase 2.144 (while retaining major 3)
  • SymbolicIndexingInterface 0.3.43
  • Symbolics 7.13
  • SymbolicUtils 4.18

This is constraint normalization and public-API repair, not an age-based
retirement.

Public API changes inside the implementation

The implementation now consumes owner-exported Symbolics.@variables,
Symbolics.build_function, SymbolicUtils.substitute,
SymbolicIndexingInterface.getname,
RuntimeGeneratedFunctions.@RuntimeGeneratedFunction, and
ModelingToolkitBase.parameters. It no longer reaches through
SymbolicUtils.Code.toexpr, SymbolicUtils.scalarize, Symbolics.value,
symbolic .name fields, or method-table .mt.name internals.

build_ratefuncs still returns Julia Expr bodies as documented. An internal
wrapper carries the compiled runtime-generated callable and the same expression
needed by RHS code generation. No FiniteStateProjection public name was added or
changed, so the existing rendered documentation remains accurate.

Validation

  • Julia 1.12.6 current graph:
    • focused symbolic regression: 11/11
    • GROUP=Core: 58/58
    • GROUP=QA: 20/20
  • Julia 1.10.11 canonical direct-symbolic floor graph:
    • GROUP=Core Pkg.test(; allow_reresolve=false): 58/58
    • all six owner-export API assertions passed
  • Julia 1.10.11 QA under the separately resolved candidate-compat nested graph:
    18/18
  • exact Distributions 0.25.88 supporting stack: 50 dependencies strictly
    precompiled; runtime and extension checks passed
  • fixed-Xoshiro clean-base/candidate comparison: 78/78 extracted lines,
    byte-for-byte identical
  • Runic: 15/15 files
  • git diff --check, public-owner scan, and TOML floor assertions passed

The canonical direct-floor Manifest remained unchanged at SHA-256
e66312cd36f422cd8cf33644040deb6eb1665efa0a52cde999263f36f7cb88e4.

One exploratory whole-root Pkg.precompile(; strict=true); Pkg.build() command
is explicitly non-authoritative and retained as a failed diagnostic. It cannot
root Distributions because that package is test-only under [extras]; build
was not reached. The official locked Core run and the separate exact
Distributions/Rmath strict probe are the relevant validation paths.

Known pre-existing issue

The independent clean-main investigation found an intermittent randomized
SSRootfind normalization defect and opened
#72. It is outside this
patch. The final Core runs passed, and the fixed-RNG clean/candidate outputs were
byte-identical.

Project.toml is already on unreleased 0.4.0. No version change is included;
the pre-1.0 compatibility narrowing belongs in that minor release.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Post-creation scratchpad comment

Implementation/evidence checkpoint for commit
bcba92ff5721822855739fbb5778f8b0d6223968:

  1. Resolver analysis showed that the removed ranges were unreachable under the
    simultaneous graph. ModelingToolkitBase 1 starts at SymbolicUtils 4.6+ and
    Symbolics 7.1.1+; Catalyst 15's Symbolics 6 range cannot coexist with it.
  2. The SciML downgrade workflow (SciML/.github v1 at
    f8bbdfe74f4c95803c7b678812afdbca8a066f5e, julia-downgrade-compat v2 at
    fab1defb76df9fd672f63c94df73ce131d32e134) selected direct floors Catalyst
    16.2.0, ModelingToolkitBase 1.17.0, SciMLBase 2.144.0,
    SymbolicIndexingInterface 0.3.43, Symbolics 7.13.0, and SymbolicUtils 4.18.0.
  3. The code uses only names exported by their owner modules. A Julia 1.10 exact
    floor probe verified all six owner exports at runtime.
  4. build_ratefuncs remains an Expr-returning API; the internal wrapper is an
    implementation detail. The new test locks this contract and direct/rhs
    behavior.
  5. Current Julia 1.12 validation passed: focused 11/11, Core 58/58, QA 20/20.
    Canonical direct-floor Julia 1.10 Core passed 58/58. Julia 1.10 QA passed
    18/18 under its nested candidate-compat graph, whose Manifest SHA-256 is
    c7e8d1cee879446750367959570646c45f01c2658e96f99d85b5166cac7d4728.
  6. The canonical direct-floor Manifest remained byte-identical at
    e66312cd36f422cd8cf33644040deb6eb1665efa0a52cde999263f36f7cb88e4.
  7. The exact Distributions 0.25.88 / StatsFuns 1.5.2 / Rmath 0.9.0 supporting
    stack strictly precompiled 50 dependencies and passed runtime/extension
    checks.
  8. Fixed-RNG clean/candidate diagnostics matched byte-for-byte across 78
    extracted lines. Runic passed 15/15; static and TOML checks passed.
  9. DIAGNOSTIC-UNSUPPORTED-root-strict-precompile-unrooted-test-extras-julia1.10.log
    is not a passing or authoritative gate. Whole-root strict precompile exited 1
    because [extras] does not make Distributions root-loadable; build was not
    reached. The failure is retained without being caught or silenced.
  10. The independent clean-main randomized steady-state investigation is tracked
    at SteadyStateProblem(FSPSystem, ...) is underdetermined and SSRootfind can return the zero vector #72 and is not
    modified by this patch.

The branch was prepared from the then-current origin/main; the worktree was
clean after the commit and the required Chris Rackauckas co-author trailer is
present. Publication was intentionally left to the parent workflow.

@ChrisRackauckas
ChrisRackauckas marked this pull request as ready for review July 22, 2026 20:39
@ChrisRackauckas
ChrisRackauckas merged commit 991fd30 into SciML:main Jul 22, 2026
8 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants