diff --git a/.editorconfig b/.editorconfig
index 20935edd..86fce5ad 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -6,4 +6,6 @@ dotnet_diagnostic.S3776.severity = none
# Disable CS1570/CS1584/CS1658 for all codegen
dotnet_diagnostic.CS1570.severity = none
dotnet_diagnostic.CS1584.severity = none
-dotnet_diagnostic.CS1658.severity = none
\ No newline at end of file
+dotnet_diagnostic.CS1658.severity = none
+# Disable CA1815: generated value types carry data only; equality semantics are not part of their contract
+dotnet_diagnostic.CA1815.severity = none
\ No newline at end of file
diff --git a/SysML2.NET.CodeGenerator.Tests/Generators/UmlHandleBarsGenerators/ImpliedGuardParserTestFixture.cs b/SysML2.NET.CodeGenerator.Tests/Generators/UmlHandleBarsGenerators/ImpliedGuardParserTestFixture.cs
new file mode 100644
index 00000000..715eb53f
--- /dev/null
+++ b/SysML2.NET.CodeGenerator.Tests/Generators/UmlHandleBarsGenerators/ImpliedGuardParserTestFixture.cs
@@ -0,0 +1,195 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.CodeGenerator.Tests.Generators.UmlHandleBarsGenerators
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.CodeGenerator.Extensions;
+
+ using uml4net.Classification;
+ using uml4net.SimpleClassifiers;
+ using uml4net.StructuredClassifiers;
+
+ [TestFixture]
+ public class ImpliedGuardParserTestFixture
+ {
+ ///
+ /// The metaclass names an owning-Type kind test over two alternatives yields.
+ ///
+ private static readonly string[] ExpectedPartTypeNames = ["PartDefinition", "PartUsage"];
+
+ ///
+ /// The metaclass name an owned-typing kind test yields.
+ ///
+ private static readonly string[] ExpectedDataTypeNames = ["DataType"];
+
+ [Test]
+ public void VerifyParse()
+ {
+ using (Assert.EnterMultipleScope())
+ {
+ var owningTypeKind = ImpliedGuardParser.Parse("isComposite and owningType <> null and (owningType.oclIsKindOf(PartDefinition) or owningType.oclIsKindOf(PartUsage))");
+ Assert.That(owningTypeKind.Shape, Is.EqualTo(ImpliedGuardShape.OwningTypeKind));
+ Assert.That(owningTypeKind.RequiresComposite, Is.True);
+ Assert.That(owningTypeKind.TypeNames, Is.EqualTo(ExpectedPartTypeNames));
+
+ var withoutComposite = ImpliedGuardParser.Parse("owningType <> null and (owningType.oclIsKindOf(ViewDefinition) or owningType.oclIsKindOf(ViewUsage))");
+ Assert.That(withoutComposite.Shape, Is.EqualTo(ImpliedGuardShape.OwningTypeKind));
+ Assert.That(withoutComposite.RequiresComposite, Is.False);
+
+ var operationCall = ImpliedGuardParser.Parse("isSubactionUsage()");
+ Assert.That(operationCall.Shape, Is.EqualTo(ImpliedGuardShape.OperationCall));
+ Assert.That(operationCall.MemberName, Is.EqualTo("isSubactionUsage"));
+ Assert.That(operationCall.IsNegated, Is.False);
+
+ var negated = ImpliedGuardParser.Parse("not isTriggerAction()");
+ Assert.That(negated.Shape, Is.EqualTo(ImpliedGuardShape.OperationCall));
+ Assert.That(negated.IsNegated, Is.True);
+
+ var withArgument = ImpliedGuardParser.Parse("isSubstateUsage(true)");
+ Assert.That(withArgument.Shape, Is.EqualTo(ImpliedGuardShape.OperationCall));
+ Assert.That(withArgument.Literal, Is.EqualTo("true"));
+
+ var endCount = ImpliedGuardParser.Parse("ownedEndFeature->size() = 2");
+ Assert.That(endCount.Shape, Is.EqualTo(ImpliedGuardShape.OwnedEndFeatureCount));
+ Assert.That(endCount.Literal, Is.EqualTo("2"));
+
+ var notEmpty = ImpliedGuardParser.Parse("ownedEndFeatures->notEmpty()");
+ Assert.That(notEmpty.Shape, Is.EqualTo(ImpliedGuardShape.OwnedEndFeatureCount));
+ Assert.That(notEmpty.Literal, Is.Null);
+
+ var ownedTyping = ImpliedGuardParser.Parse("ownedTyping.type->exists(selectByKind(DataType))");
+ Assert.That(ownedTyping.Shape, Is.EqualTo(ImpliedGuardShape.OwnedTypingKind));
+ Assert.That(ownedTyping.TypeNames, Is.EqualTo(ExpectedDataTypeNames));
+
+ var membership = ImpliedGuardParser.Parse("owningFeatureMembership <> null and owningFeatureMembership.oclIsKindOf(StakeholderMembership)");
+ Assert.That(membership.Shape, Is.EqualTo(ImpliedGuardShape.OwningFeatureMembershipKind));
+
+ var enumeration = ImpliedGuardParser.Parse("portionKind = PortionKind::timeslice");
+ Assert.That(enumeration.Shape, Is.EqualTo(ImpliedGuardShape.EnumerationComparison));
+ Assert.That(enumeration.MemberName, Is.EqualTo("portionKind"));
+ Assert.That(enumeration.Literal, Is.EqualTo("timeslice"));
+
+ var booleanProperty = ImpliedGuardParser.Parse("isIndividual");
+ Assert.That(booleanProperty.Shape, Is.EqualTo(ImpliedGuardShape.BooleanProperty));
+
+ // Multi-line OCL from the XMI must normalise before matching.
+ var multiLine = ImpliedGuardParser.Parse("owningType <> null and\n (owningType.oclIsKindOf(Behavior) or\n owningType.oclIsKindOf(Step))");
+ Assert.That(multiLine.Shape, Is.EqualTo(ImpliedGuardShape.OwningTypeKind));
+ }
+ }
+
+ [Test]
+ public void VerifyParseRejectsWhatItCannotTranslate()
+ {
+ using (Assert.EnterMultipleScope())
+ {
+ // A nested oclAsType navigation is beyond the recognised shapes and must NOT be approximated.
+ var nested = ImpliedGuardParser.Parse("isComposite and owningType <> null and (owningType.oclIsKindOf(Structure) or owningType.oclIsKindOf(Feature) and owningType.oclAsType(Feature).type->exists(oclIsKindOf(Structure)))");
+ Assert.That(nested.Shape, Is.EqualTo(ImpliedGuardShape.RequiresHandCoding));
+
+ // An extra conjunct beyond the recognised owner-kind shape likewise falls back.
+ var extraConjunct = ImpliedGuardParser.Parse("isComposite and owningType <> null and (owningType.oclIsKindOf(StateDefinition) or owningType.oclIsKindOf(StateUsage)) and source <> null and source.oclIsKindOf(StateUsage)");
+ Assert.That(extraConjunct.Shape, Is.EqualTo(ImpliedGuardShape.RequiresHandCoding));
+
+ Assert.That(ImpliedGuardParser.Parse(null).Shape, Is.EqualTo(ImpliedGuardShape.RequiresHandCoding));
+ Assert.That(ImpliedGuardParser.Parse(string.Empty).Shape, Is.EqualTo(ImpliedGuardShape.RequiresHandCoding));
+ Assert.That(ImpliedGuardParser.Parse(" ").Shape, Is.EqualTo(ImpliedGuardShape.RequiresHandCoding));
+ }
+ }
+
+ ///
+ /// Pins how much of the REAL constraint set the parser covers, so a regression in the patterns shows
+ /// up as a coverage drop rather than silently shifting guards into hand-coding.
+ ///
+ [Test]
+ public void VerifyCoverageOfTheActualConstraintSet()
+ {
+ var guarded = GeneratorSetupFixture.XmiReaderResult
+ .QueryImpliedRelationshipRules()
+ .Where(rule => rule.Form == ImpliedRuleForm.GuardedLibrarySpecialization)
+ .ToList();
+
+ var parsed = guarded
+ .Select(rule => ImpliedGuardParser.Parse(rule.GuardExpression))
+ .ToList();
+
+ var translatable = parsed.Count(expression => expression.Shape != ImpliedGuardShape.RequiresHandCoding);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(guarded, Has.Count.EqualTo(63), "The number of guarded constraints in the abstract syntax changed.");
+ Assert.That(translatable, Is.EqualTo(46), "Guard-shape coverage changed; re-check the patterns against the OCL.");
+ }
+ }
+
+ ///
+ /// Emits a predicate for every translatable guard in the real constraint set, so a shape that parses
+ /// but cannot be rendered — an unknown metaclass, say — is caught here rather than as a compile
+ /// failure in the generated assembly.
+ ///
+ [Test]
+ public void VerifyEveryTranslatableGuardEmitsAPredicate()
+ {
+ var interfaceFqnByName = QueryInterfaceFqnByName();
+ var enumerationFqnByName = QueryEnumerationFqnByName();
+
+ var unrenderable = GeneratorSetupFixture.XmiReaderResult
+ .QueryImpliedRelationshipRules()
+ .Where(rule => rule.Form == ImpliedRuleForm.GuardedLibrarySpecialization)
+ .Select(rule => new
+ {
+ rule.ConstraintName,
+ rule.MetaclassName,
+ Expression = ImpliedGuardParser.Parse(rule.GuardExpression)
+ })
+ .Where(candidate => candidate.Expression.Shape != ImpliedGuardShape.RequiresHandCoding)
+ .Where(candidate => !interfaceFqnByName.TryGetValue(candidate.MetaclassName, out var declaringFqn)
+ || ImpliedGuardEmitter.Emit(candidate.Expression, declaringFqn, interfaceFqnByName, enumerationFqnByName) == null)
+ .Select(candidate => candidate.ConstraintName)
+ .ToList();
+
+ Assert.That(unrenderable, Is.Empty, $"These guards parse but emit no predicate: {string.Join(", ", unrenderable)}");
+ }
+
+ private static Dictionary QueryInterfaceFqnByName()
+ {
+ return GeneratorSetupFixture.XmiReaderResult
+ .QueryContainedAndImported("SysML")
+ .SelectMany(package => package.PackagedElement.OfType())
+ .GroupBy(umlClass => umlClass.Name, StringComparer.Ordinal)
+ .ToDictionary(group => group.Key, group => group.First().QueryFullyQualifiedTypeName(), StringComparer.Ordinal);
+ }
+
+ private static Dictionary QueryEnumerationFqnByName()
+ {
+ return GeneratorSetupFixture.XmiReaderResult
+ .QueryContainedAndImported("SysML")
+ .SelectMany(package => package.PackagedElement.OfType())
+ .GroupBy(enumeration => enumeration.Name, StringComparer.Ordinal)
+ .ToDictionary(group => group.Key, group => group.First().QueryFullyQualifiedTypeName(), StringComparer.Ordinal);
+ }
+ }
+}
diff --git a/SysML2.NET.CodeGenerator.Tests/Generators/UmlHandleBarsGenerators/ImpliedRelationshipExtensionsTestFixture.cs b/SysML2.NET.CodeGenerator.Tests/Generators/UmlHandleBarsGenerators/ImpliedRelationshipExtensionsTestFixture.cs
new file mode 100644
index 00000000..0070af2a
--- /dev/null
+++ b/SysML2.NET.CodeGenerator.Tests/Generators/UmlHandleBarsGenerators/ImpliedRelationshipExtensionsTestFixture.cs
@@ -0,0 +1,89 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.CodeGenerator.Tests.Generators.UmlHandleBarsGenerators
+{
+ using System.Linq;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.CodeGenerator.Extensions;
+
+ [TestFixture]
+ public class ImpliedRelationshipExtensionsTestFixture
+ {
+ [Test]
+ public void VerifyQueryImpliedRelationshipRules()
+ {
+ var rules = GeneratorSetupFixture.XmiReaderResult.QueryImpliedRelationshipRules();
+
+ using (Assert.EnterMultipleScope())
+ {
+ // Only `check` rules are semantic constraints. `derive` rules are derivations and `validate`
+ // rules are validation constraints (KerML §8.3.1); neither implies a Relationship, and both
+ // carry the same category keywords in their names, so they must not leak in.
+ Assert.That(rules.Select(rule => rule.ConstraintName), Is.All.StartWith("check"));
+
+ // Category totals, cross-checked against an independent scan of the raw XMI.
+ Assert.That(rules.Count(rule => rule.Category == ImpliedConstraintCategory.Specialization), Is.EqualTo(175));
+ Assert.That(rules.Count(rule => rule.Category == ImpliedConstraintCategory.Redefinition), Is.EqualTo(15));
+ Assert.That(rules.Count(rule => rule.Category == ImpliedConstraintCategory.TypeFeaturing), Is.EqualTo(7));
+ Assert.That(rules.Count(rule => rule.Category == ImpliedConstraintCategory.BindingConnector), Is.EqualTo(11));
+
+ // Form split — this is what decides how much is generated versus hand-written.
+ Assert.That(rules.Count(rule => rule.Form == ImpliedRuleForm.UnconditionalLibrarySpecialization), Is.EqualTo(85));
+ Assert.That(rules.Count(rule => rule.Form == ImpliedRuleForm.GuardedLibrarySpecialization), Is.EqualTo(63));
+ Assert.That(rules.Count(rule => rule.Form == ImpliedRuleForm.SpecificationTbd), Is.EqualTo(2));
+ }
+
+ // A representative unconditional rule: the whole body is the library target.
+ var portUsage = rules.Single(rule => rule.ConstraintName == "checkPortUsageSpecialization");
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(portUsage.MetaclassName, Is.EqualTo("PortUsage"));
+ Assert.That(portUsage.Form, Is.EqualTo(ImpliedRuleForm.UnconditionalLibrarySpecialization));
+ Assert.That(portUsage.TargetLibraryName, Is.EqualTo("Ports::ports"));
+ Assert.That(portUsage.GuardExpression, Is.Null);
+ }
+
+ // A representative guarded rule: the target is still extracted mechanically, and the guard is
+ // captured verbatim for a hand-written predicate.
+ var subport = rules.Single(rule => rule.ConstraintName == "checkPortUsageSubportSpecialization");
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(subport.Form, Is.EqualTo(ImpliedRuleForm.GuardedLibrarySpecialization));
+ Assert.That(subport.TargetLibraryName, Is.EqualTo("Ports::Port::subports"));
+ Assert.That(subport.GuardExpression, Is.Not.Empty);
+ Assert.That(subport.GuardExpression, Does.Not.Contain("specializesFromLibrary"));
+ }
+
+ // Categories 2-4 relate user-model elements, so they never carry a library target.
+ Assert.That(
+ rules.Where(rule => rule.Category != ImpliedConstraintCategory.Specialization).Select(rule => rule.TargetLibraryName),
+ Is.All.Null);
+
+ // Every rule carries the OCL it was classified from, so a hand-coded arm can be checked
+ // against the source of truth without re-reading the XMI.
+ Assert.That(rules.Select(rule => rule.Ocl), Is.All.Not.Null);
+ }
+ }
+}
diff --git a/SysML2.NET.CodeGenerator.Tests/Generators/UmlHandleBarsGenerators/UmlCoreImpliedRelationshipGeneratorTestFixture.cs b/SysML2.NET.CodeGenerator.Tests/Generators/UmlHandleBarsGenerators/UmlCoreImpliedRelationshipGeneratorTestFixture.cs
new file mode 100644
index 00000000..ce778b8b
--- /dev/null
+++ b/SysML2.NET.CodeGenerator.Tests/Generators/UmlHandleBarsGenerators/UmlCoreImpliedRelationshipGeneratorTestFixture.cs
@@ -0,0 +1,88 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.CodeGenerator.Tests.Generators.UmlHandleBarsGenerators
+{
+ using System.IO;
+ using System.Threading.Tasks;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.CodeGenerator.Generators.UmlHandleBarsGenerators;
+
+ [TestFixture]
+ public class UmlCoreImpliedRelationshipGeneratorTestFixture
+ {
+ private DirectoryInfo outputDirectory;
+ private UmlCoreImpliedRelationshipGenerator generator;
+
+ [OneTimeSetUp]
+ public void OneTimeSetup()
+ {
+ var directoryInfo = new DirectoryInfo(TestContext.CurrentContext.TestDirectory);
+
+ var path = Path.Combine("UML", "_SysML2.NET.Semantics.AutoGenImplied");
+
+ this.outputDirectory = directoryInfo.CreateSubdirectory(path);
+ this.generator = new UmlCoreImpliedRelationshipGenerator();
+ }
+
+ [Test]
+ public async Task VerifyImpliedRelationshipTableIsGenerated()
+ {
+ await Assert.ThatAsync(
+ () => this.generator.GenerateAsync(GeneratorSetupFixture.XmiReaderResult, this.outputDirectory),
+ Throws.Nothing);
+ }
+
+ [Test]
+ public async Task VerifyGeneratedTableCarriesTheExtractedRules()
+ {
+ var generatedCode = await this.generator.GenerateImpliedRelationshipTable(
+ GeneratorSetupFixture.XmiReaderResult,
+ this.outputDirectory);
+
+ using (Assert.EnterMultipleScope())
+ {
+ // An unconditional rule declared on the metaclass itself.
+ Assert.That(generatedCode, Does.Contain(@"new(""checkPortUsageSpecialization"", ""Ports::ports"", ""PortUsage"", false)"));
+
+ // A guarded rule keeps its target but is flagged so the caller consults the hand-written
+ // predicate before applying it.
+ Assert.That(generatedCode, Does.Contain(@"new(""checkPortUsageSubportSpecialization"", ""Ports::Port::subports"", ""PortUsage"", true)"));
+
+ // Constraints are flattened DOWN the metaclass hierarchy: PartUsage declares none of these,
+ // it inherits them, and the generated arm must still carry them.
+ Assert.That(generatedCode, Does.Contain("IPartUsageRules").Or.Contain("PartUsageRules"));
+ Assert.That(generatedCode, Does.Contain(@"""checkFeatureSpecialization"", ""Base::things"", ""Feature"""));
+
+ // The manifest must account for every constraint that could not be generated, including the
+ // two whose specification body the OMG left as TBD.
+ Assert.That(generatedCode, Does.Contain("checkInvocationExpressionDefaultValueBindingConnector"));
+ Assert.That(generatedCode, Does.Contain("specification body is TBD"));
+
+ // The hand-maintained half of the table — the part the OCL cannot supply — must survive
+ // into the generated file.
+ Assert.That(generatedCode, Does.Contain("SubclassificationMetaclasses"));
+ Assert.That(generatedCode, Does.Contain(@"""PartDefinition"""));
+ }
+ }
+ }
+}
diff --git a/SysML2.NET.CodeGenerator/Extensions/ImpliedGuardEmitter.cs b/SysML2.NET.CodeGenerator/Extensions/ImpliedGuardEmitter.cs
new file mode 100644
index 00000000..67d69148
--- /dev/null
+++ b/SysML2.NET.CodeGenerator/Extensions/ImpliedGuardEmitter.cs
@@ -0,0 +1,209 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.CodeGenerator.Extensions
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ ///
+ /// Translates a parsed guard expression into the C# predicate the generated guard evaluates.
+ ///
+ ///
+ /// The emitted predicate is a single boolean expression over a parameter named element. A shape
+ /// the emitter cannot render — because a referenced metaclass is unknown, for instance — yields
+ /// null, which keeps the constraint in the hand-coded set rather than emitting something that
+ /// does not compile or, worse, compiles and is wrong.
+ ///
+ public static class ImpliedGuardEmitter
+ {
+ ///
+ /// Emits the C# predicate for a parsed guard expression.
+ ///
+ /// The parsed guard expression.
+ /// The fully qualified interface of the declaring metaclass.
+ /// The fully qualified interface of every known metaclass, by name.
+ /// The fully qualified name of every known enumeration, by name.
+ /// The predicate over element, or null when it cannot be rendered.
+ /// Thrown when is null.
+ public static string Emit(ImpliedGuardExpression expression, string declaringInterfaceFqn, IReadOnlyDictionary interfaceFqnByName, IReadOnlyDictionary enumerationFqnByName)
+ {
+ ArgumentNullException.ThrowIfNull(expression);
+
+ if (string.IsNullOrWhiteSpace(declaringInterfaceFqn))
+ {
+ return null;
+ }
+
+ var subject = $"element is {declaringInterfaceFqn} guardSubject";
+
+ return expression.Shape switch
+ {
+ ImpliedGuardShape.BooleanProperty => $"element is {declaringInterfaceFqn} {{ {PascalCase(expression.MemberName)}: true }}",
+ ImpliedGuardShape.OperationCall => EmitOperationCall(expression, subject),
+ ImpliedGuardShape.OwningTypeKind => EmitOwningTypeKind(expression, declaringInterfaceFqn, interfaceFqnByName),
+ ImpliedGuardShape.OwnedEndFeatureCount => EmitOwnedEndFeatureCount(expression, subject),
+ ImpliedGuardShape.OwnedTypingKind => EmitOwnedTypingKind(expression, subject, interfaceFqnByName),
+ ImpliedGuardShape.OwningFeatureMembershipKind => EmitOwningFeatureMembershipKind(expression, declaringInterfaceFqn, interfaceFqnByName),
+ ImpliedGuardShape.EnumerationComparison => EmitEnumerationComparison(expression, declaringInterfaceFqn, enumerationFqnByName),
+ _ => null
+ };
+ }
+
+ ///
+ /// Emits a boolean operation call, honouring negation and an optional boolean argument.
+ ///
+ /// The parsed guard expression.
+ /// The type-pattern prefix binding guardSubject.
+ /// The predicate.
+ private static string EmitOperationCall(ImpliedGuardExpression expression, string subject)
+ {
+ var argument = expression.Literal ?? string.Empty;
+ var call = $"guardSubject.{PascalCase(expression.MemberName)}({argument})";
+
+ return $"{subject} && {(expression.IsNegated ? "!" : string.Empty)}{call}";
+ }
+
+ ///
+ /// Emits an owning-Type kind test, optionally conjoined with the composite flag.
+ ///
+ /// The parsed guard expression.
+ /// The fully qualified interface of the declaring metaclass.
+ /// The fully qualified interface of every known metaclass, by name.
+ /// The predicate, or null when a metaclass is unknown.
+ ///
+ /// Emitted as one merged property pattern rather than a chain of conjuncts, so the whole condition
+ /// reads as a single shape test.
+ ///
+ private static string EmitOwningTypeKind(ImpliedGuardExpression expression, string declaringInterfaceFqn, IReadOnlyDictionary interfaceFqnByName)
+ {
+ if (!TryQueryInterfaces(expression.TypeNames, interfaceFqnByName, out var alternatives))
+ {
+ return null;
+ }
+
+ var composite = expression.RequiresComposite ? "IsComposite: true, " : string.Empty;
+
+ return $"element is {declaringInterfaceFqn} {{ {composite}owningType: {string.Join(" or ", alternatives)} }}";
+ }
+
+ ///
+ /// Emits an owned-end-Feature cardinality test.
+ ///
+ /// The parsed guard expression.
+ /// The type-pattern prefix binding guardSubject.
+ /// The predicate.
+ ///
+ /// The abstract syntax spells the property both ownedEndFeature and ownedEndFeatures;
+ /// only the singular exists, so the emitted code always uses it.
+ ///
+ private static string EmitOwnedEndFeatureCount(ImpliedGuardExpression expression, string subject)
+ {
+ var comparison = expression.Literal == null
+ ? "Count > 0"
+ : $"Count == {expression.Literal}";
+
+ return $"{subject} && ((SysML2.NET.Core.POCO.Core.Types.IType)guardSubject).ownedEndFeature.{comparison}";
+ }
+
+ ///
+ /// Emits an owned-typing kind test.
+ ///
+ /// The parsed guard expression.
+ /// The type-pattern prefix binding guardSubject.
+ /// The fully qualified interface of every known metaclass, by name.
+ /// The predicate, or null when the metaclass is unknown.
+ private static string EmitOwnedTypingKind(ImpliedGuardExpression expression, string subject, IReadOnlyDictionary interfaceFqnByName)
+ {
+ return TryQueryInterfaces(expression.TypeNames, interfaceFqnByName, out var alternatives)
+ ? $"{subject} && guardSubject.ownedTyping.Any(featureTyping => featureTyping.Type is {alternatives[0]})"
+ : null;
+ }
+
+ ///
+ /// Emits an owning-FeatureMembership kind test.
+ ///
+ /// The parsed guard expression.
+ /// The fully qualified interface of the declaring metaclass.
+ /// The fully qualified interface of every known metaclass, by name.
+ /// The predicate, or null when the metaclass is unknown.
+ private static string EmitOwningFeatureMembershipKind(ImpliedGuardExpression expression, string declaringInterfaceFqn, IReadOnlyDictionary interfaceFqnByName)
+ {
+ return TryQueryInterfaces(expression.TypeNames, interfaceFqnByName, out var alternatives)
+ ? $"element is {declaringInterfaceFqn} {{ owningFeatureMembership: {alternatives[0]} }}"
+ : null;
+ }
+
+ ///
+ /// Emits an enumeration-literal comparison.
+ ///
+ /// The parsed guard expression.
+ /// The fully qualified interface of the declaring metaclass.
+ /// The fully qualified name of every known enumeration, by name.
+ /// The predicate, or null when the enumeration is unknown.
+ private static string EmitEnumerationComparison(ImpliedGuardExpression expression, string declaringInterfaceFqn, IReadOnlyDictionary enumerationFqnByName)
+ {
+ return enumerationFqnByName.TryGetValue(expression.TypeNames[0], out var enumerationFqn)
+ ? $"element is {declaringInterfaceFqn} {{ {PascalCase(expression.MemberName)}: {enumerationFqn}.{PascalCase(expression.Literal)} }}"
+ : null;
+ }
+
+ ///
+ /// Resolves metaclass names to their fully qualified interfaces.
+ ///
+ /// The metaclass names to resolve.
+ /// The fully qualified interface of every known metaclass, by name.
+ /// The resolved interfaces, when every name resolved and at least one was given.
+ /// when the guard can be emitted from these names.
+ ///
+ /// A Try pattern rather than a nullable collection: "a metaclass name is unknown" is an OUTCOME —
+ /// the guard then falls back to hand-coding — not an empty result, and the two must not be
+ /// conflated by a caller that iterates what it gets back.
+ ///
+ private static bool TryQueryInterfaces(IReadOnlyList typeNames, IReadOnlyDictionary interfaceFqnByName, out List interfaces)
+ {
+ var resolved = new List();
+
+ foreach (var typeName in typeNames)
+ {
+ if (!interfaceFqnByName.TryGetValue(typeName, out var interfaceFqn))
+ {
+ interfaces = null;
+
+ return false;
+ }
+
+ resolved.Add(interfaceFqn);
+ }
+
+ interfaces = resolved;
+
+ return resolved.Count != 0;
+ }
+
+ ///
+ /// Upper-cases the first character, turning an OCL member name into its C# counterpart.
+ ///
+ /// The OCL member name.
+ /// The C# member name.
+ private static string PascalCase(string name) => string.IsNullOrEmpty(name) ? name : char.ToUpperInvariant(name[0]) + name[1..];
+ }
+}
diff --git a/SysML2.NET.CodeGenerator/Extensions/ImpliedGuardExpression.cs b/SysML2.NET.CodeGenerator/Extensions/ImpliedGuardExpression.cs
new file mode 100644
index 00000000..1e1e697a
--- /dev/null
+++ b/SysML2.NET.CodeGenerator/Extensions/ImpliedGuardExpression.cs
@@ -0,0 +1,68 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.CodeGenerator.Extensions
+{
+ using System.Collections.Generic;
+
+ ///
+ /// A guard expression parsed into the operands a C# predicate needs.
+ ///
+ public class ImpliedGuardExpression
+ {
+ ///
+ /// Gets the recognised shape, or .
+ ///
+ public ImpliedGuardShape Shape { get; init; }
+
+ ///
+ /// Gets the OCL the expression was parsed from, retained for the generated doc comment.
+ ///
+ public string Ocl { get; init; }
+
+ ///
+ /// Gets the property or operation name the shape tests, e.g. isComposite or
+ /// isSubactionUsage.
+ ///
+ public string MemberName { get; init; }
+
+ ///
+ /// Gets the metaclass names the shape tests against, e.g. PartDefinition and
+ /// PartUsage.
+ ///
+ public IReadOnlyList TypeNames { get; init; } = [];
+
+ ///
+ /// Gets a value indicating whether the expression is negated, as in not isTriggerAction().
+ ///
+ public bool IsNegated { get; init; }
+
+ ///
+ /// Gets a value indicating whether the shape is additionally conjoined with isComposite.
+ ///
+ public bool RequiresComposite { get; init; }
+
+ ///
+ /// Gets the literal the shape compares against — an enumeration literal, a boolean argument, or a
+ /// cardinality — or null when the shape has none.
+ ///
+ public string Literal { get; init; }
+ }
+}
diff --git a/SysML2.NET.CodeGenerator/Extensions/ImpliedGuardParser.cs b/SysML2.NET.CodeGenerator/Extensions/ImpliedGuardParser.cs
new file mode 100644
index 00000000..a285b1ac
--- /dev/null
+++ b/SysML2.NET.CodeGenerator/Extensions/ImpliedGuardParser.cs
@@ -0,0 +1,206 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.CodeGenerator.Extensions
+{
+ using System.Text.RegularExpressions;
+
+ ///
+ /// Parses the guard expression of a semantic constraint into one of the mechanically translatable
+ /// shapes.
+ ///
+ ///
+ /// The parser is deliberately strict: an expression it does not recognise EXACTLY is reported as
+ /// rather than approximated. A guard that silently
+ /// mistranslates would inject Specializations a model does not require, corrupting every inheritance
+ /// result computed from it.
+ ///
+ public static partial class ImpliedGuardParser
+ {
+ ///
+ /// Upper bound on a single match, guarding against catastrophic backtracking.
+ ///
+ private const int MatchTimeoutMilliseconds = 1000;
+
+ ///
+ /// The capture group holding the boolean argument of an operation call.
+ ///
+ private const string LiteralGroup = "literal";
+
+ ///
+ /// Matches a bare boolean property, e.g. isIndividual.
+ ///
+ private static readonly Regex BooleanPropertyPattern =
+ new(@"^(?is[A-Za-z]+)$", RegexOptions.Compiled, System.TimeSpan.FromMilliseconds(MatchTimeoutMilliseconds));
+
+ ///
+ /// Matches a boolean operation call, optionally negated and optionally with a boolean argument.
+ ///
+ private static readonly Regex OperationCallPattern =
+ new(@"^(?not\s+)?(?is[A-Za-z]+)\((?true|false)?\)$", RegexOptions.Compiled, System.TimeSpan.FromMilliseconds(MatchTimeoutMilliseconds));
+
+ ///
+ /// Matches an owning-Type kind test over two alternatives, optionally conjoined with isComposite.
+ ///
+ private static readonly Regex OwningTypeKindPattern =
+ new(@"^(?isComposite\s+and\s+)?owningType\s*<>\s*null\s+and\s*\(\s*owningType\.oclIsKindOf\((?[A-Za-z]+)\)\s+or\s+owningType\.oclIsKindOf\((?[A-Za-z]+)\)\s*\)$", RegexOptions.Compiled, System.TimeSpan.FromMilliseconds(MatchTimeoutMilliseconds));
+
+ ///
+ /// Matches an owned-end-Feature cardinality test.
+ ///
+ private static readonly Regex OwnedEndFeatureCountPattern =
+ new(@"^ownedEndFeatures?->(?:size\(\)\s*=\s*(?[0-9]+)|(?notEmpty\(\)))$", RegexOptions.Compiled, System.TimeSpan.FromMilliseconds(MatchTimeoutMilliseconds));
+
+ ///
+ /// Matches an owned-typing kind test.
+ ///
+ private static readonly Regex OwnedTypingKindPattern =
+ new(@"^ownedTyping\.type->exists\(selectByKind\((?[A-Za-z]+)\)\)$", RegexOptions.Compiled, System.TimeSpan.FromMilliseconds(MatchTimeoutMilliseconds));
+
+ ///
+ /// Matches an owning-FeatureMembership kind test.
+ ///
+ private static readonly Regex OwningFeatureMembershipKindPattern =
+ new(@"^owningFeatureMembership\s*<>\s*null\s+and\s+owningFeatureMembership\.oclIsKindOf\((?[A-Za-z]+)\)$", RegexOptions.Compiled, System.TimeSpan.FromMilliseconds(MatchTimeoutMilliseconds));
+
+ ///
+ /// Matches an enumeration-literal comparison.
+ ///
+ private static readonly Regex EnumerationComparisonPattern =
+ new(@"^(?[a-z][A-Za-z]*)\s*=\s*(?[A-Za-z]+)::(?[a-zA-Z]+)$", RegexOptions.Compiled, System.TimeSpan.FromMilliseconds(MatchTimeoutMilliseconds));
+
+ ///
+ /// Parses a guard expression into the operands a C# predicate needs.
+ ///
+ /// The guard OCL, i.e. the antecedent of the implies.
+ /// The parsed expression; its shape is RequiresHandCoding when unrecognised.
+ public static ImpliedGuardExpression Parse(string guardOcl)
+ {
+ var normalised = Normalise(guardOcl);
+
+ if (string.IsNullOrWhiteSpace(normalised))
+ {
+ return new ImpliedGuardExpression { Shape = ImpliedGuardShape.RequiresHandCoding, Ocl = guardOcl };
+ }
+
+ var owningTypeKind = OwningTypeKindPattern.Match(normalised);
+
+ if (owningTypeKind.Success)
+ {
+ return new ImpliedGuardExpression
+ {
+ Shape = ImpliedGuardShape.OwningTypeKind,
+ Ocl = normalised,
+ TypeNames = [owningTypeKind.Groups["first"].Value, owningTypeKind.Groups["second"].Value],
+ RequiresComposite = owningTypeKind.Groups["composite"].Success
+ };
+ }
+
+ var operationCall = OperationCallPattern.Match(normalised);
+
+ if (operationCall.Success)
+ {
+ return new ImpliedGuardExpression
+ {
+ Shape = ImpliedGuardShape.OperationCall,
+ Ocl = normalised,
+ MemberName = operationCall.Groups["member"].Value,
+ IsNegated = operationCall.Groups["not"].Success,
+ Literal = operationCall.Groups[LiteralGroup].Success ? operationCall.Groups[LiteralGroup].Value : null
+ };
+ }
+
+ var ownedEndFeatureCount = OwnedEndFeatureCountPattern.Match(normalised);
+
+ if (ownedEndFeatureCount.Success)
+ {
+ return new ImpliedGuardExpression
+ {
+ Shape = ImpliedGuardShape.OwnedEndFeatureCount,
+ Ocl = normalised,
+ Literal = ownedEndFeatureCount.Groups["notEmpty"].Success ? null : ownedEndFeatureCount.Groups[LiteralGroup].Value
+ };
+ }
+
+ var ownedTypingKind = OwnedTypingKindPattern.Match(normalised);
+
+ if (ownedTypingKind.Success)
+ {
+ return new ImpliedGuardExpression
+ {
+ Shape = ImpliedGuardShape.OwnedTypingKind,
+ Ocl = normalised,
+ TypeNames = [ownedTypingKind.Groups["first"].Value]
+ };
+ }
+
+ var owningFeatureMembershipKind = OwningFeatureMembershipKindPattern.Match(normalised);
+
+ if (owningFeatureMembershipKind.Success)
+ {
+ return new ImpliedGuardExpression
+ {
+ Shape = ImpliedGuardShape.OwningFeatureMembershipKind,
+ Ocl = normalised,
+ TypeNames = [owningFeatureMembershipKind.Groups["first"].Value]
+ };
+ }
+
+ var enumerationComparison = EnumerationComparisonPattern.Match(normalised);
+
+ if (enumerationComparison.Success)
+ {
+ return new ImpliedGuardExpression
+ {
+ Shape = ImpliedGuardShape.EnumerationComparison,
+ Ocl = normalised,
+ MemberName = enumerationComparison.Groups["member"].Value,
+ TypeNames = [enumerationComparison.Groups["enumeration"].Value],
+ Literal = enumerationComparison.Groups[LiteralGroup].Value
+ };
+ }
+
+ var booleanProperty = BooleanPropertyPattern.Match(normalised);
+
+ return booleanProperty.Success
+ ? new ImpliedGuardExpression
+ {
+ Shape = ImpliedGuardShape.BooleanProperty,
+ Ocl = normalised,
+ MemberName = booleanProperty.Groups["member"].Value
+ }
+ : new ImpliedGuardExpression { Shape = ImpliedGuardShape.RequiresHandCoding, Ocl = normalised };
+ }
+
+ ///
+ /// Collapses the whitespace an XMI body carries across lines into single spaces.
+ ///
+ /// The raw guard OCL.
+ /// The single-line form, or null when the input is null.
+ private static string Normalise(string guardOcl) => guardOcl == null ? null : WhitespaceRunPattern().Replace(guardOcl, " ").Trim();
+
+ ///
+ /// Matches a run of whitespace, including the line breaks an XMI body carries.
+ ///
+ /// The source-generated pattern.
+ [GeneratedRegex(@"\s+", RegexOptions.None, MatchTimeoutMilliseconds)]
+ private static partial Regex WhitespaceRunPattern();
+ }
+}
diff --git a/SysML2.NET.CodeGenerator/Extensions/ImpliedGuardShape.cs b/SysML2.NET.CodeGenerator/Extensions/ImpliedGuardShape.cs
new file mode 100644
index 00000000..d33e5fa0
--- /dev/null
+++ b/SysML2.NET.CodeGenerator/Extensions/ImpliedGuardShape.cs
@@ -0,0 +1,78 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.CodeGenerator.Extensions
+{
+ ///
+ /// The mechanically translatable shapes a semantic-constraint guard expression can take.
+ ///
+ ///
+ /// A guard is the antecedent of an <guard> implies specializesFromLibrary('…') constraint.
+ /// These shapes cover the majority of them; anything else is reported as
+ /// so it is never silently mistranslated.
+ ///
+ public enum ImpliedGuardShape
+ {
+ ///
+ /// The guard is not one of the recognised shapes and must be written by hand.
+ ///
+ RequiresHandCoding,
+
+ ///
+ /// A bare boolean property, e.g. isIndividual.
+ ///
+ BooleanProperty,
+
+ ///
+ /// A boolean operation call, optionally negated, e.g. isSubactionUsage(),
+ /// not isTriggerAction(), isSubstateUsage(true).
+ ///
+ OperationCall,
+
+ ///
+ /// An owning-Type kind test over two alternatives, optionally conjoined with isComposite,
+ /// e.g. owningType <> null and (owningType.oclIsKindOf(PartDefinition) or
+ /// owningType.oclIsKindOf(PartUsage)).
+ ///
+ OwningTypeKind,
+
+ ///
+ /// An owned-end-Feature cardinality test, e.g. ownedEndFeature->size() = 2 or
+ /// ownedEndFeatures->notEmpty().
+ ///
+ OwnedEndFeatureCount,
+
+ ///
+ /// An owned-typing kind test, e.g. ownedTyping.type->exists(selectByKind(DataType)).
+ ///
+ OwnedTypingKind,
+
+ ///
+ /// An owning-FeatureMembership kind test, e.g. owningFeatureMembership <> null and
+ /// owningFeatureMembership.oclIsKindOf(StakeholderMembership).
+ ///
+ OwningFeatureMembershipKind,
+
+ ///
+ /// An enumeration-literal comparison, e.g. portionKind = PortionKind::timeslice.
+ ///
+ EnumerationComparison
+ }
+}
diff --git a/SysML2.NET.CodeGenerator/Extensions/ImpliedRelationshipExtensions.cs b/SysML2.NET.CodeGenerator/Extensions/ImpliedRelationshipExtensions.cs
new file mode 100644
index 00000000..703c14d2
--- /dev/null
+++ b/SysML2.NET.CodeGenerator/Extensions/ImpliedRelationshipExtensions.cs
@@ -0,0 +1,236 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.CodeGenerator.Extensions
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text.RegularExpressions;
+
+ using uml4net.CommonStructure;
+ using uml4net.StructuredClassifiers;
+ using uml4net.Values;
+ using uml4net.xmi.Readers;
+
+ ///
+ /// Extracts the KerML/SysML semantic constraints that a tool may satisfy by inserting implied
+ /// Relationships, as described in KerML 1.0 §8.4.2.
+ ///
+ ///
+ /// §8.4.2 names four categories of semantic constraint and fixes a naming convention for each — the
+ /// constraint name always contains the word Specialization, Redefinition,
+ /// TypeFeaturing or BindingConnector. Only the check-prefixed rules are semantic
+ /// constraints; derive rules are derivations and validate rules are validation constraints
+ /// (§8.3.1), and neither implies a Relationship.
+ ///
+ /// The normative catalogue of what to insert for each constraint is the set of tables in KerML §8.4.3.1.1
+ /// (Tables 8, 9), §8.4.4.1 (Tables 10, 11) and SysML §Tables 31-33. This extractor reads the machine-readable
+ /// XMI as a proxy for those tables. Where the two disagree, the tables win — reconciling them is a
+ /// deliberate follow-up, and exists so that no constraint
+ /// is silently dropped in the meantime.
+ ///
+ ///
+ public static partial class ImpliedRelationshipExtensions
+ {
+ ///
+ /// Upper bound on a single match, so a pathological OCL body cannot stall generation.
+ ///
+ private const int MatchTimeoutMilliseconds = 2000;
+
+ ///
+ /// Matches an OCL body that is nothing but a library specialization, e.g.
+ /// specializesFromLibrary('Ports::ports').
+ ///
+ /// The source-generated pattern.
+ [GeneratedRegex(@"^specializesFromLibrary\('(?[^']+)'\)$", RegexOptions.None, MatchTimeoutMilliseconds)]
+ private static partial Regex UnconditionalLibraryPattern();
+
+ ///
+ /// Matches an OCL body of the form <guard> implies specializesFromLibrary('X::y'). The
+ /// guard is captured verbatim; translating it into a C# predicate is hand-work, but the TARGET is
+ /// still extracted mechanically.
+ ///
+ /// The source-generated pattern.
+ [GeneratedRegex(@"^(?.+?)\bimplies\b\s*specializesFromLibrary\('(?[^']+)'\)$", RegexOptions.None, MatchTimeoutMilliseconds)]
+ private static partial Regex GuardedLibraryPattern();
+
+ ///
+ /// The four category keywords of KerML §8.4.2, in the order the specification lists them.
+ ///
+ private static readonly (string Keyword, ImpliedConstraintCategory Category)[] CategoryKeywords =
+ [
+ ("Specialization", ImpliedConstraintCategory.Specialization),
+ ("Redefinition", ImpliedConstraintCategory.Redefinition),
+ ("TypeFeaturing", ImpliedConstraintCategory.TypeFeaturing),
+ ("BindingConnector", ImpliedConstraintCategory.BindingConnector)
+ ];
+
+ ///
+ /// Extracts every semantic constraint that may be satisfied by an implied Relationship, from
+ /// every reachable from the merged model.
+ ///
+ ///
+ /// The holding the merged KerML + SysML model
+ ///
+ ///
+ /// The extracted rules, ordered by metaclass then constraint name
+ ///
+ public static IReadOnlyList QueryImpliedRelationshipRules(this XmiReaderResult xmiReaderResult)
+ {
+ ArgumentNullException.ThrowIfNull(xmiReaderResult);
+
+ var rules = new List();
+
+ foreach (var umlClass in xmiReaderResult.QueryContainedAndImported("SysML").SelectMany(package => package.PackagedElement.OfType()))
+ {
+ rules.AddRange(umlClass.OwnedRule
+ .Where(IsSemanticConstraint)
+ .Select(rule => CreateRule(umlClass, rule))
+ .Where(rule => rule != null));
+ }
+
+ return
+ [
+ ..rules
+ .OrderBy(rule => rule.MetaclassName, StringComparer.Ordinal)
+ .ThenBy(rule => rule.ConstraintName, StringComparer.Ordinal)
+ ];
+ }
+
+ ///
+ /// Determines whether a constraint is one of the §8.4.2 semantic constraints — a check rule
+ /// whose name carries one of the four category keywords.
+ ///
+ ///
+ /// The to test
+ ///
+ ///
+ /// True when the constraint may imply a Relationship
+ ///
+ private static bool IsSemanticConstraint(IConstraint constraint)
+ {
+ return !string.IsNullOrWhiteSpace(constraint.Name)
+ && constraint.Name.StartsWith("check", StringComparison.Ordinal)
+ && CategoryKeywords.Any(candidate => constraint.Name.Contains(candidate.Keyword, StringComparison.Ordinal));
+ }
+
+ ///
+ /// Projects a single constraint into an , classifying how far the
+ /// OCL body can be turned into generated code.
+ ///
+ ///
+ /// The the constraint is declared on
+ ///
+ ///
+ /// The to project
+ ///
+ ///
+ /// The rule, or null when the constraint carries no OCL body at all
+ ///
+ private static ImpliedRelationshipRule CreateRule(IClass umlClass, IConstraint constraint)
+ {
+ var ocl = QueryOclBody(constraint);
+
+ if (ocl == null)
+ {
+ return null;
+ }
+
+ var category = CategoryKeywords.First(candidate => constraint.Name.Contains(candidate.Keyword, StringComparison.Ordinal)).Category;
+
+ var (form, target, guard) = ClassifyOcl(ocl, category);
+
+ return new ImpliedRelationshipRule
+ {
+ ConstraintName = constraint.Name,
+ MetaclassName = umlClass.Name,
+ Category = category,
+ Form = form,
+ TargetLibraryName = target,
+ GuardExpression = guard,
+ Ocl = ocl
+ };
+ }
+
+ ///
+ /// Classifies an OCL body into the form that decides how much of the rule can be generated.
+ ///
+ ///
+ /// The normalised OCL body
+ ///
+ ///
+ /// The §8.4.2 category the constraint belongs to
+ ///
+ ///
+ /// The form, the library target when there is one, and the guard when there is one
+ ///
+ private static (ImpliedRuleForm Form, string Target, string Guard) ClassifyOcl(string ocl, ImpliedConstraintCategory category)
+ {
+ if (string.Equals(ocl, "TBD", StringComparison.OrdinalIgnoreCase))
+ {
+ return (ImpliedRuleForm.SpecificationTbd, null, null);
+ }
+
+ // Only specialization constraints target the model libraries by qualified name; redefinition,
+ // type-featuring and binding-connector constraints relate user-model elements to each other and
+ // have no mechanically extractable target (§8.4.2 categories 2-4).
+ if (category != ImpliedConstraintCategory.Specialization)
+ {
+ return (ImpliedRuleForm.RequiresHandCoding, null, null);
+ }
+
+ var unconditional = UnconditionalLibraryPattern().Match(ocl);
+
+ if (unconditional.Success)
+ {
+ return (ImpliedRuleForm.UnconditionalLibrarySpecialization, unconditional.Groups["target"].Value, null);
+ }
+
+ var guarded = GuardedLibraryPattern().Match(ocl);
+
+ return guarded.Success
+ ? (ImpliedRuleForm.GuardedLibrarySpecialization, guarded.Groups["target"].Value, guarded.Groups["guard"].Value.Trim())
+ : (ImpliedRuleForm.RequiresHandCoding, null, null);
+ }
+
+ ///
+ /// Returns the constraint's OCL body as a single whitespace-normalised line, or null when the
+ /// constraint carries no non-blank body.
+ ///
+ ///
+ /// The to read
+ ///
+ ///
+ /// The normalised OCL, or null
+ ///
+ private static string QueryOclBody(IConstraint constraint)
+ {
+ var opaqueExpression = constraint.Specification?.OfType().FirstOrDefault();
+
+ var body = opaqueExpression?.Body?.FirstOrDefault(candidate => !string.IsNullOrWhiteSpace(candidate));
+
+ // Corrected before classification, so the target, the guard and the recorded OCL all agree.
+ return body == null
+ ? null
+ : OclErrata.Apply(string.Join(' ', body.Split((char[])null, StringSplitOptions.RemoveEmptyEntries)));
+ }
+ }
+}
diff --git a/SysML2.NET.CodeGenerator/Extensions/ImpliedRelationshipRule.cs b/SysML2.NET.CodeGenerator/Extensions/ImpliedRelationshipRule.cs
new file mode 100644
index 00000000..ee11a0a7
--- /dev/null
+++ b/SysML2.NET.CodeGenerator/Extensions/ImpliedRelationshipRule.cs
@@ -0,0 +1,118 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.CodeGenerator.Extensions
+{
+ ///
+ /// The category of semantic constraint, per KerML 1.0 §8.4.2.
+ ///
+ public enum ImpliedConstraintCategory
+ {
+ ///
+ /// Requires a Type to directly or indirectly specialize a base Type, normally from a model library.
+ ///
+ Specialization,
+
+ ///
+ /// Requires a Redefinition between two Features of a user model.
+ ///
+ Redefinition,
+
+ ///
+ /// Requires a TypeFeaturing between a Feature and a Type of a user model.
+ ///
+ TypeFeaturing,
+
+ ///
+ /// Requires a BindingConnector to exist between two Features of a user model.
+ ///
+ BindingConnector
+ }
+
+ ///
+ /// How much of a semantic constraint can be turned into generated code.
+ ///
+ public enum ImpliedRuleForm
+ {
+ ///
+ /// The whole OCL body is specializesFromLibrary('X::y') — fully generatable.
+ ///
+ UnconditionalLibrarySpecialization,
+
+ ///
+ /// The OCL body is <guard> implies specializesFromLibrary('X::y') — the target is
+ /// generatable, the guard needs a hand-written predicate.
+ ///
+ GuardedLibrarySpecialization,
+
+ ///
+ /// The constraint relates user-model elements, or its OCL is not in a mechanically extractable
+ /// shape; the whole rule needs hand-coding.
+ ///
+ RequiresHandCoding,
+
+ ///
+ /// The specification itself leaves the OCL body as TBD, so there is nothing to implement.
+ ///
+ SpecificationTbd
+ }
+
+ ///
+ /// A single semantic constraint that may be satisfied by inserting an implied Relationship.
+ ///
+ public sealed class ImpliedRelationshipRule
+ {
+ ///
+ /// Gets the name of the constraint as declared in the XMI, e.g. checkPortUsageSpecialization.
+ ///
+ public string ConstraintName { get; init; }
+
+ ///
+ /// Gets the name of the metaclass the constraint is declared on.
+ ///
+ public string MetaclassName { get; init; }
+
+ ///
+ /// Gets the §8.4.2 category of the constraint.
+ ///
+ public ImpliedConstraintCategory Category { get; init; }
+
+ ///
+ /// Gets how much of the constraint can be generated.
+ ///
+ public ImpliedRuleForm Form { get; init; }
+
+ ///
+ /// Gets the qualified name of the library Type that must be specialized, or null when the constraint
+ /// does not target a library element.
+ ///
+ public string TargetLibraryName { get; init; }
+
+ ///
+ /// Gets the OCL guard that gates the specialization, or null when the constraint is unconditional.
+ ///
+ public string GuardExpression { get; init; }
+
+ ///
+ /// Gets the whitespace-normalised OCL body the rule was extracted from.
+ ///
+ public string Ocl { get; init; }
+ }
+}
diff --git a/SysML2.NET.CodeGenerator/Extensions/OclErrata.cs b/SysML2.NET.CodeGenerator/Extensions/OclErrata.cs
new file mode 100644
index 00000000..ea4c5b3d
--- /dev/null
+++ b/SysML2.NET.CodeGenerator/Extensions/OclErrata.cs
@@ -0,0 +1,114 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.CodeGenerator.Extensions
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ ///
+ /// Corrects known defects in the OCL bodies carried by the UML XMI, at generation time.
+ ///
+ ///
+ /// The XMI files under Resources/ are OMG source and are never edited, and the generated output
+ /// is never hand-edited either — so a defect in a normative OCL body can only be corrected here, on the
+ /// way from the one to the other.
+ /// Every entry below is a library qualified name that no Type in the Kernel Semantic Library or
+ /// the Systems Library declares, so the constraint that carries it cannot be satisfied by any model.
+ /// Each is evidenced by the same XMI spelling the name correctly elsewhere, by the library declaring
+ /// the corrected name, or both. Nothing here reinterprets what a constraint MEANS: an erratum only
+ /// repairs a name that is demonstrably a typo.
+ /// These corrections are expected to become unnecessary as OMG publishes fixes. On a new XMI
+ /// release, run the generator and prune whatever reports — an entry
+ /// that no longer matches has been fixed upstream. `ImpliedRelationshipTargetsTestFixture` fails if a
+ /// target stops resolving, so a regression cannot pass unnoticed.
+ ///
+ public static class OclErrata
+ {
+ ///
+ /// The corrections applied to OCL bodies, keyed by the exact quoted literal they replace.
+ ///
+ ///
+ /// Matching includes the surrounding single quotes, so a correction cannot partially match a
+ /// longer name — 'Items::Item::subitem' does not match 'Items::Item::subitems' — and
+ /// re-applying a correction to already-corrected text is a no-op.
+ ///
+ private static readonly OclErratum[] Entries =
+ [
+ new("'Action::Action::controls'", "'Actions::Action::controls'",
+ "The package is 'Actions'; the same XMI uses 'Actions::Action::…' in every other Action constraint."),
+ new("'Actions::Action::join'", "'Actions::Action::joins'",
+ "The Systems Library declares 'joins'; no Feature named 'join' exists."),
+ new("'Items::Item::subitem'", "'Items::Item::subitems'",
+ "The Systems Library declares 'subitems'; no Feature named 'subitem' exists."),
+ new("'Objects::Object::ownedPerformance'", "'Objects::Object::ownedPerformances'",
+ "The Kernel Semantic Library declares 'ownedPerformances'; no Feature named 'ownedPerformance' exists."),
+ new("'Occurrence::Occurrence::portions'", "'Occurrences::Occurrence::portions'",
+ "The package is 'Occurrences'; the same XMI uses 'Occurrences::Occurrence::…' for snapshots, timeSlices and timeEnclosedOccurrences."),
+ new("'Occurrence::Occurrence::suboccurrences'", "'Occurrences::Occurrence::suboccurrences'",
+ "The package is 'Occurrences'; the same XMI spells this exact name correctly in other constraints."),
+ new("'Performances::Performance::enclosedPerformance'", "'Performances::Performance::enclosedPerformances'",
+ "The Kernel Semantic Library declares 'enclosedPerformances'; no Feature named 'enclosedPerformance' exists."),
+ new("'Performances::Performance::subperformance'", "'Performances::Performance::subperformances'",
+ "The Kernel Semantic Library declares 'subperformances'; no Feature named 'subperformance' exists.")
+ ];
+
+ ///
+ /// The corrections that have matched at least one OCL body during this generator run.
+ ///
+ private static readonly HashSet AppliedOriginals = [];
+
+ ///
+ /// Applies every known correction to an OCL body.
+ ///
+ /// The OCL body read from the XMI, which may be null.
+ /// The corrected OCL body, or unchanged when nothing applies.
+ public static string Apply(string ocl)
+ {
+ if (string.IsNullOrWhiteSpace(ocl))
+ {
+ return ocl;
+ }
+
+ return Entries
+ .Where(erratum => ocl.Contains(erratum.Original, StringComparison.Ordinal))
+ .Aggregate(ocl, (corrected, erratum) =>
+ {
+ AppliedOriginals.Add(erratum.Original);
+
+ return corrected.Replace(erratum.Original, erratum.Replacement);
+ });
+ }
+
+ ///
+ /// Returns the corrections that matched no OCL body during this generator run.
+ ///
+ /// The stale entries, which should be pruned from .
+ ///
+ /// Only meaningful once every constraint has been read. A stale entry means the XMI no longer
+ /// carries the defect — either OMG fixed it, or the constraint was removed.
+ ///
+ public static IReadOnlyList QueryUnappliedErrata()
+ {
+ return [..Entries.Where(erratum => !AppliedOriginals.Contains(erratum.Original))];
+ }
+ }
+}
diff --git a/SysML2.NET.CodeGenerator/Extensions/OclErratum.cs b/SysML2.NET.CodeGenerator/Extensions/OclErratum.cs
new file mode 100644
index 00000000..db6a1553
--- /dev/null
+++ b/SysML2.NET.CodeGenerator/Extensions/OclErratum.cs
@@ -0,0 +1,74 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.CodeGenerator.Extensions
+{
+ using System;
+
+ ///
+ /// A single correction applied to an OCL body carried by the UML XMI.
+ ///
+ public sealed class OclErratum
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The exact text the XMI carries, including any surrounding quotes.
+ /// The text it is corrected to.
+ /// The evidence that the original is a defect rather than intent.
+ /// Thrown when any argument is null or whitespace.
+ public OclErratum(string original, string replacement, string justification)
+ {
+ if (string.IsNullOrWhiteSpace(original))
+ {
+ throw new ArgumentException("The original text is required.", nameof(original));
+ }
+
+ if (string.IsNullOrWhiteSpace(replacement))
+ {
+ throw new ArgumentException("The replacement text is required.", nameof(replacement));
+ }
+
+ if (string.IsNullOrWhiteSpace(justification))
+ {
+ throw new ArgumentException("A justification is required so the correction can be audited.", nameof(justification));
+ }
+
+ this.Original = original;
+ this.Replacement = replacement;
+ this.Justification = justification;
+ }
+
+ ///
+ /// Gets the exact text the XMI carries.
+ ///
+ public string Original { get; }
+
+ ///
+ /// Gets the text it is corrected to.
+ ///
+ public string Replacement { get; }
+
+ ///
+ /// Gets the evidence that the original is a defect rather than intent.
+ ///
+ public string Justification { get; }
+ }
+}
diff --git a/SysML2.NET.CodeGenerator/Generators/UmlHandleBarsGenerators/UmlCoreImpliedRelationshipGenerator.cs b/SysML2.NET.CodeGenerator/Generators/UmlHandleBarsGenerators/UmlCoreImpliedRelationshipGenerator.cs
new file mode 100644
index 00000000..59cde8dc
--- /dev/null
+++ b/SysML2.NET.CodeGenerator/Generators/UmlHandleBarsGenerators/UmlCoreImpliedRelationshipGenerator.cs
@@ -0,0 +1,480 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.CodeGenerator.Generators.UmlHandleBarsGenerators
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Threading.Tasks;
+
+ using SysML2.NET.CodeGenerator.Extensions;
+
+ using uml4net.Classification;
+ using uml4net.Extensions;
+ using uml4net.HandleBars;
+ using uml4net.SimpleClassifiers;
+ using uml4net.StructuredClassifiers;
+ using uml4net.xmi.Readers;
+
+ using ClassHelper = SysML2.NET.CodeGenerator.HandleBarHelpers.ClassHelper;
+ using NamedElementHelper = SysML2.NET.CodeGenerator.HandleBarHelpers.NamedElementHelper;
+ using PropertyHelper = SysML2.NET.CodeGenerator.HandleBarHelpers.PropertyHelper;
+
+ ///
+ /// Generates the table of implied library Specializations that KerML 1.0 §8.4.2 allows a tool to
+ /// insert in order to satisfy the specialization constraints of the abstract syntax.
+ ///
+ ///
+ /// Only the machine-readable half of each constraint is generated: the constrained metaclass and the
+ /// qualified name of the library Type, both taken from the constraint's OCL body. The half that the OCL
+ /// does NOT carry — whether the implied Relationship is a Subclassification or a
+ /// Subsetting — lives only in the specification tables (KerML Tables 8 and 10, SysML Tables
+ /// 31-33) and is hard-coded in the Handlebars template.
+ ///
+ /// Constraints whose OCL is not a bare or guarded specializesFromLibrary call are NOT generated;
+ /// they are emitted into a manifest on the generated class so that no semantic constraint is silently
+ /// dropped while the hand-coded arms are still outstanding.
+ ///
+ ///
+ public class UmlCoreImpliedRelationshipGenerator : UmlHandleBarsGenerator
+ {
+ ///
+ /// The name of the Handlebars template that emits the table.
+ ///
+ private const string ImpliedRelationshipTemplateName = "core-implied-relationship-table-template";
+
+ ///
+ /// The name of the file to write into the output directory.
+ ///
+ private const string OutputFileName = "ImpliedRelationshipTable.cs";
+
+ ///
+ /// The name of the template rendering the generated guards.
+ ///
+ private const string ImpliedGuardsTemplateName = "core-implied-guards-template";
+
+ ///
+ /// The name of the file the generated guards are written to.
+ ///
+ private const string GuardsOutputFileName = "GeneratedImpliedRuleGuards.cs";
+
+ ///
+ /// Generates the file in the supplied .
+ ///
+ ///
+ /// The with the loaded UML model
+ ///
+ ///
+ /// The target directory
+ ///
+ ///
+ /// An awaitable
+ ///
+ public override async Task GenerateAsync(XmiReaderResult xmiReaderResult, DirectoryInfo outputDirectory)
+ {
+ await this.GenerateImpliedRelationshipTable(xmiReaderResult, outputDirectory);
+ await this.GenerateImpliedRuleGuards(xmiReaderResult, outputDirectory);
+ }
+
+ ///
+ /// Generates the file in the supplied .
+ ///
+ /// The carrying the abstract syntax.
+ /// The directory the file is written to.
+ /// The rendered content.
+ /// Thrown when either argument is null.
+ public async Task GenerateImpliedRuleGuards(XmiReaderResult xmiReaderResult, DirectoryInfo outputDirectory)
+ {
+ ArgumentNullException.ThrowIfNull(xmiReaderResult);
+ ArgumentNullException.ThrowIfNull(outputDirectory);
+
+ var payload = QueryImpliedRelationshipPayload(xmiReaderResult);
+
+ var template = this.Templates[ImpliedGuardsTemplateName];
+ var rendered = template(payload);
+ rendered = this.CodeCleanup(rendered);
+
+ await WriteAsync(rendered, outputDirectory, GuardsOutputFileName);
+
+ return rendered;
+ }
+
+ ///
+ /// Renders the table, writes it to and returns the generated
+ /// source for assertion in expected-output tests.
+ ///
+ ///
+ /// The with the loaded UML model
+ ///
+ ///
+ /// The target directory
+ ///
+ ///
+ /// The generated C# source, after CodeCleanup
+ ///
+ public async Task GenerateImpliedRelationshipTable(XmiReaderResult xmiReaderResult, DirectoryInfo outputDirectory)
+ {
+ ArgumentNullException.ThrowIfNull(xmiReaderResult);
+ ArgumentNullException.ThrowIfNull(outputDirectory);
+
+ var payload = QueryImpliedRelationshipPayload(xmiReaderResult);
+
+ var template = this.Templates[ImpliedRelationshipTemplateName];
+ var rendered = template(payload);
+ rendered = this.CodeCleanup(rendered);
+
+ await WriteAsync(rendered, outputDirectory, OutputFileName);
+
+ return rendered;
+ }
+
+ ///
+ /// Register the custom Handlebars helpers used by the template.
+ ///
+ protected override void RegisterHelpers()
+ {
+ this.Handlebars.RegisterStringHelper();
+ this.Handlebars.RegisterPropertyHelper();
+ this.Handlebars.RegisterClassHelper();
+ NamedElementHelper.RegisterNamedElementHelper(this.Handlebars);
+ PropertyHelper.RegisterPropertyHelper(this.Handlebars);
+ ClassHelper.RegisterClassHelper(this.Handlebars);
+ }
+
+ ///
+ /// Register the code template.
+ ///
+ protected override void RegisterTemplates()
+ {
+ this.RegisterTemplate(ImpliedRelationshipTemplateName);
+ this.RegisterTemplate(ImpliedGuardsTemplateName);
+ }
+
+ ///
+ /// Builds the payload: one entry per metaclass that carries at least one generatable specialization
+ /// constraint, with the constraints of its supertypes FLATTENED IN, plus the manifest of constraints
+ /// that still need hand-coding.
+ ///
+ ///
+ /// Flattening at generation time is deliberate: a PartUsage is subject to the specialization
+ /// constraints of OccurrenceUsage, Usage, Feature and Type as well as its
+ /// own, and resolving that at run time would mean walking the metaclass hierarchy on every query.
+ /// Note that this does NOT pre-apply the §8.4.2 redundancy rules — rule 1 asks whether one implied
+ /// target is a subtype of another, and the targets are library elements that are not present in
+ /// these XMI files, so that reduction can only happen at run time.
+ ///
+ ///
+ /// The with the loaded UML model
+ ///
+ ///
+ /// The payload consumed by the template
+ ///
+ private static ImpliedRelationshipPayload QueryImpliedRelationshipPayload(XmiReaderResult xmiReaderResult)
+ {
+ var rules = xmiReaderResult.QueryImpliedRelationshipRules();
+
+ // Every constraint has now been read, so a correction that matched nothing is stale: the XMI no
+ // longer carries the defect it repairs. Reported rather than thrown, since a fix upstream must
+ // not break generation.
+ foreach (var stale in OclErrata.QueryUnappliedErrata())
+ {
+ Console.WriteLine($"[OclErrata] STALE — {stale.Original} matched no OCL body and should be pruned. Recorded reason: {stale.Justification}");
+ }
+
+ var generatable = rules
+ .Where(rule => rule.Form is ImpliedRuleForm.UnconditionalLibrarySpecialization or ImpliedRuleForm.GuardedLibrarySpecialization)
+ .ToLookup(rule => rule.MetaclassName, StringComparer.Ordinal);
+
+ var classesByName = xmiReaderResult.QueryContainedAndImported("SysML")
+ .SelectMany(package => package.PackagedElement.OfType())
+ .GroupBy(umlClass => umlClass.Name, StringComparer.Ordinal)
+ .ToDictionary(group => group.Key, group => group.First(), StringComparer.Ordinal);
+
+ var metaclasses = classesByName.Values
+ .Select(umlClass => CreateMetaclassRules(umlClass, generatable))
+ .Where(metaclass => metaclass.Rules.Count > 0)
+ .OrderByDescending(metaclass => metaclass.InheritanceDepth)
+ .ThenBy(metaclass => metaclass.MetaclassName, StringComparer.Ordinal)
+ .ToList();
+
+ var notCovered = rules
+ .Where(rule => rule.Form is ImpliedRuleForm.RequiresHandCoding or ImpliedRuleForm.SpecificationTbd)
+ .Select(rule => new NotCoveredConstraint
+ {
+ ConstraintName = rule.ConstraintName,
+ MetaclassName = rule.MetaclassName,
+ Category = rule.Category.ToString(),
+ Reason = rule.Form == ImpliedRuleForm.SpecificationTbd ? "specification body is TBD" : "OCL is not a specializesFromLibrary call"
+ })
+ .ToList();
+
+ var allConstraintNames = rules
+ .Select(rule => rule.ConstraintName)
+ .Distinct(StringComparer.Ordinal)
+ .OrderBy(constraintName => constraintName, StringComparer.Ordinal)
+ .ToList();
+
+ var interfaceFqnByName = classesByName.ToDictionary(entry => entry.Key, entry => entry.Value.QueryFullyQualifiedTypeName(), StringComparer.Ordinal);
+
+ var enumerationFqnByName = xmiReaderResult.QueryContainedAndImported("SysML")
+ .SelectMany(package => package.PackagedElement.OfType())
+ .GroupBy(enumeration => enumeration.Name, StringComparer.Ordinal)
+ .ToDictionary(group => group.Key, group => group.First().QueryFullyQualifiedTypeName(), StringComparer.Ordinal);
+
+ var guards = rules
+ .Where(rule => rule.Form == ImpliedRuleForm.GuardedLibrarySpecialization)
+ .Select(rule => new
+ {
+ rule.ConstraintName,
+ Expression = ImpliedGuardParser.Parse(rule.GuardExpression),
+ DeclaringInterfaceFqn = interfaceFqnByName.TryGetValue(rule.MetaclassName, out var declaringFqn) ? declaringFqn : null
+ })
+ .Select(candidate => new ImpliedGuardPayload
+ {
+ ConstraintName = candidate.ConstraintName,
+ Ocl = candidate.Expression.Ocl,
+ Predicate = ImpliedGuardEmitter.Emit(candidate.Expression, candidate.DeclaringInterfaceFqn, interfaceFqnByName, enumerationFqnByName)
+ })
+ .Where(guard => guard.Predicate != null)
+ .GroupBy(guard => guard.ConstraintName, StringComparer.Ordinal)
+ .Select(group => group.First())
+ .OrderBy(guard => guard.ConstraintName, StringComparer.Ordinal)
+ .ToList();
+
+ var conditionalConstraintNames = rules
+ .Where(rule => rule.Form == ImpliedRuleForm.GuardedLibrarySpecialization)
+ .Select(rule => rule.ConstraintName)
+ .Distinct(StringComparer.Ordinal)
+ .OrderBy(constraintName => constraintName, StringComparer.Ordinal)
+ .ToList();
+
+ var allLibraryTargets = rules
+ .Where(rule => !string.IsNullOrWhiteSpace(rule.TargetLibraryName))
+ .Select(rule => rule.TargetLibraryName)
+ .Distinct(StringComparer.Ordinal)
+ .OrderBy(libraryTarget => libraryTarget, StringComparer.Ordinal)
+ .ToList();
+
+ return new ImpliedRelationshipPayload
+ {
+ Metaclasses = metaclasses,
+ NotCovered = notCovered,
+ AllConstraintNames = allConstraintNames,
+ ConditionalConstraintNames = conditionalConstraintNames,
+ AllLibraryTargets = allLibraryTargets,
+ Guards = guards
+ };
+ }
+
+ ///
+ /// Collects the generatable specialization constraints that apply to a metaclass — its own plus every
+ /// one inherited from a general classifier — ordered most-general first so the emitted array reads
+ /// from the root of the hierarchy downwards.
+ ///
+ ///
+ /// The metaclass to project
+ ///
+ ///
+ /// The generatable rules, keyed by declaring metaclass name
+ ///
+ ///
+ /// The metaclass entry, possibly with an empty rule list
+ ///
+ private static ImpliedMetaclassRules CreateMetaclassRules(IClass umlClass, ILookup generatable)
+ {
+ var generalClassifiers = umlClass.QueryAllGeneralClassifiers().ToList();
+
+ var applicable = generalClassifiers
+ .Select(general => general.Name)
+ .Append(umlClass.Name)
+ .Distinct(StringComparer.Ordinal)
+ .SelectMany(name => generatable[name])
+ .OrderBy(rule => rule.ConstraintName, StringComparer.Ordinal)
+ .Select(rule => new ImpliedLibraryRule
+ {
+ ConstraintName = rule.ConstraintName,
+ DeclaringMetaclassName = rule.MetaclassName,
+ TargetLibraryName = rule.TargetLibraryName,
+ RequiresGuard = rule.Form == ImpliedRuleForm.GuardedLibrarySpecialization
+ })
+ .ToList();
+
+ return new ImpliedMetaclassRules
+ {
+ MetaclassName = umlClass.Name,
+ InterfaceFqn = umlClass.QueryFullyQualifiedTypeName(),
+ InheritanceDepth = generalClassifiers.Count,
+ IsAbstract = umlClass.IsAbstract,
+ Rules = applicable
+ };
+ }
+ }
+
+ ///
+ /// The payload consumed by the implied-relationship-table template.
+ ///
+ public class ImpliedRelationshipPayload
+ {
+ ///
+ /// Gets the metaclasses carrying at least one generatable specialization constraint, ordered
+ /// most-derived first so the emitted switch matches the narrowest interface first.
+ ///
+ public IReadOnlyList Metaclasses { get; init; }
+
+ ///
+ /// Gets the semantic constraints that could not be generated, emitted as a manifest so that none is
+ /// silently dropped.
+ ///
+ public IReadOnlyList NotCovered { get; init; }
+
+ ///
+ /// Gets the names of every semantic constraint found in the model, covered or not, so a consumer can
+ /// report what it does not compute without hard-coding a list.
+ ///
+ public IReadOnlyList AllConstraintNames { get; init; }
+
+ ///
+ /// Gets the names of the constraints whose application is conditional, i.e. every row that requires
+ /// a guard.
+ ///
+ public IReadOnlyList ConditionalConstraintNames { get; init; }
+
+ ///
+ /// Gets the qualified name of every library Type targeted by a row, without duplicates, so that
+ /// resolution can be asserted for the whole table.
+ ///
+ public IReadOnlyList AllLibraryTargets { get; init; }
+
+ ///
+ /// Gets the conditional constraints whose guard OCL was mechanically translated into a predicate.
+ ///
+ public IReadOnlyList Guards { get; init; }
+ }
+
+ ///
+ /// One conditional constraint whose guard was translated into a C# predicate.
+ ///
+ public class ImpliedGuardPayload
+ {
+ ///
+ /// Gets the constraint the guard decides.
+ ///
+ public string ConstraintName { get; init; }
+
+ ///
+ /// Gets the guard OCL, emitted as the generated member's doc comment.
+ ///
+ public string Ocl { get; init; }
+
+ ///
+ /// Gets the C# boolean expression over a parameter named element.
+ ///
+ public string Predicate { get; init; }
+ }
+
+ ///
+ /// The generatable specialization constraints that apply to one metaclass.
+ ///
+ public class ImpliedMetaclassRules
+ {
+ ///
+ /// Gets the metaclass name, e.g. PartUsage.
+ ///
+ public string MetaclassName { get; init; }
+
+ ///
+ /// Gets the fully qualified POCO interface name, e.g.
+ /// SysML2.NET.Core.POCO.Systems.Parts.IPartUsage.
+ ///
+ public string InterfaceFqn { get; init; }
+
+ ///
+ /// Gets the number of general classifiers, used to order the emitted switch most-derived first.
+ ///
+ public int InheritanceDepth { get; init; }
+
+ ///
+ /// Gets a value indicating whether the metaclass is abstract.
+ ///
+ public bool IsAbstract { get; init; }
+
+ ///
+ /// Gets the applicable rules, own and inherited, ordered by constraint name.
+ ///
+ public IReadOnlyList Rules { get; init; }
+ }
+
+ ///
+ /// A single implied library specialization.
+ ///
+ public class ImpliedLibraryRule
+ {
+ ///
+ /// Gets the name of the constraint the rule was extracted from.
+ ///
+ public string ConstraintName { get; init; }
+
+ ///
+ /// Gets the metaclass the constraint is declared on, which may be a supertype of the metaclass the
+ /// rule is emitted for. The relationship KIND is decided from this name, not from the inheriting
+ /// metaclass.
+ ///
+ public string DeclaringMetaclassName { get; init; }
+
+ ///
+ /// Gets the qualified name of the library Type that must be specialized.
+ ///
+ public string TargetLibraryName { get; init; }
+
+ ///
+ /// Gets a value indicating whether the constraint's OCL guards the specialization, in which case the
+ /// rule only applies when a hand-written predicate says so.
+ ///
+ public bool RequiresGuard { get; init; }
+ }
+
+ ///
+ /// A semantic constraint that the generator could not turn into a table row.
+ ///
+ public class NotCoveredConstraint
+ {
+ ///
+ /// Gets the name of the constraint.
+ ///
+ public string ConstraintName { get; init; }
+
+ ///
+ /// Gets the metaclass the constraint is declared on.
+ ///
+ public string MetaclassName { get; init; }
+
+ ///
+ /// Gets the §8.4.2 category of the constraint.
+ ///
+ public string Category { get; init; }
+
+ ///
+ /// Gets why the constraint could not be generated.
+ ///
+ public string Reason { get; init; }
+ }
+}
diff --git a/SysML2.NET.CodeGenerator/SysML2.NET.CodeGenerator.csproj b/SysML2.NET.CodeGenerator/SysML2.NET.CodeGenerator.csproj
index affa35f1..0078c0fa 100644
--- a/SysML2.NET.CodeGenerator/SysML2.NET.CodeGenerator.csproj
+++ b/SysML2.NET.CodeGenerator/SysML2.NET.CodeGenerator.csproj
@@ -235,6 +235,12 @@
Always
+
+ Always
+
+
+ Always
+
Always
diff --git a/SysML2.NET.CodeGenerator/Templates/Uml/core-implied-guards-template.hbs b/SysML2.NET.CodeGenerator/Templates/Uml/core-implied-guards-template.hbs
new file mode 100644
index 00000000..44e7193e
--- /dev/null
+++ b/SysML2.NET.CodeGenerator/Templates/Uml/core-implied-guards-template.hbs
@@ -0,0 +1,50 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------------------------------
+// --------THIS IS AN AUTOMATICALLY GENERATED FILE. ANY MANUAL CHANGES WILL BE OVERWRITTEN!--------
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using System.Collections.Generic;
+ using System.Linq;
+
+ ///
+ /// The guards whose OCL was mechanically translated from the abstract syntax.
+ ///
+ ///
+ /// A conditional semantic constraint absent from this set has a guard expression outside the
+ /// translatable shapes and must be supplied by a hand-written .
+ ///
+ public static class GeneratedImpliedRuleGuards
+ {
+ ///
+ /// The generated guards, ordered by constraint name.
+ ///
+ public static IReadOnlyList All { get; } =
+ [
+{{#each Guards as | guard |}}
+ // {{{guard.Ocl}}}
+ new GeneratedRuleGuard("{{guard.ConstraintName}}", element => {{{guard.Predicate}}}),
+{{/each}}
+ ];
+ }
+}
diff --git a/SysML2.NET.CodeGenerator/Templates/Uml/core-implied-relationship-table-template.hbs b/SysML2.NET.CodeGenerator/Templates/Uml/core-implied-relationship-table-template.hbs
new file mode 100644
index 00000000..dbf385db
--- /dev/null
+++ b/SysML2.NET.CodeGenerator/Templates/Uml/core-implied-relationship-table-template.hbs
@@ -0,0 +1,258 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------------------------------
+// --------THIS IS AN AUTOMATICALLY GENERATED FILE. ANY MANUAL CHANGES WILL BE OVERWRITTEN!--------
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using System.Collections.Generic;
+
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// The kind of Relationship that is implied to satisfy a semantic constraint.
+ ///
+ public enum ImpliedRelationshipKind
+ {
+ ///
+ /// A Subclassification, implied for a Classifier.
+ ///
+ Subclassification,
+
+ ///
+ /// A Subsetting, implied for a Feature.
+ ///
+ Subsetting
+ }
+
+ ///
+ /// A single implied library Specialization, as required by one semantic constraint of the
+ /// KerML/SysML abstract syntax.
+ ///
+ public readonly struct ImpliedLibrarySpecialization
+ {
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The name of the semantic constraint the rule was extracted from
+ ///
+ ///
+ /// The qualified name of the library Type that must be specialized
+ ///
+ ///
+ /// The metaclass the constraint is declared on, which decides
+ ///
+ ///
+ /// Whether the constraint's OCL guards the specialization
+ ///
+ public ImpliedLibrarySpecialization(string constraintName, string targetLibraryName, string declaringMetaclassName, bool requiresGuard)
+ {
+ this.ConstraintName = constraintName;
+ this.TargetLibraryName = targetLibraryName;
+ this.DeclaringMetaclassName = declaringMetaclassName;
+ this.RequiresGuard = requiresGuard;
+ }
+
+ ///
+ /// Gets the name of the semantic constraint the rule was extracted from.
+ ///
+ public string ConstraintName { get; }
+
+ ///
+ /// Gets the qualified name of the library Type that must be specialized.
+ ///
+ public string TargetLibraryName { get; }
+
+ ///
+ /// Gets the metaclass the constraint is declared on. The Relationship kind is decided from this
+ /// name, not from the metaclass that inherits the constraint.
+ ///
+ public string DeclaringMetaclassName { get; }
+
+ ///
+ /// Gets a value indicating whether the constraint's OCL guards the specialization, in which case the
+ /// rule applies only when the hand-written predicate for says so.
+ ///
+ public bool RequiresGuard { get; }
+
+ ///
+ /// Gets the kind of Relationship to imply, decided by whether the declaring metaclass is a
+ /// Classifier or a Feature.
+ ///
+ public ImpliedRelationshipKind Kind =>
+ ImpliedRelationshipTable.SubclassificationMetaclasses.Contains(this.DeclaringMetaclassName)
+ ? ImpliedRelationshipKind.Subclassification
+ : ImpliedRelationshipKind.Subsetting;
+ }
+
+ ///
+ /// The table of implied library Specializations that KerML 1.0 §8.4.2 allows a tool to insert to
+ /// satisfy the specialization constraints of the abstract syntax.
+ ///
+ ///
+ ///
+ /// The metaclass and the library target of each row come from the constraint's OCL body in the UML XMI.
+ /// The does NOT: the OCL says only what to specialize, never
+ /// whether the implied Relationship is a Subclassification or a Subsetting. That is stated only in the
+ /// specification tables — KerML 1.0 Table 8 (§8.4.3.1.1) and Table 10 (§8.4.4.1), and SysML 2.0
+ /// Tables 31-33 — so below is transcribed by hand from those
+ /// tables and lives in the Handlebars template, not in the generator.
+ ///
+ ///
+ /// Rows are NOT reduced against the §8.4.2 redundancy rules. Rule 1 suppresses an implied Specialization
+ /// whose general Type is a supertype of another applicable one, and deciding that needs the library
+ /// Types resolved — they are not present in the metamodel XMI. The reduction therefore belongs to the
+ /// caller, which must also apply rule 2 (de-duplicate identical targets). Neither rule applies to
+ /// Redefinitions.
+ ///
+ ///
+ public static class ImpliedRelationshipTable
+ {
+ ///
+ /// The metaclasses whose implied Specialization is a Subclassification rather than a
+ /// Subsetting — that is, the Classifiers.
+ ///
+ ///
+ /// HAND-MAINTAINED. This is the one part of the table that cannot be derived from the OCL; it is
+ /// transcribed from KerML Table 8 / Table 10 and SysML Tables 31-33. KerML Table 8 note 1 is the
+ /// reason Type is absent: checkTypeSpecialization applies to every Type, but the
+ /// Subclassification is only implied for Classifiers. Anything not listed here is a Feature and
+ /// implies a Subsetting.
+ ///
+ internal static readonly HashSet SubclassificationMetaclasses =
+ [
+ "ActionDefinition",
+ "AllocationDefinition",
+ "AnalysisCaseDefinition",
+ "Association",
+ "AssociationStructure",
+ "Behavior",
+ "CalculationDefinition",
+ "CaseDefinition",
+ "Class",
+ "ConcernDefinition",
+ "ConnectionDefinition",
+ "ConstraintDefinition",
+ "DataType",
+ "FlowDefinition",
+ "Function",
+ "InterfaceDefinition",
+ "ItemDefinition",
+ "Metaclass",
+ "MetadataDefinition",
+ "OccurrenceDefinition",
+ "PartDefinition",
+ "PortDefinition",
+ "Predicate",
+ "RenderingDefinition",
+ "RequirementDefinition",
+ "StateDefinition",
+ "Structure",
+ "UseCaseDefinition",
+ "VerificationCaseDefinition",
+ "ViewDefinition",
+ "ViewpointDefinition"
+ ];
+
+ ///
+ /// The semantic constraints that are NOT represented in this table, with the reason. Emitted so that
+ /// no constraint of KerML §8.4.2 is silently dropped while its hand-coded arm is outstanding.
+ ///
+ public static IReadOnlyList NotCovered { get; } =
+ [
+{{#each NotCovered as | constraint |}}
+ "{{constraint.MetaclassName}}.{{constraint.ConstraintName}} ({{constraint.Category}}) - {{constraint.Reason}}",
+{{/each}}
+ ];
+
+ ///
+ /// The name of every semantic constraint declared in the abstract syntax, covered or not.
+ ///
+ public static IReadOnlyList AllConstraintNames { get; } =
+ [
+{{#each AllConstraintNames as | constraintName |}}
+ "{{constraintName}}",
+{{/each}}
+ ];
+
+ ///
+ /// The name of every constraint whose application is conditional, i.e. every row that requires a
+ /// guard before its implied Relationship may be included.
+ ///
+ public static IReadOnlyList AllConditionalConstraintNames { get; } =
+ [
+{{#each ConditionalConstraintNames as | constraintName |}}
+ "{{constraintName}}",
+{{/each}}
+ ];
+
+ ///
+ /// The qualified name of every library Type targeted by a row of this table, without duplicates.
+ ///
+ ///
+ /// Every name here must resolve against a full model-library load, or the constraint that carries
+ /// it can never be satisfied. Exposed so that resolution can be asserted for the whole table rather
+ /// than only for the rows a given corpus happens to exercise.
+ ///
+ public static IReadOnlyList AllLibraryTargets { get; } =
+ [
+{{#each AllLibraryTargets as | libraryTarget |}}
+ "{{libraryTarget}}",
+{{/each}}
+ ];
+
+ ///
+ /// Returns the implied library Specializations that apply to the supplied element, including
+ /// those inherited from its supertypes in the metamodel.
+ ///
+ ///
+ /// The to query
+ ///
+ ///
+ /// The applicable rules, or an empty list when the metaclass carries none
+ ///
+ public static IReadOnlyList QueryImpliedLibrarySpecializations(IElement element)
+ {
+ return element switch
+ {
+{{#each Metaclasses as | metaclass |}}
+ {{metaclass.InterfaceFqn}} => {{metaclass.MetaclassName}}Rules,
+{{/each}}
+ _ => []
+ };
+ }
+
+{{#each Metaclasses as | metaclass |}}
+ ///
+ /// The implied library Specializations applying to {{metaclass.MetaclassName}}, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] {{metaclass.MetaclassName}}Rules =
+ [
+{{#each metaclass.Rules as | rule |}}
+ new("{{rule.ConstraintName}}", "{{rule.TargetLibraryName}}", "{{rule.DeclaringMetaclassName}}", {{#if rule.RequiresGuard}}true{{else}}false{{/if}}),
+{{/each}}
+ ];
+
+{{/each}}
+ }
+}
diff --git a/SysML2.NET.Semantics.Tests/Implied/Guards/ImpliedRuleGuardTestFixture.cs b/SysML2.NET.Semantics.Tests/Implied/Guards/ImpliedRuleGuardTestFixture.cs
new file mode 100644
index 00000000..0182dc59
--- /dev/null
+++ b/SysML2.NET.Semantics.Tests/Implied/Guards/ImpliedRuleGuardTestFixture.cs
@@ -0,0 +1,326 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Tests.Implied.Guards
+{
+ using System;
+ using System.Linq;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Core.POCO.Kernel.Associations;
+ using SysML2.NET.Core.POCO.Kernel.Classes;
+ using SysML2.NET.Core.POCO.Kernel.Connectors;
+ using SysML2.NET.Core.POCO.Kernel.DataTypes;
+ using SysML2.NET.Core.POCO.Kernel.Structures;
+ using SysML2.NET.Core.POCO.Systems.Occurrences;
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Systems.Actions;
+ using SysML2.NET.Core.POCO.Systems.Connections;
+ using SysML2.NET.Core.POCO.Systems.Parts;
+ using SysML2.NET.Semantics.Implied;
+ using SysML2.NET.Semantics.Implied.Guards;
+
+ [TestFixture]
+ public class ImpliedRuleGuardTestFixture
+ {
+ [Test]
+ public void VerifyFeatureDataValueSpecializationGuard()
+ {
+ var guard = Generated("checkFeatureDataValueSpecialization");
+
+ var typedByDataType = new Feature { Id = Guid.NewGuid() };
+ Type(typedByDataType, new DataType { Id = Guid.NewGuid(), DeclaredName = "Real" });
+
+ var typedByClass = new Feature { Id = Guid.NewGuid() };
+ Type(typedByClass, new Class { Id = Guid.NewGuid(), DeclaredName = "Widget" });
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(guard.ConstraintName, Is.EqualTo("checkFeatureDataValueSpecialization"));
+ Assert.That(guard.Applies(typedByDataType), Is.True);
+ Assert.That(guard.Applies(typedByClass), Is.False);
+ Assert.That(guard.Applies(new Feature { Id = Guid.NewGuid() }), Is.False);
+ Assert.That(guard.Applies(new Class { Id = Guid.NewGuid() }), Is.False);
+ Assert.That(() => guard.Applies(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyConnectionUsageBinarySpecializationGuard()
+ {
+ var guard = Generated("checkConnectionUsageBinarySpecialization");
+
+ var binary = new ConnectionUsage { Id = Guid.NewGuid() };
+ AddEnds(binary, 2);
+
+ var nary = new ConnectionUsage { Id = Guid.NewGuid() };
+ AddEnds(nary, 3);
+
+ var unary = new ConnectionUsage { Id = Guid.NewGuid() };
+ AddEnds(unary, 1);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(guard.ConstraintName, Is.EqualTo("checkConnectionUsageBinarySpecialization"));
+ Assert.That(guard.Applies(binary), Is.True);
+
+ // The OCL is an EXACT count, so an n-ary connection must decline, not merely a unary one.
+ Assert.That(guard.Applies(nary), Is.False);
+ Assert.That(guard.Applies(unary), Is.False);
+ Assert.That(guard.Applies(new ConnectionUsage { Id = Guid.NewGuid() }), Is.False);
+ Assert.That(guard.Applies(new Feature { Id = Guid.NewGuid() }), Is.False);
+ Assert.That(() => guard.Applies(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyActionUsageOwnedActionSpecializationGuard()
+ {
+ var guard = Generated("checkActionUsageOwnedActionSpecialization");
+
+ var ownedByPartUsage = CreateActionUsage(true, new PartUsage { Id = Guid.NewGuid() });
+ var ownedByPartDefinition = CreateActionUsage(true, new PartDefinition { Id = Guid.NewGuid() });
+ var notComposite = CreateActionUsage(false, new PartUsage { Id = Guid.NewGuid() });
+ var ownedByNonPart = CreateActionUsage(true, new ActionUsage { Id = Guid.NewGuid() });
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(guard.ConstraintName, Is.EqualTo("checkActionUsageOwnedActionSpecialization"));
+ Assert.That(guard.Applies(ownedByPartUsage), Is.True);
+ Assert.That(guard.Applies(ownedByPartDefinition), Is.True);
+
+ // Both conjuncts matter: composite alone, or a part owner alone, is not enough.
+ Assert.That(guard.Applies(notComposite), Is.False);
+ Assert.That(guard.Applies(ownedByNonPart), Is.False);
+
+ // owningType is null when the ActionUsage is not owned by a Type at all.
+ Assert.That(guard.Applies(new ActionUsage { Id = Guid.NewGuid(), IsComposite = true }), Is.False);
+ Assert.That(guard.Applies(new Feature { Id = Guid.NewGuid() }), Is.False);
+ Assert.That(() => guard.Applies(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyFeatureEndSpecializationGuard()
+ {
+ var guard = new FeatureEndSpecializationGuard();
+
+ var associationEnd = CreateEnd(true, new Association { Id = Guid.NewGuid() });
+ var connectorEnd = CreateEnd(true, new Connector { Id = Guid.NewGuid() });
+ var notAnEnd = CreateEnd(false, new Association { Id = Guid.NewGuid() });
+ var ownedByPlainType = CreateEnd(true, new Class { Id = Guid.NewGuid() });
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(guard.ConstraintName, Is.EqualTo("checkFeatureEndSpecialization"));
+ Assert.That(guard.Applies(associationEnd), Is.True);
+ Assert.That(guard.Applies(connectorEnd), Is.True);
+
+ // Both conjuncts matter: an end owned by a plain Type, or a non-end owned by an Association.
+ Assert.That(guard.Applies(notAnEnd), Is.False);
+ Assert.That(guard.Applies(ownedByPlainType), Is.False);
+ Assert.That(guard.Applies(new Feature { Id = Guid.NewGuid(), IsEnd = true }), Is.False);
+ Assert.That(() => guard.Applies(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyConnectorBinaryObjectSpecializationGuard()
+ {
+ var guard = new ConnectorBinaryObjectSpecializationGuard();
+
+ var binaryStructure = CreateConnector(2, new AssociationStructure { Id = Guid.NewGuid() });
+ var binaryPlainAssociation = CreateConnector(2, new Association { Id = Guid.NewGuid() });
+ var naryStructure = CreateConnector(3, new AssociationStructure { Id = Guid.NewGuid() });
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(guard.ConstraintName, Is.EqualTo("checkConnectorBinaryObjectSpecialization"));
+ Assert.That(guard.Applies(binaryStructure), Is.True);
+
+ // A binary Connector typed by a plain Association carries a DIFFERENT library Specialization.
+ Assert.That(guard.Applies(binaryPlainAssociation), Is.False);
+ Assert.That(guard.Applies(naryStructure), Is.False);
+ Assert.That(guard.Applies(new Feature { Id = Guid.NewGuid() }), Is.False);
+ Assert.That(() => guard.Applies(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyOccurrenceDefinitionIndividualSpecializationGuard()
+ {
+ var guard = Generated("checkOccurrenceDefinitionIndividualSpecialization");
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(guard.ConstraintName, Is.EqualTo("checkOccurrenceDefinitionIndividualSpecialization"));
+ Assert.That(guard.Applies(new OccurrenceDefinition { Id = Guid.NewGuid(), IsIndividual = true }), Is.True);
+ Assert.That(guard.Applies(new OccurrenceDefinition { Id = Guid.NewGuid(), IsIndividual = false }), Is.False);
+ Assert.That(guard.Applies(new Feature { Id = Guid.NewGuid() }), Is.False);
+ Assert.That(() => guard.Applies(null), Throws.TypeOf());
+ }
+ }
+
+
+ [Test]
+ public void VerifyConnectorBinarySpecializationGuard()
+ {
+ var guard = new ConnectorBinarySpecializationGuard();
+
+ var binary = CreateConnector(2, new Association { Id = Guid.NewGuid() });
+ var nary = CreateConnector(3, new Association { Id = Guid.NewGuid() });
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(guard.ConstraintName, Is.EqualTo("checkConnectorBinarySpecialization"));
+ Assert.That(guard.Applies(binary), Is.True);
+ Assert.That(guard.Applies(nary), Is.False);
+ Assert.That(guard.Applies(new Connector { Id = Guid.NewGuid() }), Is.False);
+
+ // A non-Connector must decline — this also disproves the CA1508 claim that the merged
+ // pattern is "always true".
+ Assert.That(guard.Applies(new Feature { Id = Guid.NewGuid() }), Is.False);
+ Assert.That(() => guard.Applies(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyConnectorObjectSpecializationGuard()
+ {
+ var guard = new ConnectorObjectSpecializationGuard();
+
+ var structureTyped = CreateConnector(3, new AssociationStructure { Id = Guid.NewGuid() });
+ var plainAssociation = CreateConnector(3, new Association { Id = Guid.NewGuid() });
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(guard.ConstraintName, Is.EqualTo("checkConnectorObjectSpecialization"));
+
+ // Unlike its binary counterpart the end count is irrelevant here.
+ Assert.That(guard.Applies(structureTyped), Is.True);
+ Assert.That(guard.Applies(plainAssociation), Is.False);
+ Assert.That(guard.Applies(new Connector { Id = Guid.NewGuid() }), Is.False);
+ Assert.That(guard.Applies(new Feature { Id = Guid.NewGuid() }), Is.False);
+ Assert.That(() => guard.Applies(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyFeaturePortionSpecializationGuard()
+ {
+ var guard = new FeaturePortionSpecializationGuard();
+
+ var portionOwnedByClass = CreatePortion(true, new Class { Id = Guid.NewGuid() }, typedByClass: true);
+ var notAPortion = CreatePortion(false, new Class { Id = Guid.NewGuid() }, typedByClass: true);
+ var notClassTyped = CreatePortion(true, new Class { Id = Guid.NewGuid() }, typedByClass: false);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(guard.ConstraintName, Is.EqualTo("checkFeaturePortionSpecialization"));
+ Assert.That(guard.Applies(portionOwnedByClass), Is.True);
+
+ // Every conjunct of the constraint is load-bearing.
+ Assert.That(guard.Applies(notAPortion), Is.False);
+ Assert.That(guard.Applies(notClassTyped), Is.False);
+ Assert.That(guard.Applies(new Feature { Id = Guid.NewGuid(), IsPortion = true }), Is.False);
+ Assert.That(() => guard.Applies(null), Throws.TypeOf());
+ }
+ }
+
+ private static Feature CreatePortion(bool isPortion, IElement owner, bool typedByClass)
+ {
+ var portion = new Feature { Id = Guid.NewGuid(), IsPortion = isPortion };
+
+ if (typedByClass)
+ {
+ Type(portion, new Class { Id = Guid.NewGuid() });
+ }
+
+ var membership = new FeatureMembership { Id = Guid.NewGuid() };
+ ((IContainedRelationship)membership).OwnedRelatedElement.Add(portion);
+ ((IContainedElement)owner).OwnedRelationship.Add(membership);
+
+ return portion;
+ }
+
+ private static IImpliedRuleGuard Generated(string constraintName)
+ {
+ var guard = GeneratedImpliedRuleGuards.All.SingleOrDefault(candidate => candidate.ConstraintName == constraintName);
+
+ Assert.That(guard, Is.Not.Null, $"'{constraintName}' is expected to be generated from its guard OCL.");
+
+ return guard;
+ }
+
+ private static Feature CreateEnd(bool isEnd, IElement owner)
+ {
+ var end = new Feature { Id = Guid.NewGuid(), IsEnd = isEnd };
+
+ var membership = new FeatureMembership { Id = Guid.NewGuid() };
+ ((IContainedRelationship)membership).OwnedRelatedElement.Add(end);
+ ((IContainedElement)owner).OwnedRelationship.Add(membership);
+
+ return end;
+ }
+
+ private static Connector CreateConnector(int endCount, IElement association)
+ {
+ var connector = new Connector { Id = Guid.NewGuid() };
+
+ AddEnds(connector, endCount);
+
+ var featureTyping = new FeatureTyping { Id = Guid.NewGuid(), TypedFeature = connector, Type = (IType)association };
+ ((IContainedElement)connector).OwnedRelationship.Add(featureTyping);
+
+ return connector;
+ }
+
+ private static ActionUsage CreateActionUsage(bool isComposite, IElement owner)
+ {
+ var actionUsage = new ActionUsage { Id = Guid.NewGuid(), IsComposite = isComposite };
+
+ var membership = new FeatureMembership { Id = Guid.NewGuid() };
+ ((IContainedRelationship)membership).OwnedRelatedElement.Add(actionUsage);
+ ((IContainedElement)owner).OwnedRelationship.Add(membership);
+
+ return actionUsage;
+ }
+
+ private static void Type(IFeature feature, IType type)
+ {
+ var featureTyping = new FeatureTyping { Id = Guid.NewGuid(), TypedFeature = feature, Type = type };
+ ((IContainedElement)feature).OwnedRelationship.Add(featureTyping);
+ }
+
+ private static void AddEnds(IElement owner, int count)
+ {
+ for (var endIndex = 0; endIndex < count; endIndex++)
+ {
+ var end = new Feature { Id = Guid.NewGuid(), IsEnd = true };
+ var membership = new EndFeatureMembership { Id = Guid.NewGuid() };
+ ((IContainedRelationship)membership).OwnedRelatedElement.Add(end);
+ ((IContainedElement)owner).OwnedRelationship.Add(membership);
+ }
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics.Tests/Implied/ImpliedRelationshipFactoryTestFixture.cs b/SysML2.NET.Semantics.Tests/Implied/ImpliedRelationshipFactoryTestFixture.cs
new file mode 100644
index 00000000..66528789
--- /dev/null
+++ b/SysML2.NET.Semantics.Tests/Implied/ImpliedRelationshipFactoryTestFixture.cs
@@ -0,0 +1,112 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Tests.Implied
+{
+ using System;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.Core.POCO.Core.Classifiers;
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Semantics.Implied;
+
+ [TestFixture]
+ public class ImpliedRelationshipFactoryTestFixture
+ {
+ private ImpliedRelationshipFactory factory;
+
+ [SetUp]
+ public void SetUp()
+ {
+ this.factory = new ImpliedRelationshipFactory();
+ }
+
+ [Test]
+ public void VerifyCreateImpliedSubclassification()
+ {
+ var specific = new Classifier { Id = Guid.NewGuid(), DeclaredName = "Specific" };
+ var general = new Classifier { Id = Guid.NewGuid(), DeclaredName = "General" };
+
+ var subclassification = this.factory.CreateImpliedSubclassification(specific, general);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(subclassification.IsImplied, Is.True);
+ Assert.That(subclassification.Subclassifier, Is.SameAs(specific));
+ Assert.That(subclassification.Superclassifier, Is.SameAs(general));
+ Assert.That(subclassification.Id, Is.Not.EqualTo(Guid.Empty));
+ Assert.That((subclassification).General, Is.SameAs(general));
+ Assert.That((subclassification).Specific, Is.SameAs(specific));
+
+ // The product must stay detached: attaching it would oblige the Element to declare
+ // isImpliedIncluded, which cannot be honoured while constraints remain uncovered.
+ Assert.That(specific.OwnedRelationship, Is.Empty);
+ Assert.That(general.OwnedRelationship, Is.Empty);
+
+ Assert.That(() => this.factory.CreateImpliedSubclassification(null, general), Throws.TypeOf());
+ Assert.That(() => this.factory.CreateImpliedSubclassification(specific, null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyCreateImpliedSubsetting()
+ {
+ var specific = new Feature { Id = Guid.NewGuid(), DeclaredName = "specific" };
+ var general = new Feature { Id = Guid.NewGuid(), DeclaredName = "general" };
+
+ var subsetting = this.factory.CreateImpliedSubsetting(specific, general);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(subsetting.IsImplied, Is.True);
+ Assert.That(subsetting.SubsettingFeature, Is.SameAs(specific));
+ Assert.That(subsetting.SubsettedFeature, Is.SameAs(general));
+ Assert.That(subsetting.Id, Is.Not.EqualTo(Guid.Empty));
+ Assert.That(specific.OwnedRelationship, Is.Empty);
+
+ Assert.That(() => this.factory.CreateImpliedSubsetting(null, general), Throws.TypeOf());
+ Assert.That(() => this.factory.CreateImpliedSubsetting(specific, null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyCreateImpliedRedefinition()
+ {
+ var specific = new Feature { Id = Guid.NewGuid(), DeclaredName = "specific" };
+ var general = new Feature { Id = Guid.NewGuid(), DeclaredName = "general" };
+
+ var redefinition = this.factory.CreateImpliedRedefinition(specific, general);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(redefinition.IsImplied, Is.True);
+ Assert.That(redefinition.RedefiningFeature, Is.SameAs(specific));
+ Assert.That(redefinition.RedefinedFeature, Is.SameAs(general));
+ Assert.That(redefinition.Id, Is.Not.EqualTo(Guid.Empty));
+ Assert.That(specific.OwnedRelationship, Is.Empty);
+
+ Assert.That(() => this.factory.CreateImpliedRedefinition(null, general), Throws.TypeOf());
+ Assert.That(() => this.factory.CreateImpliedRedefinition(specific, null), Throws.TypeOf());
+ }
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics.Tests/Implied/ImpliedRelationshipProviderTestFixture.cs b/SysML2.NET.Semantics.Tests/Implied/ImpliedRelationshipProviderTestFixture.cs
new file mode 100644
index 00000000..76be3f97
--- /dev/null
+++ b/SysML2.NET.Semantics.Tests/Implied/ImpliedRelationshipProviderTestFixture.cs
@@ -0,0 +1,193 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Tests.Implied
+{
+ using System;
+ using System.Linq;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Root.Namespaces;
+ using SysML2.NET.Core.POCO.Systems.DefinitionAndUsage;
+ using SysML2.NET.Core.POCO.Systems.Parts;
+ using SysML2.NET.Semantics.Implied;
+ using SysML2.NET.Semantics.Implied.Rules;
+
+ [TestFixture]
+ public class ImpliedRelationshipProviderTestFixture
+ {
+ private ImpliedRelationshipFactory factory;
+
+ private PartUsage variation;
+
+ private PartUsage variant;
+
+ [SetUp]
+ public void SetUp()
+ {
+ this.factory = new ImpliedRelationshipFactory();
+
+ this.variation = new PartUsage { Id = Guid.NewGuid(), DeclaredName = "p", IsVariation = true };
+ this.variant = new PartUsage { Id = Guid.NewGuid(), DeclaredName = "p1" };
+
+ var membership = new VariantMembership { Id = Guid.NewGuid() };
+ ((IContainedRelationship)membership).OwnedRelatedElement.Add(this.variant);
+ ((IContainedElement)this.variation).OwnedRelationship.Add(membership);
+ }
+
+ [Test]
+ public void VerifyGetImpliedSpecializations()
+ {
+ var provider = this.CreateProvider();
+
+ var specializations = provider.GetImpliedSpecializations(this.variant);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(specializations, Has.Count.EqualTo(1));
+ Assert.That(specializations[0], Is.InstanceOf());
+ Assert.That(specializations[0].General, Is.SameAs(this.variation));
+
+ // Library specializations are off by default, so nothing table-driven contributes.
+ Assert.That(specializations.All(specialization => specialization.IsImplied), Is.True);
+
+ // The model must be untouched: no implied Relationship is attached anywhere.
+ Assert.That(this.variant.OwnedRelationship, Is.Empty);
+ Assert.That(this.variation.OwnedRelationship.OfType(), Is.Empty);
+ Assert.That(this.variant.IsImpliedIncluded, Is.False);
+
+ // Memoised: the same instances come back on a second call.
+ Assert.That(provider.GetImpliedSpecializations(this.variant), Is.SameAs(specializations));
+
+ Assert.That(() => provider.GetImpliedSpecializations(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyGetImpliedRelationships()
+ {
+ var provider = this.CreateProvider();
+
+ var relationships = provider.GetImpliedRelationships(this.variant);
+
+ using (Assert.EnterMultipleScope())
+ {
+ // The Subsetting is reported once, through the Specialization arm, not twice.
+ Assert.That(relationships, Has.Count.EqualTo(1));
+ Assert.That(relationships[0], Is.InstanceOf());
+
+ Assert.That(provider.GetImpliedRelationships(this.variation), Is.Empty);
+ Assert.That(() => provider.GetImpliedRelationships(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyGetImpliedRedefinitions()
+ {
+ var provider = this.CreateProvider();
+
+ using (Assert.EnterMultipleScope())
+ {
+ // No Redefinition rule is registered yet, so none is produced.
+ Assert.That(provider.GetImpliedRedefinitions(this.variant), Is.Empty);
+ Assert.That(() => provider.GetImpliedRedefinitions(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyNotCoveredConstraints()
+ {
+ var withRules = this.CreateProvider();
+ var withoutRules = new ImpliedRelationshipProvider(
+ OwnershipTreeLibraryTypeIndex.Build([]),
+ new ImpliedRuleGuardRegistry([]),
+ this.factory,
+ new ImpliedSpecializationReducer(),
+ new ImpliedRelationshipOptions(),
+ []);
+
+ using (Assert.EnterMultipleScope())
+ {
+ // A registered rule removes its constraint from the manifest.
+ Assert.That(withRules.NotCoveredConstraints.Any(entry => entry.Contains("checkUsageVariationUsageSpecialization")), Is.False);
+ Assert.That(withoutRules.NotCoveredConstraints.Any(entry => entry.Contains("checkUsageVariationUsageSpecialization")), Is.True);
+
+ Assert.That(withRules.IsConstraintCovered("checkUsageVariationUsageSpecialization"), Is.True);
+ Assert.That(withoutRules.IsConstraintCovered("checkUsageVariationUsageSpecialization"), Is.False);
+
+ // With library specializations off, everything table-driven is honestly reported as uncovered.
+ Assert.That(withRules.NotCoveredConstraints, Has.Count.GreaterThan(ImpliedRelationshipTable.NotCovered.Count));
+ Assert.That(withRules.IsConstraintCovered("checkPortUsageSpecialization"), Is.False);
+ Assert.That(withRules.IsConstraintCovered(null), Is.False);
+ }
+ }
+
+ [Test]
+ public void VerifyGetImpliedSpecializationsThrowsWhenAGuardIsMissing()
+ {
+ // Enabling the library-specialization rules exercises the 63 conditional rows. None has a guard
+ // registered yet, so the first one reached must fail loudly rather than be applied as if it were
+ // unconditional — applying it would inject Specializations the model does not require.
+ var provider = this.CreateProvider(new ImpliedRelationshipOptions { EnableLibrarySpecializations = true });
+
+ Assert.That(() => provider.GetImpliedSpecializations(this.variant), Throws.TypeOf());
+ }
+
+ [Test]
+ public void VerifyGetImpliedSpecializationsThrowsWhenALibraryTypeIsMissing()
+ {
+ // A Classifier's constraints target library Types (Occurrences::Occurrence and friends). With an
+ // empty index — the shape produced by loading only the libraries a model happens to import —
+ // resolution must fail loudly rather than silently omit the Specialization.
+ var provider = this.CreateProvider(new ImpliedRelationshipOptions { EnableLibrarySpecializations = true });
+
+ var classifier = new PartDefinition { Id = Guid.NewGuid(), DeclaredName = "P" };
+
+ Assert.That(() => provider.GetImpliedSpecializations(classifier), Throws.TypeOf()
+ .Or.TypeOf());
+ }
+
+ private ImpliedRelationshipProvider CreateProvider(ImpliedRelationshipOptions options)
+ {
+ return new ImpliedRelationshipProvider(
+ OwnershipTreeLibraryTypeIndex.Build([]),
+ new ImpliedRuleGuardRegistry([]),
+ this.factory,
+ new ImpliedSpecializationReducer(),
+ options,
+ [new VariationUsageSpecializationRule(this.factory), new VariationDefinitionSpecializationRule(this.factory)]);
+ }
+
+ private ImpliedRelationshipProvider CreateProvider()
+ {
+ return new ImpliedRelationshipProvider(
+ OwnershipTreeLibraryTypeIndex.Build([]),
+ new ImpliedRuleGuardRegistry([]),
+ this.factory,
+ new ImpliedSpecializationReducer(),
+ new ImpliedRelationshipOptions(),
+ [new VariationUsageSpecializationRule(this.factory), new VariationDefinitionSpecializationRule(this.factory)]);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics.Tests/Implied/ImpliedRuleGuardRegistryTestFixture.cs b/SysML2.NET.Semantics.Tests/Implied/ImpliedRuleGuardRegistryTestFixture.cs
new file mode 100644
index 00000000..b660bd31
--- /dev/null
+++ b/SysML2.NET.Semantics.Tests/Implied/ImpliedRuleGuardRegistryTestFixture.cs
@@ -0,0 +1,129 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Tests.Implied
+{
+ using System;
+ using System.Linq;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Semantics.Implied;
+ using SysML2.NET.Semantics.Implied.Guards;
+
+ [TestFixture]
+ public class ImpliedRuleGuardRegistryTestFixture
+ {
+ [Test]
+ public void VerifyGetGuard()
+ {
+ var guard = new StubGuard("checkPortUsageSubportSpecialization", true);
+ var registry = new ImpliedRuleGuardRegistry([guard]);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(registry.GetGuard("checkPortUsageSubportSpecialization"), Is.SameAs(guard));
+ Assert.That(() => registry.GetGuard("checkAbsentConstraint"), Throws.TypeOf());
+ Assert.That(() => registry.GetGuard(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyHasGuard()
+ {
+ var registry = new ImpliedRuleGuardRegistry([new StubGuard("checkPortUsageSubportSpecialization", true)]);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(registry.HasGuard("checkPortUsageSubportSpecialization"), Is.True);
+ Assert.That(registry.HasGuard("checkAbsentConstraint"), Is.False);
+ Assert.That(registry.HasGuard(null), Is.False);
+ }
+ }
+
+ [Test]
+ public void VerifyConstructor()
+ {
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(() => new ImpliedRuleGuardRegistry(null), Throws.TypeOf());
+ Assert.That(() => new ImpliedRuleGuardRegistry([]), Throws.Nothing);
+
+ // Two guards deciding the same constraint is a wiring error, not a last-one-wins.
+ Assert.That(
+ () => new ImpliedRuleGuardRegistry([new StubGuard("checkDuplicate", true), new StubGuard("checkDuplicate", false)]),
+ Throws.TypeOf());
+ }
+ }
+
+ ///
+ /// Phase-2 exit criterion: every conditional row in the generated table must have a guard, whether
+ /// generated from its OCL or hand written. A row without one makes the provider throw rather than
+ /// silently apply the constraint unconditionally.
+ ///
+ [Test]
+ public void VerifyEveryConditionalConstraintHasAGuard()
+ {
+ var registry = new ImpliedRuleGuardRegistry(
+ [
+ ..GeneratedImpliedRuleGuards.All,
+ new AcceptActionUsageSubactionSpecializationGuard(),
+ new AssociationBinarySpecializationGuard(),
+ new AssociationStructureBinarySpecializationGuard(),
+ new ConnectorBinaryObjectSpecializationGuard(),
+ new ConnectorBinarySpecializationGuard(),
+ new ConnectorObjectSpecializationGuard(),
+ new FeatureEndSpecializationGuard(),
+ new FeaturePortionSpecializationGuard(),
+ new FeatureSubobjectSpecializationGuard(),
+ new FeatureSuboccurrenceSpecializationGuard(),
+ new FlowDefinitionBinarySpecializationGuard(),
+ new IncludeUseCaseUsageSpecializationGuard(),
+ new OccurrenceUsageSuboccurrenceSpecializationGuard(),
+ new StepOwnedPerformanceSpecializationGuard(),
+ new StepSubperformanceSpecializationGuard(),
+ new TransitionUsageActionSpecializationGuard(),
+ new TransitionUsageStateSpecializationGuard()
+ ]);
+
+ var unguarded = ImpliedRelationshipTable.AllConditionalConstraintNames
+ .Where(constraintName => !registry.HasGuard(constraintName))
+ .ToList();
+
+ Assert.That(unguarded, Is.Empty, $"These conditional constraints have no guard: {string.Join(", ", unguarded)}");
+ }
+
+ private sealed class StubGuard : IImpliedRuleGuard
+ {
+ private readonly bool applies;
+
+ public StubGuard(string constraintName, bool applies)
+ {
+ this.ConstraintName = constraintName;
+ this.applies = applies;
+ }
+
+ public string ConstraintName { get; }
+
+ public bool Applies(IElement element) => this.applies;
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics.Tests/Implied/ImpliedSpecializationReducerTestFixture.cs b/SysML2.NET.Semantics.Tests/Implied/ImpliedSpecializationReducerTestFixture.cs
new file mode 100644
index 00000000..c8810ef5
--- /dev/null
+++ b/SysML2.NET.Semantics.Tests/Implied/ImpliedSpecializationReducerTestFixture.cs
@@ -0,0 +1,121 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Tests.Implied
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.Core.POCO.Core.Classifiers;
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Semantics.Implied;
+
+ [TestFixture]
+ public class ImpliedSpecializationReducerTestFixture
+ {
+ private ImpliedSpecializationReducer reducer;
+
+ private ImpliedRelationshipFactory factory;
+
+ private Classifier anything;
+
+ private Classifier occurrence;
+
+ private Classifier subject;
+
+ [SetUp]
+ public void SetUp()
+ {
+ this.reducer = new ImpliedSpecializationReducer();
+ this.factory = new ImpliedRelationshipFactory();
+
+ this.anything = new Classifier { Id = Guid.NewGuid(), DeclaredName = "Anything" };
+ this.occurrence = new Classifier { Id = Guid.NewGuid(), DeclaredName = "Occurrence" };
+ this.subject = new Classifier { Id = Guid.NewGuid(), DeclaredName = "Subject" };
+
+ // Occurrence specializes Anything, so Occurrence is a strict subtype of Anything.
+ Specialize(this.occurrence, this.anything);
+ }
+
+ [Test]
+ public void VerifyReduce()
+ {
+ var impliedAnything = this.factory.CreateImpliedSubclassification(this.subject, this.anything);
+ var impliedOccurrence = this.factory.CreateImpliedSubclassification(this.subject, this.occurrence);
+ var duplicateOccurrence = this.factory.CreateImpliedSubclassification(this.subject, this.occurrence);
+
+ using (Assert.EnterMultipleScope())
+ {
+ // Rule 1 within the implied set: Occurrence is a strict subtype of Anything, so specializing
+ // Anything as well is redundant.
+ var reduced = this.reducer.Reduce(this.subject, [impliedAnything, impliedOccurrence]);
+ Assert.That(reduced.Select(specialization => specialization.General), Is.EqualTo(new IType[] { this.occurrence }));
+
+ // Rule 2: two candidates with the same general Type collapse to one.
+ var deduplicated = this.reducer.Reduce(this.subject, [impliedOccurrence, duplicateOccurrence]);
+ Assert.That(deduplicated, Has.Count.EqualTo(1));
+ Assert.That(deduplicated[0], Is.SameAs(impliedOccurrence));
+
+ // A single candidate with no competitor survives — the self-comparison must not drop it.
+ var single = this.reducer.Reduce(this.subject, [impliedOccurrence]);
+ Assert.That(single, Has.Count.EqualTo(1));
+
+ Assert.That(this.reducer.Reduce(this.subject, []), Is.Empty);
+ Assert.That(() => this.reducer.Reduce(null, []), Throws.TypeOf());
+ Assert.That(() => this.reducer.Reduce(this.subject, null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyReduceAgainstDeclaredSpecializations()
+ {
+ var declaring = new Classifier { Id = Guid.NewGuid(), DeclaredName = "Declaring" };
+ Specialize(declaring, this.occurrence);
+
+ var impliedAnything = this.factory.CreateImpliedSubclassification(declaring, this.anything);
+ var impliedOccurrence = this.factory.CreateImpliedSubclassification(declaring, this.occurrence);
+
+ using (Assert.EnterMultipleScope())
+ {
+ // The declared Specialization to Occurrence already satisfies the looser Anything constraint.
+ Assert.That(this.reducer.Reduce(declaring, [impliedAnything]), Is.Empty);
+
+ // ... and it makes an implied Specialization with the SAME general Type redundant too.
+ Assert.That(this.reducer.Reduce(declaring, [impliedOccurrence]), Is.Empty);
+ }
+ }
+
+ private static void Specialize(IClassifier specific, IClassifier general)
+ {
+ var subclassification = new Subclassification
+ {
+ Id = Guid.NewGuid(),
+ Subclassifier = specific,
+ Superclassifier = general
+ };
+
+ ((IContainedElement)specific).OwnedRelationship.Add(subclassification);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics.Tests/Implied/OwnershipTreeLibraryTypeIndexTestFixture.cs b/SysML2.NET.Semantics.Tests/Implied/OwnershipTreeLibraryTypeIndexTestFixture.cs
new file mode 100644
index 00000000..016bbc11
--- /dev/null
+++ b/SysML2.NET.Semantics.Tests/Implied/OwnershipTreeLibraryTypeIndexTestFixture.cs
@@ -0,0 +1,113 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Tests.Implied
+{
+ using System;
+ using System.Collections.Generic;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.Core.POCO.Core.Classifiers;
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Kernel.Packages;
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Root.Namespaces;
+ using SysML2.NET.Semantics.Implied;
+
+ [TestFixture]
+ public class OwnershipTreeLibraryTypeIndexTestFixture
+ {
+ private Package libraryPackage;
+
+ private Classifier occurrence;
+
+ private Feature suboccurrences;
+
+ [SetUp]
+ public void SetUp()
+ {
+ this.libraryPackage = new Package { Id = Guid.NewGuid(), DeclaredName = "Occurrences" };
+ this.occurrence = new Classifier { Id = Guid.NewGuid(), DeclaredName = "Occurrence" };
+ this.suboccurrences = new Feature { Id = Guid.NewGuid(), DeclaredName = "suboccurrences" };
+
+ Own(this.libraryPackage, this.occurrence);
+ Own(this.occurrence, this.suboccurrences);
+ }
+
+ [Test]
+ public void VerifyBuild()
+ {
+ var index = OwnershipTreeLibraryTypeIndex.Build([this.libraryPackage]);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(index.TryGetType("Occurrences::Occurrence", out var resolvedOccurrence), Is.True);
+ Assert.That(resolvedOccurrence, Is.SameAs(this.occurrence));
+
+ Assert.That(index.TryGetType("Occurrences::Occurrence::suboccurrences", out var resolvedFeature), Is.True);
+ Assert.That(resolvedFeature, Is.SameAs(this.suboccurrences));
+
+ Assert.That(index.TryGetType("Occurrences::Absent", out var missing), Is.False);
+ Assert.That(missing, Is.Null);
+
+ Assert.That(index.TryGetType(null, out _), Is.False);
+ Assert.That(index.TryGetType(string.Empty, out _), Is.False);
+ Assert.That(index.TryGetType(" ", out _), Is.False);
+
+ // The Package itself is a Namespace, not a Type, so it is walked but not indexed.
+ Assert.That(index.TryGetType("Occurrences", out _), Is.False);
+ }
+ }
+
+ [Test]
+ public void VerifyBuildWithNullAndEmptyInput()
+ {
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(() => OwnershipTreeLibraryTypeIndex.Build(null), Throws.TypeOf());
+ Assert.That(OwnershipTreeLibraryTypeIndex.Build([]).Count, Is.Zero);
+ Assert.That(OwnershipTreeLibraryTypeIndex.Build([null]).Count, Is.Zero);
+ }
+ }
+
+ [Test]
+ public void VerifyBuildWithCyclicOwnership()
+ {
+ var cyclic = new Package { Id = Guid.NewGuid(), DeclaredName = "Cyclic" };
+ var inner = new Classifier { Id = Guid.NewGuid(), DeclaredName = "Inner" };
+
+ Own(cyclic, inner);
+ Own(inner, cyclic);
+
+ var index = OwnershipTreeLibraryTypeIndex.Build([cyclic]);
+
+ Assert.That(index.TryGetType("Cyclic::Inner", out var resolved), Is.True);
+ Assert.That(resolved, Is.SameAs(inner));
+ }
+
+ private static void Own(INamespace owner, IElement ownedElement)
+ {
+ var membership = new OwningMembership { Id = Guid.NewGuid() };
+ ((IContainedRelationship)membership).OwnedRelatedElement.Add(ownedElement);
+ ((IContainedElement)owner).OwnedRelationship.Add(membership);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics.Tests/Implied/Rules/ChainSubsettingRuleTestFixture.cs b/SysML2.NET.Semantics.Tests/Implied/Rules/ChainSubsettingRuleTestFixture.cs
new file mode 100644
index 00000000..fcfeccb1
--- /dev/null
+++ b/SysML2.NET.Semantics.Tests/Implied/Rules/ChainSubsettingRuleTestFixture.cs
@@ -0,0 +1,258 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Tests.Implied.Rules
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Core.POCO.Kernel.Connectors;
+ using SysML2.NET.Core.Core.Types;
+ using SysML2.NET.Core.Systems.States;
+ using SysML2.NET.Core.POCO.Kernel.Expressions;
+ using SysML2.NET.Core.POCO.Kernel.Functions;
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Systems.DefinitionAndUsage;
+ using SysML2.NET.Core.POCO.Systems.Actions;
+ using SysML2.NET.Core.POCO.Systems.States;
+ using SysML2.NET.Extensions;
+ using SysML2.NET.Semantics.Implied;
+ using SysML2.NET.Semantics.Implied.Rules;
+
+ [TestFixture]
+ public class ChainSubsettingRuleTestFixture
+ {
+ private const string OutgoingLink = "ControlPerformances::DecisionPerformance::outgoingHBLink";
+
+ private const string IncomingLink = "ControlPerformances::MergePerformance::incomingHBLink";
+
+ private ImpliedRelationshipFactory factory;
+
+ private ILibraryTypeIndex libraryTypeIndex;
+
+ private Dictionary libraryFeatures;
+
+ [SetUp]
+ public void SetUp()
+ {
+ this.factory = new ImpliedRelationshipFactory();
+
+ this.libraryFeatures = new Dictionary
+ {
+ [OutgoingLink] = new Feature { Id = Guid.NewGuid(), DeclaredName = "outgoingHBLink" },
+ [IncomingLink] = new Feature { Id = Guid.NewGuid(), DeclaredName = "incomingHBLink" }
+ };
+
+ this.libraryTypeIndex = new StubIndex(this.libraryFeatures);
+ }
+
+ [Test]
+ public void VerifyCreateImpliedFeatureChain()
+ {
+ var first = new Feature { Id = Guid.NewGuid() };
+ var second = new Feature { Id = Guid.NewGuid() };
+
+ var chain = this.factory.CreateImpliedFeatureChain(first, second);
+
+ using (Assert.EnterMultipleScope())
+ {
+ // The chain's whole meaning is the ORDER of its chainingFeatures.
+ Assert.That(chain.chainingFeature, Is.EqualTo([first, second]));
+ Assert.That(chain.ownedFeatureChaining.All(chaining => chaining.IsImplied), Is.True);
+
+ Assert.That(() => this.factory.CreateImpliedFeatureChain(null, second), Throws.TypeOf());
+ Assert.That(() => this.factory.CreateImpliedFeatureChain(first, null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyDecisionNodeOutgoingSuccessionSpecializationRule()
+ {
+ var rule = new DecisionNodeOutgoingSuccessionSpecializationRule(this.libraryTypeIndex, this.factory);
+
+ var decisionNode = new DecisionNode { Id = Guid.NewGuid() };
+ var succession = BuildSuccession(decisionNode, new ActionUsage { Id = Guid.NewGuid() });
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkDecisionNodeOutgoingSuccessionSpecialization"));
+
+ var subsettings = rule.Apply(succession).OfType().ToList();
+ Assert.That(subsettings, Has.Count.EqualTo(1));
+
+ // The Succession subsets the chain, and the chain is [node, link] IN THAT ORDER.
+ Assert.That(subsettings[0].SubsettingFeature, Is.SameAs(succession));
+ Assert.That(subsettings[0].SubsettedFeature.chainingFeature,
+ Is.EqualTo([(IFeature)decisionNode, (IFeature)this.libraryFeatures[OutgoingLink]]));
+
+ // A Succession leaving something else is not this constraint's business.
+ var plain = BuildSuccession(new ActionUsage { Id = Guid.NewGuid() }, new ActionUsage { Id = Guid.NewGuid() });
+ Assert.That(rule.Apply(plain), Is.Empty);
+
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyMergeNodeIncomingSuccessionSpecializationRule()
+ {
+ var rule = new MergeNodeIncomingSuccessionSpecializationRule(this.libraryTypeIndex, this.factory);
+
+ var mergeNode = new MergeNode { Id = Guid.NewGuid() };
+ var succession = BuildSuccession(new ActionUsage { Id = Guid.NewGuid() }, mergeNode);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkMergeNodeIncomingSuccessionSpecialization"));
+
+ var subsettings = rule.Apply(succession).OfType().ToList();
+ Assert.That(subsettings, Has.Count.EqualTo(1));
+ Assert.That(subsettings[0].SubsettedFeature.chainingFeature,
+ Is.EqualTo([(IFeature)mergeNode, (IFeature)this.libraryFeatures[IncomingLink]]));
+
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyFeatureChainExpressionResultSpecializationRule()
+ {
+ var rule = new FeatureChainExpressionResultSpecializationRule(this.factory);
+
+ // `a.b` — the source is the input parameter, the target is the Feature reached through it, so
+ // the chain the result subsets is [source, target].
+ var expression = new FeatureChainExpression { Id = Guid.NewGuid() };
+
+ var sourceParameter = new Feature { Id = Guid.NewGuid(), Direction = FeatureDirectionKind.In };
+ var targetFeature = new Feature { Id = Guid.NewGuid() };
+ Own(sourceParameter, targetFeature, new FeatureMembership { Id = Guid.NewGuid() });
+ Own(expression, sourceParameter, new FeatureMembership { Id = Guid.NewGuid() });
+
+ var result = new Feature { Id = Guid.NewGuid() };
+ Own(expression, result, new ReturnParameterMembership { Id = Guid.NewGuid() });
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkFeatureChainExpressionResultSpecialization"));
+
+ var subsettings = rule.Apply(expression).OfType().ToList();
+ Assert.That(subsettings, Has.Count.EqualTo(1));
+ Assert.That(subsettings[0].SubsettingFeature, Is.SameAs(result));
+ Assert.That(subsettings[0].SubsettedFeature.chainingFeature,
+ Is.EqualTo([(IFeature)sourceParameter, (IFeature)targetFeature]));
+
+ // No input parameter means no chain to state, so nothing is implied.
+ var bare = new FeatureChainExpression { Id = Guid.NewGuid() };
+ Own(bare, new Feature { Id = Guid.NewGuid() }, new ReturnParameterMembership { Id = Guid.NewGuid() });
+ Assert.That(rule.Apply(bare), Is.Empty);
+
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyTransitionUsagePayloadSpecializationRule()
+ {
+ var rule = new TransitionUsagePayloadSpecializationRule(this.factory);
+
+ var transitionUsage = new TransitionUsage { Id = Guid.NewGuid() };
+
+ // The trigger carries the payload the transition's second input parameter must subset.
+ var accepter = new AcceptActionUsage { Id = Guid.NewGuid() };
+ var payload = new ReferenceUsage { Id = Guid.NewGuid(), Direction = FeatureDirectionKind.In };
+ Own(accepter, payload, new FeatureMembership { Id = Guid.NewGuid() });
+ Own(transitionUsage, accepter, new TransitionFeatureMembership { Id = Guid.NewGuid(), Kind = TransitionFeatureKind.Trigger });
+
+ // inputParameter(2) is 1-BASED, so two directed parameters are needed and the SECOND is the one.
+ var firstParameter = new Feature { Id = Guid.NewGuid(), Direction = FeatureDirectionKind.In };
+ var payloadParameter = new Feature { Id = Guid.NewGuid(), Direction = FeatureDirectionKind.In };
+ Own(transitionUsage, firstParameter, new FeatureMembership { Id = Guid.NewGuid() });
+ Own(transitionUsage, payloadParameter, new FeatureMembership { Id = Guid.NewGuid() });
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkTransitionUsagePayloadSpecialization"));
+
+ var subsettings = rule.Apply(transitionUsage).OfType().ToList();
+ Assert.That(subsettings, Has.Count.EqualTo(1));
+ Assert.That(subsettings[0].SubsettingFeature, Is.SameAs(payloadParameter), "the SECOND input parameter, not the first");
+ Assert.That(subsettings[0].SubsettedFeature.chainingFeature,
+ Is.EqualTo([(IFeature)accepter, (IFeature)payload]));
+
+ // An untriggered transition has no payload to bind.
+ Assert.That(rule.Apply(new TransitionUsage { Id = Guid.NewGuid() }), Is.Empty);
+
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyUnresolvedLinkThrows()
+ {
+ var rule = new DecisionNodeOutgoingSuccessionSpecializationRule(new StubIndex(new Dictionary()), this.factory);
+
+ var succession = BuildSuccession(new DecisionNode { Id = Guid.NewGuid() }, new ActionUsage { Id = Guid.NewGuid() });
+
+ Assert.That(() => rule.Apply(succession), Throws.TypeOf());
+ }
+
+ private static void Own(IElement owner, IElement owned, IRelationship membership)
+ {
+ ((IContainedRelationship)membership).OwnedRelatedElement.Add(owned);
+ ((IContainedElement)owner).OwnedRelationship.Add(membership);
+ }
+
+ private static Succession BuildSuccession(IFeature source, IFeature target)
+ {
+ // relatedFeature derives through the connector ends, each of which reaches its participant by an
+ // owned ReferenceSubsetting — so a Succession cannot be stated by assigning Source/Target.
+ var succession = new Succession { Id = Guid.NewGuid() };
+
+ foreach (var participant in new[] { source, target })
+ {
+ var end = new Feature { Id = Guid.NewGuid(), IsEnd = true };
+ end.AssignOwnership(new ReferenceSubsetting { Id = Guid.NewGuid(), ReferencedFeature = participant });
+ succession.AssignOwnership(new EndFeatureMembership { Id = Guid.NewGuid() }, end);
+ }
+
+ return succession;
+ }
+
+ private sealed class StubIndex : ILibraryTypeIndex
+ {
+ private readonly IDictionary typesByQualifiedName;
+
+ public StubIndex(IDictionary typesByQualifiedName)
+ {
+ this.typesByQualifiedName = typesByQualifiedName;
+ }
+
+ public bool TryGetType(string qualifiedName, out IType type) => this.typesByQualifiedName.TryGetValue(qualifiedName, out type);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics.Tests/Implied/Rules/LibrarySpecializationRuleTestFixture.cs b/SysML2.NET.Semantics.Tests/Implied/Rules/LibrarySpecializationRuleTestFixture.cs
new file mode 100644
index 00000000..ce8aac11
--- /dev/null
+++ b/SysML2.NET.Semantics.Tests/Implied/Rules/LibrarySpecializationRuleTestFixture.cs
@@ -0,0 +1,335 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Tests.Implied.Rules
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.Core.Core.Types;
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Classifiers;
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Core.POCO.Kernel.Expressions;
+ using SysML2.NET.Core.POCO.Kernel.Functions;
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Root.Namespaces;
+ using SysML2.NET.Core.POCO.Systems.Actions;
+ using SysML2.NET.Core.POCO.Systems.Constraints;
+ using SysML2.NET.Core.POCO.Systems.Requirements;
+ using SysML2.NET.Semantics.Implied;
+ using SysML2.NET.Semantics.Implied.Rules;
+
+ [TestFixture]
+ public class LibrarySpecializationRuleTestFixture
+ {
+ ///
+ /// Every library Feature the four condition-selected constraints can target.
+ ///
+ private static readonly string[] LibraryTargets =
+ [
+ "Constraints::assertedConstraintChecks",
+ "Constraints::negatedConstraintChecks",
+ "Requirements::satisfiedRequirementChecks",
+ "Requirements::notSatisfiedRequirementChecks",
+ "Actions::ifThenActions",
+ "Actions::ifThenElseActions",
+ "Performances::trueEvaluations",
+ "Performances::falseEvaluations",
+ "Performances::constructorEvaluations"
+ ];
+
+ private ImpliedRelationshipFactory factory;
+
+ private ILibraryTypeIndex libraryTypeIndex;
+
+ private Dictionary libraryFeaturesByQualifiedName;
+
+ [SetUp]
+ public void SetUp()
+ {
+ this.factory = new ImpliedRelationshipFactory();
+
+ this.libraryFeaturesByQualifiedName = LibraryTargets.ToDictionary(
+ qualifiedName => qualifiedName,
+ qualifiedName => (IType)new Feature { Id = Guid.NewGuid(), DeclaredName = qualifiedName });
+
+ this.libraryTypeIndex = new StubLibraryTypeIndex(this.libraryFeaturesByQualifiedName);
+ }
+
+ [Test]
+ public void VerifyAssertConstraintUsageSpecializationRule()
+ {
+ var rule = new AssertConstraintUsageSpecializationRule(this.libraryTypeIndex, this.factory);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkAssertConstraintUsageSpecialization"));
+
+ Assert.That(SubsettedBy(rule, new AssertConstraintUsage { Id = Guid.NewGuid() }),
+ Is.EqualTo([this.Library("Constraints::assertedConstraintChecks")]));
+
+ Assert.That(SubsettedBy(rule, new AssertConstraintUsage { Id = Guid.NewGuid(), IsNegated = true }),
+ Is.EqualTo([this.Library("Constraints::negatedConstraintChecks")]));
+
+ // A SatisfyRequirementUsage IS an AssertConstraintUsage but has its own constraint, so this
+ // rule must stand down or the element would imply two unrelated library subsettings.
+ Assert.That(rule.Apply(new SatisfyRequirementUsage { Id = Guid.NewGuid() }), Is.Empty);
+
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifySatisfyRequirementUsageSpecializationRule()
+ {
+ var rule = new SatisfyRequirementUsageSpecializationRule(this.libraryTypeIndex, this.factory);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkSatisfyRequirementUsageSpecialization"));
+
+ Assert.That(SubsettedBy(rule, new SatisfyRequirementUsage { Id = Guid.NewGuid() }),
+ Is.EqualTo([this.Library("Requirements::satisfiedRequirementChecks")]));
+
+ Assert.That(SubsettedBy(rule, new SatisfyRequirementUsage { Id = Guid.NewGuid(), IsNegated = true }),
+ Is.EqualTo([this.Library("Requirements::notSatisfiedRequirementChecks")]));
+
+ // The plain AssertConstraintUsage is the other rule's business.
+ Assert.That(rule.Apply(new AssertConstraintUsage { Id = Guid.NewGuid() }), Is.Empty);
+
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyIfActionUsageSpecializationRule()
+ {
+ var rule = new IfActionUsageSpecializationRule(this.libraryTypeIndex, this.factory);
+
+ // elseAction is inputParameter(3), so a three-parameter if action is the one with an else branch.
+ var withElse = new IfActionUsage { Id = Guid.NewGuid() };
+ AddInputParameter(withElse, new Feature { Id = Guid.NewGuid() });
+ AddInputParameter(withElse, new Feature { Id = Guid.NewGuid() });
+ AddInputParameter(withElse, new ActionUsage { Id = Guid.NewGuid() });
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkIfActionUsageSpecialization"));
+
+ Assert.That(SubsettedBy(rule, new IfActionUsage { Id = Guid.NewGuid() }),
+ Is.EqualTo([this.Library("Actions::ifThenActions")]));
+
+ Assert.That(SubsettedBy(rule, withElse),
+ Is.EqualTo([this.Library("Actions::ifThenElseActions")]));
+
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyInvariantSpecializationRule()
+ {
+ var rule = new InvariantSpecializationRule(this.libraryTypeIndex, this.factory);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkInvariantSpecialization"));
+
+ Assert.That(SubsettedBy(rule, new Invariant { Id = Guid.NewGuid() }),
+ Is.EqualTo([this.Library("Performances::trueEvaluations")]));
+
+ Assert.That(SubsettedBy(rule, new Invariant { Id = Guid.NewGuid(), IsNegated = true }),
+ Is.EqualTo([this.Library("Performances::falseEvaluations")]));
+
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyConstructorExpressionResultSpecializationRule()
+ {
+ var rule = new ConstructorExpressionResultSpecializationRule(this.factory);
+
+ // KerML 1.0 §8.4.4.9.4: a FeatureTyping when the instantiatedType is a Classifier, a Subsetting
+ // when it is a Feature. The OCL (result.specializes(instantiatedType)) does not say which.
+ var ontoClassifier = BuildConstructorExpression(new Classifier { Id = Guid.NewGuid() }, out var classifierResult);
+ var ontoFeature = BuildConstructorExpression(new Feature { Id = Guid.NewGuid() }, out var featureResult);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkConstructorExpressionResultSpecialization"));
+
+ var typing = rule.Apply(ontoClassifier).OfType().ToList();
+ Assert.That(typing, Has.Count.EqualTo(1));
+ Assert.That(typing[0].TypedFeature, Is.SameAs(classifierResult));
+
+ var subsetting = rule.Apply(ontoFeature).OfType().ToList();
+ Assert.That(subsetting, Has.Count.EqualTo(1));
+ Assert.That(subsetting[0].SubsettingFeature, Is.SameAs(featureResult));
+
+ // No instantiatedType and no result are both legitimately silent, not errors.
+ Assert.That(rule.Apply(new ConstructorExpression { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyConstructorExpressionSpecializationRule()
+ {
+ var rule = new ConstructorExpressionSpecializationRule(this.libraryTypeIndex, this.factory);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkConstructorExpressionSpecialization"));
+
+ Assert.That(SubsettedBy(rule, new ConstructorExpression { Id = Guid.NewGuid() }),
+ Is.EqualTo([this.Library("Performances::constructorEvaluations")]));
+
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyInvocationExpressionSpecializationRule()
+ {
+ var rule = new InvocationExpressionSpecializationRule(this.factory);
+
+ // KerML 1.0 §8.4.4.9.5: ALWAYS a FeatureTyping, whether the instantiatedType is a Classifier or
+ // a Feature — unlike the ConstructorExpression result, where the kind depends on it.
+ var ontoClassifier = BuildInvocationExpression(new Classifier { Id = Guid.NewGuid() });
+ var ontoFeature = BuildInvocationExpression(new Feature { Id = Guid.NewGuid() });
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkInvocationExpressionSpecialization"));
+
+ Assert.That(rule.Apply(ontoClassifier).OfType().Count(), Is.EqualTo(1));
+ Assert.That(rule.Apply(ontoFeature).OfType().Count(), Is.EqualTo(1));
+ Assert.That(rule.Apply(ontoFeature).OfType(), Is.Empty);
+
+ Assert.That(rule.Apply(new InvocationExpression { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyFeatureReferenceExpressionResultSpecializationRule()
+ {
+ var rule = new FeatureReferenceExpressionResultSpecializationRule(this.factory);
+
+ var referent = new Feature { Id = Guid.NewGuid() };
+
+ var expression = new FeatureReferenceExpression { Id = Guid.NewGuid() };
+ var result = new Feature { Id = Guid.NewGuid() };
+ Own(expression, result, new ReturnParameterMembership { Id = Guid.NewGuid() });
+ ((IContainedElement)expression).OwnedRelationship.Add(new Membership { Id = Guid.NewGuid(), MemberElement = referent });
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkFeatureReferenceExpressionResultSpecialization"));
+
+ var subsetting = rule.Apply(expression).OfType().ToList();
+ Assert.That(subsetting, Has.Count.EqualTo(1));
+ Assert.That(subsetting[0].SubsettingFeature, Is.SameAs(result));
+ Assert.That(subsetting[0].SubsettedFeature, Is.SameAs(referent));
+
+ Assert.That(rule.Apply(new FeatureReferenceExpression { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyUnresolvedLibraryTypeThrows()
+ {
+ // The library name is part of the rule, not of the model, so failing to resolve it is a
+ // configuration fault the caller must see rather than an element that simply implies nothing.
+ var rule = new InvariantSpecializationRule(new StubLibraryTypeIndex(new Dictionary()), this.factory);
+
+ Assert.That(() => rule.Apply(new Invariant { Id = Guid.NewGuid() }), Throws.TypeOf());
+ }
+
+ private static ConstructorExpression BuildConstructorExpression(IType instantiatedType, out IFeature result)
+ {
+ var constructorExpression = new ConstructorExpression { Id = Guid.NewGuid() };
+
+ result = new Feature { Id = Guid.NewGuid() };
+ Own(constructorExpression, result, new ReturnParameterMembership { Id = Guid.NewGuid() });
+
+ // instantiatedType is the member of the first ownedMembership that is NOT a FeatureMembership —
+ // the `alias of T` of KerML 1.0 §8.4.4.9.4 — so a plain Membership, not a typing.
+ ((IContainedElement)constructorExpression).OwnedRelationship.Add(new Membership { Id = Guid.NewGuid(), MemberElement = instantiatedType });
+
+ return constructorExpression;
+ }
+
+ private static InvocationExpression BuildInvocationExpression(IType instantiatedType)
+ {
+ var invocationExpression = new InvocationExpression { Id = Guid.NewGuid() };
+ ((IContainedElement)invocationExpression).OwnedRelationship.Add(new Membership { Id = Guid.NewGuid(), MemberElement = instantiatedType });
+
+ return invocationExpression;
+ }
+
+ private static void Own(IElement owner, IElement owned, IRelationship relationship)
+ {
+ ((IContainedRelationship)relationship).OwnedRelatedElement.Add(owned);
+ ((IContainedElement)owner).OwnedRelationship.Add(relationship);
+ }
+
+ private static void AddInputParameter(IElement owner, IFeature parameter)
+ {
+ parameter.Direction = FeatureDirectionKind.In;
+
+ var membership = new FeatureMembership { Id = Guid.NewGuid() };
+ ((IContainedRelationship)membership).OwnedRelatedElement.Add(parameter);
+ ((IContainedElement)owner).OwnedRelationship.Add(membership);
+ }
+
+ private IFeature Library(string qualifiedName) => (IFeature)this.libraryFeaturesByQualifiedName[qualifiedName];
+
+ private static IReadOnlyList SubsettedBy(IImpliedRelationshipRule rule, IElement element)
+ {
+ return [..rule.Apply(element).OfType().Select(subsetting => subsetting.SubsettedFeature)];
+ }
+
+ private sealed class StubLibraryTypeIndex : ILibraryTypeIndex
+ {
+ private readonly IDictionary typesByQualifiedName;
+
+ public StubLibraryTypeIndex(IDictionary typesByQualifiedName)
+ {
+ this.typesByQualifiedName = typesByQualifiedName;
+ }
+
+ public bool TryGetType(string qualifiedName, out IType type) => this.typesByQualifiedName.TryGetValue(qualifiedName, out type);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics.Tests/Implied/Rules/RedefinitionRuleTestFixture.cs b/SysML2.NET.Semantics.Tests/Implied/Rules/RedefinitionRuleTestFixture.cs
new file mode 100644
index 00000000..695c1aa6
--- /dev/null
+++ b/SysML2.NET.Semantics.Tests/Implied/Rules/RedefinitionRuleTestFixture.cs
@@ -0,0 +1,293 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Tests.Implied.Rules
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.Core.POCO.Core.Classifiers;
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Core.POCO.Kernel.Associations;
+ using SysML2.NET.Core.POCO.Kernel.Functions;
+ using SysML2.NET.Core.POCO.Kernel.Interactions;
+ using SysML2.NET.Core.POCO.Systems.Actions;
+ using SysML2.NET.Core.POCO.Systems.States;
+ using SysML2.NET.Core.POCO.Systems.Views;
+ using SysML2.NET.Core.Systems.States;
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Semantics.Implied;
+ using SysML2.NET.Semantics.Implied.Rules;
+
+ [TestFixture]
+ public class RedefinitionRuleTestFixture
+ {
+ ///
+ /// The redefinition constraints no hand-coded rule covers yet.
+ ///
+ private static readonly string[] ExpectedUncoveredConstraints = ["checkConstructorExpressionResultFeatureRedefinition"];
+
+ private ImpliedRelationshipFactory factory;
+
+ [SetUp]
+ public void SetUp()
+ {
+ this.factory = new ImpliedRelationshipFactory();
+ }
+
+ [Test]
+ public void VerifyFeatureEndRedefinitionRule()
+ {
+ var rule = new FeatureEndRedefinitionRule(this.factory);
+
+ var supertype = new Association { Id = Guid.NewGuid() };
+ var supertypeFirstEnd = AddEnd(supertype);
+ var supertypeSecondEnd = AddEnd(supertype);
+
+ var subtype = new Association { Id = Guid.NewGuid() };
+ var firstEnd = AddEnd(subtype);
+ var secondEnd = AddEnd(subtype);
+
+ Specialize(subtype, supertype);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkFeatureEndRedefinition"));
+
+ // The correspondence is positional: end 1 redefines end 1, end 2 redefines end 2.
+ Assert.That(RedefinedBy(rule, firstEnd), Is.EqualTo(new[] { supertypeFirstEnd }));
+ Assert.That(RedefinedBy(rule, secondEnd), Is.EqualTo(new[] { supertypeSecondEnd }));
+
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid(), IsEnd = true }), Is.Empty);
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ }
+ }
+
+ [Test]
+ public void VerifyFeatureEndRedefinitionRuleWhenTheSupertypeHasFewerEnds()
+ {
+ var rule = new FeatureEndRedefinitionRule(this.factory);
+
+ var supertype = new Association { Id = Guid.NewGuid() };
+ var supertypeOnlyEnd = AddEnd(supertype);
+
+ var subtype = new Association { Id = Guid.NewGuid() };
+ var firstEnd = AddEnd(subtype);
+ var secondEnd = AddEnd(subtype);
+
+ Specialize(subtype, supertype);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(RedefinedBy(rule, firstEnd), Is.EqualTo(new[] { supertypeOnlyEnd }));
+
+ // The OCL guards with `endFeature->size() >= i`, so a supertype without an end at this
+ // position contributes nothing rather than throwing.
+ Assert.That(rule.Apply(secondEnd), Is.Empty);
+ }
+ }
+
+ [Test]
+ public void VerifyFeatureResultRedefinitionRule()
+ {
+ var rule = new FeatureResultRedefinitionRule(this.factory);
+
+ var supertype = new Function { Id = Guid.NewGuid() };
+ var supertypeResult = AddResult(supertype);
+
+ var subtype = new Function { Id = Guid.NewGuid() };
+ var result = AddResult(subtype);
+
+ Specialize(subtype, supertype);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(rule.ConstraintName, Is.EqualTo("checkFeatureResultRedefinition"));
+ Assert.That(RedefinedBy(rule, result), Is.EqualTo(new[] { supertypeResult }));
+
+ // A Feature owned by the Function but which is NOT its result is out of scope.
+ var ordinary = new Feature { Id = Guid.NewGuid() };
+ Own(subtype, ordinary);
+ Assert.That(rule.Apply(ordinary), Is.Empty);
+
+ Assert.That(() => rule.Apply(null), Throws.TypeOf());
+ Assert.That(rule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ }
+ }
+
+ [Test]
+ public void VerifyLibraryRedefinitionRules()
+ {
+ var payload = new Feature { Id = Guid.NewGuid(), DeclaredName = "payload" };
+ var viewRendering = new Feature { Id = Guid.NewGuid(), DeclaredName = "viewRendering" };
+ var entryAction = new Feature { Id = Guid.NewGuid(), DeclaredName = "entryAction" };
+ var exitAction = new Feature { Id = Guid.NewGuid(), DeclaredName = "exitAction" };
+ var loopVar = new Feature { Id = Guid.NewGuid(), DeclaredName = "var" };
+
+ var index = new StubLibraryTypeIndex(new Dictionary
+ {
+ ["Transfers::Transfer::payload"] = payload,
+ ["Views::View::viewRendering"] = viewRendering,
+ ["States::StateAction::entryAction"] = entryAction,
+ ["States::StateAction::exitAction"] = exitAction,
+ ["Actions::ForLoopAction::var"] = loopVar
+ });
+
+ var payloadFeature = new PayloadFeature { Id = Guid.NewGuid() };
+
+ var stateSubaction = new ActionUsage { Id = Guid.NewGuid() };
+ var membership = new StateSubactionMembership { Id = Guid.NewGuid(), Kind = StateSubactionKind.Entry };
+ ((IContainedRelationship)membership).OwnedRelatedElement.Add(stateSubaction);
+ ((IContainedElement)new ActionUsage { Id = Guid.NewGuid() }).OwnedRelationship.Add(membership);
+
+ using (Assert.EnterMultipleScope())
+ {
+ var payloadRule = new PayloadFeatureRedefinitionRule(index, this.factory);
+ Assert.That(RedefinedBy(payloadRule, payloadFeature), Is.EqualTo(new[] { payload }));
+ Assert.That(payloadRule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+ Assert.That(() => payloadRule.Apply(null), Throws.TypeOf());
+
+ // The kind of the owning membership selects which library action is redefined.
+ var stateRule = new ActionUsageStateActionRedefinitionRule(index, this.factory);
+ Assert.That(RedefinedBy(stateRule, stateSubaction), Is.EqualTo(new[] { entryAction }));
+
+ membership.Kind = StateSubactionKind.Exit;
+ Assert.That(RedefinedBy(stateRule, stateSubaction), Is.EqualTo(new[] { exitAction }));
+
+ // An ActionUsage owned any other way is out of scope.
+ Assert.That(stateRule.Apply(new ActionUsage { Id = Guid.NewGuid() }), Is.Empty);
+
+ var renderingRule = new RenderingUsageRedefinitionRule(index, this.factory);
+ Assert.That(renderingRule.Apply(new RenderingUsage { Id = Guid.NewGuid() }), Is.Empty);
+
+ var forLoopRule = new ForLoopActionUsageVarRedefinitionRule(index, this.factory);
+ Assert.That(forLoopRule.Apply(new ForLoopActionUsage { Id = Guid.NewGuid() }), Is.Empty);
+
+ // An unindexed library Feature must fail loudly rather than silently omit the Redefinition.
+ var emptyIndex = new StubLibraryTypeIndex(new Dictionary());
+ Assert.That(() => new PayloadFeatureRedefinitionRule(emptyIndex, this.factory).Apply(payloadFeature),
+ Throws.TypeOf());
+ }
+ }
+
+ ///
+ /// Set B is complete except for one constraint. checkConstructorExpressionResultFeatureRedefinition
+ /// asserts a CARDINALITY over redefinitions that already exist —
+ /// f.ownedRedefinition.redefinedFeature->intersection(features)->size() = 1 — rather than
+ /// naming which Feature must be redefined. It is a well-formedness check, not a source of implied
+ /// Relationships, so it stays uncovered rather than being satisfied by an invented correspondence.
+ ///
+ [Test]
+ public void VerifyEveryRedefinitionConstraintIsCoveredOrDeliberatelyNot()
+ {
+ var index = new StubLibraryTypeIndex(new Dictionary());
+
+ IImpliedRelationshipRule[] rules =
+ [
+ new FeatureEndRedefinitionRule(this.factory),
+ new FeatureResultRedefinitionRule(this.factory),
+ new FeatureParameterRedefinitionRule(this.factory),
+ new RequirementUsageObjectiveRedefinitionRule(this.factory),
+ new AssignmentActionUsageReferentRedefinitionRule(this.factory),
+ new FeatureChainExpressionSourceTargetRedefinitionRule(this.factory),
+ new PayloadFeatureRedefinitionRule(index, this.factory),
+ new RenderingUsageRedefinitionRule(index, this.factory),
+ new ActionUsageStateActionRedefinitionRule(index, this.factory),
+ new ForLoopActionUsageVarRedefinitionRule(index, this.factory),
+ new AssignmentActionUsageStartingAtRedefinitionRule(index, this.factory),
+ new AssignmentActionUsageAccessedFeatureRedefinitionRule(index, this.factory),
+ new FeatureChainExpressionTargetRedefinitionRule(index, this.factory),
+ new FeatureFlowFeatureRedefinitionRule(index, this.factory)
+ ];
+
+ var covered = rules.Select(rule => rule.ConstraintName).ToList();
+
+ var redefinitionConstraints = ImpliedRelationshipTable.AllConstraintNames
+ .Where(constraintName => constraintName.EndsWith("Redefinition", StringComparison.Ordinal))
+ .ToList();
+
+ var uncovered = redefinitionConstraints.Except(covered, StringComparer.Ordinal).ToList();
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(redefinitionConstraints, Has.Count.EqualTo(15));
+ Assert.That(covered, Has.Count.EqualTo(14));
+ Assert.That(uncovered, Is.EqualTo(ExpectedUncoveredConstraints));
+ }
+ }
+
+ private sealed class StubLibraryTypeIndex : ILibraryTypeIndex
+ {
+ private readonly IDictionary typesByQualifiedName;
+
+ public StubLibraryTypeIndex(IDictionary typesByQualifiedName)
+ {
+ this.typesByQualifiedName = typesByQualifiedName;
+ }
+
+ public bool TryGetType(string qualifiedName, out IType type) => this.typesByQualifiedName.TryGetValue(qualifiedName, out type);
+ }
+
+ private static IReadOnlyList RedefinedBy(IImpliedRelationshipRule rule, IElement element)
+ {
+ return [..rule.Apply(element).OfType().Select(redefinition => redefinition.RedefinedFeature)];
+ }
+
+ private static Feature AddEnd(IType owner)
+ {
+ var end = new Feature { Id = Guid.NewGuid(), IsEnd = true };
+ Own(owner, end, new EndFeatureMembership { Id = Guid.NewGuid() });
+
+ return end;
+ }
+
+ private static Feature AddResult(IType owner)
+ {
+ var result = new Feature { Id = Guid.NewGuid() };
+ Own(owner, result, new ReturnParameterMembership { Id = Guid.NewGuid() });
+
+ return result;
+ }
+
+ private static void Own(IElement owner, IElement owned, IRelationship membership = null)
+ {
+ var relationship = membership ?? new FeatureMembership { Id = Guid.NewGuid() };
+ ((IContainedRelationship)relationship).OwnedRelatedElement.Add(owned);
+ ((IContainedElement)owner).OwnedRelationship.Add(relationship);
+ }
+
+ private static void Specialize(IClassifier specific, IClassifier general)
+ {
+ var subclassification = new Subclassification
+ {
+ Id = Guid.NewGuid(),
+ Subclassifier = specific,
+ Superclassifier = general
+ };
+
+ ((IContainedElement)specific).OwnedRelationship.Add(subclassification);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics.Tests/Implied/Rules/VariationSpecializationRuleTestFixture.cs b/SysML2.NET.Semantics.Tests/Implied/Rules/VariationSpecializationRuleTestFixture.cs
new file mode 100644
index 00000000..77712a40
--- /dev/null
+++ b/SysML2.NET.Semantics.Tests/Implied/Rules/VariationSpecializationRuleTestFixture.cs
@@ -0,0 +1,152 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Tests.Implied.Rules
+{
+ using System;
+ using System.Linq;
+
+ using NUnit.Framework;
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Root.Namespaces;
+ using SysML2.NET.Core.POCO.Systems.DefinitionAndUsage;
+ using SysML2.NET.Core.POCO.Systems.Parts;
+ using SysML2.NET.Semantics.Implied;
+ using SysML2.NET.Semantics.Implied.Rules;
+
+ [TestFixture]
+ public class VariationSpecializationRuleTestFixture
+ {
+ private ImpliedRelationshipFactory factory;
+
+ private VariationUsageSpecializationRule usageRule;
+
+ private VariationDefinitionSpecializationRule definitionRule;
+
+ [SetUp]
+ public void SetUp()
+ {
+ this.factory = new ImpliedRelationshipFactory();
+ this.usageRule = new VariationUsageSpecializationRule(this.factory);
+ this.definitionRule = new VariationDefinitionSpecializationRule(this.factory);
+ }
+
+ [Test]
+ public void VerifyApplyForVariationUsage()
+ {
+ // variation part p { variant part p1; } -> member feature p1 subsets p
+ var variation = new PartUsage { Id = Guid.NewGuid(), DeclaredName = "p", IsVariation = true };
+ var variant = new PartUsage { Id = Guid.NewGuid(), DeclaredName = "p1" };
+
+ OwnAsVariant(variation, variant);
+
+ var implied = this.usageRule.Apply(variant);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(implied, Has.Count.EqualTo(1));
+ Assert.That(implied[0], Is.InstanceOf());
+
+ var subsetting = (ISubsetting)implied[0];
+ Assert.That(subsetting.IsImplied, Is.True);
+ Assert.That(subsetting.SubsettingFeature, Is.SameAs(variant));
+ Assert.That(subsetting.SubsettedFeature, Is.SameAs(variation));
+
+ // The Definition rule must decline: the owner is a Usage, not a Definition.
+ Assert.That(this.definitionRule.Apply(variant), Is.Empty);
+ }
+ }
+
+ [Test]
+ public void VerifyApplyForVariationDefinition()
+ {
+ // variation part def P { variant part p1; } -> member feature p1 : P
+ var variation = new PartDefinition { Id = Guid.NewGuid(), DeclaredName = "P", IsVariation = true };
+ var variant = new PartUsage { Id = Guid.NewGuid(), DeclaredName = "p1" };
+
+ OwnAsVariant(variation, variant);
+
+ var implied = this.definitionRule.Apply(variant);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(implied, Has.Count.EqualTo(1));
+ Assert.That(implied[0], Is.InstanceOf());
+
+ var featureTyping = (IFeatureTyping)implied[0];
+ Assert.That(featureTyping.IsImplied, Is.True);
+ Assert.That(featureTyping.TypedFeature, Is.SameAs(variant));
+ Assert.That(featureTyping.Type, Is.SameAs(variation));
+
+ // A Definition is a Classifier, not a Usage, so the Usage rule must decline.
+ Assert.That(this.usageRule.Apply(variant), Is.Empty);
+ }
+ }
+
+ [Test]
+ public void VerifyApplyDeclinesNonVariants()
+ {
+ var owner = new PartUsage { Id = Guid.NewGuid(), DeclaredName = "owner" };
+ var ordinary = new PartUsage { Id = Guid.NewGuid(), DeclaredName = "ordinary" };
+
+ // An ordinary OwningMembership is NOT a VariantMembership, so neither rule applies.
+ var membership = new OwningMembership { Id = Guid.NewGuid() };
+ ((IContainedRelationship)membership).OwnedRelatedElement.Add(ordinary);
+ ((IContainedElement)owner).OwnedRelationship.Add(membership);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(this.usageRule.Apply(ordinary), Is.Empty);
+ Assert.That(this.definitionRule.Apply(ordinary), Is.Empty);
+ Assert.That(this.usageRule.Apply(new Feature { Id = Guid.NewGuid() }), Is.Empty);
+
+ Assert.That(() => this.usageRule.Apply(null), Throws.TypeOf());
+ Assert.That(() => this.definitionRule.Apply(null), Throws.TypeOf());
+
+ Assert.That(() => new VariationUsageSpecializationRule(null), Throws.TypeOf());
+ Assert.That(() => new VariationDefinitionSpecializationRule(null), Throws.TypeOf());
+ }
+ }
+
+ [Test]
+ public void VerifyConstraintName()
+ {
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(this.usageRule.ConstraintName, Is.EqualTo("checkUsageVariationUsageSpecialization"));
+ Assert.That(this.definitionRule.ConstraintName, Is.EqualTo("checkUsageVariationDefinitionSpecialization"));
+
+ // Both names must exist in the generated manifest, otherwise the rule covers nothing.
+ Assert.That(ImpliedRelationshipTable.AllConstraintNames, Contains.Item(this.usageRule.ConstraintName));
+ Assert.That(ImpliedRelationshipTable.AllConstraintNames, Contains.Item(this.definitionRule.ConstraintName));
+ Assert.That(ImpliedRelationshipTable.NotCovered.Any(entry => entry.Contains(this.usageRule.ConstraintName)), Is.True);
+ }
+ }
+
+ private static void OwnAsVariant(INamespace variation, IElement variant)
+ {
+ var membership = new VariantMembership { Id = Guid.NewGuid() };
+ ((IContainedRelationship)membership).OwnedRelatedElement.Add(variant);
+ ((IContainedElement)variation).OwnedRelationship.Add(membership);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics.Tests/SysML2.NET.Semantics.Tests.csproj b/SysML2.NET.Semantics.Tests/SysML2.NET.Semantics.Tests.csproj
new file mode 100644
index 00000000..a7a44e5e
--- /dev/null
+++ b/SysML2.NET.Semantics.Tests/SysML2.NET.Semantics.Tests.csproj
@@ -0,0 +1,41 @@
+
+
+
+ net10.0
+ 14.0
+ Starion Group S.A.
+ Sam Gerene
+ Nunit test suite for the SysML2.NET.Semantics Library
+ Copyright © Starion Group S.A.
+ Apache-2.0
+ https://github.com/STARIONGROUP/SysML2.NET.git
+ Git
+ false
+ disable
+ false
+ true
+ en-US
+
+
+
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
diff --git a/SysML2.NET.Semantics/AutoGenImplied/GeneratedImpliedRuleGuards.cs b/SysML2.NET.Semantics/AutoGenImplied/GeneratedImpliedRuleGuards.cs
new file mode 100644
index 00000000..bde03ada
--- /dev/null
+++ b/SysML2.NET.Semantics/AutoGenImplied/GeneratedImpliedRuleGuards.cs
@@ -0,0 +1,138 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------------------------------
+// --------THIS IS AN AUTOMATICALLY GENERATED FILE. ANY MANUAL CHANGES WILL BE OVERWRITTEN!--------
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using System.Collections.Generic;
+ using System.Linq;
+
+ ///
+ /// The guards whose OCL was mechanically translated from the abstract syntax.
+ ///
+ ///
+ /// A conditional semantic constraint absent from this set has a guard expression outside the
+ /// translatable shapes and must be supplied by a hand-written .
+ ///
+ public static class GeneratedImpliedRuleGuards
+ {
+ ///
+ /// The generated guards, ordered by constraint name.
+ ///
+ public static IReadOnlyList All { get; } =
+ [
+ // not isTriggerAction()
+ new GeneratedRuleGuard("checkAcceptActionUsageSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Actions.IAcceptActionUsage guardSubject && !guardSubject.IsTriggerAction()),
+ // isTriggerAction()
+ new GeneratedRuleGuard("checkAcceptActionUsageTriggerActionSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Actions.IAcceptActionUsage guardSubject && guardSubject.IsTriggerAction()),
+ // isComposite and owningType <> null and (owningType.oclIsKindOf(PartDefinition) or owningType.oclIsKindOf(PartUsage))
+ new GeneratedRuleGuard("checkActionUsageOwnedActionSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Actions.IActionUsage { IsComposite: true, owningType: SysML2.NET.Core.POCO.Systems.Parts.IPartDefinition or SysML2.NET.Core.POCO.Systems.Parts.IPartUsage }),
+ // isSubactionUsage()
+ new GeneratedRuleGuard("checkActionUsageSubactionSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Actions.IActionUsage guardSubject && guardSubject.IsSubactionUsage()),
+ // isComposite and owningType <> null and (owningType.oclIsKindOf(AnalysisCaseDefinition) or owningType.oclIsKindOf(AnalysisCaseUsage))
+ new GeneratedRuleGuard("checkAnalysisCaseUsageSubAnalysisCaseSpecialization", element => element is SysML2.NET.Core.POCO.Systems.AnalysisCases.IAnalysisCaseUsage { IsComposite: true, owningType: SysML2.NET.Core.POCO.Systems.AnalysisCases.IAnalysisCaseDefinition or SysML2.NET.Core.POCO.Systems.AnalysisCases.IAnalysisCaseUsage }),
+ // isSubactionUsage()
+ new GeneratedRuleGuard("checkAssignmentActionUsageSubactionSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Actions.IAssignmentActionUsage guardSubject && guardSubject.IsSubactionUsage()),
+ // owningType <> null and (owningType.oclIsKindOf(CalculationDefinition) or owningType.oclIsKindOf(CalculationUsage))
+ new GeneratedRuleGuard("checkCalculationUsageSubcalculationSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Calculations.ICalculationUsage { owningType: SysML2.NET.Core.POCO.Systems.Calculations.ICalculationDefinition or SysML2.NET.Core.POCO.Systems.Calculations.ICalculationUsage }),
+ // isComposite and owningType <> null and (owningType.oclIsKindOf(CaseDefinition) or owningType.oclIsKindOf(CaseUsage))
+ new GeneratedRuleGuard("checkCaseUsageSubcaseSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Cases.ICaseUsage { IsComposite: true, owningType: SysML2.NET.Core.POCO.Systems.Cases.ICaseDefinition or SysML2.NET.Core.POCO.Systems.Cases.ICaseUsage }),
+ // owningFeatureMembership <> null and owningFeatureMembership.oclIsKindOf(FramedConcernMembership)
+ new GeneratedRuleGuard("checkConcernUsageFramedConcernSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Requirements.IConcernUsage { owningFeatureMembership: SysML2.NET.Core.POCO.Systems.Requirements.IFramedConcernMembership }),
+ // ownedEndFeature->size() = 2
+ new GeneratedRuleGuard("checkConnectionDefinitionBinarySpecialization", element => element is SysML2.NET.Core.POCO.Systems.Connections.IConnectionDefinition guardSubject && ((SysML2.NET.Core.POCO.Core.Types.IType)guardSubject).ownedEndFeature.Count == 2),
+ // ownedEndFeature->size() = 2
+ new GeneratedRuleGuard("checkConnectionUsageBinarySpecialization", element => element is SysML2.NET.Core.POCO.Systems.Connections.IConnectionUsage guardSubject && ((SysML2.NET.Core.POCO.Core.Types.IType)guardSubject).ownedEndFeature.Count == 2),
+ // owningType <> null and (owningType.oclIsKindOf(ItemDefinition) or owningType.oclIsKindOf(ItemUsage))
+ new GeneratedRuleGuard("checkConstraintUsageCheckedConstraintSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Constraints.IConstraintUsage { owningType: SysML2.NET.Core.POCO.Systems.Items.IItemDefinition or SysML2.NET.Core.POCO.Systems.Items.IItemUsage }),
+ // owningType <> null and (owningType.oclIsKindOf(OccurrenceDefinition) or owningType.oclIsKindOf(OccurrenceUsage))
+ new GeneratedRuleGuard("checkEventOccurrenceUsageSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Occurrences.IEventOccurrenceUsage { owningType: SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceDefinition or SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceUsage }),
+ // owningType <> null and (owningType.oclIsKindOf(PartDefinition) or owningType.oclIsKindOf(PartUsage))
+ new GeneratedRuleGuard("checkExhibitStateUsageSpecialization", element => element is SysML2.NET.Core.POCO.Systems.States.IExhibitStateUsage { owningType: SysML2.NET.Core.POCO.Systems.Parts.IPartDefinition or SysML2.NET.Core.POCO.Systems.Parts.IPartUsage }),
+ // ownedTyping.type->exists(selectByKind(DataType))
+ new GeneratedRuleGuard("checkFeatureDataValueSpecialization", element => element is SysML2.NET.Core.POCO.Core.Features.IFeature guardSubject && guardSubject.ownedTyping.Any(featureTyping => featureTyping.Type is SysML2.NET.Core.POCO.Kernel.DataTypes.IDataType)),
+ // ownedTyping.type->exists(selectByKind(Structure))
+ new GeneratedRuleGuard("checkFeatureObjectSpecialization", element => element is SysML2.NET.Core.POCO.Core.Features.IFeature guardSubject && guardSubject.ownedTyping.Any(featureTyping => featureTyping.Type is SysML2.NET.Core.POCO.Kernel.Structures.IStructure)),
+ // ownedTyping.type->exists(selectByKind(Class))
+ new GeneratedRuleGuard("checkFeatureOccurrenceSpecialization", element => element is SysML2.NET.Core.POCO.Core.Features.IFeature guardSubject && guardSubject.ownedTyping.Any(featureTyping => featureTyping.Type is SysML2.NET.Core.POCO.Kernel.Classes.IClass)),
+ // ownedEndFeatures->notEmpty()
+ new GeneratedRuleGuard("checkFlowUsageFlowSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Flows.IFlowUsage guardSubject && ((SysML2.NET.Core.POCO.Core.Types.IType)guardSubject).ownedEndFeature.Count > 0),
+ // ownedEndFeatures->notEmpty()
+ new GeneratedRuleGuard("checkFlowWithEndsSpecialization", element => element is SysML2.NET.Core.POCO.Kernel.Interactions.IFlow guardSubject && ((SysML2.NET.Core.POCO.Core.Types.IType)guardSubject).ownedEndFeature.Count > 0),
+ // isSubactionUsage()
+ new GeneratedRuleGuard("checkForLoopActionUsageSubactionSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Actions.IForLoopActionUsage guardSubject && guardSubject.IsSubactionUsage()),
+ // isSubactionUsage()
+ new GeneratedRuleGuard("checkIfActionUsageSubactionSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Actions.IIfActionUsage guardSubject && guardSubject.IsSubactionUsage()),
+ // ownedEndFeature->size() = 2
+ new GeneratedRuleGuard("checkInterfaceDefinitionBinarySpecialization", element => element is SysML2.NET.Core.POCO.Systems.Interfaces.IInterfaceDefinition guardSubject && ((SysML2.NET.Core.POCO.Core.Types.IType)guardSubject).ownedEndFeature.Count == 2),
+ // ownedEndFeature->size() = 2
+ new GeneratedRuleGuard("checkInterfaceUsageBinarySpecialization", element => element is SysML2.NET.Core.POCO.Systems.Interfaces.IInterfaceUsage guardSubject && ((SysML2.NET.Core.POCO.Core.Types.IType)guardSubject).ownedEndFeature.Count == 2),
+ // isComposite and owningType <> null and (owningType.oclIsKindOf(ItemDefinition) or owningType.oclIsKindOf(ItemUsage))
+ new GeneratedRuleGuard("checkItemUsageSubitemSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Items.IItemUsage { IsComposite: true, owningType: SysML2.NET.Core.POCO.Systems.Items.IItemDefinition or SysML2.NET.Core.POCO.Systems.Items.IItemUsage }),
+ // isIndividual
+ new GeneratedRuleGuard("checkOccurrenceDefinitionIndividualSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceDefinition { IsIndividual: true }),
+ // portionKind = PortionKind::snapshot
+ new GeneratedRuleGuard("checkOccurrenceUsageSnapshotSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceUsage { PortionKind: SysML2.NET.Core.Systems.Occurrences.PortionKind.Snapshot }),
+ // portionKind = PortionKind::timeslice
+ new GeneratedRuleGuard("checkOccurrenceUsageTimeSliceSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceUsage { PortionKind: SysML2.NET.Core.Systems.Occurrences.PortionKind.Timeslice }),
+ // owningFeatureMembership <> null and owningFeatureMembership.oclIsKindOf(StakeholderMembership)
+ new GeneratedRuleGuard("checkPartUsageStakeholderSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Parts.IPartUsage { owningFeatureMembership: SysML2.NET.Core.POCO.Systems.Requirements.IStakeholderMembership }),
+ // isComposite and owningType <> null and (owningType.oclIsKindOf(ItemDefinition) or owningType.oclIsKindOf(ItemUsage))
+ new GeneratedRuleGuard("checkPartUsageSubpartSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Parts.IPartUsage { IsComposite: true, owningType: SysML2.NET.Core.POCO.Systems.Items.IItemDefinition or SysML2.NET.Core.POCO.Systems.Items.IItemUsage }),
+ // owningType <> null and (owningType.oclIsKindOf(PartDefinition) or owningType.oclIsKindOf(PartUsage))
+ new GeneratedRuleGuard("checkPerformActionUsageSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Actions.IPerformActionUsage { owningType: SysML2.NET.Core.POCO.Systems.Parts.IPartDefinition or SysML2.NET.Core.POCO.Systems.Parts.IPartUsage }),
+ // owningType <> null and (owningType.oclIsKindOf(PartDefinition) or owningType.oclIsKindOf(PartUsage))
+ new GeneratedRuleGuard("checkPortUsageOwnedPortSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Ports.IPortUsage { owningType: SysML2.NET.Core.POCO.Systems.Parts.IPartDefinition or SysML2.NET.Core.POCO.Systems.Parts.IPartUsage }),
+ // isComposite and owningType <> null and (owningType.oclIsKindOf(PortDefinition) or owningType.oclIsKindOf(PortUsage))
+ new GeneratedRuleGuard("checkPortUsageSubportSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Ports.IPortUsage { IsComposite: true, owningType: SysML2.NET.Core.POCO.Systems.Ports.IPortDefinition or SysML2.NET.Core.POCO.Systems.Ports.IPortUsage }),
+ // owningType <> null and (owningType.oclIsKindOf(RenderingDefinition) or owningType.oclIsKindOf(RenderingUsage))
+ new GeneratedRuleGuard("checkRenderingUsageSubrenderingSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Views.IRenderingUsage { owningType: SysML2.NET.Core.POCO.Systems.Views.IRenderingDefinition or SysML2.NET.Core.POCO.Systems.Views.IRenderingUsage }),
+ // owningFeatureMembership <> null and owningFeatureMembership.oclIsKindOf(RequirementVerificationMembership)
+ new GeneratedRuleGuard("checkRequirementUsageRequirementVerificationSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Requirements.IRequirementUsage { owningFeatureMembership: SysML2.NET.Core.POCO.Systems.VerificationCases.IRequirementVerificationMembership }),
+ // isComposite and owningType <> null and (owningType.oclIsKindOf(RequirementDefinition) or owningType.oclIsKindOf(RequirementUsage))
+ new GeneratedRuleGuard("checkRequirementUsageSubrequirementSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Requirements.IRequirementUsage { IsComposite: true, owningType: SysML2.NET.Core.POCO.Systems.Requirements.IRequirementDefinition or SysML2.NET.Core.POCO.Systems.Requirements.IRequirementUsage }),
+ // isSubactionUsage()
+ new GeneratedRuleGuard("checkSendActionUsageSubactionSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Actions.ISendActionUsage guardSubject && guardSubject.IsSubactionUsage()),
+ // isSubstateUsage(false)
+ new GeneratedRuleGuard("checkStateUsageExclusiveStateSpecialization", element => element is SysML2.NET.Core.POCO.Systems.States.IStateUsage guardSubject && guardSubject.IsSubstateUsage(false)),
+ // isComposite and owningType <> null and (owningType.oclIsKindOf(PartDefinition) or owningType.oclIsKindOf(PartUsage))
+ new GeneratedRuleGuard("checkStateUsageOwnedStateSpecialization", element => element is SysML2.NET.Core.POCO.Systems.States.IStateUsage { IsComposite: true, owningType: SysML2.NET.Core.POCO.Systems.Parts.IPartDefinition or SysML2.NET.Core.POCO.Systems.Parts.IPartUsage }),
+ // isSubstateUsage(true)
+ new GeneratedRuleGuard("checkStateUsageSubstateSpecialization", element => element is SysML2.NET.Core.POCO.Systems.States.IStateUsage guardSubject && guardSubject.IsSubstateUsage(true)),
+ // owningType <> null and (owningType.oclIsKindOf(Behavior) or owningType.oclIsKindOf(Step))
+ new GeneratedRuleGuard("checkStepEnclosedPerformanceSpecialization", element => element is SysML2.NET.Core.POCO.Kernel.Behaviors.IStep { owningType: SysML2.NET.Core.POCO.Kernel.Behaviors.IBehavior or SysML2.NET.Core.POCO.Kernel.Behaviors.IStep }),
+ // isSubactionUsage()
+ new GeneratedRuleGuard("checkTerminateActionUsageSubactionSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Actions.ITerminateActionUsage guardSubject && guardSubject.IsSubactionUsage()),
+ // isComposite and owningType <> null and (owningType.oclIsKindOf(UseCaseDefinition) or owningType.oclIsKindOf(UseCaseUsage))
+ new GeneratedRuleGuard("checkUseCaseUsageSubUseCaseSpecialization", element => element is SysML2.NET.Core.POCO.Systems.UseCases.IUseCaseUsage { IsComposite: true, owningType: SysML2.NET.Core.POCO.Systems.UseCases.IUseCaseDefinition or SysML2.NET.Core.POCO.Systems.UseCases.IUseCaseUsage }),
+ // isComposite and owningType <> null and (owningType.oclIsKindOf(VerificationCaseDefinition) or owningType.oclIsKindOf(VerificationCaseUsage))
+ new GeneratedRuleGuard("checkVerificationCaseUsageSubVerificationCaseSpecialization", element => element is SysML2.NET.Core.POCO.Systems.VerificationCases.IVerificationCaseUsage { IsComposite: true, owningType: SysML2.NET.Core.POCO.Systems.VerificationCases.IVerificationCaseDefinition or SysML2.NET.Core.POCO.Systems.VerificationCases.IVerificationCaseUsage }),
+ // owningType <> null and (owningType.oclIsKindOf(ViewDefinition) or owningType.oclIsKindOf(ViewUsage))
+ new GeneratedRuleGuard("checkViewUsageSubviewSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Views.IViewUsage { owningType: SysML2.NET.Core.POCO.Systems.Views.IViewDefinition or SysML2.NET.Core.POCO.Systems.Views.IViewUsage }),
+ // isComposite and owningType <> null and (owningType.oclIsKindOf(ViewDefinition) or owningType.oclIsKindOf(ViewUsage))
+ new GeneratedRuleGuard("checkViewpointUsageViewpointSatisfactionSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Views.IViewpointUsage { IsComposite: true, owningType: SysML2.NET.Core.POCO.Systems.Views.IViewDefinition or SysML2.NET.Core.POCO.Systems.Views.IViewUsage }),
+ // isSubactionUsage()
+ new GeneratedRuleGuard("checkWhileLoopActionUsageSubactionSpecialization", element => element is SysML2.NET.Core.POCO.Systems.Actions.IWhileLoopActionUsage guardSubject && guardSubject.IsSubactionUsage()),
+ ];
+ }
+}
diff --git a/SysML2.NET.Semantics/AutoGenImplied/ImpliedRelationshipTable.cs b/SysML2.NET.Semantics/AutoGenImplied/ImpliedRelationshipTable.cs
new file mode 100644
index 00000000..f9dd1fbb
--- /dev/null
+++ b/SysML2.NET.Semantics/AutoGenImplied/ImpliedRelationshipTable.cs
@@ -0,0 +1,3402 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------------------------------
+// --------THIS IS AN AUTOMATICALLY GENERATED FILE. ANY MANUAL CHANGES WILL BE OVERWRITTEN!--------
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using System.Collections.Generic;
+
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// The kind of Relationship that is implied to satisfy a semantic constraint.
+ ///
+ public enum ImpliedRelationshipKind
+ {
+ ///
+ /// A Subclassification, implied for a Classifier.
+ ///
+ Subclassification,
+
+ ///
+ /// A Subsetting, implied for a Feature.
+ ///
+ Subsetting
+ }
+
+ ///
+ /// A single implied library Specialization, as required by one semantic constraint of the
+ /// KerML/SysML abstract syntax.
+ ///
+ public readonly struct ImpliedLibrarySpecialization
+ {
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The name of the semantic constraint the rule was extracted from
+ ///
+ ///
+ /// The qualified name of the library Type that must be specialized
+ ///
+ ///
+ /// The metaclass the constraint is declared on, which decides
+ ///
+ ///
+ /// Whether the constraint's OCL guards the specialization
+ ///
+ public ImpliedLibrarySpecialization(string constraintName, string targetLibraryName, string declaringMetaclassName, bool requiresGuard)
+ {
+ this.ConstraintName = constraintName;
+ this.TargetLibraryName = targetLibraryName;
+ this.DeclaringMetaclassName = declaringMetaclassName;
+ this.RequiresGuard = requiresGuard;
+ }
+
+ ///
+ /// Gets the name of the semantic constraint the rule was extracted from.
+ ///
+ public string ConstraintName { get; }
+
+ ///
+ /// Gets the qualified name of the library Type that must be specialized.
+ ///
+ public string TargetLibraryName { get; }
+
+ ///
+ /// Gets the metaclass the constraint is declared on. The Relationship kind is decided from this
+ /// name, not from the metaclass that inherits the constraint.
+ ///
+ public string DeclaringMetaclassName { get; }
+
+ ///
+ /// Gets a value indicating whether the constraint's OCL guards the specialization, in which case the
+ /// rule applies only when the hand-written predicate for says so.
+ ///
+ public bool RequiresGuard { get; }
+
+ ///
+ /// Gets the kind of Relationship to imply, decided by whether the declaring metaclass is a
+ /// Classifier or a Feature.
+ ///
+ public ImpliedRelationshipKind Kind =>
+ ImpliedRelationshipTable.SubclassificationMetaclasses.Contains(this.DeclaringMetaclassName)
+ ? ImpliedRelationshipKind.Subclassification
+ : ImpliedRelationshipKind.Subsetting;
+ }
+
+ ///
+ /// The table of implied library Specializations that KerML 1.0 §8.4.2 allows a tool to insert to
+ /// satisfy the specialization constraints of the abstract syntax.
+ ///
+ ///
+ ///
+ /// The metaclass and the library target of each row come from the constraint's OCL body in the UML XMI.
+ /// The does NOT: the OCL says only what to specialize, never
+ /// whether the implied Relationship is a Subclassification or a Subsetting. That is stated only in the
+ /// specification tables — KerML 1.0 Table 8 (§8.4.3.1.1) and Table 10 (§8.4.4.1), and SysML 2.0
+ /// Tables 31-33 — so below is transcribed by hand from those
+ /// tables and lives in the Handlebars template, not in the generator.
+ ///
+ ///
+ /// Rows are NOT reduced against the §8.4.2 redundancy rules. Rule 1 suppresses an implied Specialization
+ /// whose general Type is a supertype of another applicable one, and deciding that needs the library
+ /// Types resolved — they are not present in the metamodel XMI. The reduction therefore belongs to the
+ /// caller, which must also apply rule 2 (de-duplicate identical targets). Neither rule applies to
+ /// Redefinitions.
+ ///
+ ///
+ public static class ImpliedRelationshipTable
+ {
+ ///
+ /// The metaclasses whose implied Specialization is a Subclassification rather than a
+ /// Subsetting — that is, the Classifiers.
+ ///
+ ///
+ /// HAND-MAINTAINED. This is the one part of the table that cannot be derived from the OCL; it is
+ /// transcribed from KerML Table 8 / Table 10 and SysML Tables 31-33. KerML Table 8 note 1 is the
+ /// reason Type is absent: checkTypeSpecialization applies to every Type, but the
+ /// Subclassification is only implied for Classifiers. Anything not listed here is a Feature and
+ /// implies a Subsetting.
+ ///
+ internal static readonly HashSet SubclassificationMetaclasses =
+ [
+ "ActionDefinition",
+ "AllocationDefinition",
+ "AnalysisCaseDefinition",
+ "Association",
+ "AssociationStructure",
+ "Behavior",
+ "CalculationDefinition",
+ "CaseDefinition",
+ "Class",
+ "ConcernDefinition",
+ "ConnectionDefinition",
+ "ConstraintDefinition",
+ "DataType",
+ "FlowDefinition",
+ "Function",
+ "InterfaceDefinition",
+ "ItemDefinition",
+ "Metaclass",
+ "MetadataDefinition",
+ "OccurrenceDefinition",
+ "PartDefinition",
+ "PortDefinition",
+ "Predicate",
+ "RenderingDefinition",
+ "RequirementDefinition",
+ "StateDefinition",
+ "Structure",
+ "UseCaseDefinition",
+ "VerificationCaseDefinition",
+ "ViewDefinition",
+ "ViewpointDefinition"
+ ];
+
+ ///
+ /// The semantic constraints that are NOT represented in this table, with the reason. Emitted so that
+ /// no constraint of KerML §8.4.2 is silently dropped while its hand-coded arm is outstanding.
+ ///
+ public static IReadOnlyList NotCovered { get; } =
+ [
+ "AcceptActionUsage.checkAcceptActionUsageReceiverBindingConnector (BindingConnector) - OCL is not a specializesFromLibrary call",
+ "ActionUsage.checkActionUsageStateActionRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "AssertConstraintUsage.checkAssertConstraintUsageSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "AssignmentActionUsage.checkAssignmentActionUsageAccessedFeatureRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "AssignmentActionUsage.checkAssignmentActionUsageReferentRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "AssignmentActionUsage.checkAssignmentActionUsageStartingAtRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "Connector.checkConnectorTypeFeaturing (TypeFeaturing) - OCL is not a specializesFromLibrary call",
+ "ConstraintUsage.checkConstraintUsageRequirementConstraintSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "ConstructorExpression.checkConstructorExpressionResultDefaultValueBindingConnector (BindingConnector) - specification body is TBD",
+ "ConstructorExpression.checkConstructorExpressionResultFeatureRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "ConstructorExpression.checkConstructorExpressionResultSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "ConstructorExpression.checkConstructorExpressionSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "DecisionNode.checkDecisionNodeOutgoingSuccessionSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "Expression.checkExpressionResultBindingConnector (BindingConnector) - OCL is not a specializesFromLibrary call",
+ "Expression.checkExpressionTypeFeaturing (TypeFeaturing) - OCL is not a specializesFromLibrary call",
+ "Feature.checkFeatureCrossingSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "Feature.checkFeatureEndRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "Feature.checkFeatureFeatureMembershipTypeFeaturing (TypeFeaturing) - OCL is not a specializesFromLibrary call",
+ "Feature.checkFeatureFlowFeatureRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "Feature.checkFeatureOwnedCrossFeatureRedefinitionSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "Feature.checkFeatureOwnedCrossFeatureSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "Feature.checkFeatureOwnedCrossFeatureTypeFeaturing (TypeFeaturing) - OCL is not a specializesFromLibrary call",
+ "Feature.checkFeatureParameterRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "Feature.checkFeatureResultRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "Feature.checkFeatureValuationSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "FeatureChainExpression.checkFeatureChainExpressionResultSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "FeatureChainExpression.checkFeatureChainExpressionSourceTargetRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "FeatureChainExpression.checkFeatureChainExpressionTargetRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "FeatureReferenceExpression.checkFeatureReferenceExpressionBindingConnector (BindingConnector) - OCL is not a specializesFromLibrary call",
+ "FeatureReferenceExpression.checkFeatureReferenceExpressionResultSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "FeatureValue.checkFeatureValueBindingConnector (BindingConnector) - OCL is not a specializesFromLibrary call",
+ "ForLoopActionUsage.checkForLoopActionUsageVarRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "Function.checkFunctionResultBindingConnector (BindingConnector) - OCL is not a specializesFromLibrary call",
+ "IfActionUsage.checkIfActionUsageSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "IndexExpression.checkIndexExpressionResultSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "Invariant.checkInvariantSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "InvocationExpression.checkInvocationExpressionBehaviorBindingConnector (BindingConnector) - OCL is not a specializesFromLibrary call",
+ "InvocationExpression.checkInvocationExpressionBehaviorResultSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "InvocationExpression.checkInvocationExpressionDefaultValueBindingConnector (BindingConnector) - specification body is TBD",
+ "InvocationExpression.checkInvocationExpressionSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "MergeNode.checkMergeNodeIncomingSuccessionSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "MetadataFeature.checkMetadataFeatureSemanticSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "Multiplicity.checkMultiplicityTypeFeaturing (TypeFeaturing) - OCL is not a specializesFromLibrary call",
+ "MultiplicityRange.checkMultiplicityRangeExpressionTypeFeaturing (TypeFeaturing) - OCL is not a specializesFromLibrary call",
+ "OccurrenceDefinition.checkOccurrenceDefinitionMultiplicitySpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "PartUsage.checkPartUsageActorSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "PayloadFeature.checkPayloadFeatureRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "RenderingUsage.checkRenderingUsageRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "RequirementUsage.checkRequirementUsageObjectiveRedefinition (Redefinition) - OCL is not a specializesFromLibrary call",
+ "SatisfyRequirementUsage.checkSatisfyRequirementUsageBindingConnector (BindingConnector) - OCL is not a specializesFromLibrary call",
+ "SatisfyRequirementUsage.checkSatisfyRequirementUsageSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "SelectExpression.checkSelectExpressionResultSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "TransitionUsage.checkTransitionUsagePayloadSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "TransitionUsage.checkTransitionUsageSourceBindingConnector (BindingConnector) - OCL is not a specializesFromLibrary call",
+ "TransitionUsage.checkTransitionUsageSuccessionBindingConnector (BindingConnector) - OCL is not a specializesFromLibrary call",
+ "TransitionUsage.checkTransitionUsageSuccessionSourceSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "TransitionUsage.checkTransitionUsageTransitionFeatureSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "Usage.checkUsageVariationDefinitionSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "Usage.checkUsageVariationUsageSpecialization (Specialization) - OCL is not a specializesFromLibrary call",
+ "Usage.checkUsageVariationUsageTypeFeaturing (TypeFeaturing) - OCL is not a specializesFromLibrary call",
+ ];
+
+ ///
+ /// The name of every semantic constraint declared in the abstract syntax, covered or not.
+ ///
+ public static IReadOnlyList AllConstraintNames { get; } =
+ [
+ "checkAcceptActionUsageReceiverBindingConnector",
+ "checkAcceptActionUsageSpecialization",
+ "checkAcceptActionUsageSubactionSpecialization",
+ "checkAcceptActionUsageTriggerActionSpecialization",
+ "checkActionDefinitionSpecialization",
+ "checkActionUsageOwnedActionSpecialization",
+ "checkActionUsageSpecialization",
+ "checkActionUsageStateActionRedefinition",
+ "checkActionUsageSubactionSpecialization",
+ "checkAllocationDefinitionSpecialization",
+ "checkAllocationUsageSpecialization",
+ "checkAnalysisCaseDefinitionSpecialization",
+ "checkAnalysisCaseUsageSpecialization",
+ "checkAnalysisCaseUsageSubAnalysisCaseSpecialization",
+ "checkAssertConstraintUsageSpecialization",
+ "checkAssignmentActionUsageAccessedFeatureRedefinition",
+ "checkAssignmentActionUsageReferentRedefinition",
+ "checkAssignmentActionUsageSpecialization",
+ "checkAssignmentActionUsageStartingAtRedefinition",
+ "checkAssignmentActionUsageSubactionSpecialization",
+ "checkAssociationBinarySpecialization",
+ "checkAssociationSpecialization",
+ "checkAssociationStructureBinarySpecialization",
+ "checkAssociationStructureSpecialization",
+ "checkAttributeUsageSpecialization",
+ "checkBehaviorSpecialization",
+ "checkBindingConnectorSpecialization",
+ "checkBooleanExpressionSpecialization",
+ "checkCalculationDefinitionSpecialization",
+ "checkCalculationUsageSpecialization",
+ "checkCalculationUsageSubcalculationSpecialization",
+ "checkCaseDefinitionSpecialization",
+ "checkCaseUsageSpecialization",
+ "checkCaseUsageSubcaseSpecialization",
+ "checkClassSpecialization",
+ "checkConcernDefinitionSpecialization",
+ "checkConcernUsageFramedConcernSpecialization",
+ "checkConcernUsageSpecialization",
+ "checkConnectionDefinitionBinarySpecialization",
+ "checkConnectionDefinitionSpecializations",
+ "checkConnectionUsageBinarySpecialization",
+ "checkConnectionUsageSpecialization",
+ "checkConnectorBinaryObjectSpecialization",
+ "checkConnectorBinarySpecialization",
+ "checkConnectorObjectSpecialization",
+ "checkConnectorSpecialization",
+ "checkConnectorTypeFeaturing",
+ "checkConstraintDefinitionSpecialization",
+ "checkConstraintUsageCheckedConstraintSpecialization",
+ "checkConstraintUsageRequirementConstraintSpecialization",
+ "checkConstraintUsageSpecialization",
+ "checkConstructorExpressionResultDefaultValueBindingConnector",
+ "checkConstructorExpressionResultFeatureRedefinition",
+ "checkConstructorExpressionResultSpecialization",
+ "checkConstructorExpressionSpecialization",
+ "checkControlNodeSpecialization",
+ "checkDataTypeSpecialization",
+ "checkDecisionNodeOutgoingSuccessionSpecialization",
+ "checkDecisionNodeSpecialization",
+ "checkEventOccurrenceUsageSpecialization",
+ "checkExhibitStateUsageSpecialization",
+ "checkExpressionResultBindingConnector",
+ "checkExpressionSpecialization",
+ "checkExpressionTypeFeaturing",
+ "checkFeatureChainExpressionResultSpecialization",
+ "checkFeatureChainExpressionSourceTargetRedefinition",
+ "checkFeatureChainExpressionTargetRedefinition",
+ "checkFeatureCrossingSpecialization",
+ "checkFeatureDataValueSpecialization",
+ "checkFeatureEndRedefinition",
+ "checkFeatureEndSpecialization",
+ "checkFeatureFeatureMembershipTypeFeaturing",
+ "checkFeatureFlowFeatureRedefinition",
+ "checkFeatureObjectSpecialization",
+ "checkFeatureOccurrenceSpecialization",
+ "checkFeatureOwnedCrossFeatureRedefinitionSpecialization",
+ "checkFeatureOwnedCrossFeatureSpecialization",
+ "checkFeatureOwnedCrossFeatureTypeFeaturing",
+ "checkFeatureParameterRedefinition",
+ "checkFeaturePortionSpecialization",
+ "checkFeatureReferenceExpressionBindingConnector",
+ "checkFeatureReferenceExpressionResultSpecialization",
+ "checkFeatureResultRedefinition",
+ "checkFeatureSpecialization",
+ "checkFeatureSubobjectSpecialization",
+ "checkFeatureSuboccurrenceSpecialization",
+ "checkFeatureValuationSpecialization",
+ "checkFeatureValueBindingConnector",
+ "checkFlowDefinitionBinarySpecialization",
+ "checkFlowDefinitionSpecialization",
+ "checkFlowSpecialization",
+ "checkFlowUsageFlowSpecialization",
+ "checkFlowUsageSpecialization",
+ "checkFlowWithEndsSpecialization",
+ "checkForLoopActionUsageSpecialization",
+ "checkForLoopActionUsageSubactionSpecialization",
+ "checkForLoopActionUsageVarRedefinition",
+ "checkForkNodeSpecialization",
+ "checkFunctionResultBindingConnector",
+ "checkFunctionSpecialization",
+ "checkIfActionUsageSpecialization",
+ "checkIfActionUsageSubactionSpecialization",
+ "checkIncludeUseCaseUsageSpecialization",
+ "checkIndexExpressionResultSpecialization",
+ "checkInterfaceDefinitionBinarySpecialization",
+ "checkInterfaceDefinitionSpecialization",
+ "checkInterfaceUsageBinarySpecialization",
+ "checkInterfaceUsageSpecialization",
+ "checkInvariantSpecialization",
+ "checkInvocationExpressionBehaviorBindingConnector",
+ "checkInvocationExpressionBehaviorResultSpecialization",
+ "checkInvocationExpressionDefaultValueBindingConnector",
+ "checkInvocationExpressionSpecialization",
+ "checkItemDefinitionSpecialization",
+ "checkItemUsageSpecialization",
+ "checkItemUsageSubitemSpecialization",
+ "checkJoinNodeSpecialization",
+ "checkLiteralBooleanSpecialization",
+ "checkLiteralExpressionSpecialization",
+ "checkLiteralInfinitySpecialization",
+ "checkLiteralIntegerSpecialization",
+ "checkLiteralRationalSpecialization",
+ "checkLiteralStringSpecialization",
+ "checkMergeNodeIncomingSuccessionSpecialization",
+ "checkMergeNodeSpecialization",
+ "checkMetaclassSpecialization",
+ "checkMetadataAccessExpressionSpecialization",
+ "checkMetadataDefinitionSpecialization",
+ "checkMetadataFeatureSemanticSpecialization",
+ "checkMetadataFeatureSpecialization",
+ "checkMetadataUsageSpecialization",
+ "checkMultiplicityRangeExpressionTypeFeaturing",
+ "checkMultiplicitySpecialization",
+ "checkMultiplicityTypeFeaturing",
+ "checkNullExpressionSpecialization",
+ "checkOccurrenceDefinitionIndividualSpecialization",
+ "checkOccurrenceDefinitionMultiplicitySpecialization",
+ "checkOccurrenceUsageSnapshotSpecialization",
+ "checkOccurrenceUsageSpecialization",
+ "checkOccurrenceUsageSuboccurrenceSpecialization",
+ "checkOccurrenceUsageTimeSliceSpecialization",
+ "checkPartDefinitionSpecialization",
+ "checkPartUsageActorSpecialization",
+ "checkPartUsageSpecialization",
+ "checkPartUsageStakeholderSpecialization",
+ "checkPartUsageSubpartSpecialization",
+ "checkPayloadFeatureRedefinition",
+ "checkPerformActionUsageSpecialization",
+ "checkPortDefinitionSpecialization",
+ "checkPortUsageOwnedPortSpecialization",
+ "checkPortUsageSpecialization",
+ "checkPortUsageSubportSpecialization",
+ "checkPredicateSpecialization",
+ "checkRenderingDefinitionSpecialization",
+ "checkRenderingUsageRedefinition",
+ "checkRenderingUsageSpecialization",
+ "checkRenderingUsageSubrenderingSpecialization",
+ "checkRequirementDefinitionSpecialization",
+ "checkRequirementUsageObjectiveRedefinition",
+ "checkRequirementUsageRequirementVerificationSpecialization",
+ "checkRequirementUsageSpecialization",
+ "checkRequirementUsageSubrequirementSpecialization",
+ "checkSatisfyRequirementUsageBindingConnector",
+ "checkSatisfyRequirementUsageSpecialization",
+ "checkSelectExpressionResultSpecialization",
+ "checkSendActionUsageSpecialization",
+ "checkSendActionUsageSubactionSpecialization",
+ "checkStateDefinitionSpecialization",
+ "checkStateUsageExclusiveStateSpecialization",
+ "checkStateUsageOwnedStateSpecialization",
+ "checkStateUsageSpecialization",
+ "checkStateUsageSubstateSpecialization",
+ "checkStepEnclosedPerformanceSpecialization",
+ "checkStepOwnedPerformanceSpecialization",
+ "checkStepSpecialization",
+ "checkStepSubperformanceSpecialization",
+ "checkStructureSpecialization",
+ "checkSuccessionFlowSpecialization",
+ "checkSuccessionFlowUsageSpecialization",
+ "checkSuccessionSpecialization",
+ "checkTerminateActionUsageSpecialization",
+ "checkTerminateActionUsageSubactionSpecialization",
+ "checkTransitionUsageActionSpecialization",
+ "checkTransitionUsagePayloadSpecialization",
+ "checkTransitionUsageSourceBindingConnector",
+ "checkTransitionUsageSpecialization",
+ "checkTransitionUsageStateSpecialization",
+ "checkTransitionUsageSuccessionBindingConnector",
+ "checkTransitionUsageSuccessionSourceSpecialization",
+ "checkTransitionUsageTransitionFeatureSpecialization",
+ "checkTypeSpecialization",
+ "checkUsageVariationDefinitionSpecialization",
+ "checkUsageVariationUsageSpecialization",
+ "checkUsageVariationUsageTypeFeaturing",
+ "checkUseCaseDefinitionSpecialization",
+ "checkUseCaseUsageSpecialization",
+ "checkUseCaseUsageSubUseCaseSpecialization",
+ "checkVerificationCaseSpecialization",
+ "checkVerificationCaseUsageSpecialization",
+ "checkVerificationCaseUsageSubVerificationCaseSpecialization",
+ "checkViewDefinitionSpecialization",
+ "checkViewUsageSpecialization",
+ "checkViewUsageSubviewSpecialization",
+ "checkViewpointDefinitionSpecialization",
+ "checkViewpointUsageSpecialization",
+ "checkViewpointUsageViewpointSatisfactionSpecialization",
+ "checkWhileLoopActionUsageSpecialization",
+ "checkWhileLoopActionUsageSubactionSpecialization",
+ ];
+
+ ///
+ /// The name of every constraint whose application is conditional, i.e. every row that requires a
+ /// guard before its implied Relationship may be included.
+ ///
+ public static IReadOnlyList AllConditionalConstraintNames { get; } =
+ [
+ "checkAcceptActionUsageSpecialization",
+ "checkAcceptActionUsageSubactionSpecialization",
+ "checkAcceptActionUsageTriggerActionSpecialization",
+ "checkActionUsageOwnedActionSpecialization",
+ "checkActionUsageSubactionSpecialization",
+ "checkAnalysisCaseUsageSubAnalysisCaseSpecialization",
+ "checkAssignmentActionUsageSubactionSpecialization",
+ "checkAssociationBinarySpecialization",
+ "checkAssociationStructureBinarySpecialization",
+ "checkCalculationUsageSubcalculationSpecialization",
+ "checkCaseUsageSubcaseSpecialization",
+ "checkConcernUsageFramedConcernSpecialization",
+ "checkConnectionDefinitionBinarySpecialization",
+ "checkConnectionUsageBinarySpecialization",
+ "checkConnectorBinaryObjectSpecialization",
+ "checkConnectorBinarySpecialization",
+ "checkConnectorObjectSpecialization",
+ "checkConstraintUsageCheckedConstraintSpecialization",
+ "checkEventOccurrenceUsageSpecialization",
+ "checkExhibitStateUsageSpecialization",
+ "checkFeatureDataValueSpecialization",
+ "checkFeatureEndSpecialization",
+ "checkFeatureObjectSpecialization",
+ "checkFeatureOccurrenceSpecialization",
+ "checkFeaturePortionSpecialization",
+ "checkFeatureSubobjectSpecialization",
+ "checkFeatureSuboccurrenceSpecialization",
+ "checkFlowDefinitionBinarySpecialization",
+ "checkFlowUsageFlowSpecialization",
+ "checkFlowWithEndsSpecialization",
+ "checkForLoopActionUsageSubactionSpecialization",
+ "checkIfActionUsageSubactionSpecialization",
+ "checkIncludeUseCaseUsageSpecialization",
+ "checkInterfaceDefinitionBinarySpecialization",
+ "checkInterfaceUsageBinarySpecialization",
+ "checkItemUsageSubitemSpecialization",
+ "checkOccurrenceDefinitionIndividualSpecialization",
+ "checkOccurrenceUsageSnapshotSpecialization",
+ "checkOccurrenceUsageSuboccurrenceSpecialization",
+ "checkOccurrenceUsageTimeSliceSpecialization",
+ "checkPartUsageStakeholderSpecialization",
+ "checkPartUsageSubpartSpecialization",
+ "checkPerformActionUsageSpecialization",
+ "checkPortUsageOwnedPortSpecialization",
+ "checkPortUsageSubportSpecialization",
+ "checkRenderingUsageSubrenderingSpecialization",
+ "checkRequirementUsageRequirementVerificationSpecialization",
+ "checkRequirementUsageSubrequirementSpecialization",
+ "checkSendActionUsageSubactionSpecialization",
+ "checkStateUsageExclusiveStateSpecialization",
+ "checkStateUsageOwnedStateSpecialization",
+ "checkStateUsageSubstateSpecialization",
+ "checkStepEnclosedPerformanceSpecialization",
+ "checkStepOwnedPerformanceSpecialization",
+ "checkStepSubperformanceSpecialization",
+ "checkTerminateActionUsageSubactionSpecialization",
+ "checkTransitionUsageActionSpecialization",
+ "checkTransitionUsageStateSpecialization",
+ "checkUseCaseUsageSubUseCaseSpecialization",
+ "checkVerificationCaseUsageSubVerificationCaseSpecialization",
+ "checkViewUsageSubviewSpecialization",
+ "checkViewpointUsageViewpointSatisfactionSpecialization",
+ "checkWhileLoopActionUsageSubactionSpecialization",
+ ];
+
+ ///
+ /// The qualified name of every library Type targeted by a row of this table, without duplicates.
+ ///
+ ///
+ /// Every name here must resolve against a full model-library load, or the constraint that carries
+ /// it can never be satisfied. Exposed so that resolution can be asserted for the whole table rather
+ /// than only for the rows a given corpus happens to exercise.
+ ///
+ public static IReadOnlyList AllLibraryTargets { get; } =
+ [
+ "Actions::Action",
+ "Actions::Action::acceptSubactions",
+ "Actions::Action::assignments",
+ "Actions::Action::controls",
+ "Actions::Action::decisionTransitions",
+ "Actions::Action::decisions",
+ "Actions::Action::forLoops",
+ "Actions::Action::forks",
+ "Actions::Action::ifSubactions",
+ "Actions::Action::joins",
+ "Actions::Action::merges",
+ "Actions::Action::subactions",
+ "Actions::Action::terminateSubactions",
+ "Actions::Action::whileLoops",
+ "Actions::TransitionAction::accepter",
+ "Actions::acceptActions",
+ "Actions::actions",
+ "Actions::assignmentActions",
+ "Actions::forLoopActions",
+ "Actions::sendActions",
+ "Actions::terminateActions",
+ "Actions::transitionActions",
+ "Actions::whileLoopActions",
+ "Allocations::Allocation",
+ "Allocations::allocations",
+ "AnalysisCases::AnalysisCase",
+ "AnalysisCases::AnalysisCase::subAnalysisCases",
+ "AnalysisCases::analysisCases",
+ "Base::Anything",
+ "Base::DataValue",
+ "Base::dataValues",
+ "Base::naturals",
+ "Base::things",
+ "Calculations::Calculation",
+ "Calculations::Calculation::subcalculations",
+ "Calculations::calculations",
+ "Cases::Case",
+ "Cases::Case::subcases",
+ "Cases::cases",
+ "Connections::BinaryConnection",
+ "Connections::Connection",
+ "Connections::binaryConnections",
+ "Connections::connections",
+ "Constraints::ConstraintCheck",
+ "Constraints::constraintChecks",
+ "Flows::Message",
+ "Flows::MessageAction",
+ "Flows::flows",
+ "Flows::messages",
+ "Flows::successionFlows",
+ "Interfaces::BinaryInterface",
+ "Interfaces::Interface",
+ "Interfaces::binaryInterfaces",
+ "Interfaces::interfaces",
+ "Items::Item",
+ "Items::Item::checkedConstraints",
+ "Items::Item::subitems",
+ "Items::Item::subparts",
+ "Items::items",
+ "Links::BinaryLink",
+ "Links::Link",
+ "Links::Link::participant",
+ "Links::binaryLinks",
+ "Links::links",
+ "Links::selfLinks",
+ "Metadata::MetadataItem",
+ "Metadata::metadataItems",
+ "Metaobjects::Metaobject",
+ "Metaobjects::metaobjects",
+ "Objects::BinaryLinkObject",
+ "Objects::LinkObject",
+ "Objects::Object",
+ "Objects::Object::ownedPerformances",
+ "Objects::binaryLinkObjects",
+ "Objects::linkObjects",
+ "Objects::objects",
+ "Occurrences::Life",
+ "Occurrences::Occurrence",
+ "Occurrences::Occurrence::portions",
+ "Occurrences::Occurrence::snapshots",
+ "Occurrences::Occurrence::suboccurrences",
+ "Occurrences::Occurrence::timeEnclosedOccurrences",
+ "Occurrences::Occurrence::timeSlices",
+ "Occurrences::happensBeforeLinks",
+ "Occurrences::occurrences",
+ "Parts::Part",
+ "Parts::Part::exhibitedStates",
+ "Parts::Part::ownedActions",
+ "Parts::Part::ownedPorts",
+ "Parts::Part::ownedStates",
+ "Parts::Part::performedActions",
+ "Parts::parts",
+ "Performances::BooleanEvaluation",
+ "Performances::Evaluation",
+ "Performances::Performance",
+ "Performances::Performance::enclosedPerformances",
+ "Performances::Performance::subperformances",
+ "Performances::booleanEvaluations",
+ "Performances::evaluations",
+ "Performances::literalBooleanEvaluations",
+ "Performances::literalEvaluations",
+ "Performances::literalIntegerEvaluations",
+ "Performances::literalRationalEvaluations",
+ "Performances::literalStringEvaluations",
+ "Performances::metadataAccessEvaluations",
+ "Performances::nullEvaluations",
+ "Performances::performances",
+ "Ports::Port",
+ "Ports::Port::subports",
+ "Ports::ports",
+ "Requirements::ConcernCheck",
+ "Requirements::RequirementCheck",
+ "Requirements::RequirementCheck::concerns",
+ "Requirements::RequirementCheck::stakeholders",
+ "Requirements::RequirementCheck::subrequirements",
+ "Requirements::concernChecks",
+ "Requirements::requirementChecks",
+ "States::StateAction",
+ "States::StateAction::exclusiveStates",
+ "States::StateAction::stateTransitions",
+ "States::StateAction::substates",
+ "States::stateActions",
+ "Transfers::flowTransfers",
+ "Transfers::flowTransfersBefore",
+ "Transfers::transfers",
+ "UseCases::UseCase",
+ "UseCases::UseCase::includedUseCases",
+ "UseCases::UseCase::subUseCases",
+ "UseCases::useCases",
+ "VerificationCases::VerificationCase",
+ "VerificationCases::VerificationCase::obj::requirementVerifications",
+ "VerificationCases::VerificationCase::subVerificationCases",
+ "VerificationCases::verificationCases",
+ "Views::Rendering",
+ "Views::Rendering::subrenderings",
+ "Views::View",
+ "Views::View::subviews",
+ "Views::View::viewpointSatisfactions",
+ "Views::ViewpointCheck",
+ "Views::renderings",
+ "Views::viewpointChecks",
+ "Views::views",
+ ];
+
+ ///
+ /// Returns the implied library Specializations that apply to the supplied element, including
+ /// those inherited from its supertypes in the metamodel.
+ ///
+ ///
+ /// The to query
+ ///
+ ///
+ /// The applicable rules, or an empty list when the metaclass carries none
+ ///
+ public static IReadOnlyList QueryImpliedLibrarySpecializations(IElement element)
+ {
+ return element switch
+ {
+ SysML2.NET.Core.POCO.Systems.Flows.ISuccessionFlowUsage => SuccessionFlowUsageRules,
+ SysML2.NET.Core.POCO.Systems.Allocations.IAllocationDefinition => AllocationDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.UseCases.IIncludeUseCaseUsage => IncludeUseCaseUsageRules,
+ SysML2.NET.Core.POCO.Systems.Interfaces.IInterfaceDefinition => InterfaceDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Connections.IConnectionDefinition => ConnectionDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Requirements.ISatisfyRequirementUsage => SatisfyRequirementUsageRules,
+ SysML2.NET.Core.POCO.Systems.Allocations.IAllocationUsage => AllocationUsageRules,
+ SysML2.NET.Core.POCO.Systems.AnalysisCases.IAnalysisCaseDefinition => AnalysisCaseDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Requirements.IConcernDefinition => ConcernDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Flows.IFlowDefinition => FlowDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Flows.IFlowUsage => FlowUsageRules,
+ SysML2.NET.Core.POCO.Systems.Interfaces.IInterfaceUsage => InterfaceUsageRules,
+ SysML2.NET.Core.POCO.Systems.UseCases.IUseCaseDefinition => UseCaseDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.VerificationCases.IVerificationCaseDefinition => VerificationCaseDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Views.IViewpointDefinition => ViewpointDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.AnalysisCases.IAnalysisCaseUsage => AnalysisCaseUsageRules,
+ SysML2.NET.Core.POCO.Systems.Constraints.IAssertConstraintUsage => AssertConstraintUsageRules,
+ SysML2.NET.Core.POCO.Systems.Cases.ICaseDefinition => CaseDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Requirements.IConcernUsage => ConcernUsageRules,
+ SysML2.NET.Core.POCO.Systems.Connections.IConnectionUsage => ConnectionUsageRules,
+ SysML2.NET.Core.POCO.Systems.States.IExhibitStateUsage => ExhibitStateUsageRules,
+ SysML2.NET.Core.POCO.Systems.Requirements.IRequirementDefinition => RequirementDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.UseCases.IUseCaseUsage => UseCaseUsageRules,
+ SysML2.NET.Core.POCO.Systems.VerificationCases.IVerificationCaseUsage => VerificationCaseUsageRules,
+ SysML2.NET.Core.POCO.Systems.Views.IViewpointUsage => ViewpointUsageRules,
+ SysML2.NET.Core.POCO.Systems.Calculations.ICalculationDefinition => CalculationDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Cases.ICaseUsage => CaseUsageRules,
+ SysML2.NET.Core.POCO.Systems.Constraints.IConstraintDefinition => ConstraintDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Metadata.IMetadataDefinition => MetadataDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Views.IRenderingDefinition => RenderingDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Requirements.IRequirementUsage => RequirementUsageRules,
+ SysML2.NET.Core.POCO.Systems.Views.IViewDefinition => ViewDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Connections.IBindingConnectorAsUsage => BindingConnectorAsUsageRules,
+ SysML2.NET.Core.POCO.Systems.Calculations.ICalculationUsage => CalculationUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.ICollectExpression => CollectExpressionRules,
+ SysML2.NET.Core.POCO.Systems.Ports.IConjugatedPortDefinition => ConjugatedPortDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Constraints.IConstraintUsage => ConstraintUsageRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IDecisionNode => DecisionNodeRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.IFeatureChainExpression => FeatureChainExpressionRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IForLoopActionUsage => ForLoopActionUsageRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IForkNode => ForkNodeRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.IIndexExpression => IndexExpressionRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IJoinNode => JoinNodeRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IMergeNode => MergeNodeRules,
+ SysML2.NET.Core.POCO.Systems.Metadata.IMetadataUsage => MetadataUsageRules,
+ SysML2.NET.Core.POCO.Systems.Parts.IPartDefinition => PartDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IPerformActionUsage => PerformActionUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.ISelectExpression => SelectExpressionRules,
+ SysML2.NET.Core.POCO.Systems.States.IStateDefinition => StateDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Connections.ISuccessionAsUsage => SuccessionAsUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Interactions.ISuccessionFlow => SuccessionFlowRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IWhileLoopActionUsage => WhileLoopActionUsageRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IAcceptActionUsage => AcceptActionUsageRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IActionDefinition => ActionDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IAssignmentActionUsage => AssignmentActionUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Associations.IAssociationStructure => AssociationStructureRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IControlNode => ControlNodeRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IIfActionUsage => IfActionUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Interactions.IInteraction => InteractionRules,
+ SysML2.NET.Core.POCO.Systems.Items.IItemDefinition => ItemDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Actions.ILoopActionUsage => LoopActionUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression => OperatorExpressionRules,
+ SysML2.NET.Core.POCO.Systems.Ports.IPortDefinition => PortDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Views.IRenderingUsage => RenderingUsageRules,
+ SysML2.NET.Core.POCO.Systems.Actions.ISendActionUsage => SendActionUsageRules,
+ SysML2.NET.Core.POCO.Systems.States.IStateUsage => StateUsageRules,
+ SysML2.NET.Core.POCO.Systems.Actions.ITerminateActionUsage => TerminateActionUsageRules,
+ SysML2.NET.Core.POCO.Systems.States.ITransitionUsage => TransitionUsageRules,
+ SysML2.NET.Core.POCO.Systems.Actions.ITriggerInvocationExpression => TriggerInvocationExpressionRules,
+ SysML2.NET.Core.POCO.Systems.Views.IViewUsage => ViewUsageRules,
+ SysML2.NET.Core.POCO.Systems.Actions.IActionUsage => ActionUsageRules,
+ SysML2.NET.Core.POCO.Systems.Connections.IConnectorAsUsage => ConnectorAsUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.IConstructorExpression => ConstructorExpressionRules,
+ SysML2.NET.Core.POCO.Systems.Enumerations.IEnumerationDefinition => EnumerationDefinitionRules,
+ SysML2.NET.Core.POCO.Kernel.Interactions.IFlow => FlowRules,
+ SysML2.NET.Core.POCO.Kernel.Functions.IInvariant => InvariantRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.IInvocationExpression => InvocationExpressionRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.ILiteralBoolean => LiteralBooleanRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.ILiteralInfinity => LiteralInfinityRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.ILiteralInteger => LiteralIntegerRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.ILiteralRational => LiteralRationalRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.ILiteralString => LiteralStringRules,
+ SysML2.NET.Core.POCO.Systems.Parts.IPartUsage => PartUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Functions.IPredicate => PredicateRules,
+ SysML2.NET.Core.POCO.Systems.Attributes.IAttributeDefinition => AttributeDefinitionRules,
+ SysML2.NET.Core.POCO.Kernel.Connectors.IBindingConnector => BindingConnectorRules,
+ SysML2.NET.Core.POCO.Kernel.Functions.IBooleanExpression => BooleanExpressionRules,
+ SysML2.NET.Core.POCO.Systems.Enumerations.IEnumerationUsage => EnumerationUsageRules,
+ SysML2.NET.Core.POCO.Systems.Occurrences.IEventOccurrenceUsage => EventOccurrenceUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.IFeatureReferenceExpression => FeatureReferenceExpressionRules,
+ SysML2.NET.Core.POCO.Kernel.Functions.IFunction => FunctionRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.IInstantiationExpression => InstantiationExpressionRules,
+ SysML2.NET.Core.POCO.Systems.Items.IItemUsage => ItemUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.ILiteralExpression => LiteralExpressionRules,
+ SysML2.NET.Core.POCO.Kernel.Metadata.IMetaclass => MetaclassRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.IMetadataAccessExpression => MetadataAccessExpressionRules,
+ SysML2.NET.Core.POCO.Kernel.Expressions.INullExpression => NullExpressionRules,
+ SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceDefinition => OccurrenceDefinitionRules,
+ SysML2.NET.Core.POCO.Systems.Ports.IPortUsage => PortUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Connectors.ISuccession => SuccessionRules,
+ SysML2.NET.Core.POCO.Kernel.Associations.IAssociation => AssociationRules,
+ SysML2.NET.Core.POCO.Systems.Attributes.IAttributeUsage => AttributeUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Behaviors.IBehavior => BehaviorRules,
+ SysML2.NET.Core.POCO.Kernel.Connectors.IConnector => ConnectorRules,
+ SysML2.NET.Core.POCO.Kernel.Functions.IExpression => ExpressionRules,
+ SysML2.NET.Core.POCO.Kernel.Metadata.IMetadataFeature => MetadataFeatureRules,
+ SysML2.NET.Core.POCO.Kernel.Multiplicities.IMultiplicityRange => MultiplicityRangeRules,
+ SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceUsage => OccurrenceUsageRules,
+ SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage => ReferenceUsageRules,
+ SysML2.NET.Core.POCO.Kernel.Structures.IStructure => StructureRules,
+ SysML2.NET.Core.POCO.Kernel.Classes.IClass => ClassRules,
+ SysML2.NET.Core.POCO.Kernel.DataTypes.IDataType => DataTypeRules,
+ SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IDefinition => DefinitionRules,
+ SysML2.NET.Core.POCO.Kernel.Interactions.IFlowEnd => FlowEndRules,
+ SysML2.NET.Core.POCO.Core.Types.IMultiplicity => MultiplicityRules,
+ SysML2.NET.Core.POCO.Kernel.Interactions.IPayloadFeature => PayloadFeatureRules,
+ SysML2.NET.Core.POCO.Kernel.Behaviors.IStep => StepRules,
+ SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage => UsageRules,
+ SysML2.NET.Core.POCO.Core.Classifiers.IClassifier => ClassifierRules,
+ SysML2.NET.Core.POCO.Core.Features.IFeature => FeatureRules,
+ SysML2.NET.Core.POCO.Core.Types.IType => TypeRules,
+ _ => []
+ };
+ }
+
+ ///
+ /// The implied library Specializations applying to SuccessionFlowUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] SuccessionFlowUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFlowSpecialization", "Transfers::transfers", "Flow", false),
+ new("checkFlowUsageFlowSpecialization", "Flows::flows", "FlowUsage", true),
+ new("checkFlowUsageSpecialization", "Flows::messages", "FlowUsage", false),
+ new("checkFlowWithEndsSpecialization", "Transfers::flowTransfers", "Flow", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkSuccessionFlowSpecialization", "Transfers::flowTransfersBefore", "SuccessionFlow", false),
+ new("checkSuccessionFlowUsageSpecialization", "Flows::successionFlows", "SuccessionFlowUsage", false),
+ new("checkSuccessionSpecialization", "Occurrences::happensBeforeLinks", "Succession", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to AllocationDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] AllocationDefinitionRules =
+ [
+ new("checkAllocationDefinitionSpecialization", "Allocations::Allocation", "AllocationDefinition", false),
+ new("checkAssociationBinarySpecialization", "Links::BinaryLink", "Association", true),
+ new("checkAssociationSpecialization", "Links::Link", "Association", false),
+ new("checkAssociationStructureBinarySpecialization", "Objects::BinaryLinkObject", "AssociationStructure", true),
+ new("checkAssociationStructureSpecialization", "Objects::LinkObject", "AssociationStructure", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkConnectionDefinitionBinarySpecialization", "Connections::BinaryConnection", "ConnectionDefinition", true),
+ new("checkConnectionDefinitionSpecializations", "Connections::Connection", "ConnectionDefinition", false),
+ new("checkItemDefinitionSpecialization", "Items::Item", "ItemDefinition", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkPartDefinitionSpecialization", "Parts::Part", "PartDefinition", false),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to IncludeUseCaseUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] IncludeUseCaseUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkCalculationUsageSpecialization", "Calculations::calculations", "CalculationUsage", false),
+ new("checkCalculationUsageSubcalculationSpecialization", "Calculations::Calculation::subcalculations", "CalculationUsage", true),
+ new("checkCaseUsageSpecialization", "Cases::cases", "CaseUsage", false),
+ new("checkCaseUsageSubcaseSpecialization", "Cases::Case::subcases", "CaseUsage", true),
+ new("checkEventOccurrenceUsageSpecialization", "Occurrences::Occurrence::timeEnclosedOccurrences", "EventOccurrenceUsage", true),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkIncludeUseCaseUsageSpecialization", "UseCases::UseCase::includedUseCases", "IncludeUseCaseUsage", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkPerformActionUsageSpecialization", "Parts::Part::performedActions", "PerformActionUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ new("checkUseCaseUsageSpecialization", "UseCases::useCases", "UseCaseUsage", false),
+ new("checkUseCaseUsageSubUseCaseSpecialization", "UseCases::UseCase::subUseCases", "UseCaseUsage", true),
+ ];
+
+ ///
+ /// The implied library Specializations applying to InterfaceDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] InterfaceDefinitionRules =
+ [
+ new("checkAssociationBinarySpecialization", "Links::BinaryLink", "Association", true),
+ new("checkAssociationSpecialization", "Links::Link", "Association", false),
+ new("checkAssociationStructureBinarySpecialization", "Objects::BinaryLinkObject", "AssociationStructure", true),
+ new("checkAssociationStructureSpecialization", "Objects::LinkObject", "AssociationStructure", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkConnectionDefinitionBinarySpecialization", "Connections::BinaryConnection", "ConnectionDefinition", true),
+ new("checkConnectionDefinitionSpecializations", "Connections::Connection", "ConnectionDefinition", false),
+ new("checkInterfaceDefinitionBinarySpecialization", "Interfaces::BinaryInterface", "InterfaceDefinition", true),
+ new("checkInterfaceDefinitionSpecialization", "Interfaces::Interface", "InterfaceDefinition", false),
+ new("checkItemDefinitionSpecialization", "Items::Item", "ItemDefinition", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkPartDefinitionSpecialization", "Parts::Part", "PartDefinition", false),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ConnectionDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ConnectionDefinitionRules =
+ [
+ new("checkAssociationBinarySpecialization", "Links::BinaryLink", "Association", true),
+ new("checkAssociationSpecialization", "Links::Link", "Association", false),
+ new("checkAssociationStructureBinarySpecialization", "Objects::BinaryLinkObject", "AssociationStructure", true),
+ new("checkAssociationStructureSpecialization", "Objects::LinkObject", "AssociationStructure", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkConnectionDefinitionBinarySpecialization", "Connections::BinaryConnection", "ConnectionDefinition", true),
+ new("checkConnectionDefinitionSpecializations", "Connections::Connection", "ConnectionDefinition", false),
+ new("checkItemDefinitionSpecialization", "Items::Item", "ItemDefinition", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkPartDefinitionSpecialization", "Parts::Part", "PartDefinition", false),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to SatisfyRequirementUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] SatisfyRequirementUsageRules =
+ [
+ new("checkBooleanExpressionSpecialization", "Performances::booleanEvaluations", "BooleanExpression", false),
+ new("checkConstraintUsageCheckedConstraintSpecialization", "Items::Item::checkedConstraints", "ConstraintUsage", true),
+ new("checkConstraintUsageSpecialization", "Constraints::constraintChecks", "ConstraintUsage", false),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkRequirementUsageRequirementVerificationSpecialization", "VerificationCases::VerificationCase::obj::requirementVerifications", "RequirementUsage", true),
+ new("checkRequirementUsageSpecialization", "Requirements::requirementChecks", "RequirementUsage", false),
+ new("checkRequirementUsageSubrequirementSpecialization", "Requirements::RequirementCheck::subrequirements", "RequirementUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to AllocationUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] AllocationUsageRules =
+ [
+ new("checkAllocationUsageSpecialization", "Allocations::allocations", "AllocationUsage", false),
+ new("checkConnectionUsageBinarySpecialization", "Connections::binaryConnections", "ConnectionUsage", true),
+ new("checkConnectionUsageSpecialization", "Connections::connections", "ConnectionUsage", false),
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkItemUsageSpecialization", "Items::items", "ItemUsage", false),
+ new("checkItemUsageSubitemSpecialization", "Items::Item::subitems", "ItemUsage", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkPartUsageSpecialization", "Parts::parts", "PartUsage", false),
+ new("checkPartUsageStakeholderSpecialization", "Requirements::RequirementCheck::stakeholders", "PartUsage", true),
+ new("checkPartUsageSubpartSpecialization", "Items::Item::subparts", "PartUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to AnalysisCaseDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] AnalysisCaseDefinitionRules =
+ [
+ new("checkActionDefinitionSpecialization", "Actions::Action", "ActionDefinition", false),
+ new("checkAnalysisCaseDefinitionSpecialization", "AnalysisCases::AnalysisCase", "AnalysisCaseDefinition", false),
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkCalculationDefinitionSpecialization", "Calculations::Calculation", "CalculationDefinition", false),
+ new("checkCaseDefinitionSpecialization", "Cases::Case", "CaseDefinition", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkFunctionSpecialization", "Performances::Evaluation", "Function", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ConcernDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ConcernDefinitionRules =
+ [
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkConcernDefinitionSpecialization", "Requirements::ConcernCheck", "ConcernDefinition", false),
+ new("checkConstraintDefinitionSpecialization", "Constraints::ConstraintCheck", "ConstraintDefinition", false),
+ new("checkFunctionSpecialization", "Performances::Evaluation", "Function", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkPredicateSpecialization", "Performances::BooleanEvaluation", "Predicate", false),
+ new("checkRequirementDefinitionSpecialization", "Requirements::RequirementCheck", "RequirementDefinition", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to FlowDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] FlowDefinitionRules =
+ [
+ new("checkActionDefinitionSpecialization", "Actions::Action", "ActionDefinition", false),
+ new("checkAssociationBinarySpecialization", "Links::BinaryLink", "Association", true),
+ new("checkAssociationSpecialization", "Links::Link", "Association", false),
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkFlowDefinitionBinarySpecialization", "Flows::Message", "FlowDefinition", true),
+ new("checkFlowDefinitionSpecialization", "Flows::MessageAction", "FlowDefinition", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to FlowUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] FlowUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFlowSpecialization", "Transfers::transfers", "Flow", false),
+ new("checkFlowUsageFlowSpecialization", "Flows::flows", "FlowUsage", true),
+ new("checkFlowUsageSpecialization", "Flows::messages", "FlowUsage", false),
+ new("checkFlowWithEndsSpecialization", "Transfers::flowTransfers", "Flow", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to InterfaceUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] InterfaceUsageRules =
+ [
+ new("checkConnectionUsageBinarySpecialization", "Connections::binaryConnections", "ConnectionUsage", true),
+ new("checkConnectionUsageSpecialization", "Connections::connections", "ConnectionUsage", false),
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkInterfaceUsageBinarySpecialization", "Interfaces::binaryInterfaces", "InterfaceUsage", true),
+ new("checkInterfaceUsageSpecialization", "Interfaces::interfaces", "InterfaceUsage", false),
+ new("checkItemUsageSpecialization", "Items::items", "ItemUsage", false),
+ new("checkItemUsageSubitemSpecialization", "Items::Item::subitems", "ItemUsage", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkPartUsageSpecialization", "Parts::parts", "PartUsage", false),
+ new("checkPartUsageStakeholderSpecialization", "Requirements::RequirementCheck::stakeholders", "PartUsage", true),
+ new("checkPartUsageSubpartSpecialization", "Items::Item::subparts", "PartUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to UseCaseDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] UseCaseDefinitionRules =
+ [
+ new("checkActionDefinitionSpecialization", "Actions::Action", "ActionDefinition", false),
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkCalculationDefinitionSpecialization", "Calculations::Calculation", "CalculationDefinition", false),
+ new("checkCaseDefinitionSpecialization", "Cases::Case", "CaseDefinition", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkFunctionSpecialization", "Performances::Evaluation", "Function", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ new("checkUseCaseDefinitionSpecialization", "UseCases::UseCase", "UseCaseDefinition", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to VerificationCaseDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] VerificationCaseDefinitionRules =
+ [
+ new("checkActionDefinitionSpecialization", "Actions::Action", "ActionDefinition", false),
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkCalculationDefinitionSpecialization", "Calculations::Calculation", "CalculationDefinition", false),
+ new("checkCaseDefinitionSpecialization", "Cases::Case", "CaseDefinition", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkFunctionSpecialization", "Performances::Evaluation", "Function", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ new("checkVerificationCaseSpecialization", "VerificationCases::VerificationCase", "VerificationCaseDefinition", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ViewpointDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ViewpointDefinitionRules =
+ [
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkConstraintDefinitionSpecialization", "Constraints::ConstraintCheck", "ConstraintDefinition", false),
+ new("checkFunctionSpecialization", "Performances::Evaluation", "Function", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkPredicateSpecialization", "Performances::BooleanEvaluation", "Predicate", false),
+ new("checkRequirementDefinitionSpecialization", "Requirements::RequirementCheck", "RequirementDefinition", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ new("checkViewpointDefinitionSpecialization", "Views::ViewpointCheck", "ViewpointDefinition", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to AnalysisCaseUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] AnalysisCaseUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkAnalysisCaseUsageSpecialization", "AnalysisCases::analysisCases", "AnalysisCaseUsage", false),
+ new("checkAnalysisCaseUsageSubAnalysisCaseSpecialization", "AnalysisCases::AnalysisCase::subAnalysisCases", "AnalysisCaseUsage", true),
+ new("checkCalculationUsageSpecialization", "Calculations::calculations", "CalculationUsage", false),
+ new("checkCalculationUsageSubcalculationSpecialization", "Calculations::Calculation::subcalculations", "CalculationUsage", true),
+ new("checkCaseUsageSpecialization", "Cases::cases", "CaseUsage", false),
+ new("checkCaseUsageSubcaseSpecialization", "Cases::Case::subcases", "CaseUsage", true),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to AssertConstraintUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] AssertConstraintUsageRules =
+ [
+ new("checkBooleanExpressionSpecialization", "Performances::booleanEvaluations", "BooleanExpression", false),
+ new("checkConstraintUsageCheckedConstraintSpecialization", "Items::Item::checkedConstraints", "ConstraintUsage", true),
+ new("checkConstraintUsageSpecialization", "Constraints::constraintChecks", "ConstraintUsage", false),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to CaseDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] CaseDefinitionRules =
+ [
+ new("checkActionDefinitionSpecialization", "Actions::Action", "ActionDefinition", false),
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkCalculationDefinitionSpecialization", "Calculations::Calculation", "CalculationDefinition", false),
+ new("checkCaseDefinitionSpecialization", "Cases::Case", "CaseDefinition", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkFunctionSpecialization", "Performances::Evaluation", "Function", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ConcernUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ConcernUsageRules =
+ [
+ new("checkBooleanExpressionSpecialization", "Performances::booleanEvaluations", "BooleanExpression", false),
+ new("checkConcernUsageFramedConcernSpecialization", "Requirements::RequirementCheck::concerns", "ConcernUsage", true),
+ new("checkConcernUsageSpecialization", "Requirements::concernChecks", "ConcernUsage", false),
+ new("checkConstraintUsageCheckedConstraintSpecialization", "Items::Item::checkedConstraints", "ConstraintUsage", true),
+ new("checkConstraintUsageSpecialization", "Constraints::constraintChecks", "ConstraintUsage", false),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkRequirementUsageRequirementVerificationSpecialization", "VerificationCases::VerificationCase::obj::requirementVerifications", "RequirementUsage", true),
+ new("checkRequirementUsageSpecialization", "Requirements::requirementChecks", "RequirementUsage", false),
+ new("checkRequirementUsageSubrequirementSpecialization", "Requirements::RequirementCheck::subrequirements", "RequirementUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ConnectionUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ConnectionUsageRules =
+ [
+ new("checkConnectionUsageBinarySpecialization", "Connections::binaryConnections", "ConnectionUsage", true),
+ new("checkConnectionUsageSpecialization", "Connections::connections", "ConnectionUsage", false),
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkItemUsageSpecialization", "Items::items", "ItemUsage", false),
+ new("checkItemUsageSubitemSpecialization", "Items::Item::subitems", "ItemUsage", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkPartUsageSpecialization", "Parts::parts", "PartUsage", false),
+ new("checkPartUsageStakeholderSpecialization", "Requirements::RequirementCheck::stakeholders", "PartUsage", true),
+ new("checkPartUsageSubpartSpecialization", "Items::Item::subparts", "PartUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ExhibitStateUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ExhibitStateUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkEventOccurrenceUsageSpecialization", "Occurrences::Occurrence::timeEnclosedOccurrences", "EventOccurrenceUsage", true),
+ new("checkExhibitStateUsageSpecialization", "Parts::Part::exhibitedStates", "ExhibitStateUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkPerformActionUsageSpecialization", "Parts::Part::performedActions", "PerformActionUsage", true),
+ new("checkStateUsageExclusiveStateSpecialization", "States::StateAction::exclusiveStates", "StateUsage", true),
+ new("checkStateUsageOwnedStateSpecialization", "Parts::Part::ownedStates", "StateUsage", true),
+ new("checkStateUsageSpecialization", "States::stateActions", "StateUsage", false),
+ new("checkStateUsageSubstateSpecialization", "States::StateAction::substates", "StateUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to RequirementDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] RequirementDefinitionRules =
+ [
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkConstraintDefinitionSpecialization", "Constraints::ConstraintCheck", "ConstraintDefinition", false),
+ new("checkFunctionSpecialization", "Performances::Evaluation", "Function", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkPredicateSpecialization", "Performances::BooleanEvaluation", "Predicate", false),
+ new("checkRequirementDefinitionSpecialization", "Requirements::RequirementCheck", "RequirementDefinition", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to UseCaseUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] UseCaseUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkCalculationUsageSpecialization", "Calculations::calculations", "CalculationUsage", false),
+ new("checkCalculationUsageSubcalculationSpecialization", "Calculations::Calculation::subcalculations", "CalculationUsage", true),
+ new("checkCaseUsageSpecialization", "Cases::cases", "CaseUsage", false),
+ new("checkCaseUsageSubcaseSpecialization", "Cases::Case::subcases", "CaseUsage", true),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ new("checkUseCaseUsageSpecialization", "UseCases::useCases", "UseCaseUsage", false),
+ new("checkUseCaseUsageSubUseCaseSpecialization", "UseCases::UseCase::subUseCases", "UseCaseUsage", true),
+ ];
+
+ ///
+ /// The implied library Specializations applying to VerificationCaseUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] VerificationCaseUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkCalculationUsageSpecialization", "Calculations::calculations", "CalculationUsage", false),
+ new("checkCalculationUsageSubcalculationSpecialization", "Calculations::Calculation::subcalculations", "CalculationUsage", true),
+ new("checkCaseUsageSpecialization", "Cases::cases", "CaseUsage", false),
+ new("checkCaseUsageSubcaseSpecialization", "Cases::Case::subcases", "CaseUsage", true),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ new("checkVerificationCaseUsageSpecialization", "VerificationCases::verificationCases", "VerificationCaseUsage", false),
+ new("checkVerificationCaseUsageSubVerificationCaseSpecialization", "VerificationCases::VerificationCase::subVerificationCases", "VerificationCaseUsage", true),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ViewpointUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ViewpointUsageRules =
+ [
+ new("checkBooleanExpressionSpecialization", "Performances::booleanEvaluations", "BooleanExpression", false),
+ new("checkConstraintUsageCheckedConstraintSpecialization", "Items::Item::checkedConstraints", "ConstraintUsage", true),
+ new("checkConstraintUsageSpecialization", "Constraints::constraintChecks", "ConstraintUsage", false),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkRequirementUsageRequirementVerificationSpecialization", "VerificationCases::VerificationCase::obj::requirementVerifications", "RequirementUsage", true),
+ new("checkRequirementUsageSpecialization", "Requirements::requirementChecks", "RequirementUsage", false),
+ new("checkRequirementUsageSubrequirementSpecialization", "Requirements::RequirementCheck::subrequirements", "RequirementUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ new("checkViewpointUsageSpecialization", "Views::viewpointChecks", "ViewpointUsage", false),
+ new("checkViewpointUsageViewpointSatisfactionSpecialization", "Views::View::viewpointSatisfactions", "ViewpointUsage", true),
+ ];
+
+ ///
+ /// The implied library Specializations applying to CalculationDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] CalculationDefinitionRules =
+ [
+ new("checkActionDefinitionSpecialization", "Actions::Action", "ActionDefinition", false),
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkCalculationDefinitionSpecialization", "Calculations::Calculation", "CalculationDefinition", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkFunctionSpecialization", "Performances::Evaluation", "Function", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to CaseUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] CaseUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkCalculationUsageSpecialization", "Calculations::calculations", "CalculationUsage", false),
+ new("checkCalculationUsageSubcalculationSpecialization", "Calculations::Calculation::subcalculations", "CalculationUsage", true),
+ new("checkCaseUsageSpecialization", "Cases::cases", "CaseUsage", false),
+ new("checkCaseUsageSubcaseSpecialization", "Cases::Case::subcases", "CaseUsage", true),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ConstraintDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ConstraintDefinitionRules =
+ [
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkConstraintDefinitionSpecialization", "Constraints::ConstraintCheck", "ConstraintDefinition", false),
+ new("checkFunctionSpecialization", "Performances::Evaluation", "Function", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkPredicateSpecialization", "Performances::BooleanEvaluation", "Predicate", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to MetadataDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] MetadataDefinitionRules =
+ [
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkItemDefinitionSpecialization", "Items::Item", "ItemDefinition", false),
+ new("checkMetaclassSpecialization", "Metaobjects::Metaobject", "Metaclass", false),
+ new("checkMetadataDefinitionSpecialization", "Metadata::MetadataItem", "MetadataDefinition", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to RenderingDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] RenderingDefinitionRules =
+ [
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkItemDefinitionSpecialization", "Items::Item", "ItemDefinition", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkPartDefinitionSpecialization", "Parts::Part", "PartDefinition", false),
+ new("checkRenderingDefinitionSpecialization", "Views::Rendering", "RenderingDefinition", false),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to RequirementUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] RequirementUsageRules =
+ [
+ new("checkBooleanExpressionSpecialization", "Performances::booleanEvaluations", "BooleanExpression", false),
+ new("checkConstraintUsageCheckedConstraintSpecialization", "Items::Item::checkedConstraints", "ConstraintUsage", true),
+ new("checkConstraintUsageSpecialization", "Constraints::constraintChecks", "ConstraintUsage", false),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkRequirementUsageRequirementVerificationSpecialization", "VerificationCases::VerificationCase::obj::requirementVerifications", "RequirementUsage", true),
+ new("checkRequirementUsageSpecialization", "Requirements::requirementChecks", "RequirementUsage", false),
+ new("checkRequirementUsageSubrequirementSpecialization", "Requirements::RequirementCheck::subrequirements", "RequirementUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ViewDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ViewDefinitionRules =
+ [
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkItemDefinitionSpecialization", "Items::Item", "ItemDefinition", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkPartDefinitionSpecialization", "Parts::Part", "PartDefinition", false),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ new("checkViewDefinitionSpecialization", "Views::View", "ViewDefinition", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to BindingConnectorAsUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] BindingConnectorAsUsageRules =
+ [
+ new("checkBindingConnectorSpecialization", "Links::selfLinks", "BindingConnector", false),
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to CalculationUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] CalculationUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkCalculationUsageSpecialization", "Calculations::calculations", "CalculationUsage", false),
+ new("checkCalculationUsageSubcalculationSpecialization", "Calculations::Calculation::subcalculations", "CalculationUsage", true),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to CollectExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] CollectExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ConjugatedPortDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ConjugatedPortDefinitionRules =
+ [
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkPortDefinitionSpecialization", "Ports::Port", "PortDefinition", false),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ConstraintUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ConstraintUsageRules =
+ [
+ new("checkBooleanExpressionSpecialization", "Performances::booleanEvaluations", "BooleanExpression", false),
+ new("checkConstraintUsageCheckedConstraintSpecialization", "Items::Item::checkedConstraints", "ConstraintUsage", true),
+ new("checkConstraintUsageSpecialization", "Constraints::constraintChecks", "ConstraintUsage", false),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to DecisionNode, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] DecisionNodeRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkControlNodeSpecialization", "Actions::Action::controls", "ControlNode", false),
+ new("checkDecisionNodeSpecialization", "Actions::Action::decisions", "DecisionNode", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to FeatureChainExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] FeatureChainExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ForLoopActionUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ForLoopActionUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkForLoopActionUsageSpecialization", "Actions::forLoopActions", "ForLoopActionUsage", false),
+ new("checkForLoopActionUsageSubactionSpecialization", "Actions::Action::forLoops", "ForLoopActionUsage", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ForkNode, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ForkNodeRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkControlNodeSpecialization", "Actions::Action::controls", "ControlNode", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkForkNodeSpecialization", "Actions::Action::forks", "ForkNode", false),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to IndexExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] IndexExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to JoinNode, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] JoinNodeRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkControlNodeSpecialization", "Actions::Action::controls", "ControlNode", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkJoinNodeSpecialization", "Actions::Action::joins", "JoinNode", false),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to MergeNode, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] MergeNodeRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkControlNodeSpecialization", "Actions::Action::controls", "ControlNode", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkMergeNodeSpecialization", "Actions::Action::merges", "MergeNode", false),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to MetadataUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] MetadataUsageRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkItemUsageSpecialization", "Items::items", "ItemUsage", false),
+ new("checkItemUsageSubitemSpecialization", "Items::Item::subitems", "ItemUsage", true),
+ new("checkMetadataFeatureSpecialization", "Metaobjects::metaobjects", "MetadataFeature", false),
+ new("checkMetadataUsageSpecialization", "Metadata::metadataItems", "MetadataUsage", false),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to PartDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] PartDefinitionRules =
+ [
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkItemDefinitionSpecialization", "Items::Item", "ItemDefinition", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkPartDefinitionSpecialization", "Parts::Part", "PartDefinition", false),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to PerformActionUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] PerformActionUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkEventOccurrenceUsageSpecialization", "Occurrences::Occurrence::timeEnclosedOccurrences", "EventOccurrenceUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkPerformActionUsageSpecialization", "Parts::Part::performedActions", "PerformActionUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to SelectExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] SelectExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to StateDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] StateDefinitionRules =
+ [
+ new("checkActionDefinitionSpecialization", "Actions::Action", "ActionDefinition", false),
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkStateDefinitionSpecialization", "States::StateAction", "StateDefinition", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to SuccessionAsUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] SuccessionAsUsageRules =
+ [
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkSuccessionSpecialization", "Occurrences::happensBeforeLinks", "Succession", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to SuccessionFlow, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] SuccessionFlowRules =
+ [
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFlowSpecialization", "Transfers::transfers", "Flow", false),
+ new("checkFlowWithEndsSpecialization", "Transfers::flowTransfers", "Flow", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkSuccessionFlowSpecialization", "Transfers::flowTransfersBefore", "SuccessionFlow", false),
+ new("checkSuccessionSpecialization", "Occurrences::happensBeforeLinks", "Succession", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to WhileLoopActionUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] WhileLoopActionUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ new("checkWhileLoopActionUsageSpecialization", "Actions::whileLoopActions", "WhileLoopActionUsage", false),
+ new("checkWhileLoopActionUsageSubactionSpecialization", "Actions::Action::whileLoops", "WhileLoopActionUsage", true),
+ ];
+
+ ///
+ /// The implied library Specializations applying to AcceptActionUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] AcceptActionUsageRules =
+ [
+ new("checkAcceptActionUsageSpecialization", "Actions::acceptActions", "AcceptActionUsage", true),
+ new("checkAcceptActionUsageSubactionSpecialization", "Actions::Action::acceptSubactions", "AcceptActionUsage", true),
+ new("checkAcceptActionUsageTriggerActionSpecialization", "Actions::TransitionAction::accepter", "AcceptActionUsage", true),
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ActionDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ActionDefinitionRules =
+ [
+ new("checkActionDefinitionSpecialization", "Actions::Action", "ActionDefinition", false),
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to AssignmentActionUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] AssignmentActionUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkAssignmentActionUsageSpecialization", "Actions::assignmentActions", "AssignmentActionUsage", false),
+ new("checkAssignmentActionUsageSubactionSpecialization", "Actions::Action::assignments", "AssignmentActionUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to AssociationStructure, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] AssociationStructureRules =
+ [
+ new("checkAssociationBinarySpecialization", "Links::BinaryLink", "Association", true),
+ new("checkAssociationSpecialization", "Links::Link", "Association", false),
+ new("checkAssociationStructureBinarySpecialization", "Objects::BinaryLinkObject", "AssociationStructure", true),
+ new("checkAssociationStructureSpecialization", "Objects::LinkObject", "AssociationStructure", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ControlNode, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ControlNodeRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkControlNodeSpecialization", "Actions::Action::controls", "ControlNode", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to IfActionUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] IfActionUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkIfActionUsageSubactionSpecialization", "Actions::Action::ifSubactions", "IfActionUsage", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Interaction, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] InteractionRules =
+ [
+ new("checkAssociationBinarySpecialization", "Links::BinaryLink", "Association", true),
+ new("checkAssociationSpecialization", "Links::Link", "Association", false),
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ItemDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ItemDefinitionRules =
+ [
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkItemDefinitionSpecialization", "Items::Item", "ItemDefinition", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to LoopActionUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] LoopActionUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to OperatorExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] OperatorExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to PortDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] PortDefinitionRules =
+ [
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkPortDefinitionSpecialization", "Ports::Port", "PortDefinition", false),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to RenderingUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] RenderingUsageRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkItemUsageSpecialization", "Items::items", "ItemUsage", false),
+ new("checkItemUsageSubitemSpecialization", "Items::Item::subitems", "ItemUsage", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkPartUsageSpecialization", "Parts::parts", "PartUsage", false),
+ new("checkPartUsageStakeholderSpecialization", "Requirements::RequirementCheck::stakeholders", "PartUsage", true),
+ new("checkPartUsageSubpartSpecialization", "Items::Item::subparts", "PartUsage", true),
+ new("checkRenderingUsageSpecialization", "Views::renderings", "RenderingUsage", false),
+ new("checkRenderingUsageSubrenderingSpecialization", "Views::Rendering::subrenderings", "RenderingUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to SendActionUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] SendActionUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkSendActionUsageSpecialization", "Actions::sendActions", "SendActionUsage", false),
+ new("checkSendActionUsageSubactionSpecialization", "Actions::Action::acceptSubactions", "SendActionUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to StateUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] StateUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStateUsageExclusiveStateSpecialization", "States::StateAction::exclusiveStates", "StateUsage", true),
+ new("checkStateUsageOwnedStateSpecialization", "Parts::Part::ownedStates", "StateUsage", true),
+ new("checkStateUsageSpecialization", "States::stateActions", "StateUsage", false),
+ new("checkStateUsageSubstateSpecialization", "States::StateAction::substates", "StateUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to TerminateActionUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] TerminateActionUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTerminateActionUsageSpecialization", "Actions::terminateActions", "TerminateActionUsage", false),
+ new("checkTerminateActionUsageSubactionSpecialization", "Actions::Action::terminateSubactions", "TerminateActionUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to TransitionUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] TransitionUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTransitionUsageActionSpecialization", "Actions::Action::decisionTransitions", "TransitionUsage", true),
+ new("checkTransitionUsageSpecialization", "Actions::transitionActions", "TransitionUsage", false),
+ new("checkTransitionUsageStateSpecialization", "States::StateAction::stateTransitions", "TransitionUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to TriggerInvocationExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] TriggerInvocationExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ViewUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ViewUsageRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkItemUsageSpecialization", "Items::items", "ItemUsage", false),
+ new("checkItemUsageSubitemSpecialization", "Items::Item::subitems", "ItemUsage", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkPartUsageSpecialization", "Parts::parts", "PartUsage", false),
+ new("checkPartUsageStakeholderSpecialization", "Requirements::RequirementCheck::stakeholders", "PartUsage", true),
+ new("checkPartUsageSubpartSpecialization", "Items::Item::subparts", "PartUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ new("checkViewUsageSpecialization", "Views::views", "ViewUsage", false),
+ new("checkViewUsageSubviewSpecialization", "Views::View::subviews", "ViewUsage", true),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ActionUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ActionUsageRules =
+ [
+ new("checkActionUsageOwnedActionSpecialization", "Parts::Part::ownedActions", "ActionUsage", true),
+ new("checkActionUsageSpecialization", "Actions::actions", "ActionUsage", false),
+ new("checkActionUsageSubactionSpecialization", "Actions::Action::subactions", "ActionUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ConnectorAsUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ConnectorAsUsageRules =
+ [
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ConstructorExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ConstructorExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to EnumerationDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] EnumerationDefinitionRules =
+ [
+ new("checkDataTypeSpecialization", "Base::DataValue", "DataType", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Flow, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] FlowRules =
+ [
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFlowSpecialization", "Transfers::transfers", "Flow", false),
+ new("checkFlowWithEndsSpecialization", "Transfers::flowTransfers", "Flow", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Invariant, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] InvariantRules =
+ [
+ new("checkBooleanExpressionSpecialization", "Performances::booleanEvaluations", "BooleanExpression", false),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to InvocationExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] InvocationExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to LiteralBoolean, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] LiteralBooleanRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkLiteralBooleanSpecialization", "Performances::literalBooleanEvaluations", "LiteralBoolean", false),
+ new("checkLiteralExpressionSpecialization", "Performances::literalEvaluations", "LiteralExpression", false),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to LiteralInfinity, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] LiteralInfinityRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkLiteralExpressionSpecialization", "Performances::literalEvaluations", "LiteralExpression", false),
+ new("checkLiteralInfinitySpecialization", "Performances::literalIntegerEvaluations", "LiteralInfinity", false),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to LiteralInteger, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] LiteralIntegerRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkLiteralExpressionSpecialization", "Performances::literalEvaluations", "LiteralExpression", false),
+ new("checkLiteralIntegerSpecialization", "Performances::literalIntegerEvaluations", "LiteralInteger", false),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to LiteralRational, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] LiteralRationalRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkLiteralExpressionSpecialization", "Performances::literalEvaluations", "LiteralExpression", false),
+ new("checkLiteralRationalSpecialization", "Performances::literalRationalEvaluations", "LiteralRational", false),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to LiteralString, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] LiteralStringRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkLiteralExpressionSpecialization", "Performances::literalEvaluations", "LiteralExpression", false),
+ new("checkLiteralStringSpecialization", "Performances::literalStringEvaluations", "LiteralString", false),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to PartUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] PartUsageRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkItemUsageSpecialization", "Items::items", "ItemUsage", false),
+ new("checkItemUsageSubitemSpecialization", "Items::Item::subitems", "ItemUsage", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkPartUsageSpecialization", "Parts::parts", "PartUsage", false),
+ new("checkPartUsageStakeholderSpecialization", "Requirements::RequirementCheck::stakeholders", "PartUsage", true),
+ new("checkPartUsageSubpartSpecialization", "Items::Item::subparts", "PartUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Predicate, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] PredicateRules =
+ [
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkFunctionSpecialization", "Performances::Evaluation", "Function", false),
+ new("checkPredicateSpecialization", "Performances::BooleanEvaluation", "Predicate", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to AttributeDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] AttributeDefinitionRules =
+ [
+ new("checkDataTypeSpecialization", "Base::DataValue", "DataType", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to BindingConnector, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] BindingConnectorRules =
+ [
+ new("checkBindingConnectorSpecialization", "Links::selfLinks", "BindingConnector", false),
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to BooleanExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] BooleanExpressionRules =
+ [
+ new("checkBooleanExpressionSpecialization", "Performances::booleanEvaluations", "BooleanExpression", false),
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to EnumerationUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] EnumerationUsageRules =
+ [
+ new("checkAttributeUsageSpecialization", "Base::dataValues", "AttributeUsage", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to EventOccurrenceUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] EventOccurrenceUsageRules =
+ [
+ new("checkEventOccurrenceUsageSpecialization", "Occurrences::Occurrence::timeEnclosedOccurrences", "EventOccurrenceUsage", true),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to FeatureReferenceExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] FeatureReferenceExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Function, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] FunctionRules =
+ [
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkFunctionSpecialization", "Performances::Evaluation", "Function", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to InstantiationExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] InstantiationExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ItemUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ItemUsageRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkItemUsageSpecialization", "Items::items", "ItemUsage", false),
+ new("checkItemUsageSubitemSpecialization", "Items::Item::subitems", "ItemUsage", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to LiteralExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] LiteralExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkLiteralExpressionSpecialization", "Performances::literalEvaluations", "LiteralExpression", false),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Metaclass, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] MetaclassRules =
+ [
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkMetaclassSpecialization", "Metaobjects::Metaobject", "Metaclass", false),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to MetadataAccessExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] MetadataAccessExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkMetadataAccessExpressionSpecialization", "Performances::metadataAccessEvaluations", "MetadataAccessExpression", false),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to NullExpression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] NullExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkNullExpressionSpecialization", "Performances::nullEvaluations", "NullExpression", false),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to OccurrenceDefinition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] OccurrenceDefinitionRules =
+ [
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkOccurrenceDefinitionIndividualSpecialization", "Occurrences::Life", "OccurrenceDefinition", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to PortUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] PortUsageRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkPortUsageOwnedPortSpecialization", "Parts::Part::ownedPorts", "PortUsage", true),
+ new("checkPortUsageSpecialization", "Ports::ports", "PortUsage", false),
+ new("checkPortUsageSubportSpecialization", "Ports::Port::subports", "PortUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Succession, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] SuccessionRules =
+ [
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkSuccessionSpecialization", "Occurrences::happensBeforeLinks", "Succession", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Association, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] AssociationRules =
+ [
+ new("checkAssociationBinarySpecialization", "Links::BinaryLink", "Association", true),
+ new("checkAssociationSpecialization", "Links::Link", "Association", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to AttributeUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] AttributeUsageRules =
+ [
+ new("checkAttributeUsageSpecialization", "Base::dataValues", "AttributeUsage", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Behavior, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] BehaviorRules =
+ [
+ new("checkBehaviorSpecialization", "Performances::Performance", "Behavior", false),
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Connector, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ConnectorRules =
+ [
+ new("checkConnectorBinaryObjectSpecialization", "Objects::binaryLinkObjects", "Connector", true),
+ new("checkConnectorBinarySpecialization", "Links::binaryLinks", "Connector", true),
+ new("checkConnectorObjectSpecialization", "Objects::linkObjects", "Connector", true),
+ new("checkConnectorSpecialization", "Links::links", "Connector", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Expression, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ExpressionRules =
+ [
+ new("checkExpressionSpecialization", "Performances::evaluations", "Expression", false),
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to MetadataFeature, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] MetadataFeatureRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkMetadataFeatureSpecialization", "Metaobjects::metaobjects", "MetadataFeature", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to MultiplicityRange, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] MultiplicityRangeRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkMultiplicitySpecialization", "Base::naturals", "Multiplicity", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to OccurrenceUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] OccurrenceUsageRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkOccurrenceUsageSnapshotSpecialization", "Occurrences::Occurrence::snapshots", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageSpecialization", "Occurrences::occurrences", "OccurrenceUsage", false),
+ new("checkOccurrenceUsageSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "OccurrenceUsage", true),
+ new("checkOccurrenceUsageTimeSliceSpecialization", "Occurrences::Occurrence::timeSlices", "OccurrenceUsage", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to ReferenceUsage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ReferenceUsageRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Structure, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] StructureRules =
+ [
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkStructureSpecialization", "Objects::Object", "Structure", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Class, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ClassRules =
+ [
+ new("checkClassSpecialization", "Occurrences::Occurrence", "Class", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to DataType, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] DataTypeRules =
+ [
+ new("checkDataTypeSpecialization", "Base::DataValue", "DataType", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Definition, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] DefinitionRules =
+ [
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to FlowEnd, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] FlowEndRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Multiplicity, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] MultiplicityRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkMultiplicitySpecialization", "Base::naturals", "Multiplicity", false),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to PayloadFeature, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] PayloadFeatureRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Step, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] StepRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkStepEnclosedPerformanceSpecialization", "Performances::Performance::enclosedPerformances", "Step", true),
+ new("checkStepOwnedPerformanceSpecialization", "Objects::Object::ownedPerformances", "Step", true),
+ new("checkStepSpecialization", "Performances::performances", "Step", false),
+ new("checkStepSubperformanceSpecialization", "Performances::Performance::subperformances", "Step", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Usage, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] UsageRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Classifier, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] ClassifierRules =
+ [
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Feature, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] FeatureRules =
+ [
+ new("checkFeatureDataValueSpecialization", "Base::dataValues", "Feature", true),
+ new("checkFeatureEndSpecialization", "Links::Link::participant", "Feature", true),
+ new("checkFeatureObjectSpecialization", "Objects::objects", "Feature", true),
+ new("checkFeatureOccurrenceSpecialization", "Occurrences::occurrences", "Feature", true),
+ new("checkFeaturePortionSpecialization", "Occurrences::Occurrence::portions", "Feature", true),
+ new("checkFeatureSpecialization", "Base::things", "Feature", false),
+ new("checkFeatureSubobjectSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkFeatureSuboccurrenceSpecialization", "Occurrences::Occurrence::suboccurrences", "Feature", true),
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ ///
+ /// The implied library Specializations applying to Type, own and inherited.
+ ///
+ private static readonly ImpliedLibrarySpecialization[] TypeRules =
+ [
+ new("checkTypeSpecialization", "Base::Anything", "Type", false),
+ ];
+
+ }
+}
diff --git a/SysML2.NET.Semantics/Extensions/ServiceCollectionExtensions.cs b/SysML2.NET.Semantics/Extensions/ServiceCollectionExtensions.cs
new file mode 100644
index 00000000..f14b12c0
--- /dev/null
+++ b/SysML2.NET.Semantics/Extensions/ServiceCollectionExtensions.cs
@@ -0,0 +1,210 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Extensions
+{
+ using System;
+ using System.Collections.Generic;
+
+ using Microsoft.Extensions.DependencyInjection;
+
+ using SysML2.NET.Semantics.Implied;
+ using SysML2.NET.Semantics.Implied.Guards;
+ using SysML2.NET.Semantics.Implied.Rules;
+
+ ///
+ /// Registers the semantics layer with a dependency-injection container.
+ ///
+ public static class ServiceCollectionExtensions
+ {
+ ///
+ /// Registers the implied-relationship services with their default configuration.
+ ///
+ /// The service collection to register with.
+ /// The same service collection, to allow chaining.
+ /// Thrown when is null.
+ ///
+ /// An is NOT registered here: only the caller knows where the model
+ /// libraries were loaded from, so it must register one built from its own loaded Namespaces.
+ ///
+ public static IServiceCollection AddSysML2Semantics(this IServiceCollection services) => services.AddSysML2Semantics(_ => { });
+
+ ///
+ /// Registers the implied-relationship services with a caller-supplied configuration.
+ ///
+ /// The service collection to register with.
+ /// The delegate configuring the options.
+ /// The same service collection, to allow chaining.
+ /// Thrown when either argument is null.
+ public static IServiceCollection AddSysML2Semantics(this IServiceCollection services, Action configure)
+ {
+ if (services == null)
+ {
+ throw new ArgumentNullException(nameof(services));
+ }
+
+ if (configure == null)
+ {
+ throw new ArgumentNullException(nameof(configure));
+ }
+
+ var options = new ImpliedRelationshipOptions();
+ configure(options);
+
+ services.AddSingleton(options);
+ services.AddScoped();
+ services.AddScoped();
+ services.AddScoped(serviceProvider => new ImpliedRuleGuardRegistry(serviceProvider.GetServices()));
+ services.AddScoped();
+
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+
+ // Constraints whose OCL selects BETWEEN two library Features by a condition, which the
+ // single-target generated table cannot express.
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+
+ // Constraints whose OCL calls specializes(…) rather than specializesFromLibrary(…), or whose
+ // Relationship KIND the OCL leaves to the specification prose.
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+
+ // Chain-subsetting constraints: the Subsetting's general is a SYNTHESIZED feature chain.
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+ services.AddImpliedRelationshipRule();
+
+ // The mechanically translatable guards come from the generator; only the shapes its parser
+ // deliberately declines are hand-written.
+ foreach (var generatedGuard in GeneratedImpliedRuleGuards.All)
+ {
+ services.AddSingleton(generatedGuard);
+ }
+
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+ services.AddImpliedRuleGuard();
+
+ return services;
+ }
+
+ ///
+ /// Registers a hand-coded rule for a semantic constraint the generated table cannot express.
+ ///
+ /// The rule to register.
+ /// The service collection to register with.
+ /// The same service collection, to allow chaining.
+ /// Thrown when is null.
+ public static IServiceCollection AddImpliedRelationshipRule(this IServiceCollection services)
+ where TRule : class, IImpliedRelationshipRule
+ {
+ return services == null
+ ? throw new ArgumentNullException(nameof(services))
+ : services.AddScoped();
+ }
+
+ ///
+ /// Registers a guard for a conditional semantic constraint.
+ ///
+ /// The guard to register.
+ /// The service collection to register with.
+ /// The same service collection, to allow chaining.
+ /// Thrown when is null.
+ ///
+ /// Guards are registered explicitly rather than discovered by assembly scanning, so the registered
+ /// set stays visible in source and the assembly stays trimmable.
+ ///
+ public static IServiceCollection AddImpliedRuleGuard(this IServiceCollection services)
+ where TGuard : class, IImpliedRuleGuard
+ {
+ return services == null
+ ? throw new ArgumentNullException(nameof(services))
+ : services.AddScoped();
+ }
+
+ ///
+ /// Registers an built from the supplied library root Namespaces.
+ ///
+ /// The service collection to register with.
+ /// The library root Namespaces to index.
+ /// The same service collection, to allow chaining.
+ /// Thrown when either argument is null.
+ public static IServiceCollection AddLibraryTypeIndex(this IServiceCollection services, IEnumerable libraryNamespaces)
+ {
+ if (services == null)
+ {
+ throw new ArgumentNullException(nameof(services));
+ }
+
+ if (libraryNamespaces == null)
+ {
+ throw new ArgumentNullException(nameof(libraryNamespaces));
+ }
+
+ var index = OwnershipTreeLibraryTypeIndex.Build(libraryNamespaces);
+
+ return services.AddSingleton(index);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/GeneratedRuleGuard.cs b/SysML2.NET.Semantics/Implied/GeneratedRuleGuard.cs
new file mode 100644
index 00000000..ddd65e1b
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/GeneratedRuleGuard.cs
@@ -0,0 +1,73 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using System;
+
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Adapts a predicate translated from a constraint's guard OCL to the
+ /// contract.
+ ///
+ ///
+ /// This exists so the mechanically translatable guards are emitted as data — one line each — rather than
+ /// as a class file each, while still reaching the provider through the same interface as a hand-written
+ /// guard.
+ ///
+ public class GeneratedRuleGuard : IImpliedRuleGuard
+ {
+ ///
+ /// The translated guard expression.
+ ///
+ private readonly Func predicate;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The constraint the guard decides.
+ /// The translated guard expression.
+ /// Thrown when either argument is null.
+ public GeneratedRuleGuard(string constraintName, Func predicate)
+ {
+ this.ConstraintName = constraintName ?? throw new ArgumentNullException(nameof(constraintName));
+ this.predicate = predicate ?? throw new ArgumentNullException(nameof(predicate));
+ }
+
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName { get; }
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when the constraint applies.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : this.predicate(element);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/AcceptActionUsageSubactionSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/AcceptActionUsageSubactionSpecializationGuard.cs
new file mode 100644
index 00000000..14ce99b6
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/AcceptActionUsageSubactionSpecializationGuard.cs
@@ -0,0 +1,54 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Systems.Actions;
+
+ ///
+ /// Guards checkAcceptActionUsageSubactionSpecialization: a subaction AcceptActionUsage that is not a trigger action specializes Actions::Action::acceptSubactions.
+ ///
+ ///
+ /// OCL: isSubactionUsage() and not isTriggerAction() implies specializesFromLibrary('Actions::Action::acceptSubactions')
+ ///
+ public class AcceptActionUsageSubactionSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkAcceptActionUsageSubactionSpecialization";
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when the constraint applies.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IAcceptActionUsage acceptActionUsage && acceptActionUsage.IsSubactionUsage() && !acceptActionUsage.IsTriggerAction();
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/AssociationBinarySpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/AssociationBinarySpecializationGuard.cs
new file mode 100644
index 00000000..b3b3568e
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/AssociationBinarySpecializationGuard.cs
@@ -0,0 +1,57 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+
+ using SysML2.NET.Core.POCO.Kernel.Associations;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Guards checkAssociationBinarySpecialization: an Association with exactly two ends specializes
+ /// Links::BinaryLink.
+ ///
+ ///
+ /// OCL: associationEnd->size() = 2 implies specializesFromLibrary('Links::BinaryLink'). Hand
+ /// written because the count is over associationEnd, a different property from the
+ /// ownedEndFeature the generator's cardinality shape recognises.
+ ///
+ public class AssociationBinarySpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkAssociationBinarySpecialization";
+
+ ///
+ /// Asserts whether the Association has exactly two ends.
+ ///
+ /// The Element under evaluation.
+ /// True when the Element is an Association with exactly two association ends.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IAssociation { associationEnd.Count: 2 };
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/AssociationStructureBinarySpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/AssociationStructureBinarySpecializationGuard.cs
new file mode 100644
index 00000000..a0c83b0c
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/AssociationStructureBinarySpecializationGuard.cs
@@ -0,0 +1,55 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Core.POCO.Kernel.Associations;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Guards checkAssociationStructureBinarySpecialization: an AssociationStructure with exactly two end Features specializes Objects::BinaryLinkObject.
+ ///
+ ///
+ /// OCL: endFeature->size() = 2 implies specializesFromLibrary('Objects::BinaryLinkObject')
+ ///
+ public class AssociationStructureBinarySpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkAssociationStructureBinarySpecialization";
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when the constraint applies.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IAssociationStructure associationStructure && ((IType)associationStructure).endFeature.Count == 2;
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/ConnectorBinaryObjectSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/ConnectorBinaryObjectSpecializationGuard.cs
new file mode 100644
index 00000000..93a1882e
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/ConnectorBinaryObjectSpecializationGuard.cs
@@ -0,0 +1,61 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+ using System.Linq;
+
+ using SysML2.NET.Core.POCO.Kernel.Associations;
+ using SysML2.NET.Core.POCO.Kernel.Connectors;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Guards checkConnectorBinaryObjectSpecialization: a binary Connector typed by an AssociationStructure
+ /// specializes Objects::binaryLinkObjects.
+ ///
+ ///
+ /// OCL: connectorEnds->size() = 2 and
+ /// association->exists(oclIsKindOf(AssociationStructure)) implies
+ /// specializesFromLibrary('Objects::binaryLinkObjects'). Both conjuncts are required: a binary
+ /// Connector typed by a plain Association carries a different library Specialization.
+ ///
+ public class ConnectorBinaryObjectSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkConnectorBinaryObjectSpecialization";
+
+ ///
+ /// Asserts whether the Connector has exactly two ends and is typed by an AssociationStructure.
+ ///
+ /// The Element under evaluation.
+ /// True when the Element is a binary Connector typed by an AssociationStructure.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IConnector { connectorEnd.Count: 2 } connector
+ && connector.association.Any(association => association is IAssociationStructure);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/ConnectorBinarySpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/ConnectorBinarySpecializationGuard.cs
new file mode 100644
index 00000000..a03ee0d7
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/ConnectorBinarySpecializationGuard.cs
@@ -0,0 +1,58 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+
+ using SysML2.NET.Core.POCO.Kernel.Connectors;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Guards checkConnectorBinarySpecialization: a Connector with exactly two ends specializes
+ /// Links::binaryLinks.
+ ///
+ ///
+ /// OCL: connectorEnd->size() = 2 implies specializesFromLibrary('Links::binaryLinks'). This is
+ /// the unconditioned binary case; adds the
+ /// AssociationStructure condition for the stronger Objects::binaryLinkObjects Specialization, and the
+ /// 8.4.2 redundancy rules decide which survives when both apply.
+ ///
+ public class ConnectorBinarySpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkConnectorBinarySpecialization";
+
+ ///
+ /// Asserts whether the Connector has exactly two ends.
+ ///
+ /// The Element under evaluation.
+ /// True when the Element is a Connector with exactly two ends.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IConnector { connectorEnd.Count: 2 };
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/ConnectorObjectSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/ConnectorObjectSpecializationGuard.cs
new file mode 100644
index 00000000..e29455d4
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/ConnectorObjectSpecializationGuard.cs
@@ -0,0 +1,61 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+ using System.Linq;
+
+ using SysML2.NET.Core.POCO.Kernel.Associations;
+ using SysML2.NET.Core.POCO.Kernel.Connectors;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Guards checkConnectorObjectSpecialization: a Connector typed by an AssociationStructure specializes
+ /// Objects::linkObjects.
+ ///
+ ///
+ /// OCL: association->exists(oclIsKindOf(AssociationStructure)) implies
+ /// specializesFromLibrary('Objects::linkObjects'). The exists navigation over a collection is
+ /// outside the generator's translatable shapes, so the guard is written by hand. It is the unconditioned
+ /// counterpart of , which adds the two-end
+ /// condition.
+ ///
+ public class ConnectorObjectSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkConnectorObjectSpecialization";
+
+ ///
+ /// Asserts whether the Connector is typed by an AssociationStructure.
+ ///
+ /// The Element under evaluation.
+ /// True when the Element is a Connector with an AssociationStructure among its associations.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IConnector connector && connector.association.Any(association => association is IAssociationStructure);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/FeatureEndSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/FeatureEndSpecializationGuard.cs
new file mode 100644
index 00000000..ebb580bb
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/FeatureEndSpecializationGuard.cs
@@ -0,0 +1,60 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Kernel.Associations;
+ using SysML2.NET.Core.POCO.Kernel.Connectors;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Guards checkFeatureEndSpecialization: an end Feature of an Association or Connector specializes
+ /// Links::Link::participant.
+ ///
+ ///
+ /// OCL: isEnd and owningType <> null and (owningType.oclIsKindOf(Association) or
+ /// owningType.oclIsKindOf(Connector)) implies
+ /// specializesFromLibrary('Links::Link::participant'). An end Feature owned by anything else — a
+ /// plain Type, for instance — is out of scope.
+ ///
+ public class FeatureEndSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkFeatureEndSpecialization";
+
+ ///
+ /// Asserts whether the Feature is an end of an Association or Connector.
+ ///
+ /// The Element under evaluation.
+ /// True when the Element is an end Feature owned by an Association or Connector.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IFeature { IsEnd: true, owningType: IAssociation or IConnector };
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/FeaturePortionSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/FeaturePortionSpecializationGuard.cs
new file mode 100644
index 00000000..f4f31a4e
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/FeaturePortionSpecializationGuard.cs
@@ -0,0 +1,82 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+ using System.Linq;
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Core.POCO.Kernel.Classes;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Guards checkFeaturePortionSpecialization: a portion Feature typed by a Class, owned by a Class or by
+ /// a Class-typed Feature, specializes Occurrences::Occurrence::portions.
+ ///
+ ///
+ /// OCL: isPortion and ownedTyping.type->includes(oclIsKindOf(Class)) and owningType <> null
+ /// and (owningType.oclIsKindOf(Class) or owningType.oclIsKindOf(Feature) and
+ /// owningType.oclAsType(Feature).type->exists(oclIsKindOf(Class))). The nested
+ /// oclAsType(Feature).type navigation in the final disjunct is outside the generator's
+ /// translatable shapes, so the guard is written by hand.
+ ///
+ public class FeaturePortionSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkFeaturePortionSpecialization";
+
+ ///
+ /// Asserts whether the Feature is a Class-typed portion owned by a Class or a Class-typed Feature.
+ ///
+ /// The Element under evaluation.
+ /// True when every conjunct of the constraint holds.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ if (element == null)
+ {
+ throw new ArgumentNullException(nameof(element));
+ }
+
+ return element is IFeature { IsPortion: true } feature
+ && feature.ownedTyping.Any(featureTyping => featureTyping.Type is IClass)
+ && IsOwnedByAClassOrAClassTypedFeature(feature.owningType);
+ }
+
+ ///
+ /// Asserts whether an owning Type is a Class, or a Feature that is itself typed by a Class.
+ ///
+ /// The owning Type, which may be null.
+ /// True when the owning Type satisfies the constraint's final disjunct.
+ private static bool IsOwnedByAClassOrAClassTypedFeature(IType owningType)
+ {
+ return owningType switch
+ {
+ IClass => true,
+ IFeature owningFeature => owningFeature.type.Any(type => type is IClass),
+ _ => false
+ };
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/FeatureSubobjectSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/FeatureSubobjectSpecializationGuard.cs
new file mode 100644
index 00000000..cefa43ee
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/FeatureSubobjectSpecializationGuard.cs
@@ -0,0 +1,60 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+ using System.Linq;
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Kernel.Structures;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Guards checkFeatureSubobjectSpecialization: a composite Structure-typed Feature owned by a Structure specializes Occurrence::Occurrence::suboccurrences.
+ ///
+ ///
+ /// OCL: isComposite and ownedTyping.type->includes(oclIsKindOf(Structure)) and owningType <> null and (owningType.oclIsKindOf(Structure) or owningType.type->includes(oclIsKindOf(Structure)))
+ /// Hand written because the owner disjunct navigates oclAsType(Feature).type, which is
+ /// outside the generator's translatable shapes.
+ ///
+ public class FeatureSubobjectSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkFeatureSubobjectSpecialization";
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when every conjunct of the constraint holds.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IFeature { IsComposite: true } feature
+ && feature.ownedTyping.Any(featureTyping => featureTyping.Type is IStructure)
+ && OwningTypePredicates.IsOrIsTypedBy(feature.owningType);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/FeatureSuboccurrenceSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/FeatureSuboccurrenceSpecializationGuard.cs
new file mode 100644
index 00000000..42c7243b
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/FeatureSuboccurrenceSpecializationGuard.cs
@@ -0,0 +1,60 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+ using System.Linq;
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Kernel.Classes;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Guards checkFeatureSuboccurrenceSpecialization: a composite Class-typed Feature owned by a Class specializes Occurrence::Occurrence::suboccurrences.
+ ///
+ ///
+ /// OCL: isComposite and ownedTyping.type->includes(oclIsKindOf(Class)) and owningType <> null and (owningType.oclIsKindOf(Class) or owningType.oclIsKindOf(Feature) and owningType.oclAsType(Feature).type->exists(oclIsKindOf(Class)))
+ /// Hand written because the owner disjunct navigates oclAsType(Feature).type, which is
+ /// outside the generator's translatable shapes.
+ ///
+ public class FeatureSuboccurrenceSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkFeatureSuboccurrenceSpecialization";
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when every conjunct of the constraint holds.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IFeature { IsComposite: true } feature
+ && feature.ownedTyping.Any(featureTyping => featureTyping.Type is IClass)
+ && OwningTypePredicates.IsOrIsTypedBy(feature.owningType);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/FlowDefinitionBinarySpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/FlowDefinitionBinarySpecializationGuard.cs
new file mode 100644
index 00000000..8608e2fa
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/FlowDefinitionBinarySpecializationGuard.cs
@@ -0,0 +1,54 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Systems.Flows;
+
+ ///
+ /// Guards checkFlowDefinitionBinarySpecialization: a FlowDefinition with exactly two flow ends specializes Flows::Message.
+ ///
+ ///
+ /// OCL: flowEnd->size() = 2 implies specializesFromLibrary('Flows::Message')
+ ///
+ public class FlowDefinitionBinarySpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkFlowDefinitionBinarySpecialization";
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when the constraint applies.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IFlowDefinition { flowEnd.Count: 2 };
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/IncludeUseCaseUsageSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/IncludeUseCaseUsageSpecializationGuard.cs
new file mode 100644
index 00000000..a9362d55
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/IncludeUseCaseUsageSpecializationGuard.cs
@@ -0,0 +1,54 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Systems.UseCases;
+
+ ///
+ /// Guards checkIncludeUseCaseUsageSpecialization: an IncludeUseCaseUsage owned by a use case specializes UseCases::UseCase::includedUseCases.
+ ///
+ ///
+ /// OCL: owningType <> null and (owningType.oclIsKindOf(UseCaseDefinition) or owningType.oclIsKindOf(UseCaseUsage) implies specializesFromLibrary('UseCases::UseCase::includedUseCases')
+ ///
+ public class IncludeUseCaseUsageSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkIncludeUseCaseUsageSpecialization";
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when the constraint applies.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IIncludeUseCaseUsage { owningType: IUseCaseDefinition or IUseCaseUsage };
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/OccurrenceUsageSuboccurrenceSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/OccurrenceUsageSuboccurrenceSpecializationGuard.cs
new file mode 100644
index 00000000..30490365
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/OccurrenceUsageSuboccurrenceSpecializationGuard.cs
@@ -0,0 +1,60 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+ using System.Linq;
+
+ using SysML2.NET.Core.POCO.Kernel.Classes;
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Systems.Occurrences;
+
+ ///
+ /// Guards checkOccurrenceUsageSuboccurrenceSpecialization: a composite OccurrenceUsage owned by a Class, OccurrenceUsage or Class-typed Feature specializes Occurrences::Occurrence::suboccurrences.
+ ///
+ ///
+ /// OCL: isComposite and owningType <> null and (owningType.oclIsKindOf(Class) or owningType.oclIsKindOf(OccurrenceUsage) or owningType.oclIsKindOf(Feature) and owningType.oclAsType(Feature).type->exists(oclIsKind(Class)))
+ /// Hand written because the owner disjunct navigates oclAsType(Feature).type, which is
+ /// outside the generator's translatable shapes.
+ ///
+ public class OccurrenceUsageSuboccurrenceSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkOccurrenceUsageSuboccurrenceSpecialization";
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when every conjunct of the constraint holds.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IOccurrenceUsage { IsComposite: true } occurrenceUsage
+ && (occurrenceUsage.owningType is IOccurrenceUsage
+ || OwningTypePredicates.IsOrIsTypedBy(occurrenceUsage.owningType));
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/OwningTypePredicates.cs b/SysML2.NET.Semantics/Implied/Guards/OwningTypePredicates.cs
new file mode 100644
index 00000000..c45cf741
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/OwningTypePredicates.cs
@@ -0,0 +1,55 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System.Linq;
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Types;
+
+ ///
+ /// The owning-Type navigations shared by several semantic-constraint guards.
+ ///
+ ///
+ /// Four constraints repeat the disjunct owningType.oclIsKindOf(T) or
+ /// owningType.oclAsType(Feature).type->exists(oclIsKindOf(T)) — "owned by a T, or by a Feature
+ /// typed by a T". It is factored out here so the navigation is written and reasoned about once.
+ ///
+ internal static class OwningTypePredicates
+ {
+ ///
+ /// Asserts whether an owning Type is a , or a Feature typed by one.
+ ///
+ /// The Type kind the owner must be, or be typed by.
+ /// The owning Type, which may be null.
+ /// True when the owning Type satisfies either disjunct.
+ internal static bool IsOrIsTypedBy(IType owningType)
+ where TType : class, IType
+ {
+ return owningType switch
+ {
+ TType => true,
+ IFeature owningFeature => owningFeature.type.Any(type => type is TType),
+ _ => false
+ };
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/StepOwnedPerformanceSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/StepOwnedPerformanceSpecializationGuard.cs
new file mode 100644
index 00000000..05324916
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/StepOwnedPerformanceSpecializationGuard.cs
@@ -0,0 +1,58 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+ using System.Linq;
+
+ using SysML2.NET.Core.POCO.Kernel.Behaviors;
+ using SysML2.NET.Core.POCO.Kernel.Structures;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Guards checkStepOwnedPerformanceSpecialization: a composite Step owned by a Structure or Structure-typed Feature specializes Objects::Object::ownedPerformance.
+ ///
+ ///
+ /// OCL: isComposite and owningType <> null and (owningType.oclIsKindOf(Structure) or owningType.oclIsKindOf(Feature) and owningType.oclAsType(Feature).type->exists(oclIsKindOf(Structure))
+ /// Hand written because the owner disjunct navigates oclAsType(Feature).type, which is
+ /// outside the generator's translatable shapes.
+ ///
+ public class StepOwnedPerformanceSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkStepOwnedPerformanceSpecialization";
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when every conjunct of the constraint holds.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IStep { IsComposite: true } step && OwningTypePredicates.IsOrIsTypedBy(step.owningType);
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/StepSubperformanceSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/StepSubperformanceSpecializationGuard.cs
new file mode 100644
index 00000000..372338e7
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/StepSubperformanceSpecializationGuard.cs
@@ -0,0 +1,54 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+
+ using SysML2.NET.Core.POCO.Kernel.Behaviors;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Guards checkStepSubperformanceSpecialization: a composite Step owned by a Behavior or Step specializes Performances::Performance::subperformance.
+ ///
+ ///
+ /// OCL: owningType <> null and (owningType.oclIsKindOf(Behavior) or owningType.oclIsKindOf(Step)) and self.isComposite implies specializesFromLibrary('Performances::Performance::subperformance')
+ ///
+ public class StepSubperformanceSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkStepSubperformanceSpecialization";
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when the constraint applies.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is IStep { IsComposite: true, owningType: IBehavior or IStep };
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/TransitionUsageActionSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/TransitionUsageActionSpecializationGuard.cs
new file mode 100644
index 00000000..436dac41
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/TransitionUsageActionSpecializationGuard.cs
@@ -0,0 +1,62 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Systems.Actions;
+ using SysML2.NET.Core.POCO.Systems.States;
+
+ ///
+ /// Guards checkTransitionUsageActionSpecialization: a composite TransitionUsage owned by an action, whose source is not a StateUsage, specializes Actions::Action::decisionTransitions.
+ ///
+ ///
+ /// OCL: isComposite and owningType <> null and (owningType.oclIsKindOf(ActionDefinition) or owningType.oclIsKindOf(ActionUsage)) and source <> null and not source.oclIsKindOf(StateUsage)
+ /// Hand written because of the trailing source conjunct, which is outside the generator's
+ /// translatable shapes. It is what separates this constraint from its state counterpart.
+ ///
+ public class TransitionUsageActionSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkTransitionUsageActionSpecialization";
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when every conjunct of the constraint holds.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is ITransitionUsage
+ {
+ IsComposite: true,
+ owningType: IActionDefinition or IActionUsage,
+ source: not null and not IStateUsage
+ };
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/Guards/TransitionUsageStateSpecializationGuard.cs b/SysML2.NET.Semantics/Implied/Guards/TransitionUsageStateSpecializationGuard.cs
new file mode 100644
index 00000000..4b4f9599
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/Guards/TransitionUsageStateSpecializationGuard.cs
@@ -0,0 +1,57 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied.Guards
+{
+ using System;
+
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Systems.Actions;
+ using SysML2.NET.Core.POCO.Systems.States;
+
+ ///
+ /// Guards checkTransitionUsageStateSpecialization: a composite TransitionUsage owned by a state, whose source is a StateUsage, specializes States::StateAction::stateTransitions.
+ ///
+ ///
+ /// OCL: isComposite and owningType <> null and (owningType.oclIsKindOf(StateDefinition) or owningType.oclIsKindOf(StateUsage)) and source <> null and source.oclIsKindOf(StateUsage)
+ /// Hand written because of the trailing source conjunct, which is outside the generator's
+ /// translatable shapes. It is what separates this constraint from its action counterpart.
+ ///
+ public class TransitionUsageStateSpecializationGuard : IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides.
+ ///
+ public string ConstraintName => "checkTransitionUsageStateSpecialization";
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when every conjunct of the constraint holds.
+ /// Thrown when is null.
+ public bool Applies(IElement element)
+ {
+ return element == null
+ ? throw new ArgumentNullException(nameof(element))
+ : element is ITransitionUsage { IsComposite: true, owningType: IStateDefinition or IStateUsage, source: IStateUsage };
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/IImpliedRelationshipFactory.cs b/SysML2.NET.Semantics/Implied/IImpliedRelationshipFactory.cs
new file mode 100644
index 00000000..8130e806
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/IImpliedRelationshipFactory.cs
@@ -0,0 +1,89 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using SysML2.NET.Core.POCO.Core.Classifiers;
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Types;
+
+ ///
+ /// Creates the Relationship instances that satisfy a semantic constraint.
+ ///
+ ///
+ /// Every product carries isImplied and is DETACHED: it is not added to any ownedRelationship, so the
+ /// model stays a faithful match to what was read and isImpliedIncluded stays false.
+ ///
+ public interface IImpliedRelationshipFactory
+ {
+ ///
+ /// Creates an implied Subclassification between two Classifiers.
+ ///
+ /// The specializing Classifier.
+ /// The Classifier being specialized.
+ /// A detached Subclassification with isImplied set.
+ /// Thrown when either argument is null.
+ ISubclassification CreateImpliedSubclassification(IClassifier specific, IClassifier general);
+
+ ///
+ /// Creates an implied Subsetting between two Features.
+ ///
+ /// The subsetting Feature.
+ /// The Feature being subsetted.
+ /// A detached Subsetting with isImplied set.
+ /// Thrown when either argument is null.
+ ISubsetting CreateImpliedSubsetting(IFeature specific, IFeature general);
+
+ ///
+ /// Creates a detached Feature whose chainingFeatures are the two supplied Features, in order.
+ ///
+ /// The first Feature of the chain.
+ /// The second Feature of the chain.
+ /// A detached Feature standing for the chain first.second.
+ ///
+ /// The subsetsChain(first, second) constraints are satisfied by specializing a Feature whose
+ /// last two chainingFeatures are the given pair. No such Feature need exist in the model, so one is
+ /// synthesized here to be the general of the implied Subsetting.
+ /// Unlike every other product of this factory, this is an ELEMENT rather than a Relationship,
+ /// and it is a NEW element rather than one the caller already holds. A consumer that walks
+ /// SubsettedFeature must therefore be prepared for a Feature that is absent from the model and
+ /// carries no name — its meaning is entirely in its chainingFeature list.
+ ///
+ IFeature CreateImpliedFeatureChain(IFeature first, IFeature second);
+
+ ///
+ /// Creates an implied Redefinition between two Features.
+ ///
+ /// The redefining Feature.
+ /// The Feature being redefined.
+ /// A detached Redefinition with isImplied set.
+ /// Thrown when either argument is null.
+ IRedefinition CreateImpliedRedefinition(IFeature specific, IFeature general);
+
+ ///
+ /// Creates an implied FeatureTyping between a Feature and the Type that types it.
+ ///
+ /// The Feature being typed.
+ /// The Type typing the Feature.
+ /// A detached FeatureTyping with isImplied set.
+ /// Thrown when either argument is null.
+ IFeatureTyping CreateImpliedFeatureTyping(IFeature typedFeature, IType type);
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/IImpliedRelationshipProvider.cs b/SysML2.NET.Semantics/Implied/IImpliedRelationshipProvider.cs
new file mode 100644
index 00000000..01c0604c
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/IImpliedRelationshipProvider.cs
@@ -0,0 +1,77 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using System.Collections.Generic;
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Computes the implied Relationships that KerML 8.4.2 semantic constraints require of a model,
+ /// without adding them to the model.
+ ///
+ ///
+ /// Element.isImpliedIncluded is all-or-nothing: an Element whose ownedRelationship contains an implied
+ /// Relationship must declare isImpliedIncluded, and while is
+ /// non-empty no complete closure can be produced. Implementations therefore never mutate the model and
+ /// never set that flag.
+ ///
+ public interface IImpliedRelationshipProvider
+ {
+ ///
+ /// Gets the names of the semantic constraints this provider cannot yet compute.
+ ///
+ IReadOnlyList NotCoveredConstraints { get; }
+
+ ///
+ /// Returns the implied Relationships required of the supplied Element.
+ ///
+ /// The Element to compute implied Relationships for.
+ /// The detached implied Relationships; empty when none are required.
+ /// Thrown when is null.
+ IReadOnlyList GetImpliedRelationships(IElement element);
+
+ ///
+ /// Returns the implied Specializations required of the supplied Type, after 8.4.2 redundancy reduction.
+ ///
+ /// The Type to compute implied Specializations for.
+ /// The detached implied Specializations; empty when none are required.
+ /// Thrown when is null.
+ IReadOnlyList GetImpliedSpecializations(IType type);
+
+ ///
+ /// Returns the implied Redefinitions required of the supplied Feature.
+ ///
+ /// The Feature to compute implied Redefinitions for.
+ /// The detached implied Redefinitions; empty when none are required.
+ /// Thrown when is null.
+ IReadOnlyList GetImpliedRedefinitions(IFeature feature);
+
+ ///
+ /// Asserts whether the named semantic constraint is computed by this provider.
+ ///
+ /// The constraint name, for example checkPortUsageSpecialization.
+ /// True when the constraint is computed, false when it is listed as not covered.
+ bool IsConstraintCovered(string constraintName);
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/IImpliedRelationshipRule.cs b/SysML2.NET.Semantics/Implied/IImpliedRelationshipRule.cs
new file mode 100644
index 00000000..b44d4cd0
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/IImpliedRelationshipRule.cs
@@ -0,0 +1,53 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using System.Collections.Generic;
+
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Computes the implied Relationships of a single semantic constraint that the generated table cannot
+ /// express.
+ ///
+ ///
+ /// The generated table only covers constraints whose OCL is a specializesFromLibrary call. Constraints
+ /// that relate two elements of the USER model — every Redefinition constraint, and the variation
+ /// Specialization constraints among others — are hand-coded as rules and registered explicitly. A
+ /// registered rule removes its constraint from the provider's not-covered manifest.
+ ///
+ public interface IImpliedRelationshipRule
+ {
+ ///
+ /// Gets the name of the semantic constraint this rule implements, for example
+ /// checkUsageVariationUsageSpecialization.
+ ///
+ string ConstraintName { get; }
+
+ ///
+ /// Computes the implied Relationships the constraint requires of the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// The detached implied Relationships; empty when the constraint does not apply.
+ /// Thrown when is null.
+ IReadOnlyList Apply(IElement element);
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/IImpliedRuleGuard.cs b/SysML2.NET.Semantics/Implied/IImpliedRuleGuard.cs
new file mode 100644
index 00000000..d8835a71
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/IImpliedRuleGuard.cs
@@ -0,0 +1,49 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Decides whether a conditional semantic constraint applies to a given Element.
+ ///
+ ///
+ /// The generated rule table flags a row as requiring a guard when its OCL is a conditional
+ /// specializesFromLibrary call. Such a row must never be applied unconditionally, so a missing guard is
+ /// an error rather than an implicit yes.
+ ///
+ public interface IImpliedRuleGuard
+ {
+ ///
+ /// Gets the name of the semantic constraint this guard decides, for example
+ /// checkPortUsageSubportSpecialization.
+ ///
+ string ConstraintName { get; }
+
+ ///
+ /// Asserts whether the constraint applies to the supplied Element.
+ ///
+ /// The Element under evaluation.
+ /// True when the constraint applies and its implied Relationship is required.
+ /// Thrown when is null.
+ bool Applies(IElement element);
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/IImpliedRuleGuardRegistry.cs b/SysML2.NET.Semantics/Implied/IImpliedRuleGuardRegistry.cs
new file mode 100644
index 00000000..55c3d2ec
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/IImpliedRuleGuardRegistry.cs
@@ -0,0 +1,44 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ ///
+ /// Resolves the registered for a conditional semantic constraint.
+ ///
+ public interface IImpliedRuleGuardRegistry
+ {
+ ///
+ /// Returns the guard registered for the named constraint.
+ ///
+ /// The constraint name to resolve a guard for.
+ /// The registered guard.
+ /// Thrown when is null.
+ /// Thrown when no guard is registered for the constraint.
+ IImpliedRuleGuard GetGuard(string constraintName);
+
+ ///
+ /// Asserts whether a guard is registered for the named constraint.
+ ///
+ /// The constraint name to test.
+ /// True when a guard is registered.
+ bool HasGuard(string constraintName);
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/IImpliedSpecializationReducer.cs b/SysML2.NET.Semantics/Implied/IImpliedSpecializationReducer.cs
new file mode 100644
index 00000000..ec94b15a
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/IImpliedSpecializationReducer.cs
@@ -0,0 +1,47 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using System.Collections.Generic;
+
+ using SysML2.NET.Core.POCO.Core.Types;
+
+ ///
+ /// Drops the implied Specializations that KerML 8.4.2 considers redundant for a Type.
+ ///
+ ///
+ /// Two rules apply: an implied Specialization is dropped when the Type already has an ownedSpecialization
+ /// with the same general Type, or when any owned or implied Specialization has a general Type that is a
+ /// strict subtype of it; and only one of several implied Specializations sharing a general Type is kept.
+ /// Neither rule applies to Redefinitions, whose semantics go beyond basic Specialization.
+ ///
+ public interface IImpliedSpecializationReducer
+ {
+ ///
+ /// Reduces the candidate implied Specializations of a Type to the non-redundant set.
+ ///
+ /// The Type the candidates were computed for.
+ /// The implied Specializations to reduce.
+ /// The retained Specializations, in the order the candidates were supplied.
+ /// Thrown when either argument is null.
+ IReadOnlyList Reduce(IType type, IReadOnlyList candidates);
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/ILibraryTypeIndex.cs b/SysML2.NET.Semantics/Implied/ILibraryTypeIndex.cs
new file mode 100644
index 00000000..b4b443ee
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/ILibraryTypeIndex.cs
@@ -0,0 +1,45 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using SysML2.NET.Core.POCO.Core.Types;
+
+ ///
+ /// Resolves a model-library Type by its qualified name, for the semantic constraints that require a
+ /// user Type to specialize a specific library Type.
+ ///
+ ///
+ /// Implementations must index the library ownership tree directly and must NOT resolve through
+ /// Namespace.resolve: resolution consults inheritedMembership, which is what the implied layer exists to
+ /// supply, so routing through it re-enters that bootstrap cycle. For the same reason the index is
+ /// populated eagerly, before any resolution runs, rather than faulting libraries in on first miss.
+ ///
+ public interface ILibraryTypeIndex
+ {
+ ///
+ /// Attempts to resolve the library Type carrying the supplied qualified name.
+ ///
+ /// The qualified name, for example Occurrences::Occurrence::suboccurrences.
+ /// When this method returns true, the resolved Type; otherwise null.
+ /// True when the qualified name resolves to an indexed Type.
+ bool TryGetType(string qualifiedName, out IType type);
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/ImpliedRelationshipFactory.cs b/SysML2.NET.Semantics/Implied/ImpliedRelationshipFactory.cs
new file mode 100644
index 00000000..bcba158f
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/ImpliedRelationshipFactory.cs
@@ -0,0 +1,181 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using System;
+
+ using SysML2.NET.Core.POCO.Core.Classifiers;
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Extensions;
+
+ ///
+ /// Creates detached Relationship instances that carry isImplied.
+ ///
+ ///
+ /// Each product is given a fresh Id so that instances remain distinguishable in the dictionaries and sets
+ /// the computation uses. Nothing created here is attached to an ownedRelationship, so the model read from
+ /// disk is left untouched and isImpliedIncluded stays false.
+ ///
+ public class ImpliedRelationshipFactory : IImpliedRelationshipFactory
+ {
+ ///
+ /// Creates an implied Subclassification between two Classifiers.
+ ///
+ /// The specializing Classifier.
+ /// The Classifier being specialized.
+ /// A detached Subclassification with isImplied set.
+ /// Thrown when either argument is null.
+ public ISubclassification CreateImpliedSubclassification(IClassifier specific, IClassifier general)
+ {
+ if (specific == null)
+ {
+ throw new ArgumentNullException(nameof(specific));
+ }
+
+ if (general == null)
+ {
+ throw new ArgumentNullException(nameof(general));
+ }
+
+ return new Subclassification
+ {
+ Id = Guid.NewGuid(),
+ IsImplied = true,
+ Subclassifier = specific,
+ Superclassifier = general
+ };
+ }
+
+ ///
+ /// Creates an implied Subsetting between two Features.
+ ///
+ /// The subsetting Feature.
+ /// The Feature being subsetted.
+ /// A detached Subsetting with isImplied set.
+ /// Thrown when either argument is null.
+ public ISubsetting CreateImpliedSubsetting(IFeature specific, IFeature general)
+ {
+ if (specific == null)
+ {
+ throw new ArgumentNullException(nameof(specific));
+ }
+
+ if (general == null)
+ {
+ throw new ArgumentNullException(nameof(general));
+ }
+
+ return new Subsetting
+ {
+ Id = Guid.NewGuid(),
+ IsImplied = true,
+ SubsettingFeature = specific,
+ SubsettedFeature = general
+ };
+ }
+
+ ///
+ /// Creates a detached Feature whose chainingFeatures are the two supplied Features, in order.
+ ///
+ /// The first Feature of the chain.
+ /// The second Feature of the chain.
+ /// A detached Feature standing for the chain first.second.
+ /// Thrown when either Feature is null.
+ public IFeature CreateImpliedFeatureChain(IFeature first, IFeature second)
+ {
+ if (first == null)
+ {
+ throw new ArgumentNullException(nameof(first));
+ }
+
+ if (second == null)
+ {
+ throw new ArgumentNullException(nameof(second));
+ }
+
+ var chain = new Feature { Id = Guid.NewGuid() };
+
+ // The chain is expressed through owned FeatureChainings, which is what chainingFeature derives
+ // from — setting the derived list directly would not survive a re-read of the property.
+ chain.AssignOwnership(new FeatureChaining { Id = Guid.NewGuid(), IsImplied = true, ChainingFeature = first });
+ chain.AssignOwnership(new FeatureChaining { Id = Guid.NewGuid(), IsImplied = true, ChainingFeature = second });
+
+ return chain;
+ }
+
+ ///
+ /// Creates an implied Redefinition between two Features.
+ ///
+ /// The redefining Feature.
+ /// The Feature being redefined.
+ /// A detached Redefinition with isImplied set.
+ /// Thrown when either argument is null.
+ public IRedefinition CreateImpliedRedefinition(IFeature specific, IFeature general)
+ {
+ if (specific == null)
+ {
+ throw new ArgumentNullException(nameof(specific));
+ }
+
+ if (general == null)
+ {
+ throw new ArgumentNullException(nameof(general));
+ }
+
+ return new Redefinition
+ {
+ Id = Guid.NewGuid(),
+ IsImplied = true,
+ RedefiningFeature = specific,
+ RedefinedFeature = general
+ };
+ }
+
+ ///
+ /// Creates an implied FeatureTyping between a Feature and the Type that types it.
+ ///
+ /// The Feature being typed.
+ /// The Type typing the Feature.
+ /// A detached FeatureTyping with isImplied set.
+ /// Thrown when either argument is null.
+ public IFeatureTyping CreateImpliedFeatureTyping(IFeature typedFeature, IType type)
+ {
+ if (typedFeature == null)
+ {
+ throw new ArgumentNullException(nameof(typedFeature));
+ }
+
+ if (type == null)
+ {
+ throw new ArgumentNullException(nameof(type));
+ }
+
+ return new FeatureTyping
+ {
+ Id = Guid.NewGuid(),
+ IsImplied = true,
+ TypedFeature = typedFeature,
+ Type = type
+ };
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/ImpliedRelationshipOptions.cs b/SysML2.NET.Semantics/Implied/ImpliedRelationshipOptions.cs
new file mode 100644
index 00000000..8737f83b
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/ImpliedRelationshipOptions.cs
@@ -0,0 +1,48 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ ///
+ /// Configures which families of semantic constraint the provider computes.
+ ///
+ public class ImpliedRelationshipOptions
+ {
+ ///
+ /// Gets or sets a value indicating whether the library-specialization constraints are computed.
+ ///
+ ///
+ /// Off by default. These constraints attach the bulk of the Kernel Semantic Library to a model and
+ /// change what inheritance yields for almost every Type, so enabling them re-baselines any output
+ /// derived from inheritance. Turn on deliberately, in a change of its own.
+ ///
+ public bool EnableLibrarySpecializations { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether redundant implied Specializations are dropped per
+ /// KerML 8.4.2.
+ ///
+ ///
+ /// On by default. Switching it off is a diagnostic aid for seeing every constraint a Type triggers,
+ /// not a supported production configuration.
+ ///
+ public bool ReduceRedundantSpecializations { get; set; } = true;
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/ImpliedRelationshipProvider.cs b/SysML2.NET.Semantics/Implied/ImpliedRelationshipProvider.cs
new file mode 100644
index 00000000..198f0f94
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/ImpliedRelationshipProvider.cs
@@ -0,0 +1,372 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using SysML2.NET.Core.POCO.Core.Classifiers;
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Core.POCO.Root.Elements;
+
+ ///
+ /// Computes implied Relationships from the generated constraint table, the registered guards and the
+ /// model-library index.
+ ///
+ ///
+ /// Nothing computed here is attached to the model: every product is a detached Relationship carrying
+ /// isImplied, so isImpliedIncluded stays false and the model remains a faithful match to what was read.
+ /// Results are memoised for the lifetime of this instance, which is therefore scoped to one model — the
+ /// object graph is mutable and the SDK offers no invalidation hook.
+ ///
+ public class ImpliedRelationshipProvider : IImpliedRelationshipProvider
+ {
+ ///
+ /// The memoised implied Specializations, keyed by the Type they were computed for.
+ ///
+ private readonly Dictionary> specializationsByType = [];
+
+ ///
+ /// The index used to resolve the library Types the constraints target.
+ ///
+ private readonly ILibraryTypeIndex libraryTypeIndex;
+
+ ///
+ /// The registry consulted for conditional constraints.
+ ///
+ private readonly IImpliedRuleGuardRegistry guardRegistry;
+
+ ///
+ /// The factory creating the detached Relationships.
+ ///
+ private readonly IImpliedRelationshipFactory factory;
+
+ ///
+ /// The reducer applying the KerML 8.4.2 redundancy rules.
+ ///
+ private readonly IImpliedSpecializationReducer reducer;
+
+ ///
+ /// The configured behaviour.
+ ///
+ private readonly ImpliedRelationshipOptions options;
+
+ ///
+ /// The hand-coded rules for constraints the generated table cannot express.
+ ///
+ private readonly IReadOnlyList rules;
+
+ ///
+ /// The constraint names the hand-coded rules cover.
+ ///
+ private readonly HashSet ruleConstraintNames;
+
+ ///
+ /// The constraints this provider cannot compute, settled once at construction.
+ ///
+ ///
+ /// Every input is fixed for the lifetime of the instance, so the answer is too. Computing it per
+ /// access allocated a fresh list on a property that reads as a field — and
+ /// consults it per constraint, so the copy was on a hot path
+ /// rather than an occasional one.
+ ///
+ private readonly IReadOnlyList notCoveredConstraints;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The index resolving the library Types the constraints target.
+ /// The registry of guards for conditional constraints.
+ /// The factory creating the detached Relationships.
+ /// The reducer applying the redundancy rules.
+ /// The configured behaviour.
+ /// The hand-coded rules for constraints the generated table cannot express.
+ /// Thrown when any argument is null.
+ public ImpliedRelationshipProvider(ILibraryTypeIndex libraryTypeIndex, IImpliedRuleGuardRegistry guardRegistry, IImpliedRelationshipFactory factory, IImpliedSpecializationReducer reducer, ImpliedRelationshipOptions options, IEnumerable rules)
+ {
+ if (rules == null)
+ {
+ throw new ArgumentNullException(nameof(rules));
+ }
+
+ this.libraryTypeIndex = libraryTypeIndex ?? throw new ArgumentNullException(nameof(libraryTypeIndex));
+ this.guardRegistry = guardRegistry ?? throw new ArgumentNullException(nameof(guardRegistry));
+ this.factory = factory ?? throw new ArgumentNullException(nameof(factory));
+ this.reducer = reducer ?? throw new ArgumentNullException(nameof(reducer));
+ this.options = options ?? throw new ArgumentNullException(nameof(options));
+ this.rules = rules.ToList();
+ this.ruleConstraintNames = [..this.rules.Select(rule => rule.ConstraintName)];
+
+ var uncovered = this.options.EnableLibrarySpecializations
+ ? ImpliedRelationshipTable.NotCovered
+ : ImpliedRelationshipTable.AllConstraintNames;
+
+ this.notCoveredConstraints = [..uncovered
+ .Where(constraint => !this.ruleConstraintNames.Any(ruleConstraintName => constraint.Contains(ruleConstraintName, StringComparison.Ordinal)))];
+ }
+
+ ///
+ /// Gets the names of the semantic constraints this provider cannot yet compute.
+ ///
+ ///
+ /// The manifest is the table's own not-covered list, minus the constraints a registered hand-coded
+ /// rule supplies. When library specializations are disabled the answer widens to every constraint,
+ /// since nothing table-driven is computed at all.
+ ///
+ public IReadOnlyList NotCoveredConstraints => this.notCoveredConstraints;
+
+ ///
+ /// Returns the implied Relationships required of the supplied Element.
+ ///
+ /// The Element to compute implied Relationships for.
+ /// The detached implied Relationships; empty when none are required.
+ /// Thrown when is null.
+ /// Thrown when a conditional constraint has no registered guard.
+ /// Thrown when a targeted library Type is not indexed.
+ public IReadOnlyList GetImpliedRelationships(IElement element)
+ {
+ if (element == null)
+ {
+ throw new ArgumentNullException(nameof(element));
+ }
+
+ var relationships = new List();
+
+ if (element is IType type)
+ {
+ relationships.AddRange(this.GetImpliedSpecializations(type));
+ }
+
+ // Specializations are already accounted for above — a Redefinition, Subsetting and FeatureTyping
+ // are all Specializations, so re-adding them here would double-count.
+ relationships.AddRange(this.ApplyRules(element).Where(relationship => relationship is not ISpecialization));
+
+ return relationships;
+ }
+
+ ///
+ /// Returns the implied Specializations required of the supplied Type, after 8.4.2 redundancy reduction.
+ ///
+ /// The Type to compute implied Specializations for.
+ /// The detached implied Specializations; empty when none are required.
+ /// Thrown when is null.
+ /// Thrown when a conditional constraint has no registered guard.
+ /// Thrown when a targeted library Type is not indexed.
+ public IReadOnlyList GetImpliedSpecializations(IType type)
+ {
+ if (type == null)
+ {
+ throw new ArgumentNullException(nameof(type));
+ }
+
+ if (this.specializationsByType.TryGetValue(type, out var memoised))
+ {
+ return memoised;
+ }
+
+ var candidates = new List();
+
+ if (this.options.EnableLibrarySpecializations)
+ {
+ candidates.AddRange(ImpliedRelationshipTable.QueryImpliedLibrarySpecializations(type)
+ .Where(rule => this.Applies(rule, type))
+ .Select(rule => this.CreateSpecializationOrNull(rule, type))
+ .Where(specialization => specialization != null));
+ }
+
+ var ruleSpecializations = this.ApplyRules(type).OfType().ToList();
+
+ // A rule may return a Specialization whose SPECIFIC is a nested Element rather than the Type
+ // under evaluation — the result parameter of an Expression, the multiplicity of a Definition,
+ // the trigger of a TransitionUsage. Reduction compares candidates against THIS Type's declared
+ // generals and against each other, so admitting those would let a coincidental match on an
+ // unrelated Element's general discard a valid Specialization. They bypass reduction entirely.
+ var nonRedefinitions = ruleSpecializations.Where(specialization => specialization is not IRedefinition).ToList();
+ var notReducible = nonRedefinitions.Where(specialization => !ReferenceEquals(specialization.Specific, type)).ToList();
+
+ candidates.AddRange(nonRedefinitions.Where(specialization => ReferenceEquals(specialization.Specific, type)));
+
+ // Redundancy reduction is deliberately NOT applied to Redefinitions: KerML 8.4.2 exempts them
+ // because a Redefinition carries semantics beyond basic Specialization.
+ IReadOnlyList reduced = this.options.ReduceRedundantSpecializations
+ ? this.reducer.Reduce(type, candidates)
+ : candidates;
+
+ IReadOnlyList result =
+ [
+ ..reduced,
+ ..notReducible,
+ ..ruleSpecializations.OfType()
+ ];
+
+ this.specializationsByType[type] = result;
+
+ return result;
+ }
+
+ ///
+ /// Returns the implied Redefinitions required of the supplied Feature.
+ ///
+ /// The Feature to compute implied Redefinitions for.
+ /// The detached implied Redefinitions; empty when none are required.
+ /// Thrown when is null.
+ ///
+ /// Redefinition constraints relate two Features of the USER model rather than a user Type and a
+ /// library Type, so none is expressible in the generated table; each is supplied by a hand-coded
+ /// rule. Constraints with no registered rule are reported by .
+ ///
+ public IReadOnlyList GetImpliedRedefinitions(IFeature feature)
+ {
+ return feature == null
+ ? throw new ArgumentNullException(nameof(feature))
+ : this.ApplyRules(feature).OfType().ToList();
+ }
+
+ ///
+ /// Asserts whether the named semantic constraint is computed by this provider.
+ ///
+ /// The constraint name, for example checkPortUsageSpecialization.
+ /// True when the constraint is computed, false when it is listed as not covered.
+ public bool IsConstraintCovered(string constraintName)
+ {
+ return !string.IsNullOrWhiteSpace(constraintName)
+ && !this.NotCoveredConstraints.Any(notCovered => notCovered.Contains(constraintName, StringComparison.Ordinal));
+ }
+
+ ///
+ /// Runs every registered hand-coded rule against an Element.
+ ///
+ /// The Element under evaluation.
+ /// The implied Relationships the rules produced, in registration order.
+ private IReadOnlyList ApplyRules(IElement element) => [..this.rules.SelectMany(rule => ApplyRule(rule, element))];
+
+ ///
+ /// Applies one rule, degrading to no contribution when the library Type it targets cannot be resolved.
+ ///
+ /// The rule to apply.
+ /// The Element under evaluation.
+ /// The rule's implied Relationships, or empty when its library target is unresolvable.
+ ///
+ /// An unresolvable target has two causes and only one of them is the caller's to fix. Libraries not
+ /// loaded is a misconfiguration; a constraint naming a Feature that no library declares — a defect in
+ /// the specification OCL, or a path the index cannot express — is not. Throwing treats both alike and
+ /// costs the ENTIRE document: the exception escapes the writer mid-write and the output is truncated.
+ /// Degrading costs one Relationship instead. A name that would have been shortened through it
+ /// falls back to a longer — never an invalid — form, which is the same failure mode the writer
+ /// already accepts elsewhere.
+ ///
+ private static IReadOnlyList ApplyRule(IImpliedRelationshipRule rule, IElement element)
+ {
+ try
+ {
+ return rule.Apply(element);
+ }
+ catch (UnresolvedLibraryTypeException)
+ {
+ return [];
+ }
+ }
+
+ ///
+ /// Asserts whether a table row applies to an Element, consulting the registered guard when the row
+ /// is conditional.
+ ///
+ /// The table row under evaluation.
+ /// The Element the row was matched against.
+ /// True when the constraint applies.
+ /// Thrown when the row is conditional and no guard is registered.
+ private bool Applies(ImpliedLibrarySpecialization rule, IElement element)
+ {
+ if (!rule.RequiresGuard)
+ {
+ return true;
+ }
+
+ if (!this.guardRegistry.HasGuard(rule.ConstraintName))
+ {
+ throw new MissingImpliedRuleGuardException(rule.ConstraintName, rule.DeclaringMetaclassName);
+ }
+
+ return this.guardRegistry.GetGuard(rule.ConstraintName).Applies(element);
+ }
+
+ ///
+ /// Creates the implied Specialization for a table row, degrading to null when its library Type is
+ /// unresolvable — see for why this does not throw.
+ ///
+ /// The table row.
+ /// The Type under evaluation.
+ /// The Specialization, or null.
+ private ISpecialization CreateSpecializationOrNull(ImpliedLibrarySpecialization rule, IType type)
+ {
+ try
+ {
+ return this.CreateSpecialization(rule, type);
+ }
+ catch (UnresolvedLibraryTypeException)
+ {
+ return null;
+ }
+ }
+
+ ///
+ /// Creates the Specialization a table row implies for a Type.
+ ///
+ /// The table row to realise.
+ /// The Type the Specialization specializes from.
+ /// The detached Specialization, or null when the row's kind does not match the Type.
+ /// Thrown when the targeted library Type is not indexed.
+ private ISpecialization CreateSpecialization(ImpliedLibrarySpecialization rule, IType type)
+ {
+ if (!this.libraryTypeIndex.TryGetType(rule.TargetLibraryName, out var libraryType))
+ {
+ throw new UnresolvedLibraryTypeException(rule.TargetLibraryName, rule.ConstraintName);
+ }
+
+ return QueryKind(rule) switch
+ {
+ ImpliedRelationshipKind.Subclassification when type is IClassifier specificClassifier && libraryType is IClassifier generalClassifier =>
+ this.factory.CreateImpliedSubclassification(specificClassifier, generalClassifier),
+ ImpliedRelationshipKind.Subsetting when type is IFeature specificFeature && libraryType is IFeature generalFeature =>
+ this.factory.CreateImpliedSubsetting(specificFeature, generalFeature),
+ _ => null
+ };
+ }
+
+ ///
+ /// Determines whether a table row implies a Subclassification or a Subsetting.
+ ///
+ /// The table row to classify.
+ /// The kind of Relationship the row implies.
+ ///
+ /// The OCL does not carry the distinction, so the generator emits the set of metaclasses whose
+ /// constraints imply Subclassification; everything else implies Subsetting.
+ ///
+ private static ImpliedRelationshipKind QueryKind(ImpliedLibrarySpecialization rule)
+ {
+ return ImpliedRelationshipTable.SubclassificationMetaclasses.Contains(rule.DeclaringMetaclassName)
+ ? ImpliedRelationshipKind.Subclassification
+ : ImpliedRelationshipKind.Subsetting;
+ }
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/ImpliedRuleGuardRegistry.cs b/SysML2.NET.Semantics/Implied/ImpliedRuleGuardRegistry.cs
new file mode 100644
index 00000000..dc8f3718
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/ImpliedRuleGuardRegistry.cs
@@ -0,0 +1,94 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ ///
+ /// Resolves guards by constraint name from an explicitly supplied set.
+ ///
+ ///
+ /// Guards are registered explicitly rather than discovered by assembly scanning, so the assembly stays
+ /// trimmable and the registered set is visible in source.
+ ///
+ public class ImpliedRuleGuardRegistry : IImpliedRuleGuardRegistry
+ {
+ ///
+ /// The registered guards, keyed by the constraint each decides.
+ ///
+ private readonly Dictionary guards;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The guards to register.
+ /// Thrown when is null.
+ /// Thrown when two guards declare the same constraint name.
+ public ImpliedRuleGuardRegistry(IEnumerable guards)
+ {
+ if (guards == null)
+ {
+ throw new ArgumentNullException(nameof(guards));
+ }
+
+ var materialised = guards.ToList();
+
+ var duplicate = materialised
+ .GroupBy(guard => guard.ConstraintName, StringComparer.Ordinal)
+ .FirstOrDefault(group => group.Count() > 1);
+
+ if (duplicate != null)
+ {
+ throw new ArgumentException($"More than one IImpliedRuleGuard is registered for the constraint '{duplicate.Key}'.", nameof(guards));
+ }
+
+ this.guards = materialised.ToDictionary(guard => guard.ConstraintName, StringComparer.Ordinal);
+ }
+
+ ///
+ /// Returns the guard registered for the named constraint.
+ ///
+ /// The constraint name to resolve a guard for.
+ /// The registered guard.
+ /// Thrown when is null.
+ /// Thrown when no guard is registered for the constraint.
+ public IImpliedRuleGuard GetGuard(string constraintName)
+ {
+ if (constraintName == null)
+ {
+ throw new ArgumentNullException(nameof(constraintName));
+ }
+
+ return this.guards.TryGetValue(constraintName, out var guard)
+ ? guard
+ : throw new MissingImpliedRuleGuardException(constraintName, "unknown");
+ }
+
+ ///
+ /// Asserts whether a guard is registered for the named constraint.
+ ///
+ /// The constraint name to test.
+ /// True when a guard is registered.
+ public bool HasGuard(string constraintName) => constraintName != null && this.guards.ContainsKey(constraintName);
+ }
+}
diff --git a/SysML2.NET.Semantics/Implied/ImpliedSpecializationReducer.cs b/SysML2.NET.Semantics/Implied/ImpliedSpecializationReducer.cs
new file mode 100644
index 00000000..65ad3487
--- /dev/null
+++ b/SysML2.NET.Semantics/Implied/ImpliedSpecializationReducer.cs
@@ -0,0 +1,122 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright (C) 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Semantics.Implied
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using SysML2.NET.Core.POCO.Core.Types;
+
+ ///
+ /// Drops the implied Specializations that KerML 8.4.2 considers redundant for a Type.
+ ///
+ ///
+ /// Rule 1 drops a candidate when the Type already owns a Specialization with the same general Type, or
+ /// when any owned or surviving implied Specialization has a general Type that is a STRICT subtype of the
+ /// candidate's; the more specific Specialization already satisfies the looser constraint. Rule 2 keeps
+ /// only the first of several candidates sharing a general Type. Neither rule is applied to
+ /// Redefinitions, whose semantics go beyond basic Specialization.
+ ///
+ public class ImpliedSpecializationReducer : IImpliedSpecializationReducer
+ {
+ ///
+ /// Reduces the candidate implied Specializations of a Type to the non-redundant set.
+ ///
+ /// The Type the candidates were computed for.
+ /// The implied Specializations to reduce.
+ /// The retained Specializations, in the order the candidates were supplied.
+ /// Thrown when either argument is null.
+ public IReadOnlyList Reduce(IType type, IReadOnlyList candidates)
+ {
+ if (type == null)
+ {
+ throw new ArgumentNullException(nameof(type));
+ }
+
+ if (candidates == null)
+ {
+ throw new ArgumentNullException(nameof(candidates));
+ }
+
+ var declaredGenerals = type.ownedSpecialization
+ .Select(specialization => specialization.General)
+ .Where(general => general != null)
+ .ToList();
+
+ var retained = new List();
+ var retainedGenerals = new List();
+
+ foreach (var candidate in candidates.Where(candidate => candidate?.General != null))
+ {
+ // Rule 2: a general Type already retained makes this candidate a duplicate.
+ if (retainedGenerals.Contains(candidate.General))
+ {
+ continue;
+ }
+
+ if (IsSupersededBy(candidate.General, declaredGenerals))
+ {
+ continue;
+ }
+
+ retained.Add(candidate);
+ retainedGenerals.Add(candidate.General);
+ }
+
+ // Rule 1 across the implied set itself: a retained candidate whose general Type is a strict
+ // SUPERtype of another retained candidate's is redundant. Applied after the pass above because
+ // it needs the full surviving set, not a prefix of it. The candidate's own general Type is
+ // excluded from the comparison, since AllSupertypes includes the Type itself and would
+ // otherwise make every candidate supersede itself.
+ return retained
+ .Where(candidate => !IsStrictlySupersededBy(candidate.General, retainedGenerals))
+ .ToList();
+ }
+
+ ///