Skip to content

Handle ArrayOp slices in renamespace - #5296

Draft
xtalax wants to merge 1 commit into
SciML:masterfrom
xtalax:renamespace-arrayop
Draft

xtalax wants to merge 1 commit into
SciML:masterfrom
xtalax:renamespace-arrayop

Conversation

@xtalax

@xtalax xtalax commented Oct 20, 2026

Copy link
Copy Markdown
Member

Summary

renamespace(sys, x) had @match arms only for Sym and Term, so a range slice of an array variable, which SymbolicUtils represents as an ArrayOp, failed with matching non-exhaustive. This adds an ArrayOp arm that renamespaces the slice's expr and term.

Why it matters

A broadcast over a slice, e.g. 2 .* u[1:3], lowers to an ArrayOp whose expr contains getindex(u(t)[1:3], _1). namespace_expr treats that getindex as a variable and passes it to renamespace, whose getindex branch recurses into the ArrayOp slice and errors. Any system with slice-form array equations therefore fails mtkcompile once it is used as a subsystem. Flat systems are unaffected.

MethodOfLines emits slice-form equations since SciML/MethodOfLines.jl#701, so every MethodOfLines-discretized system currently fails when nested in another system. This blocks composing a discretized PDE with lumped components (SciML/MethodOfLines.jl#726).

Relation to #5133

#5133 fixes the same mtkcompile failure on the caller side: namespace_expr stops renamespacing the getindex call. Both fix the nested-system case. This PR additionally makes a direct renamespace(sys, u[2:3]) work, which still errors under #5133. The two changes are independent and compatible; this one is offered as a complement, and can be closed if #5133 is preferred alone.

Tests

New Array slices testset in lib/ModelingToolkitBase/test/namespacing.jl: a direct renamespace of a slice, and a nested slice-form system that compiles and solves, matching the flat solution. Before the fix both error with matching non-exhaustive.

Run against this branch (rebased on master 9cde066) in an environment that develops the local ModelingToolkitBase, including each file directly:

File Result
namespacing.jl 24/24
variable_scope.jl 44/44
abstractsystem_interface.jl 73/73

The full test suite was not run locally. Runic --check passes on both changed files.

🤖 Posted by an AI agent · harness: Claude Code 2.1.305 · model: claude-opus-5-5
Review: unreviewed
Session: fe6e5fd4-da2b-43af-8f0d-e3c4ab662c0d

SymbolicUtils represents a range slice of an array variable, e.g.
`u(t)[1:3]`, as an ArrayOp with `expr = getindex(u(t), _1)` and
`term = getindex(u(t), 1:3)`. A broadcast over a slice contains
`getindex(slice, _1)`, which `namespace_expr` treats as a variable and
passes to `renamespace`. Its getindex branch then calls `renamespace` on
the ArrayOp slice, which had no match arm and failed with "matching
non-exhaustive". Any system with slice-form array equations therefore
failed `mtkcompile` once used as a subsystem.

Add an ArrayOp arm that renamespaces `expr` and `term` and rebuilds the
ArrayOp. `renamespace` only receives variable-like expressions; for a
variable slice both fields are getindex Terms handled by the existing
arm, so no general expression traversal is needed. Arithmetic ArrayOps
are not variables and still go through `namespace_expr`.

Tests cover the direct `renamespace` call on a slice and compile and
solve a slice-form system as a subsystem, checking it against the flat
system's solution.

Agent-Harness: Claude Code 2.1.303
Agent-Model: claude-opus-5-5
Agent-Session: fe6e5fd4-da2b-43af-8f0d-e3c4ab662c0d
Agent-Review: unreviewed
Co-authored-by: Claude Code <agent@noreply.juliahub.com>

This branch has not been deployed

No deployments
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.

1 participant