Skip to content

ST6RI-947 Remove model mutation in adapters for default multiplicity - #815

Merged
seidewitz merged 2 commits into
masterfrom
ST6RI-947
Oct 14, 2026
Merged

seidewitz merged 2 commits into
masterfrom
ST6RI-947

Conversation

@adaussy

@adaussy adaussy commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

This PR revises the implementation of default multiplicities for SysML so that they are not physically inserted into the model during getter operations. It also proactively resolves the following OMG issue, presuming that the adopted resolution to the issue will insert default multiplicities during parsing, not as implied members.

  • SYSML21-185 Default multiplicities are not formally specified

Background

The SysML Language Specification, subclause 7.6.3 Usages, describes three conditions for a SysML usage to have a default multiplicity of 1..1:

  1. The usage is an attribute usage, an item usage (including a part usage, except if it is a connection usage), or a port usage.
  2. The usage is owned by a definition or another usage (not a package).
  3. The usage does not have any explicit owned subsettings or owned redefinitions.

In addition, subclause 7.13.2 Connection Definitions and Usages states that

If a multiplicity is not explicitly declared for an end feature, then a default of 1..1 is implicitly declared for it (regardless of the usual conditions for default multiplicity given in 7.6.3).

However, as identified in SYSML21-185, there is no formal specification (in normative specification Clause 8) for inserting a default multiplicity based on the above criteria. Nevertheless, a default multiplicity mechanism was implemented, following the criteria, except for a modification to the third ("The usage does not have any explicit owned subsettings or owned redefinitions that have no owning type").

Previously, the default multiplicity mechanism used the adapter addAdditionalMembers method to physically add default multiplicities as necessary during the transformation of the relevant kinds of elements. But addAdditionalMembers was also being called in other places. For example, TypeAdapter.getFeaturesRedefinedByType called it before computing its cache. As a result, calling getFeature on a usage with an implicit Redefinition sometimes caused a mutation of the model as default multiplicities were added.

Impact

As a result of the situation described above, code that merely read features could change loaded models, making resolution tests and serialized expected models depend on getter call order.

Changes

The following changes resolve the problem of possibly mutating a model when a getter is called, consistent with the expected resolution to SYSML21-185.

  1. Moved the code for adding default multiplicity from adapter classes to post-processor classes.
  2. Removed the adding of default multplicities for criterion 3 above.

As previously, "adding a default multiplicity" means adding a Multiplicity element (not a MultiplicityRange) via an OwningMembership (not a FeatureMembership). The default multiplicity bounds are determined later by adding an implied specialization to Base::exactlyOne. This is not changed by the PR.

Move the initialization to the post processors instead of inserting the
multiplicity on demand.

Apply the ST6RI-774 decision to check only usage kind and ownership.
Subsettings and redefinitions no longer exclude defaults, and their
targets are never inspected during multiplicity preparation. Preserve
end defaults, explicit ranges, and the use of Multiplicity rather than
MultiplicityRange.
@seidewitz seidewitz self-assigned this Oct 9, 2026
@seidewitz seidewitz added this to the 2026-09 milestone Oct 9, 2026
@seidewitz seidewitz changed the title ST6RI-947 - Move multiplicity initialization to Post Processors ST6RI-947 Type.getFeature() mutates Usage models by materializing default Multiplicity Oct 9, 2026
@seidewitz
seidewitz self-requested a review October 9, 2026 15:49

@seidewitz seidewitz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functional revisions look good. The only place I would like to see some changes is in the unit test class MultiplicityPreparationTest. Rather than list the changes here, I have pushed a commit with a proposed update to this class.

  1. Removed the call that turned off use of the library index. Not using the index slows the test down considerably, and I don't understand what the benefit is.
  2. Took more advantage of the functionality available in SysMLInteractive. This simplifies the test code a bit. I had some ideas for making the test a true SysMLInteractiveTest, but, in the end, it didn't seem worth the time and effort to get it to work that way.
  3. Made some updates to other files:
    • Added getOwnedMultiplicitiesOf to TypeUtil, and used this method instead of your ownedMultiplicities method. This is a good utility method for future use.
    • Added setResource to SysMLInteractive.

The test results are the same as before the above changes. I have also checked that their are test failures if MultiplicityPreparationTest is run on the commit previous to this PR, which are fixed by the changes in the PR.

Please let me know if you concur.

Also:

- Removed turn-off of library index.
- Added getOwnedMultiplicitiesOf to TypeUtil.
- Added setResource to SysMLInteractive.
@adaussy

adaussy commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

The functional revisions look good. The only place I would like to see some changes is in the unit test class MultiplicityPreparationTest. Rather than list the changes here, I have pushed a commit with a proposed update to this class.

  1. Removed the call that turned off use of the library index. Not using the index slows the test down considerably, and I don't understand what the benefit is.

  2. Took more advantage of the functionality available in SysMLInteractive. This simplifies the test code a bit. I had some ideas for making the test a true SysMLInteractiveTest, but, in the end, it didn't seem worth the time and effort to get it to work that way.

  3. Made some updates to other files:

    • Added getOwnedMultiplicitiesOf to TypeUtil, and used this method instead of your ownedMultiplicities method. This is a good utility method for future use.
    • Added setResource to SysMLInteractive.

The test results are the same as before the above changes. I have also checked that their are test failures if MultiplicityPreparationTest is run on the commit previous to this PR, which are fixed by the changes in the PR.

Please let me know if you concur.

That looks good to me. Feel free to merge the PR whenever you're ready.

@seidewitz
seidewitz self-requested a review October 14, 2026 14:57
@seidewitz
seidewitz merged commit d69dbff into master Oct 14, 2026
2 checks passed
@seidewitz seidewitz changed the title ST6RI-947 Type.getFeature() mutates Usage models by materializing default Multiplicity ST6RI-947 Remove model mutation in adapters for default multiplicity Oct 14, 2026
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