Skip to content

Restore Initial-dependent parameter guess resolution#4731

Closed
ChrisRackauckas-Claude wants to merge 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:agent/restore-symbolic-guess-resolution
Closed

Restore Initial-dependent parameter guess resolution#4731
ChrisRackauckas-Claude wants to merge 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:agent/restore-symbolic-guess-resolution

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member

This PR should be ignored until reviewed by @ChrisRackauckas.

Summary

  • Keep the IR-based variable-map substitution fast path.
  • If that path leaves a symbolic value, finish evaluation with the generic fixpoint substituter.
  • Add a regression test for an array parameter whose guess depends on Initial(X1 + X2).

Root cause

ModelingToolkitBase v1.48.1 introduced the specialized IRStructure/IRSubstituter path in #4674. IRSubstituter uses a filter that treats Symbolics.Operator calls such as Initial as atomic, while the prior generic fixpoint_sub path descends into those calls. As a result, an Initial-dependent parameter guess could remain symbolic and later fall back to a placeholder value.

For Catalyst systems with eliminated conserved species, that stored Γ = 1 instead of 3 and made the corresponding observed species 0 instead of 2. The regression boundary is ModelingToolkitBase 1.48.0 (correct) to 1.48.1 (incorrect); see #4721.

The fallback only runs when the IR result is still symbolic, so fully resolved values retain the specialized fast path.

Validation

  • Pure ModelingToolkitBase boundary reproduction on Julia 1.12.6:
    • v1.48.0: X2 stored = 2.0, Gamma stored = 3.0
    • v1.48.1: X2 stored = 0.0, Gamma stored = 1.0
  • Final fixed MWE, exit 0:
    • ModelingToolkitBase 1.51.0
    • X2 stored = 2.0
    • Gamma stored = 3.0
  • GROUP=Initialization julia +1.12 --project=. -e 'using Pkg; Pkg.test(; coverage=false)', isolated depot, exit 0:
    • Initialization | 795 passed, 12 broken, 807 total
    • ModelingToolkit tests passed
  • Catalyst master GROUP=Modeling, isolated depot, exit 0:
    • Conservation Laws | 250 passed, 17 broken, 267 total
    • Catalyst tests passed
  • Baseline Catalyst master with unmodified ModelingToolkit, exit 1:
    • Conservation Laws | 242 passed, 8 failed, 17 broken, 267 total
  • Repository-wide Runic --check ., exit 0.
  • git diff --check, exit 0.

Related downstream workaround: SciML/Catalyst.jl#1506. The separate released-Catalyst stale @test_broken failure is already fixed by SciML/Catalyst.jl#1495 and requires a Catalyst release.

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Investigation checkpoint for this commit:

The ReleaseTest failure is separate: released Catalyst v16.2.1 contains a stale @test_broken; SciML/Catalyst.jl#1495 already fixed it on Catalyst master. The same released-package failure is visible in https://github.com/SciML/SciMLBase.jl/actions/runs/29194023668/job/86653653225.

@ChrisRackauckas-Claude
ChrisRackauckas-Claude force-pushed the agent/restore-symbolic-guess-resolution branch from e83376c to 71a27e2 Compare July 12, 2026 22:21
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

CI checkpoint after the rebase:

  • The initialization fix itself remains locally verified: frozen Initialization 795 pass / 12 pre-existing broken, and Catalyst Modeling improves from 242 pass / 8 fail / 17 broken to 250 pass / 17 broken.
  • Most rebased red jobs resolved before NonlinearSolveQuasiNewton 1.14.0 entered General and fail on the independently reproduced 1.13.3 plus NonlinearSolveBase 2.34.0 maybe_pinv load error. The corrected pair was separately verified.
  • Exact clean current-master ModelingToolkitBase InterfaceII completed locally with 7234 pass / 2 errors / 4 pre-existing broken. The only errors are the unrelated BoundaryValueDiffEq MIRK dual-cache failures in Lotka-Volterra and cost-function compilation; existing upstream work is BoundaryValueDiffEq issue Change parameters in README #556 and draft PR build_function is allocating for StaticArrays #559.
  • Downgrade floor failures are being handled separately in ModelingToolkit PR Raise ModelingToolkitBase JumpProcesses floor to 9.27.0 (fix downgrade SSAIntegrator crash) #4710 and focused stacked follow-ups.

No observed failure points to the Initial-dependent guess substitution change, and no tests were skipped, silenced, or loosened.

@AayushSabharwal

Copy link
Copy Markdown
Member

This is not the correct fix. The issue is that calling fixpoint_sub directly uses a different filterer (Symbolics.FPSubFilterer) which will substitute inside operator calls by default. This is circumvented by constructing FixpointSubstituter from an IRSubstituter, since the former can't change the filterer in the latter. The correct fix is to pass filterer = Symbolics.FPSubFilterer{Nothing}() to IRSubstituter.

Pass `filterer = Symbolics.FPSubFilterer{Nothing}()` to the `IRSubstituter`
used in `evaluate_varmap!` so substitution descends into operator calls such
as `Initial`, matching the generic `fixpoint_sub` path. The default IR filterer
treats operators as atomic, which left `Initial`-dependent parameter guesses
unresolved (regression introduced in SciML#4674, ModelingToolkitBase v1.48.1).

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas-Claude
ChrisRackauckas-Claude force-pushed the agent/restore-symbolic-guess-resolution branch from 71a27e2 to 5cb0374 Compare July 13, 2026 09:36
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Thanks @AayushSabharwal — you're right, the fallback approach was papering over the wrong filterer. Updated to pass filterer = Symbolics.FPSubFilterer{Nothing}() to the IRSubstituter in evaluate_varmap! and dropped the fixpoint_sub fallback entirely.

Verified locally on Julia 1.12.4 against dev'd ModelingToolkitBase (Symbolics 7.24 / SymbolicUtils resolved):

  • With the filterer: X2 stored = 2.0, Gamma stored = 3.0 (PASS).
  • Counter-check — reverting just the filterer (back to the default IR filterer) fails the X2 == 2.0 assertion, confirming the filterer is what resolves the Initial-dependent guess.

Runic --check clean on the changed file. Force-pushed the amended commit (single-commit branch, no other contributors).

@AayushSabharwal

AayushSabharwal commented Jul 13, 2026

Copy link
Copy Markdown
Member

#4704 will fix this, so I'm closing the PR

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.

3 participants