Expand flow specifications over feature group arrays 🤖 - #3114
Open
lwrage wants to merge 2 commits into
Open
Conversation
A flow specification end reached through a feature group that is an array becomes a single flow specification instance on the first element of that group. The expansion decides whether an end is an array element from the index of the end itself, and a feature of a feature group type is never indexed: the index sits on the enclosing feature group instance. The model declares an array of feature groups on two devices, a flow source and a flow path over it on one and a flow sink on the other, a feature group connection that joins the two arrays, and an end to end flow over that connection. Connection instantiation already expands the connection across both elements, which the test asserts alongside the flows, so the assertions show the two sides disagreeing rather than a bare count. The flow specification assertion expects one instance per element, named and paired the way issue #2787 established for an end that is a feature array itself, and the end to end flow assertion expects one instance per element over the connection instance of that element. Both fail today with everything pinned to element 1 and nothing reported. The diagnostics assertion keeps the silence from being traded for a warning. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
An end reached through a feature group that is an array kept the first element of that group. The expansion decided whether an end was an array element from the index of the end itself, and a feature of a feature group type is never indexed, so the pairing was skipped and every element but the first was left without a flow specification instance, silently. Connection instantiation expands a connection across the elements of such a group, so the connection set and the flow specifications disagreed, and the end to end flows built over the flow specification instances inherited the disagreement. Find the array element an end belongs to by walking up from the end: the end itself when it is a feature array, and otherwise the enclosing feature group instance that carries the index, remembering the features that lead back down. The size of the dimension is the number of elements of that feature instance, and the element for a paired-up index is reached by taking the sibling with that index and following the remembered features down again. An end that is a feature array itself has an empty descent, so it behaves as before. At most one step of a path is indexed: a feature declared inside a feature group type may not be an array, so nothing below an indexed feature group instance is indexed in turn. The nearest indexed ancestor is therefore the only one. Nothing else needed a change. The pairing arithmetic does not care where an index came from, and the end to end flows already fork over the flow specification instances of a specification and keep a branch on its element by requiring the next connection instance to start exactly at the previous element's destination feature instance. The instance serializer characterization recorded the old behavior for the one array feature group in its fixture, so its f7 becomes f7_1 and f7_2. Its f6, an array declared inside a feature group type, is still a single feature and still a single flow. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3113
Cause and correction
FlowSpecArrayExpanderdecided whether a flow specification end was an array element by testingFeatureInstance.getIndex()on the end itself. A feature declared inside a feature group type is neverindexed — the index sits on the enclosing feature group instance — so an end reached through a feature
group that is an array looked like a scalar, the pairing was skipped, and every element but the first was
left without a flow specification instance. Nothing was reported.
ConnectionArrayExpanderalready treats an indexed enclosing feature group instance as a dimension of aconnection end, so the connection set covered every element while the flow specifications covered only
the first, and the end-to-end flows built over them inherited the disagreement.
The fix adds
arrayEnd, which walks up from an end to the indexed feature instance — the end itself whenit is a feature array, the enclosing feature group instance otherwise — recording the features that lead
back down. The dimension size is the number of elements of that feature instance, and
elementAttakesthe sibling with the paired-up index and follows the recorded features down again. A direct feature array
has an empty descent, so it behaves exactly as before.
At most one step of a path is ever indexed, because a feature declared inside a feature group type may not
be an array (AS5506D section 8 legality rule 3, enforced by the validator and reported by
InstantiateModel.instantiateFGFeatures). The nearest indexed ancestor is therefore the only one, whichthe code and its javadoc state explicitly.
Nothing else needed changing. The pairing arithmetic in
ArrayPatternExpansiondoes not care where anindex came from, and the end-to-end flows already fork over the flow specification instances of a
specification and keep a branch on its element by requiring the next connection instance to start exactly
at the previous element's destination feature instance.
Regression model and assertions
core/org.osate.core.tests/models/issue3113/Issue3113.aadldeclares an array of feature groups on twodevices, a flow source and a flow path over it on one and a flow sink on the other, a feature group
connection that joins the two arrays, and an end-to-end flow over that connection.
emithas one arrayend and
relayhas two, which is the pairing the defaultOne_To_Oneapplies to.Issue3113Testasserts:is a feature array itself:
emit_1/emit_2,relay_1/relay_2,absorb_1/absorb_2;ete_1andete_2, each over the connection instance of itsown element;
than a bare count;
Before the fix both tests failed with everything pinned to element 1: three flow specification instances
instead of six, and a single
ete. The connection assertion passed before the fix, which is whatlocalizes the defect to the flow side.
Supporting change
Serializer1Test.testFlowSpecificationrecorded the old behavior for the one array feature group in itsfixture, so its
f7becomesf7_1andf7_2. Itsf6, an array declared inside a feature group type, isstill instantiated as a single feature and still a single flow. Folded into the fix commit so that every
commit on the branch is green.
Validation
mvn -Dtest=Issue3113Test -DfailIfNoTests=false: 2/2 pass; both fail before the fix for the intendedreason.
org.osate.core.tests: 836 tests, 0 failures. Per-class non-zero counts confirmed forIssue2787Test(6),Issue1833Test(9),Issue3037ArrayFeatureGroupTest(7),Issue3037FeatureArrayTest(4),FlowSpecificationInstantiationTest(4),FeatureArrayInstantiationTest(3),FeatureGroupInstantiationTest(6),Issue3048Test,Issue3049Test.mvn -s releng/osate.releng/settings.xml -Plocal -Dtycho.localArtifacts=ignore -Dpr.build=true -Dsign=false -Dspotbugs=false -Dcodecoverage=false -Djavadoc=false -DfailIfNoTests=false clean install: BUILD SUCCESS, 2862 tests, 0 failures, 0 errors. Reproduced with-T6.Dependencies
None. Branched from
masterat 7729ae9 and independent of the other open issue branches.Residual risk
elementAtstill falls back to the original end when a lookup misses, as it always did, so an internalinconsistency would pin the element rather than fail. No diagnostic was added, to keep the fix narrow.
Nested feature group arrays are not a concern for the reason above: a feature inside a feature group type
may not be an array, so no path has two indexed steps. Note that
ConnectionArrayExpandercarries a singlefgidxand makes the same assumption.🤖 Generated with Claude Code