From 8355cbc1c070186e068a0dfefd676b83a16f3ecf Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 19:58:09 +0000 Subject: [PATCH 1/6] fix(semantics): conform to the type a filter names by element, not by name A filter condition, import filter, filtered expose and classification compiled the type they name to its qualified name and judged conformance by that name, so a Type declared twice under one qualified name (the same package opened in two documents) admitted elements the other annotated. The compiled predicate now carries the element the name resolved to and conformance is decided through its specialization closure; the name alone decides only when no element resolved, or across copies of a library. Co-Authored-By: jason.han --- .../filter-conformance-by-element.fixed.md | 1 + docs/project/spec-compliance.md | 2 +- internal/semantic/semantics/filter.go | 75 ++++++++++----- .../semantics/filter_identity_test.go | 96 +++++++++++++++++++ internal/semantic/symbols/filter.go | 4 + .../model/filter_conformance_test.go | 72 ++++++++++++++ tests/testdata/filters/alias_import.sysml | 24 +++++ tests/testdata/filters/alias_member.sysml | 31 ++++++ tests/testdata/filters/namesake_a.sysml | 7 ++ tests/testdata/filters/namesake_b.sysml | 7 ++ 10 files changed, 292 insertions(+), 27 deletions(-) create mode 100644 changes/unreleased/filter-conformance-by-element.fixed.md create mode 100644 internal/semantic/semantics/filter_identity_test.go create mode 100644 internal/workspace/model/filter_conformance_test.go create mode 100644 tests/testdata/filters/alias_import.sysml create mode 100644 tests/testdata/filters/alias_member.sysml create mode 100644 tests/testdata/filters/namesake_a.sysml create mode 100644 tests/testdata/filters/namesake_b.sysml diff --git a/changes/unreleased/filter-conformance-by-element.fixed.md b/changes/unreleased/filter-conformance-by-element.fixed.md new file mode 100644 index 0000000000..ff8df42468 --- /dev/null +++ b/changes/unreleased/filter-conformance-by-element.fixed.md @@ -0,0 +1 @@ +- An element filter (`filter @T;`, `import P::*[@T]`, `expose X::**[@T]`) and a classification (`@T`, `@@T`) now test conformance against the Type element the name resolves to, through its specialization closure, rather than against the qualified name: a type named through an `alias` or a re-exporting import selects what the aliased Type annotates, and a distinct Type that shares the qualified name (the same package opened in another document) selects nothing it does not annotate. The name alone decides only when it resolves to no element, or across copies of a library document. diff --git a/docs/project/spec-compliance.md b/docs/project/spec-compliance.md index 579c99a115..19d8b45940 100644 --- a/docs/project/spec-compliance.md +++ b/docs/project/spec-compliance.md @@ -2260,7 +2260,7 @@ semantics layer over the conjugation parity of the typing/specialization chain. | `%render [text\|mermaid\|markdown\|dot\|plantuml\|d2\|csv\|tsv [palette]]` renders a declared or pseudo-view at the prompt; `sysml -render [-render-form
] [-render-palette ] [-o file]` renders one outside it, and `sysml -render-all [-render-form ]` writes every declared view separately. D2 writes only tree, interconnection, state, action, sequence, requirement, definition and package renderings; case and mixed views refuse it with a typed error | `repl/view.go` `Session.ViewRendering`, `renderPseudoView`, `Views`, `renderLines`, `viewRenderer` (a semantic model and resolver of its own over the session's symbol index, so no runtime is built); `model/selection.go` shares declaration-order view enumeration and targetless top-level selection across model and session paths; `repl/meta.go` (the `%render` arm, help entry), `repl/complete.go` (the form completion); `cmd/sysml/render.go` `runRender`, `runRenderAll`, `loadRenderingModel`, `writeArtifactFile` (one artifact on stdout or `-o`, or one file per declared view with render-all reporting on stderr); `cmd/sysml/main.go` (rendering modes are mutually exclusive with conversion and checks) | `repl/view_render_test.go` `TestRenderDefaultsToATree`, `TestRenderWritesMermaidWhenAskedFor`, `TestRenderOfATabularView`, `TestRenderOfAnUnknownNameReports`, `TestPseudoViewsRenderThroughTheSession`, `TestPseudoViewErrorsUseTheSessionLookupAndListAlternatives`, `TestTargetlessPseudoViewSpansLoadedDocuments`, `TestViewsListsSessionViewsInDeclarationOrder`, `TestRenderMisuseShowsUsage`, `TestRenderIsInHelpAndCompletion`, `TestRenderBetweenStepsDisturbsNothing`; `cmd/sysml/render_test.go` `TestRenderWritesTheArtifactOnStdout`, `TestRenderTextFormAndOutputFile`, `TestRenderOfATabularView`, `TestRenderAllWritesOneMachineArtifactPerView`, `TestRenderAllForcedTextUsesTxtAndUnboundedWidth`, `TestRenderAllWithoutViewsIsUnevaluable`, `TestRenderAllMutualExclusions`, `TestRenderOfATableAsDelimitedValues`, `TestRenderAllForcedDelimitedFormWritesTablesOnly`; `view/delimited_test.go` | ✅ Faithful (`%render` is a read: it materializes nothing, adds no object to the session, leaves the submission buffer alone and leaves an `%action`/`%state` debugging session stepping the same graph and objects — pinned by `TestRenderBetweenStepsDisturbsNothing`. A targeted pseudo-view uses the session's normal simple or qualified lookup; a targetless one renders loaded documents in order. `%view`'s report is unchanged) | | Diagram geometry in notation — an OpenSysML extension, not a specification rule: `DiagramLayout::Layout` (`x`, `y`, optional `width`, `height`, `collapsed`) positions the element it annotates, `DiagramLayout::Route` (`points`, a flattened `x0, y0, x1, y1, …` sequence, `ordered nonunique` since a segment repeats a coordinate) steers the edge whose declaring element it annotates, `DiagramLayout::Canvas` (`unit`, `width`, `height`) sizes a view's drawing surface; pixels, y down, origin top-left. For a (view, element) pair an `about` annotation declared in the view's body applies first, the element's own inline annotation second, none third; a view's second `about` annotation of one kind for one element is ignored in favor of the first. The geometry rides the rendering tree as values (`view.Node.Geometry`, `view.Edge.Route`, `view.Rendering.Canvas`) in every graph-shaped rendering — tree, interconnection, state, action, case, mixed — through `Render` and `RenderExposed` (no view, so element fallback only); the sequence diagram and the table carry none. The writers keep it visible: Mermaid as `%% canvas:`, `%% layout:` and `%% route:` comments after the header, text as `at (x, y)`, `size w×h`, `collapsed` and `via (x, y) …` suffixes, `opensysml/render` as optional `x`/`y`/`width`/`height`/`collapsed`/`route`/`canvas`; a model without annotations renders byte-identically | `libs/stdlib/OpenSysML Libraries/DiagramLayout.sysml`; `semantics/layout.go` `Model.LayoutSitesOf`, `LayoutOf`, `RouteOf`, `CanvasOf` (lazy, memoized, over the metadata side table `ElementMetadataOf`/`AnnotationSitesOf`); `semantics/masking.go` `directRedefinedFeatures` → `implicitMetadataBodyRedefinitions` (a metadata body's `points = (…)` is judged by the redefined `nonunique` feature); `ast/metadata.go` `DeclaredMetadata` (transition and succession bodies); `lower/state_graph.go` `StateGraph.DeclOf`, `lower/action_graph.go` (a succession body of annotations only); `view/geometry.go` `Point`, `Geometry`, `Canvas`, `Renderer.geometryOf`/`routeOf`/`canvasOf`, `view/place.go` `Renderer.Draws`/`DrawsAnywhere`, `view/clone.go`, `view/mermaid.go`, `view/text.go`; `lsp/render.go`; `passes/diagram_layout.go` `DiagramLayoutPass` at `LevelConstraint` (`diagram-layout-unplaced` warning for a `Layout`/`Route` on an element the judged rendering draws no node/edge for, `diagram-layout-value` error for odd `points` or a non-constant binding, `diagram-layout-canvas` error outside a view, `diagram-layout-duplicate` warning; source `constraint`) | `parse/view_layout_metadata.golden`; `semantics/layout_test.go` `TestLayoutOfPrefersTheViewBodyOverTheInlineAnnotation`, `TestLayoutOfPlacesAnElementInOneViewOnly`, `TestLayoutOfReadsAnAboutAnnotationNestedInTheViewBody`, `TestLayoutOfFirstViewLocalAnnotationWins`, `TestRouteOfReadsWaypointPairs`, `TestRouteOfReportsAnOddPointCount`, `TestLayoutOfReportsANonConstantBinding`, `TestCanvasOfReadsTheViewsCanvas`; `semantics/uniqueness_test.go` `TestIsUniqueInheritsIntoMetadataBody`; `view/geometry_test.go` (view-local over inline, one view of two, connection/transition/succession routes, canvas, writers, `RenderExposed`, clone, no-annotation byte identity) with `view/testdata/layout.{text,mermaid}.golden`; `lower/action_succession_test.go`; `lsp/render_test.go` `TestRenderCarriesLayoutGeometry`; `passes/diagram_layout_test.go` (one test per diagnostic); `cmd/sysml/check_test.go` `TestCheckReportsDiagramLayoutFindings`; `repl/view_layout_test.go` | ⚠️ Approximate (self-assessed: nothing in the specification to be faithful to — the notation is standard user-defined metadata, the meaning is OpenSysML's, proposed for standardization in `omg-issues.md`. No writer of this build lays a diagram out from the positions: Mermaid and text keep them visible, a layout-honoring form is pending, as is write-back from a graphical editor. Positions are absolute, so a container's children are not repositioned with it) | | A view's conformance to the viewpoints it satisfies is evaluated (SysML v2 7.24 Views and Viewpoints; a concern is a requirement, so its conditions are evaluated by the requirement engine) | `semantics/conformance.go` `Model.ViewConformance` (per satisfy claiming conformance — `IsViewpointSatisfy`, since a satisfy stating a subject asserts its requirement of that subject instead, as the stdlib `View` does: `Model.SatisfyTarget`, then every concern `Model.FramedConcernsOf` reports for the viewpoint, evaluated against the exposed elements the concern's subject admits — the view restates no framing, since `FramedConcernMember` is a requirement, concern and viewpoint body member and no view body one (8.3.20, 8.3.26) through the `ConcernEvaluator` the caller supplies — implemented in `repl/view.go` `concernEvaluator` over `runtime.Context.CheckSatisfactionOn`, so condition evaluation is not reimplemented); `passes/constraint.go` `checkViewSatisfyTarget` (code `view-satisfy-viewpoint`) | `semantics/conformance_test.go` (every concern the viewpoint frames evaluated, those it inherits included, an untyped framing, a framing naming a concern usage; a false condition; an unevaluable one; no admissible subject; an unresolved stakeholder; a satisfy inherited from a view def; a satisfy that is no viewpoint; determinism), `passes/constraint_test.go` `TestConstraintViewSatisfyNonViewpointRequirement`, `TestConstraintViewSatisfyViewpointOK`, `TestConstraintSatisfyOutsideAViewIsNotChecked`, `TestConstraintViewSatisfyRequirementBySubjectOK`, `conformance/viewpoint_framed_concern_conditions.sysml`, `viewpoint_concern_without_condition.sysml` | ⚠️ Approximate (the conditions are evaluated faithfully; the **verdict rules are tool-defined**, since SysML v2 leaves verification verdicts non-normative: a concern must hold of *every* exposed element its subject admits, and what cannot be evaluated — no condition, no admissible subject, an unresolved party, a framing whose concern reference does not resolve, a viewpoint framing no concern at all — is reported as unevaluable with a reason, never as a pass. **Adjudicated: left as found, deliberately.** This row states no name-resolution rule; its verdict rules are non-normative, so no referee can promote it, and its implementation is in `semantics/`, which this change did not own) | -| A filter condition is a model-level predicate over one candidate element, with the candidate as the implicit `self` (`@Safety`, `@@Safety`, `and`/`or`/`xor`/`not`/`implies`, and a comparison of an annotation's feature) | `semantics/filter.go` `Model.CompileElementFilter` / `EvalElementFilter` / `SatisfiesElementFilter` (compiled once per condition, memoized per candidate) over the annotations `semantics/annotations.go` collects — prefix metadata (`#Safety part def P;`), a `metadata` member of the element's body, and `metadata m about X;` or `@M about X;` — with conformance through `Model.AllSupertypes`, so `@Safety` matches a metadata type specializing `Safety`, and a metaclass classification (`@SysML::PartUsage`) reads the candidate's own kind | `semantics/filter_test.go`, `model/element_filter_test.go`, `semantics/cached_library_test.go` `TestNamespaceFilterOverALibraryIsTheSameParsedAndRestored` (the condition as parsed and the same condition compiled into an index-cache record classify alike), `TestAnnotationFactsOfALibraryElementSurviveTheCache` | ✅ Faithful (evaluated against a *symbol*, not a value: there is no instance at name-resolution time, which is what a model-level condition is defined over. A KerML declaration keyword implies its metaclass (`struct` → `Structure`, `class` → `Class`, `assoc` → `Association`, `datatype` → `DataType`, and the rest of KerML §8.2: `semantics/annotations.go` `kermlMetaclassNames`), and a metaclass *feature* (`Element::name`, `Type::isAbstract`, `Feature::isComposite`) is answered from the candidate element itself (`reflectiveFeatureValue`), from an annotation only when one binds it. A feature of a metaclass the candidate *is* an instance of but whose value no declaration gives is `ErrFilterUnevaluable` — reported through `filter-not-evaluable`, never decided false, which is the distinction that was dropping candidates and reporting their names unresolved (`kerml-examples` `Simple Tests/Filtering.kerml:38,47,48`, now clean, as the pinned `validate-kerml` is). Refereed: the pinned validators are silent on `testdata/passes/f93_element_filter.{kerml,sysml}` and on `Filtering.kerml`, and so are we (`passes/f93_element_filter_scope_test.go`). `@`/`@@` in the *runtime* value evaluator is the metadata-classification row above — a separate layer, `runtime/`, decided by this same compiled predicate) | +| A filter condition is a model-level predicate over one candidate element, with the candidate as the implicit `self` (`@Safety`, `@@Safety`, `and`/`or`/`xor`/`not`/`implies`, and a comparison of an annotation's feature) | `semantics/filter.go` `Model.CompileElementFilter` / `EvalElementFilter` / `SatisfiesElementFilter` (compiled once per condition, memoized per candidate) over the annotations `semantics/annotations.go` collects — prefix metadata (`#Safety part def P;`), a `metadata` member of the element's body, and `metadata m about X;` or `@M about X;` — with conformance against the Type element the condition's name resolves to (`FilterPredicate.Type`, through `Model.Conforms` over `Model.AllSupertypes`), so `@Safety` matches a metadata type specializing `Safety`, an `alias` of `Safety` or a re-exporting import of it selects the same elements, and a namesake `Safety` declared in another document selects none of them (the name alone decides only when it resolves to no element, or across copies of a library document, whose elements are one normative element); a metaclass classification (`@SysML::PartUsage`) reads the candidate's own kind | `semantics/filter_test.go`, `semantics/filter_identity_test.go`, `model/element_filter_test.go`, `model/filter_conformance_test.go` (`tests/testdata/filters/`: an alias member, a re-exporting import and two documents opening one `Meta::Safety`), `semantics/cached_library_test.go` `TestNamespaceFilterOverALibraryIsTheSameParsedAndRestored` (the condition as parsed and the same condition compiled into an index-cache record classify alike), `TestAnnotationFactsOfALibraryElementSurviveTheCache` | ✅ Faithful (evaluated against a *symbol*, not a value: there is no instance at name-resolution time, which is what a model-level condition is defined over. A KerML declaration keyword implies its metaclass (`struct` → `Structure`, `class` → `Class`, `assoc` → `Association`, `datatype` → `DataType`, and the rest of KerML §8.2: `semantics/annotations.go` `kermlMetaclassNames`), and a metaclass *feature* (`Element::name`, `Type::isAbstract`, `Feature::isComposite`) is answered from the candidate element itself (`reflectiveFeatureValue`), from an annotation only when one binds it. A feature of a metaclass the candidate *is* an instance of but whose value no declaration gives is `ErrFilterUnevaluable` — reported through `filter-not-evaluable`, never decided false, which is the distinction that was dropping candidates and reporting their names unresolved (`kerml-examples` `Simple Tests/Filtering.kerml:38,47,48`, now clean, as the pinned `validate-kerml` is). Refereed: the pinned validators are silent on `testdata/passes/f93_element_filter.{kerml,sysml}` and on `Filtering.kerml`, and so are we (`passes/f93_element_filter_scope_test.go`). `@`/`@@` in the *runtime* value evaluator is the metadata-classification row above — a separate layer, `runtime/`, decided by this same compiled predicate) | | A filter condition that is not boolean-valued, or that OpenSysML cannot evaluate | `passes/filter.go` `ElementFilterPass` at `LevelType`, over `semantics/filter.go` `Model.CheckElementFilter`; codes `filter-not-boolean` (error — a condition that is not a predicate can select nothing) and `filter-not-evaluable` (warning). Each fault is reported once, on the membership stating the condition (KerML §8.2.4), however many operands carry it | `passes/filter_test.go` `TestFilterNotBooleanIsReported`, `TestFilterNotEvaluableIsReported`, `TestFilterConditionsInTheSupportedSubsetAreClean` | ✅ Faithful (an unevaluable condition is **reported and not applied**, so the elements it would have selected from all stay visible: a verdict OpenSysML could not reach never silently hides model content — maintainer decision, recorded here because the spec does not say). A feature bound to nothing is *not* that case: reading it yields the empty sequence, which an ordering propagates and `==`/`!=` decide against any value (KerML `DataFunctions`, where an ordering takes `DataValue[1]` and equality `[0..1]`), so `@Safety and Safety::isMandatory == true` does not hold of an element annotated `@Safety` alone and does not surface it — a verdict, not a reported failure. An annotation inherits the values its metadata type declares, so a default the type gives the feature is what the comparison reads (`semantics/annotations.go` `addTypeDefaults`; `semantics/filter_test.go` `TestFilterUnsetAnnotationFeature`, `TestFilterAnnotationFeatureDefault`, `model/element_filter_test.go` `TestFilteredImportRejectsAnUnboundAnnotationFeature`) | | A KerML declaration specializes the library type its keyword implies (`class` → `Occurrences::Occurrence`, `struct` → `Objects::Object`, `assoc`/`association` → `Links::Link`, `behavior` → `Performances::Performance`, `function`/`predicate` → the matching evaluation, `interaction` → `Links::Link` as an association (KerML 1.1 §8.3.5.4; `Links::BinaryLink` with two ends), `metaclass` → `Metaobjects::Metaobject`, `datatype` → `Base::DataValue`, `classifier`/`type` → `Base::Anything`), so the library members it implies are inherited (KerML 1.0 §8.4.2) | `semantics/implicit.go` `implicitKerMLBases`, read by `implicitBase` when `source.KindOf` says the document is KerML (the same file-kind mechanism, no second notion) — a bare `feature` is left with no base rather than being given the SysML `attribute` one; `libs/record.go` (cache format 17) stores the semantic supertype edges so a restored library symbol inherits alike | `semantics/implicit_test.go:TestKerMLImplicitDefinitionBases`, `:TestSysMLImplicitDefinitionBasesRemainKindBased`, `semantics/cached_library_test.go:TestInheritedImplicitBaseIsTheSameParsedAndRestored`, `libs/loader_cache_test.go:TestLoaderCachePreservesRedefinitionMemberEdges` | ✅ Faithful, self-assessed (the keyword table covers the KerML §8.2 declaration kinds, and the implied *feature* bases §8.4.2 also defines are now modelled: `implicitKerMLFeatureBases` maps a feature keyword to the base feature it subsets — `step`/`behavior` → `Performances::performances`, `expr`/`function` → `Performances::evaluations`, `bool`/`predicate` → `booleanEvaluations`, `inv` → `trueEvaluations`, `class` → `Occurrences::occurrences`, `struct` → `Objects::objects`, `datatype` → `Base::dataValues`, `assoc`/`connector` → `Links::links`, `binding` → `Links::selfLinks`, `succession` → `Occurrences::happensBeforeLinks`, `interaction` → `Transfers::transfers`, `flow` → `Transfers::flowTransfers`, `metaclass` → `Metaobjects::metaobjects` — contributed as members, like the base usage, not as conformance. Every name in both tables is checked against what the bundled library declares (`semantics/w7a_library_bases_test.go:TestW7AImplicitBaseTablesNameLibraryElements`) and the member contribution by `implicit_test.go:TestW7AKerMLFeatureBaseContributesMembers`. **Evidence is KerML §8.4.2 plus these tests, not a referee**: an implicit base surfaces in no reference diagnostic — a probe declaring the keyword forms is accepted by `validate-kerml` and by us alike — so no matched run can settle it. The feature table is read for feature declarations only: a keyword that declares a *type* — `class`, `struct`, `assoc`, `behavior`, `predicate`, `interaction` — takes its base from the type table above and nothing from this one) | | A declared generalization suppresses the implicit one only when it already reaches that base, directly or indirectly (KerML 1.0 §8.4.2), so `struct MyWheel specializes Wheel` still specializes `Objects::Object` when `classifier Wheel;` reaches only `Base::Anything` | `semantics/implicit.go` `declaredGeneralizationReaches` (declared generalizations only, and cycle-guarded, so it cannot re-enter the closure the implicit base feeds), consulted for KerML documents; a SysML declaration keeps taking its supertypes from its own declaration | `semantics/implicit_test.go:TestImplicitBaseOfExplicitSupertypeIsTransitive`, `:TestSysMLImplicitBaseOfExplicitSupertypeIsTransitive` | ✅ Faithful, self-assessed (the rule is now the same in both languages and for a usage as for a definition: `implicitBase` consults `declaredGeneralizationReaches` alone, and `Model.DirectSupertypes` no longer skips the implicit base of a SysML usage that declares any generalization, so `part p :> Frames::Frame;` still specializes `Parts::Part` while `part q :> Parts::Part;` takes only what it declares. The implied feature base is suppressed by the same test. A metadata keyword is the one exception: it supplies the kind itself, so its `baseType` stands in for the kind's base (SysML v2 §7.27.4, `model/metadata_test.go:TestSemanticMetadataKeywordSubsetsBaseType`). Tests: `semantics/implicit_test.go:TestW7AKerMLFeatureBaseSuppressedWhenDeclared`, `:TestW7ASysMLSuppressionMatchesKerML`, `:TestImplicitBaseOfExplicitSupertypeIsTransitive`, `:TestSysMLImplicitBaseOfExplicitSupertypeIsTransitive`. **Evidence is KerML §8.4.2 plus these tests, not a referee** — suppression is unobservable in a reference diagnostic; what the move was checked against is the corpus ratchet, which does not change for any file because of it) | diff --git a/internal/semantic/semantics/filter.go b/internal/semantic/semantics/filter.go index 91cd3885bb..e8d7db6eed 100644 --- a/internal/semantic/semantics/filter.go +++ b/internal/semantic/semantics/filter.go @@ -185,7 +185,7 @@ func (m *Model) compileConstructor(scope *symbols.Scope, e *ast.ConstructorExpr) if e.Type == nil { return unsupported(span, "the constructor names no type") } - typeFQN, ok := m.resolveFQN(scope, e.Type) + _, typeFQN, ok := m.resolveType(scope, e.Type) if !ok { return unsupported(span, fmt.Sprintf("the constructed type %s does not resolve", qnText(e.Type))) } @@ -265,11 +265,11 @@ func (m *Model) classificationPredicate(scope *symbols.Scope, e *ast.OperatorExp if e.TypeRef == nil { return unsupported(span, fmt.Sprintf("`%s` names no type", e.Operator)) } - typeFQN, ok := m.resolveFQN(scope, e.TypeRef) + typ, typeFQN, ok := m.resolveType(scope, e.TypeRef) if !ok { return unsupported(span, fmt.Sprintf("the metadata type %s does not resolve", qnText(e.TypeRef))) } - return &symbols.FilterPredicate{Op: op, TypeFQN: typeFQN, Span: span} + return &symbols.FilterPredicate{Op: op, TypeFQN: typeFQN, Type: typ, Span: span} } // EvalClassification evaluates the classification `@T`/`@@T` that e writes @@ -334,30 +334,32 @@ func (m *Model) compileFeatureChain(scope *symbols.Scope, e *ast.FeatureChainExp if operand.TargetType == nil { return unsupported(span, "the cast names no type") } - typeFQN, ok := m.resolveFQN(scope, operand.TargetType) + typ, typeFQN, ok := m.resolveType(scope, operand.TargetType) if !ok { return unsupported(span, fmt.Sprintf("the metadata type %s does not resolve", qnText(operand.TargetType))) } return &symbols.FilterPredicate{ Op: symbols.FilterFeature, TypeFQN: typeFQN, + Type: typ, Feature: feature, - ResultType: m.filterMemberType(typeFQN, feature), + ResultType: m.filterMemberType(typ, feature), Span: span, } case *ast.OperatorExpr: // `self.f` and `(self as T).f` are written this way too; only the // annotation form carries a metadata type to read the feature from. if operand.Operator == ast.OpAs && operand.TypeRef != nil { - typeFQN, ok := m.resolveFQN(scope, operand.TypeRef) + typ, typeFQN, ok := m.resolveType(scope, operand.TypeRef) if !ok { return unsupported(span, fmt.Sprintf("the metadata type %s does not resolve", qnText(operand.TypeRef))) } return &symbols.FilterPredicate{ Op: symbols.FilterFeature, TypeFQN: typeFQN, + Type: typ, Feature: feature, - ResultType: m.filterMemberType(typeFQN, feature), + ResultType: m.filterMemberType(typ, feature), Span: span, } } @@ -459,6 +461,7 @@ func (m *Model) compileReference(scope *symbols.Scope, qn *ast.QualifiedName, sp return &symbols.FilterPredicate{ Op: symbols.FilterFeature, TypeFQN: ownerFQN, + Type: owner, Feature: simpleSymbolName(sym), ResultType: sym, Span: span, @@ -479,8 +482,7 @@ func (m *Model) compileReference(scope *symbols.Scope, qn *ast.QualifiedName, sp } } -func (m *Model) filterMemberType(typeFQN, feature string) *symbols.Symbol { - typ := m.typeByFQN(typeFQN) +func (m *Model) filterMemberType(typ *symbols.Symbol, feature string) *symbols.Symbol { if typ == nil { return nil } @@ -608,11 +610,8 @@ func (m *Model) evalPredicate(p *symbols.FilterPredicate, cand *symbols.Symbol) case symbols.FilterConst: return p.Value, nil - case symbols.FilterClassify: - return boolValue(m.annotatedBy(cand, p.TypeFQN)), nil - - case symbols.FilterMetaClassify: - return boolValue(m.annotatedBy(cand, p.TypeFQN)), nil + case symbols.FilterClassify, symbols.FilterMetaClassify: + return boolValue(m.annotatedByType(cand, m.predicateType(p), p.TypeFQN)), nil case symbols.FilterFeature: return m.featureValue(cand, p) @@ -884,7 +883,7 @@ func candidateName(cand *symbols.Symbol) string { // read from an annotation the candidate does not carry, has an empty value // sequence, which leaves the comparison reading it false rather than unevaluable. func (m *Model) annotationFeatureValue(cand *symbols.Symbol, p *symbols.FilterPredicate) (symbols.FilterValue, error) { - typ := m.typeByFQN(p.TypeFQN) + typ := m.predicateType(p) for _, a := range m.annotationsOf(cand) { if !m.annotationConforms(a, typ, p.TypeFQN) { continue @@ -912,7 +911,12 @@ func (m *Model) annotationFeatureValue(cand *symbols.Symbol, p *symbols.FilterPr // select the part usages among the candidates. `@@T` tests the same metadata // (KerML 1.0 §7.4.9.2: its operand is `x.metadata`, annotations then metaobject). func (m *Model) annotatedBy(cand *symbols.Symbol, typeFQN string) bool { - typ := m.typeByFQN(typeFQN) + return m.annotatedByType(cand, m.typeByFQN(typeFQN), typeFQN) +} + +// annotatedByType is annotatedBy for a type already resolved to its element, +// which a compiled condition carries; typ is nil when the name resolved to none. +func (m *Model) annotatedByType(cand, typ *symbols.Symbol, typeFQN string) bool { for _, a := range m.annotationsOf(cand) { if m.annotationConforms(a, typ, typeFQN) { return true @@ -943,13 +947,32 @@ func (m *Model) MetaclassConforms(cand *symbols.Symbol, typeFQN string) bool { } // annotationConforms reports whether an annotation's metadata type conforms to -// the type a condition names. The types are compared as symbols where both are -// indexed, and by qualified name otherwise. +// the type a condition names: the element the name resolved to, through its +// specialization closure, so an alias selects the same type and a namesake +// does not. The name alone decides when it resolved to no element, and across +// copies of a library, whose elements are the one normative element. func (m *Model) annotationConforms(a annotation, typ *symbols.Symbol, typeFQN string) bool { - if a.typ != nil && typ != nil && m.Conforms(a.typ, typ) { - return true + if a.typ == nil { + return false + } + if typ == nil { + return m.conformsByName(a.typ, typeFQN) } - return a.typ != nil && m.conformsByName(a.typ, typeFQN) + return m.Conforms(a.typ, typ) || (m.isLibraryElement(typ) && m.conformsByName(a.typ, typeFQN)) +} + +// predicateType is the type a compiled condition names: the element it +// resolved to, or the first declared under the name when only that is known. +func (m *Model) predicateType(p *symbols.FilterPredicate) *symbols.Symbol { + if p.Type != nil { + return p.Type + } + return m.typeByFQN(p.TypeFQN) +} + +// isLibraryElement reports whether sym is declared by a library document. +func (m *Model) isLibraryElement(sym *symbols.Symbol) bool { + return sym != nil && m.resolver != nil && m.resolver.Index() != nil && m.resolver.Index().IsLibraryDocument(sym.DocName) } // indexedElement returns the symbol the index holds for sym's element, which is @@ -1455,15 +1478,15 @@ func isSelfReference(n ast.Node) bool { return ref.Name.Parts[0].Text == "self" } -// resolveFQN resolves a qualified name written in scope to the name the element -// it names is indexed under. -func (m *Model) resolveFQN(scope *symbols.Scope, qn *ast.QualifiedName) (string, bool) { +// resolveType resolves a qualified name written in scope to the element it +// names and the name that element is indexed under. +func (m *Model) resolveType(scope *symbols.Scope, qn *ast.QualifiedName) (*symbols.Symbol, string, bool) { sym, ok := m.resolver.ResolveQualified(scope, qn) if !ok || sym == nil { - return "", false + return nil, "", false } fqn := m.fqnOf(sym) - return fqn, fqn != "" + return sym, fqn, fqn != "" } // spanOf is a node's span, or the zero span for a missing node. diff --git a/internal/semantic/semantics/filter_identity_test.go b/internal/semantic/semantics/filter_identity_test.go new file mode 100644 index 0000000000..9dfdf8d9dd --- /dev/null +++ b/internal/semantic/semantics/filter_identity_test.go @@ -0,0 +1,96 @@ +package semantics + +import ( + "testing" + + "github.com/Open-MBEE/OpenSysML/internal/semantic/resolve" + "github.com/Open-MBEE/OpenSysML/internal/semantic/symbols" + "github.com/Open-MBEE/OpenSysML/internal/syntax/parser" + "github.com/Open-MBEE/OpenSysML/internal/syntax/source" +) + +// filterIn parses cond as a filter condition written at the root of the named +// document of an index the model is built over. +func filterIn(t *testing.T, m *Model, doc, cond string) symbols.ElementFilter { + t.Helper() + p := parser.New(source.New("", []byte(cond))) + expr := p.ParseExpression() + if expr == nil || len(p.Diagnostics) != 0 { + t.Fatalf("failed to parse filter condition %q: %v", cond, p.Diagnostics) + } + root := m.resolver.Index().DocumentRoot(doc) + if root == nil { + t.Fatalf("%s has no root scope", doc) + } + return symbols.ElementFilter{Expr: expr, Scope: root, Span: expr.Span()} +} + +// verdict evaluates a condition for one element, failing on an unevaluable one. +func verdict(t *testing.T, m *Model, f symbols.ElementFilter, cand *symbols.Symbol) bool { + t.Helper() + got, err := m.EvalElementFilter(f, cand) + if err != nil { + t.Fatalf("unexpected error evaluating the condition for %s: %v", cand.Name, err) + } + return got +} + +// A condition naming a metadata type through an alias is compiled to the Type +// the alias names, so it selects what that Type annotates (KerML 8.3.2.3). +func TestFilterThroughAnAliasNamesTheAliasedType(t *testing.T) { + m, root := buildModel(t, ` + metadata def Safety; + metadata def CrashSafety :> Safety; + alias S for Safety; + #Safety part belt; + #CrashSafety part airBag; + part radio; + `) + f := symbols.ElementFilter{Scope: root} + f.Expr = filterIn(t, m, "t.sysml", "@S").Expr + f.Span = f.Expr.Span() + pred := m.CompileElementFilter(f) + if pred == nil || pred.Op != symbols.FilterClassify || !symbols.SameElement(pred.Type, sym(t, root, "Safety")) { + t.Fatalf("@S must compile to a classification by the Safety element, got %+v", pred) + } + for name, want := range map[string]bool{"belt": true, "airBag": true, "radio": false} { + if got := verdict(t, m, f, sym(t, root, name)); got != want { + t.Errorf("@S for %s = %v, want %v", name, got, want) + } + } +} + +// Two documents each opening Meta::Safety declare two Types under one qualified +// name; a condition names the one its own document resolves to, so an element +// the other annotates does not conform, and no name is built to decide it. +func TestFilterNamingANamesakeTypeSelectsByElement(t *testing.T) { + idx := symbols.NewIndex() + addTestDoc(t, idx, "a.sysml", `package Meta { metadata def Safety; } + package LibA { #Meta::Safety part belt; }`) + addTestDoc(t, idx, "b.sysml", `package Meta { metadata def Safety; }`) + idx.ExpandWildcardImports() + r := resolve.New(idx) + m := NewModel(r) + r.SetModel(m) + belt := idx.LookupQualified("LibA::belt")[0] + + own := filterIn(t, m, "a.sysml", "@Meta::Safety") + other := filterIn(t, m, "b.sysml", "@Meta::Safety") + if !verdict(t, m, own, belt) { + t.Fatalf("belt must conform to the Safety that annotates it") + } + if verdict(t, m, other, belt) { + t.Fatalf("belt must not conform to the other document's namesake Safety") + } + ownType, otherType := m.CompileElementFilter(own).Type, m.CompileElementFilter(other).Type + if ownType == nil || otherType == nil || symbols.SameElement(ownType, otherType) { + t.Fatalf("the two conditions must name two distinct elements, got %v and %v", ownType, otherType) + } + for _, typ := range []*symbols.Symbol{ownType, otherType} { + for _, a := range m.annotationsOf(belt) { + if allocs := testing.AllocsPerRun(20, func() { m.annotationConforms(a, typ, "Meta::Safety") }); allocs != 0 { + t.Errorf("a repeated conformance check against %s allocates %.0f objects, want 0", typ.DocName, allocs) + } + } + } +} diff --git a/internal/semantic/symbols/filter.go b/internal/semantic/symbols/filter.go index bf650795d8..18f381a85f 100644 --- a/internal/semantic/symbols/filter.go +++ b/internal/semantic/symbols/filter.go @@ -99,6 +99,10 @@ type FilterPredicate struct { // annotation a feature is read from. TypeFQN string + // Type is the element TypeFQN resolved to when the condition was compiled, + // so namesakes of it are told apart; nil when only the name is known. + Type *Symbol + // Feature is the annotation feature FilterFeature reads. Feature string diff --git a/internal/workspace/model/filter_conformance_test.go b/internal/workspace/model/filter_conformance_test.go new file mode 100644 index 0000000000..cb3e564e75 --- /dev/null +++ b/internal/workspace/model/filter_conformance_test.go @@ -0,0 +1,72 @@ +package model + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +// openFilterFixtures opens the named fixtures under tests/testdata/filters as +// one workspace and returns each document's diagnostic messages by name. +func openFilterFixtures(t *testing.T, names ...string) map[string][]string { + t.Helper() + ws := NewWorkspace() + for _, name := range names { + data, err := os.ReadFile(filepath.Join("..", "..", "..", "tests", "testdata", "filters", name)) + if err != nil { + t.Fatalf("read fixture: %v", err) + } + ws.Open("file:///"+name, []byte(data), 1) + } + out := map[string][]string{} + for _, name := range names { + for _, d := range ws.Diagnostics("file:///" + name) { + out[name] = append(out[name], d.Message) + } + } + return out +} + +// unresolvedNames is the names the messages report as unresolved references. +func unresolvedNames(msgs []string) []string { + var out []string + for _, msg := range msgs { + if _, after, ok := strings.Cut(msg, "unresolved reference: "); ok { + out = append(out, strings.Fields(after)[0]) + } + } + return out +} + +// A filter names a Type element, not a spelling: an `alias` member of it and an +// import that surfaces it under another namespace select what the Type +// annotates, through an import filter, a `filter` member and a filtered expose +// alike, and reject the rest (KerML 8.3.2.3, SysML v2 7.4.4). +func TestFilterThroughAnAliasSelectsByTheAliasedType(t *testing.T) { + for name, surfaces := range map[string]int{"alias_member.sysml": 3, "alias_import.sysml": 2} { + got := openFilterFixtures(t, name)[name] + unresolved := unresolvedNames(got) + if len(got) != surfaces || len(unresolved) != surfaces { + t.Fatalf("%s: want %d diagnostics, each an unresolved reference, got %v", name, surfaces, got) + } + for _, n := range unresolved { + if n != "radio" { + t.Errorf("%s: the alias must admit belt and reject radio only, got unresolved %s", name, n) + } + } + } +} + +// Two documents each opening `Meta::Safety` declare two Types that share a +// qualified name; a filter naming one selects nothing the other annotates, while +// the filter written beside the annotating declaration still selects it. +func TestFilterNamingANamesakeTypeDoesNotConform(t *testing.T) { + got := openFilterFixtures(t, "namesake_a.sysml", "namesake_b.sysml") + if unresolved := unresolvedNames(got["namesake_a.sysml"]); len(unresolved) != 0 { + t.Fatalf("the filter naming the annotating Safety must admit belt, got %v", got["namesake_a.sysml"]) + } + if unresolved := unresolvedNames(got["namesake_b.sysml"]); len(unresolved) != 1 || unresolved[0] != "belt" { + t.Fatalf("the filter naming the other document's Safety must reject belt, got %v", got["namesake_b.sysml"]) + } +} diff --git a/tests/testdata/filters/alias_import.sysml b/tests/testdata/filters/alias_import.sysml new file mode 100644 index 0000000000..671bd4845a --- /dev/null +++ b/tests/testdata/filters/alias_import.sysml @@ -0,0 +1,24 @@ +// A filter naming a metadata type through a re-exporting import selects the +// elements the imported type annotates: the import surfaces the same Type. +package Meta { + metadata def Safety; + metadata def Comfort; +} +package Lib { + #Meta::Safety part belt; + #Meta::Comfort part radio; +} +package Reexport { + public import Meta::Safety; +} +package ByImportFilter { + private import Lib::*[@Reexport::Safety]; + part a :> belt; + part b :> radio; +} +package ByFilterMember { + private import Lib::*; + filter @Reexport::Safety; + part a :> belt; + part b :> radio; +} diff --git a/tests/testdata/filters/alias_member.sysml b/tests/testdata/filters/alias_member.sysml new file mode 100644 index 0000000000..ef0dcbe1f8 --- /dev/null +++ b/tests/testdata/filters/alias_member.sysml @@ -0,0 +1,31 @@ +// A filter naming a metadata type through an `alias` member selects the +// elements the aliased type annotates: the alias is another name for one Type. +package Meta { + metadata def Safety; + metadata def Comfort; +} +package Lib { + #Meta::Safety part belt; + #Meta::Comfort part radio; +} +package Names { + alias S for Meta::Safety; +} +package ByImportFilter { + private import Lib::*[@Names::S]; + part a :> belt; + part b :> radio; +} +package ByFilterMember { + private import Lib::*; + filter @Names::S; + part a :> belt; + part b :> radio; +} +package ByExpose { + view v { + expose Lib::**[@Names::S]; + part a :> belt; + part b :> radio; + } +} diff --git a/tests/testdata/filters/namesake_a.sysml b/tests/testdata/filters/namesake_a.sysml new file mode 100644 index 0000000000..7cfcc2ea8f --- /dev/null +++ b/tests/testdata/filters/namesake_a.sysml @@ -0,0 +1,7 @@ +// This document's Meta::Safety annotates belt; a filter written here selects it. +package Meta { metadata def Safety; } +package LibA { #Meta::Safety part belt; } +package ClientA { + private import LibA::*[@Meta::Safety]; + part a :> belt; +} diff --git a/tests/testdata/filters/namesake_b.sysml b/tests/testdata/filters/namesake_b.sysml new file mode 100644 index 0000000000..9fef1c67a4 --- /dev/null +++ b/tests/testdata/filters/namesake_b.sysml @@ -0,0 +1,7 @@ +// This document opens a Meta::Safety of its own, a distinct Type with the same +// qualified name; a filter naming it does not select what the other annotates. +package Meta { metadata def Safety; } +package ClientB { + private import LibA::*[@Meta::Safety]; + part a :> belt; +} From 6186b2f951ca87dfbec84016966088a1d544f83c Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 20:21:16 +0000 Subject: [PATCH 2/6] test(filters): give each alias fixture its own package names so a shared root does not collide Co-Authored-By: jason.han --- tests/testdata/filters/alias_import.sysml | 22 +++++++++---------- tests/testdata/filters/alias_member.sysml | 26 +++++++++++------------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/testdata/filters/alias_import.sysml b/tests/testdata/filters/alias_import.sysml index 671bd4845a..9982b6d8ca 100644 --- a/tests/testdata/filters/alias_import.sysml +++ b/tests/testdata/filters/alias_import.sysml @@ -1,24 +1,24 @@ // A filter naming a metadata type through a re-exporting import selects the // elements the imported type annotates: the import surfaces the same Type. -package Meta { +package ReexportMeta { metadata def Safety; metadata def Comfort; } -package Lib { - #Meta::Safety part belt; - #Meta::Comfort part radio; +package ReexportLib { + #ReexportMeta::Safety part belt; + #ReexportMeta::Comfort part radio; } -package Reexport { - public import Meta::Safety; +package ReexportNames { + public import ReexportMeta::Safety; } -package ByImportFilter { - private import Lib::*[@Reexport::Safety]; +package ReexportByImportFilter { + private import ReexportLib::*[@ReexportNames::Safety]; part a :> belt; part b :> radio; } -package ByFilterMember { - private import Lib::*; - filter @Reexport::Safety; +package ReexportByFilterMember { + private import ReexportLib::*; + filter @ReexportNames::Safety; part a :> belt; part b :> radio; } diff --git a/tests/testdata/filters/alias_member.sysml b/tests/testdata/filters/alias_member.sysml index ef0dcbe1f8..a90028da25 100644 --- a/tests/testdata/filters/alias_member.sysml +++ b/tests/testdata/filters/alias_member.sysml @@ -1,30 +1,30 @@ // A filter naming a metadata type through an `alias` member selects the // elements the aliased type annotates: the alias is another name for one Type. -package Meta { +package AliasMeta { metadata def Safety; metadata def Comfort; } -package Lib { - #Meta::Safety part belt; - #Meta::Comfort part radio; +package AliasLib { + #AliasMeta::Safety part belt; + #AliasMeta::Comfort part radio; } -package Names { - alias S for Meta::Safety; +package AliasNames { + alias S for AliasMeta::Safety; } -package ByImportFilter { - private import Lib::*[@Names::S]; +package AliasByImportFilter { + private import AliasLib::*[@AliasNames::S]; part a :> belt; part b :> radio; } -package ByFilterMember { - private import Lib::*; - filter @Names::S; +package AliasByFilterMember { + private import AliasLib::*; + filter @AliasNames::S; part a :> belt; part b :> radio; } -package ByExpose { +package AliasByExpose { view v { - expose Lib::**[@Names::S]; + expose AliasLib::**[@AliasNames::S]; part a :> belt; part b :> radio; } From 4450602f9caf2b363f6aa6519b23f6e9729eeec6 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 20:21:16 +0000 Subject: [PATCH 3/6] docs(pilot-differential): record the four filter-conformance fixtures in the baseline Co-Authored-By: jason.han --- .../testing-pilot-corpora-gate/SKILL.md | 2 +- .../testing-pilot-differential/SKILL.md | 8 +- .../testing-pilot-execution-referee/SKILL.md | 2 +- .agents/skills/testing-pilot-xpect/SKILL.md | 2 +- README.md | 6 +- docs/internals/architecture.md | 4 +- docs/project/pilot-differential-baseline.json | 96 +++++++++++++++---- docs/project/pilot-differential.md | 12 +-- 8 files changed, 96 insertions(+), 36 deletions(-) diff --git a/.agents/skills/testing-pilot-corpora-gate/SKILL.md b/.agents/skills/testing-pilot-corpora-gate/SKILL.md index 78106039d3..5e088108cb 100644 --- a/.agents/skills/testing-pilot-corpora-gate/SKILL.md +++ b/.agents/skills/testing-pilot-corpora-gate/SKILL.md @@ -183,7 +183,7 @@ gate's own helpers are package-private but reusable (`pilotCorporaGate.files(t)` `actionlint`, `shellcheck`, `python3 scripts/check-doc-links.py`, `gofmt`, `go vet`, `go run -C tools ./cmd/pilot-diff` (validators pre-downloaded; ~4min, prints e.g. -the headline the committed baseline holds — `912 file(s), 510 fully agreeing; 1085 agreed +the headline the committed baseline holds — `916 file(s), 514 fully agreeing; 1091 agreed diagnostic(s), 366 only ours, 2445 only the pilot's` at the `2026-08` pin, so read it from `docs/project/pilot-differential-baseline.json` rather than from this line) and `make lint` (staticcheck+gosec, ~2min) all work. There is **no** `yamllint` and **no** diff --git a/.agents/skills/testing-pilot-differential/SKILL.md b/.agents/skills/testing-pilot-differential/SKILL.md index 0e55f41fbb..6fbf705f08 100644 --- a/.agents/skills/testing-pilot-differential/SKILL.md +++ b/.agents/skills/testing-pilot-differential/SKILL.md @@ -27,8 +27,8 @@ GNU-format diagnostics **relative to `--root`**. Consequences for testing: inputs keep its warning at `delta-v-budget.sysml:93`), then the unbounded-literal typing round (`passes/literal_infinity.sysml`: `*` bound to a Boolean, a String, a part and an enumeration is our `binding-connector-type-conformance` error where the pilot warns, four severity-only pairs, and - its `Integer[2] = *` count error is one only-ours row): `912 file(s), 510 fully agreeing; 1085 agreed, - 366 only ours, 2445 only the pilot's`, JSON totals `openSysMLDiagnostics 1462 / pilotDiagnostics 3541 / + its `Integer[2] = *` count error is one only-ours row): `916 file(s), 514 fully agreeing; 1091 agreed, + 366 only ours, 2445 only the pilot's`, JSON totals `openSysMLDiagnostics 1468 / pilotDiagnostics 3547 / severityMismatch 11`; the two only-ours rows the multiplicity rule added are the expected `action-step-multiplicity-not-fixed` warnings on `training/18. Action Performance/Action Performance Example.sysml:10` and `pilot-examples/Camera Example/Camera.sysml:4`. ~2 min wall, byte-identical across runs *and* after a from-scratch rebuild of @@ -152,8 +152,8 @@ warning (the `[1]` `RocketEquation` inputs still produce the warning at `action-step-multiplicity-not-fixed` warnings on `takePhoto[*]` in the training corpus and `takePicture[*]` in `Camera Example/Camera.sysml`, and the view concern framing round retired the six view-body `frame` `syntax` rows on `examples`, and the unbounded-literal typing round added -`passes/literal_infinity.sysml` (four severity-only pairs, one only-ours count error); a live run gives `912 file(s), 510 fully -agreeing; 1085 agreed, 366 only ours, 2445 only the pilot's`, byte-identical to the committed baseline, and +`passes/literal_infinity.sysml` (four severity-only pairs, one only-ours count error); a live run gives `916 file(s), 514 fully +agreeing; 1091 agreed, 366 only ours, 2445 only the pilot's`, byte-identical to the committed baseline, and `docs/project/pilot-differential.md`'s "Results" table matches. The prior rebaseline, when the Legend of the Red Dragon example left for its own repository, gave `380 file(s), 344 fully agreeing; 38 agreed, 42 only ours, 1614 only the pilot's`. diff --git a/.agents/skills/testing-pilot-execution-referee/SKILL.md b/.agents/skills/testing-pilot-execution-referee/SKILL.md index a15c3101a1..424a122c7d 100644 --- a/.agents/skills/testing-pilot-execution-referee/SKILL.md +++ b/.agents/skills/testing-pilot-execution-referee/SKILL.md @@ -154,7 +154,7 @@ pilot answers the representation's own. See `pilot-exec-diff: :: model no/such/model.sysml: stat : no such file or directory`. - **Additivity.** `go run -C tools ./cmd/pilot-diff` must still print the headline the - committed baseline holds (`912 file(s), 510 fully agreeing; 1085 agreed + committed baseline holds (`916 file(s), 514 fully agreeing; 1091 agreed diagnostic(s), 366 only ours, 2445 only the pilot's` at the `2026-08` pin — read it from the baseline JSON, not from this line, since each fix round moves it) and `jq -S` diff clean against `docs/project/pilot-differential-baseline.json`; `git status --porcelain` diff --git a/.agents/skills/testing-pilot-xpect/SKILL.md b/.agents/skills/testing-pilot-xpect/SKILL.md index 52bac539ee..9126b74aa2 100644 --- a/.agents/skills/testing-pilot-xpect/SKILL.md +++ b/.agents/skills/testing-pilot-xpect/SKILL.md @@ -423,7 +423,7 @@ census in `w5c_census_test.go` is live two ways: perturb one pinned triple (e.g. ## Regression neighbour `go run -C tools ./cmd/pilot-diff` (~1m12s) must still print the headline the *committed* baseline holds — -at the `2026-08` pin that is `912 file(s), 510 fully agreeing; 1085 agreed diagnostic(s), 366 +at the `2026-08` pin that is `916 file(s), 514 fully agreeing; 1091 agreed diagnostic(s), 366 only ours, 2445 only the pilot's`. Read the number out of `docs/project/pilot-differential-baseline.json` rather than trusting this line, since a landing fix round moves it. When the baseline is itself stale (it was at `19a3ce03`, holding 273 / 281 / 317), a diff --git a/README.md b/README.md index 79dab60ca0..c6ec19e706 100644 --- a/README.md +++ b/README.md @@ -346,11 +346,11 @@ The project is under active development, with the core infrastructure operationa **Measured against the pinned reference** (`PILOT_TAG=2026-08`, artifact `0.62.0`). Every number below is generated by `make docs-counts` from the committed baselines and gated; none of them is typed in by hand. -- **Corpus agreement:** 510 of 912 files agree diagnostic-by-diagnostic; 366 diagnostics are ours alone and 2445 the reference's alone, and the first number must be read by root: the aggregate includes candidate conformance differences, intentional execution-scope warnings on reference corpora and diagnostics from our own examples ([differential](docs/project/pilot-differential.md), `go run -C tools ./cmd/pilot-diff`). +- **Corpus agreement:** 514 of 916 files agree diagnostic-by-diagnostic; 366 diagnostics are ours alone and 2445 the reference's alone, and the first number must be read by root: the aggregate includes candidate conformance differences, intentional execution-scope warnings on reference corpora and diagnostics from our own examples ([differential](docs/project/pilot-differential.md), `go run -C tools ./cmd/pilot-diff`). - **Declared-diagnostic silence:** of the 512 declared `errors` rows in the reference's own Xpect suites, we report nothing for 0. 245 we report word-for-word; 248 wording-only and 7 location-only differences are agreement in substance and are not counted as gaps; 0 more we report as a warning and 2 elsewhere in the file ([Xpect oracle](docs/project/pilot-xpect.md), `go run -C tools ./cmd/pilot-xpect`). - **Scope agreement:** 230 of 230 declared scope assertions match exactly (same source). - **Permissiveness gaps:** of 334 invalid models we wrote ourselves, the reference rejects 4 that we accept by default, and 319 both reject; 4 further cases agree only when we are asked strictly. We authored every one of these cases ourselves, so the denominator measures the reach of our own corpus and not our conformance; agreement reached only under an opt-in strict mode is weaker evidence than agreement by default ([rejection oracle](docs/project/pilot-rejection.md), `go run -C tools ./cmd/pilot-reject`). -- **Declared errata:** the registry declares 16 defect(s) in the published reference material — 9 with a specification-derived correction, 7 documented without one, since no intended reading can be inferred ([OMG issues](docs/project/omg-issues.md), `tools/oracle/errata`). Every figure above is as published and stays the conformance statement; running the same oracles over the corrected text instead reports 511 of 912 files agreeing, 365 diagnostics ours alone and 2445 the reference's alone, 0 declared rows we are silent on, and 0 of 334 authored cases the reference alone rejects. The corrected figures are diagnostic only: an erratum never reclassifies a divergence category, and the published corpus is never edited. +- **Declared errata:** the registry declares 16 defect(s) in the published reference material — 9 with a specification-derived correction, 7 documented without one, since no intended reading can be inferred ([OMG issues](docs/project/omg-issues.md), `tools/oracle/errata`). Every figure above is as published and stays the conformance statement; running the same oracles over the corrected text instead reports 515 of 916 files agreeing, 365 diagnostics ours alone and 2445 the reference's alone, 0 declared rows we are silent on, and 0 of 334 authored cases the reference alone rejects. The corrected figures are diagnostic only: an erratum never reclassifies a divergence category, and the published corpus is never edited. - **Self-assessed surface:** the action, state-machine and classifier-behavior rows have no external referee at all — the four refereed figures above cannot see them, because the pinned artifact evaluates expressions but executes neither actions nor state machines. [Spec compliance](docs/project/spec-compliance.md) counts them. What these numbers cannot show: the OMG corpora are demonstrations rather than an official conformance suite; the differential is one-directional, comparing the diagnostics the two implementations report on the same files; the Xpect suites are the pilot authors' test intent rather than a certification oracle; and none of these is a percentage of the specification — no global compliance figure is claimed anywhere. @@ -362,7 +362,7 @@ What these numbers cannot show: the OMG corpora are demonstrations rather than a **Test coverage:** top-level `Test` functions (counted from the `_test.go` files, as `go test ./...` runs them) covering parsers, semantics, runtime (actions, states, instances, operators, validation), behind golden ASTs, negatives, execution conformance cases, golden traces, runtime robustness cases and gRPC conformance and robustness cases. The figures are counted from the tree when the documentation site is built into the test inventory of [spec compliance](docs/project/spec-compliance.md), never committed, so a branch adding a test does not rewrite this page. A test skips only for want of something the run did not provide, and says what: the held-image round trip declines a conformance case that creates no instance, a few gate on a PDF or Mermaid toolchain, a pinned pilot artifact, the PSSM suite, a locale, a case-insensitive filesystem or a live Flexo stack, and the OMG corpus gates skip until the corpora are downloaded unless asked to fail. **Parser coverage:** 110/110 bundled library files parse cleanly — the 94 official SysML v2 standard library files and the 16 non-normative OpenSysML extensions: `OpenSysML Libraries/AnalysisRecords.sysml`, `DiagramLayout.sysml`, `DocumentQueries.sysml`, `IdentityMetadata.sysml`, `MOSA.sysml`, `MigrationMetadata.sysml`, `OOSEM.sysml`, `OpenSysMLMathFunctions.kerml`, `OpenSysMLRenderings.sysml`, `RandomFunctions.kerml`, `Simulation.sysml`, `StateActivity.kerml`, `StateMachines.sysml`, `StateSpaceIntegration.sysml`, `Stochastic.sysml` and `SysMLValidation.sysml`. Conformance verified by [stdlib_conformance_test.go](internal/workspace/libs/stdlib_conformance_test.go). Grammar reference: [OMG Xtext grammar](https://github.com/Systems-Modeling/SysML-v2-Pilot-Implementation/tree/master/org.omg.kerml.xtext/src/org/omg/kerml/xtext). **Behavioral execution:** Calc/constraint/requirement/satisfy functional. Action/state executors handle nested invocation, control flow keywords, loop and conditional statements and the send statement (every conformance case passing). Coverage is self-assessed against the specification text and the normative library: the pinned OMG pilot implementation evaluates expressions but does not execute actions or state machines headlessly, so no external implementation currently adjudicates these rows. See [spec compliance](docs/project/spec-compliance.md). -**Reference differential:** 912 files compared diagnostic-by-diagnostic against the pinned OMG pilot implementation (`2026-08`), 510 in full agreement; every divergence is enumerated and adjudicated in [the differential](docs/project/pilot-differential.md), reproducible with `go run -C tools ./cmd/pilot-diff`. +**Reference differential:** 916 files compared diagnostic-by-diagnostic against the pinned OMG pilot implementation (`2026-08`), 514 in full agreement; every divergence is enumerated and adjudicated in [the differential](docs/project/pilot-differential.md), reproducible with `go run -C tools ./cmd/pilot-diff`. **Rejection oracle:** the reverse direction — do we reject what the reference rejects? 334 hand-written invalid models validated by both implementations, 323 rejected by both, 0 the pinned pilot rejects and we accept; the remainder only we reject — the control-node succession rules the pinned pilot leaves unimplemented and a non-Boolean succession guard it accepts once the standard library types it — and every permissiveness gap is enumerated with a reproducer and likely root cause in [the rejection oracle](docs/project/pilot-rejection.md), reproducible with `go run -C tools ./cmd/pilot-reject`. We wrote every case, so the count measures our coverage of the rejection surface, not our conformance — a sample, not a proof. **Training examples:** 100/100 files report no semantic errors, gated by `tests/corpus/testdata/training_examples_expected.txt`; the gate does not count execution-scope warnings. Download with `./scripts/download-training-examples.sh` (from the [OMG training directory](https://github.com/Systems-Modeling/SysML-v2-Pilot-Implementation/tree/master/sysml/src/training)). See [training examples](docs/project/training-examples.md) for analysis. **Semantic layer:** a complete implementation of runtime operators, feature chains and validation rules. See [examples/semantic-layer/](examples/semantic-layer/) for a full demonstration. diff --git a/docs/internals/architecture.md b/docs/internals/architecture.md index 585c4e63c4..384fc4be1b 100644 --- a/docs/internals/architecture.md +++ b/docs/internals/architecture.md @@ -859,11 +859,11 @@ Every behavioral feature must have: **Measured against the pinned reference** (`PILOT_TAG=2026-08`, artifact `0.62.0`). Every number below is generated by `make docs-counts` from the committed baselines and gated; none of them is typed in by hand. -- **Corpus agreement:** 510 of 912 files agree diagnostic-by-diagnostic; 366 diagnostics are ours alone and 2445 the reference's alone, and the first number must be read by root: the aggregate includes candidate conformance differences, intentional execution-scope warnings on reference corpora and diagnostics from our own examples ([differential](../project/pilot-differential.md), `go run -C tools ./cmd/pilot-diff`). +- **Corpus agreement:** 514 of 916 files agree diagnostic-by-diagnostic; 366 diagnostics are ours alone and 2445 the reference's alone, and the first number must be read by root: the aggregate includes candidate conformance differences, intentional execution-scope warnings on reference corpora and diagnostics from our own examples ([differential](../project/pilot-differential.md), `go run -C tools ./cmd/pilot-diff`). - **Declared-diagnostic silence:** of the 512 declared `errors` rows in the reference's own Xpect suites, we report nothing for 0. 245 we report word-for-word; 248 wording-only and 7 location-only differences are agreement in substance and are not counted as gaps; 0 more we report as a warning and 2 elsewhere in the file ([Xpect oracle](../project/pilot-xpect.md), `go run -C tools ./cmd/pilot-xpect`). - **Scope agreement:** 230 of 230 declared scope assertions match exactly (same source). - **Permissiveness gaps:** of 334 invalid models we wrote ourselves, the reference rejects 4 that we accept by default, and 319 both reject; 4 further cases agree only when we are asked strictly. We authored every one of these cases ourselves, so the denominator measures the reach of our own corpus and not our conformance; agreement reached only under an opt-in strict mode is weaker evidence than agreement by default ([rejection oracle](../project/pilot-rejection.md), `go run -C tools ./cmd/pilot-reject`). -- **Declared errata:** the registry declares 16 defect(s) in the published reference material — 9 with a specification-derived correction, 7 documented without one, since no intended reading can be inferred ([OMG issues](../project/omg-issues.md), `tools/oracle/errata`). Every figure above is as published and stays the conformance statement; running the same oracles over the corrected text instead reports 511 of 912 files agreeing, 365 diagnostics ours alone and 2445 the reference's alone, 0 declared rows we are silent on, and 0 of 334 authored cases the reference alone rejects. The corrected figures are diagnostic only: an erratum never reclassifies a divergence category, and the published corpus is never edited. +- **Declared errata:** the registry declares 16 defect(s) in the published reference material — 9 with a specification-derived correction, 7 documented without one, since no intended reading can be inferred ([OMG issues](../project/omg-issues.md), `tools/oracle/errata`). Every figure above is as published and stays the conformance statement; running the same oracles over the corrected text instead reports 515 of 916 files agreeing, 365 diagnostics ours alone and 2445 the reference's alone, 0 declared rows we are silent on, and 0 of 334 authored cases the reference alone rejects. The corrected figures are diagnostic only: an erratum never reclassifies a divergence category, and the published corpus is never edited. - **Self-assessed surface:** the action, state-machine and classifier-behavior rows have no external referee at all — the four refereed figures above cannot see them, because the pinned artifact evaluates expressions but executes neither actions nor state machines. [Spec compliance](../project/spec-compliance.md) counts them. What these numbers cannot show: the OMG corpora are demonstrations rather than an official conformance suite; the differential is one-directional, comparing the diagnostics the two implementations report on the same files; the Xpect suites are the pilot authors' test intent rather than a certification oracle; and none of these is a percentage of the specification — no global compliance figure is claimed anywhere. diff --git a/docs/project/pilot-differential-baseline.json b/docs/project/pilot-differential-baseline.json index 160f203aac..741c0fa55a 100644 --- a/docs/project/pilot-differential-baseline.json +++ b/docs/project/pilot-differential-baseline.json @@ -61,8 +61,8 @@ "name": "testdata", "dir": "tests/testdata", "origin": "ours", - "files": 32, - "digest": "sha256:dae2f9d8bb3bdc7ed299cee846cd1d97231563e6b995caa6e871271591e3b80f" + "files": 36, + "digest": "sha256:cd30a546383571509202e9eaeb3b6bf74ebe377e46f94e3f64ab2b1d29287d39" }, { "name": "examples", @@ -86,17 +86,17 @@ "digest": "sha256:c399daea865e29d2c056db2746eb3aad94ab26e591cf7669ffcb060583dfee0b" } ], - "recorded": "2026-10-20" + "recorded": "2026-10-21" }, "totals": { - "files": 912, - "filesFullyAgreeing": 510, - "agreement": 1085, + "files": 916, + "filesFullyAgreeing": 514, + "agreement": 1091, "severityMismatch": 11, "openSysMLOnly": 366, "pilotOnly": 2445, - "openSysMLDiagnostics": 1462, - "pilotDiagnostics": 3541 + "openSysMLDiagnostics": 1468, + "pilotDiagnostics": 3547 }, "roots": [ { @@ -17107,16 +17107,76 @@ "name": "testdata", "dir": "tests/testdata", "totals": { - "files": 32, - "filesFullyAgreeing": 19, - "agreement": 48, + "files": 36, + "filesFullyAgreeing": 23, + "agreement": 54, "severityMismatch": 5, "openSysMLOnly": 13, "pilotOnly": 32, - "openSysMLDiagnostics": 66, - "pilotDiagnostics": 85 + "openSysMLDiagnostics": 72, + "pilotDiagnostics": 91 }, "files": [ + { + "path": "filters/alias_import.sysml", + "agreement": [ + { + "line": 17, + "severity": "error", + "category": "unresolved-reference", + "count": 1 + }, + { + "line": 23, + "severity": "error", + "category": "unresolved-reference", + "count": 1 + } + ], + "severityMismatch": [], + "openSysMLOnly": [], + "pilotOnly": [] + }, + { + "path": "filters/alias_member.sysml", + "agreement": [ + { + "line": 17, + "severity": "error", + "category": "unresolved-reference", + "count": 1 + }, + { + "line": 23, + "severity": "error", + "category": "unresolved-reference", + "count": 1 + }, + { + "line": 29, + "severity": "error", + "category": "unresolved-reference", + "count": 1 + } + ], + "severityMismatch": [], + "openSysMLOnly": [], + "pilotOnly": [] + }, + { + "path": "filters/namesake_b.sysml", + "agreement": [ + { + "line": 6, + "severity": "error", + "category": "unresolved-reference", + "count": 1 + } + ], + "severityMismatch": [], + "openSysMLOnly": [], + "pilotOnly": [] + }, { "path": "interchange/proj/.sysand/lib/acme-widgets_1.0.0/Widgets.sysml", "agreement": [ @@ -25303,14 +25363,14 @@ } ], "totals": { - "files": 912, - "filesFullyAgreeing": 511, - "agreement": 1085, + "files": 916, + "filesFullyAgreeing": 515, + "agreement": 1091, "severityMismatch": 11, "openSysMLOnly": 365, "pilotOnly": 2445, - "openSysMLDiagnostics": 1461, - "pilotDiagnostics": 3541 + "openSysMLDiagnostics": 1467, + "pilotDiagnostics": 3547 }, "findings": [ { diff --git a/docs/project/pilot-differential.md b/docs/project/pilot-differential.md index baa56187f5..f432e36ae2 100644 --- a/docs/project/pilot-differential.md +++ b/docs/project/pilot-differential.md @@ -245,7 +245,7 @@ nor double-counted as two independent disagreements. --- -## Results (pilot `2026-08`, 912 files) +## Results (pilot `2026-08`, 916 files) | Root | Files | Fully agreeing | Ours | Pilot | Agreed | Severity-only | Only ours | Only pilot | |---|---:|---:|---:|---:|---:|---:|---:|---:| @@ -254,10 +254,10 @@ nor double-counted as two independent disagreements. | `examples/pilot-corpora/sysml-validation` | 56 | 54 | 11 | 0 | 0 | 0 | 11 | 0 | | `examples/pilot-corpora/kerml-examples` | 58 | 55 | 16 | 0 | 0 | 0 | 16 | 0 | | `examples/spec-examples` | 511 | 149 | 1093 | 3395 | 1037 | 6 | 50 | 2352 | -| `tests/testdata` | 32 | 19 | 66 | 85 | 48 | 5 | 13 | 32 | +| `tests/testdata` | 36 | 23 | 72 | 91 | 54 | 5 | 13 | 32 | | `examples` | 52 | 45 | 8 | 61 | 0 | 0 | 8 | 61 | | `tools/referee/diff/testdata` (probes) | 4 | 1 | 6 | 0 | 0 | 0 | 6 | 0 | -| **Total** | **912** | **510** | **1462** | **3541** | **1085** | **11** | **366** | **2445** | +| **Total** | **916** | **514** | **1468** | **3547** | **1091** | **11** | **366** | **2445** | **Read the `only ours` total by root, never as one number.** Step 2 removes nine resolver false positives from the reference's **own** corpora: `pilot-examples` 16 → **7** and @@ -978,7 +978,7 @@ cascades through the rest of the file. The movement is entirely one file, | Count | Before the initializer rewrite | Now | |---|---:|---:| | only pilot | 82 | **2445** | -| pilot diagnostics | 123 | **3541** | +| pilot diagnostics | 123 | **3547** | | severity-only | 9 | **11** | The rewrite itself took only-pilot to 61 and pilot diagnostics to 101; the `Now` column states @@ -1202,9 +1202,9 @@ page's history. | Count | Now | |---|---:| -| overall: fully agreeing / only ours / our diagnostics | **510 / 366 / 1462** | +| overall: fully agreeing / only ours / our diagnostics | **514 / 366 / 1468** | | only pilot | **2445** | -| pilot diagnostics | **3541** | +| pilot diagnostics | **3547** | | severity-only | **11** | | unmapped, our side | **287** | | kerml-examples: only ours | **16** | From 0e9666fb9c3d4ea77c2b339cacb664a48c33c69f Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 20:25:09 +0000 Subject: [PATCH 4/6] fix(semantics): judge a metaclass condition against the element it already resolved to Co-Authored-By: jason.han --- internal/semantic/semantics/filter.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/internal/semantic/semantics/filter.go b/internal/semantic/semantics/filter.go index e8d7db6eed..eb3dfabe89 100644 --- a/internal/semantic/semantics/filter.go +++ b/internal/semantic/semantics/filter.go @@ -851,7 +851,7 @@ func (m *Model) metaclassFeatureValue(cand *symbols.Symbol, p *symbols.FilterPre Span: p.Span, } } - if !m.metaclassConforms(cand, p.TypeFQN) { + if !m.metaclassConformsTo(cand, m.predicateType(p), p.TypeFQN) { return emptyValue(), nil // not an instance of that metaclass: nothing to read } if v, ok := m.reflectiveFeatureValue(cand, p.Feature); ok { @@ -922,18 +922,24 @@ func (m *Model) annotatedByType(cand, typ *symbols.Symbol, typeFQN string) bool return true } } - return m.metaclassConforms(cand, typeFQN) + return m.metaclassConformsTo(cand, typ, typeFQN) } // metaclassConforms reports whether the candidate's own metaclass — the KerML // metaclass of the declaration, `SysML::PartUsage` for a part usage — conforms to // the named type: the reflective metaobject among the element's metadata. func (m *Model) metaclassConforms(cand *symbols.Symbol, typeFQN string) bool { + return m.metaclassConformsTo(cand, m.typeByFQN(typeFQN), typeFQN) +} + +// metaclassConformsTo is metaclassConforms against the element the name already +// resolved to, so a compiled condition is not re-resolved per candidate. +func (m *Model) metaclassConformsTo(cand, typ *symbols.Symbol, typeFQN string) bool { meta := m.metaclassOf(cand) if meta == nil { return false } - if typ := m.typeByFQN(typeFQN); typ != nil { + if typ != nil { return m.Conforms(meta, typ) || m.conformsByName(meta, typeFQN) } // The metaclass library is not loaded, so conformance can only be judged on From ce1b6c8f88122ea17cfbb6456312aa1bef331fc0 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 21:44:28 +0000 Subject: [PATCH 5/6] docs(api-json-differential): record the four filter-conformance fixtures in the baseline Co-Authored-By: jason.han --- .../api-json-differential-baseline.json | 1734 ++++++++--------- docs/project/api-json-differential.md | 72 +- 2 files changed, 903 insertions(+), 903 deletions(-) diff --git a/docs/project/api-json-differential-baseline.json b/docs/project/api-json-differential-baseline.json index d40b0eaacb..74fd01757d 100644 --- a/docs/project/api-json-differential-baseline.json +++ b/docs/project/api-json-differential-baseline.json @@ -57,8 +57,8 @@ "name": "testdata", "dir": "tests/testdata", "origin": "ours", - "files": 32, - "digest": "sha256:dae2f9d8bb3bdc7ed299cee846cd1d97231563e6b995caa6e871271591e3b80f" + "files": 36, + "digest": "sha256:cd30a546383571509202e9eaeb3b6bf74ebe377e46f94e3f64ab2b1d29287d39" }, { "name": "examples", @@ -99,41 +99,41 @@ "Standard-library elements the pilot writes (isLibraryElement, one copy per file that refers to them) are left out and counted under pilotLibraryElements; this repository's writer refers to library elements and never writes them." ], "totals": { - "files": 920, + "files": 924, "oursRefused": 36, "oursUnconvertible": 0, - "oursColliding": 24, + "oursColliding": 26, "pilotFailed": 58, "pilotLibraryElements": 5236, "elements": { - "matched": 86974, - "oursOnly": 29497, - "pilotOnly": 40387, + "matched": 87130, + "oursOnly": 29503, + "pilotOnly": 40452, "pilotOnlyImplied": 0, "typeMismatch": 1743 }, "properties": { - "presentEqual": 596664, - "presentDifferent": 47633, - "oursMissing": 1021444, - "pilotMissing": 65920, - "absentBoth": 2020649, + "presentEqual": 597627, + "presentDifferent": 47752, + "oursMissing": 1023009, + "pilotMissing": 66058, + "absentBoth": 2023975, "indeterminate": 20867 }, "rows": 11311, - "unkeyedReferences": 100873, - "extensionProperties": 140679, + "unkeyedReferences": 101010, + "extensionProperties": 141086, "duplicateElements": { - "ours": 560, - "pilot": 78022 + "ours": 561, + "pilot": 78031 }, "ambiguousKeys": { - "ours": 289, - "pilot": 345 + "ours": 293, + "pilot": 347 }, "unkeyableElements": { - "ours": 8198, - "pilot": 32521 + "ours": 8210, + "pilot": 32527 } }, "roots": [ @@ -317,37 +317,37 @@ { "name": "testdata", "dir": "tests/testdata", - "files": 32, + "files": 36, "oursRefused": 0, "pilotFailed": 4, - "oursColliding": 11, + "oursColliding": 13, "pilotLibraryElements": 60, "elements": { - "matched": 1201, - "oursOnly": 91, - "pilotOnly": 487, + "matched": 1357, + "oursOnly": 97, + "pilotOnly": 552, "pilotOnlyImplied": 0, "typeMismatch": 30 }, "properties": { - "presentEqual": 7818, - "presentDifferent": 393, - "oursMissing": 13183, - "pilotMissing": 879, - "absentBoth": 28133, + "presentEqual": 8781, + "presentDifferent": 512, + "oursMissing": 14748, + "pilotMissing": 1017, + "absentBoth": 31459, "indeterminate": 316 }, "duplicateElements": { - "ours": 25, - "pilot": 83 + "ours": 26, + "pilot": 92 }, "ambiguousKeys": { - "ours": 69, - "pilot": 93 + "ours": 73, + "pilot": 95 }, "unkeyableElements": { - "ours": 356, - "pilot": 176 + "ours": 368, + "pilot": 182 } }, { @@ -27399,12 +27399,12 @@ 0, 0, 0, - 50, + 57, 0 ], "ElementFilterMembership.condition": [ - 25, - 25, + 30, + 27, 0, 0, 0, @@ -27415,7 +27415,7 @@ 0, 0, 0, - 50, + 57, 0 ], "ElementFilterMembership.isImplied": [ @@ -27423,7 +27423,7 @@ 0, 0, 0, - 50, + 57, 0 ], "ElementFilterMembership.isImpliedIncluded": [ @@ -27431,20 +27431,20 @@ 0, 0, 0, - 50, + 57, 0 ], "ElementFilterMembership.isLibraryElement": [ 0, 0, - 50, + 57, 0, 0, 0 ], "ElementFilterMembership.memberElement": [ - 25, - 25, + 30, + 27, 0, 0, 0, @@ -27453,13 +27453,13 @@ "ElementFilterMembership.memberElementId": [ 0, 0, - 50, + 57, 0, 0, 0 ], "ElementFilterMembership.membershipOwningNamespace": [ - 50, + 57, 0, 0, 0, @@ -27471,7 +27471,7 @@ 0, 0, 0, - 50, + 57, 0 ], "ElementFilterMembership.ownedElement": [ @@ -27479,12 +27479,12 @@ 0, 0, 0, - 50, + 57, 0 ], "ElementFilterMembership.ownedMemberElement": [ - 25, - 25, + 30, + 27, 0, 0, 0, @@ -27493,14 +27493,14 @@ "ElementFilterMembership.ownedMemberElementId": [ 0, 0, - 50, + 57, 0, 0, 0 ], "ElementFilterMembership.ownedRelatedElement": [ - 25, - 25, + 30, + 27, 0, 0, 0, @@ -27511,14 +27511,14 @@ 0, 0, 0, - 50, + 57, 0 ], "ElementFilterMembership.owner": [ 0, 0, 0, - 50, + 57, 0, 0 ], @@ -27526,12 +27526,12 @@ 0, 0, 0, - 25, + 27, 0, 0 ], "ElementFilterMembership.owningRelatedElement": [ - 50, + 57, 0, 0, 0, @@ -27542,14 +27542,14 @@ 0, 0, 0, - 25, + 27, 0, 0 ], "ElementFilterMembership.relatedElement": [ 0, 0, - 50, + 57, 0, 0, 0 @@ -27557,7 +27557,7 @@ "ElementFilterMembership.source": [ 0, 0, - 50, + 57, 0, 0, 0 @@ -27565,7 +27565,7 @@ "ElementFilterMembership.target": [ 0, 0, - 50, + 57, 0, 0, 0 @@ -27575,13 +27575,13 @@ 0, 0, 0, - 50, + 57, 0 ], "ElementFilterMembership.visibility": [ - 25, + 30, 0, - 25, + 27, 0, 0, 0 @@ -31583,7 +31583,7 @@ 0, 0, 0, - 9905, + 9915, 0 ], "Feature.chainingFeature": [ @@ -31591,7 +31591,7 @@ 40, 113, 0, - 9598, + 9608, 24 ], "Feature.chains": [ @@ -31639,7 +31639,7 @@ 0, 4, 0, - 9901, + 9911, 0 ], "Feature.directedFeature": [ @@ -31647,12 +31647,12 @@ 0, 571, 0, - 9334, + 9344, 0 ], "Feature.direction": [ - 8432, - 186, + 8437, + 191, 0, 93, 0, @@ -31671,7 +31671,7 @@ 0, 21, 0, - 9884, + 9894, 0 ], "Feature.endFeature": [ @@ -31679,7 +31679,7 @@ 0, 47, 0, - 9858, + 9868, 0 ], "Feature.endOwningType": [ @@ -31693,7 +31693,7 @@ "Feature.feature": [ 0, 0, - 9899, + 9909, 0, 6, 0 @@ -31701,7 +31701,7 @@ "Feature.featureMembership": [ 0, 0, - 9899, + 9909, 0, 6, 0 @@ -31709,7 +31709,7 @@ "Feature.featureTarget": [ 0, 0, - 9905, + 9915, 0, 0, 0 @@ -31717,7 +31717,7 @@ "Feature.featuringType": [ 67, 2, - 9626, + 9636, 0, 209, 1 @@ -31727,13 +31727,13 @@ 0, 15, 0, - 9890, + 9900, 0 ], "Feature.inheritedFeature": [ 0, 0, - 9905, + 9915, 0, 0, 0 @@ -31741,7 +31741,7 @@ "Feature.inheritedMembership": [ 0, 0, - 9905, + 9915, 0, 0, 0 @@ -31751,7 +31751,7 @@ 0, 399, 0, - 9506, + 9516, 0 ], "Feature.intersectingType": [ @@ -31759,7 +31759,7 @@ 0, 3, 0, - 9902, + 9912, 0 ], "Feature.intersects": [ @@ -31783,11 +31783,11 @@ 0, 0, 0, - 9897, + 9907, 0 ], "Feature.isComposite": [ - 9871, + 9881, 34, 0, 0, @@ -31797,7 +31797,7 @@ "Feature.isConjugated": [ 0, 0, - 9905, + 9915, 0, 0, 0 @@ -31807,7 +31807,7 @@ 0, 0, 0, - 9895, + 9905, 0 ], "Feature.isDefault": [ @@ -31823,7 +31823,7 @@ 0, 0, 0, - 9903, + 9913, 0 ], "Feature.isEnd": [ @@ -31831,7 +31831,7 @@ 0, 0, 0, - 9763, + 9773, 0 ], "Feature.isImpliedIncluded": [ @@ -31839,7 +31839,7 @@ 0, 0, 0, - 9905, + 9915, 0 ], "Feature.isInitial": [ @@ -31853,7 +31853,7 @@ "Feature.isLibraryElement": [ 0, 0, - 9905, + 9915, 0, 0, 0 @@ -31863,7 +31863,7 @@ 0, 0, 0, - 9892, + 9902, 0 ], "Feature.isPortion": [ @@ -31871,7 +31871,7 @@ 0, 0, 0, - 9871, + 9881, 0 ], "Feature.isResult": [ @@ -31887,7 +31887,7 @@ 0, 0, 0, - 9905, + 9915, 0 ], "Feature.isUnique": [ @@ -31895,7 +31895,7 @@ 0, 0, 0, - 9899, + 9909, 0 ], "Feature.isVariable": [ @@ -31903,7 +31903,7 @@ 0, 75, 0, - 9830, + 9840, 0 ], "Feature.lowerBound": [ @@ -31917,7 +31917,7 @@ "Feature.member": [ 0, 0, - 9905, + 9915, 0, 0, 0 @@ -31925,7 +31925,7 @@ "Feature.membership": [ 0, 0, - 9905, + 9915, 0, 0, 0 @@ -31941,7 +31941,7 @@ "Feature.name": [ 186, 0, - 8817, + 8827, 0, 0, 0 @@ -31951,7 +31951,7 @@ 0, 411, 0, - 9494, + 9504, 0 ], "Feature.ownedAnnotation": [ @@ -31959,7 +31959,7 @@ 0, 0, 0, - 9905, + 9915, 0 ], "Feature.ownedConjugator": [ @@ -31983,7 +31983,7 @@ 0, 4, 0, - 9901, + 9911, 0 ], "Feature.ownedDisjoining": [ @@ -31991,15 +31991,15 @@ 0, 3, 0, - 9902, + 9912, 0 ], "Feature.ownedElement": [ 0, 0, - 4849, + 4854, 0, - 5056, + 5061, 0 ], "Feature.ownedEndFeature": [ @@ -32007,7 +32007,7 @@ 0, 1, 0, - 9904, + 9914, 0 ], "Feature.ownedFeature": [ @@ -32015,7 +32015,7 @@ 4, 558, 0, - 9216, + 9226, 6 ], "Feature.ownedFeatureChaining": [ @@ -32023,7 +32023,7 @@ 0, 113, 0, - 9598, + 9608, 0 ], "Feature.ownedFeatureInverting": [ @@ -32031,7 +32031,7 @@ 0, 7, 0, - 9898, + 9908, 0 ], "Feature.ownedFeatureMembership": [ @@ -32039,7 +32039,7 @@ 1, 558, 0, - 9216, + 9226, 0 ], "Feature.ownedImport": [ @@ -32047,7 +32047,7 @@ 0, 0, 0, - 9890, + 9900, 0 ], "Feature.ownedIntersecting": [ @@ -32055,23 +32055,23 @@ 0, 3, 0, - 9902, + 9912, 0 ], "Feature.ownedMember": [ 119, 104, - 4603, + 4608, 0, - 5071, + 5076, 8 ], "Feature.ownedMembership": [ 4248, 560, - 26, + 31, 92, - 4979, + 4984, 0 ], "Feature.ownedRedefinition": [ @@ -32079,7 +32079,7 @@ 0, 633, 0, - 8996, + 9006, 0 ], "Feature.ownedReferenceSubsetting": [ @@ -32092,8 +32092,8 @@ ], "Feature.ownedRelationship": [ 3651, - 1781, - 124, + 1786, + 129, 88, 4261, 0 @@ -32101,8 +32101,8 @@ "Feature.ownedSpecialization": [ 756, 130, - 657, - 29, + 662, + 34, 8333, 0 ], @@ -32111,7 +32111,7 @@ 17, 645, 6, - 8883, + 8893, 0 ], "Feature.ownedTypeFeaturing": [ @@ -32119,14 +32119,14 @@ 0, 70, 0, - 9835, + 9845, 0 ], "Feature.ownedTyping": [ 661, 0, - 24, - 23, + 29, + 28, 9197, 0 ], @@ -32135,11 +32135,11 @@ 0, 7, 0, - 9898, + 9908, 0 ], "Feature.owner": [ - 9905, + 9915, 0, 0, 0, @@ -32149,14 +32149,14 @@ "Feature.owningFeatureMembership": [ 0, 0, - 9345, + 9355, 0, 0, 0 ], "Feature.owningMembership": [ - 9377, - 342, + 9382, + 347, 0, 0, 0, @@ -32165,14 +32165,14 @@ "Feature.owningNamespace": [ 1133, 0, - 8586, + 8596, 0, 0, 0 ], "Feature.owningRelationship": [ - 9562, - 343, + 9567, + 348, 0, 0, 0, @@ -32181,7 +32181,7 @@ "Feature.owningType": [ 0, 0, - 9345, + 9355, 0, 0, 0 @@ -32231,13 +32231,13 @@ 0, 0, 0, - 9905, + 9915, 0 ], "Feature.type": [ 346, 120, - 9266, + 9276, 0, 0, 173 @@ -32247,7 +32247,7 @@ 0, 7, 0, - 9898, + 9908, 0 ], "Feature.unions": [ @@ -33159,7 +33159,7 @@ 0, 0, 0, - 10467, + 10469, 0 ], "FeatureMembership.documentation": [ @@ -33167,7 +33167,7 @@ 0, 0, 0, - 10467, + 10469, 0 ], "FeatureMembership.isImplied": [ @@ -33175,7 +33175,7 @@ 0, 0, 0, - 10467, + 10469, 0 ], "FeatureMembership.isImpliedIncluded": [ @@ -33183,19 +33183,19 @@ 0, 0, 0, - 10467, + 10469, 0 ], "FeatureMembership.isLibraryElement": [ 0, 0, - 10467, + 10469, 0, 0, 0 ], "FeatureMembership.memberElement": [ - 8734, + 8736, 882, 0, 0, @@ -33205,7 +33205,7 @@ "FeatureMembership.memberElementId": [ 0, 0, - 10467, + 10469, 0, 0, 0 @@ -33213,7 +33213,7 @@ "FeatureMembership.memberName": [ 0, 0, - 8676, + 8678, 0, 0, 0 @@ -33227,7 +33227,7 @@ 0 ], "FeatureMembership.membershipOwningNamespace": [ - 10467, + 10469, 0, 0, 0, @@ -33239,7 +33239,7 @@ 0, 0, 0, - 10467, + 10469, 0 ], "FeatureMembership.ownedElement": [ @@ -33247,11 +33247,11 @@ 0, 0, 0, - 10467, + 10469, 0 ], "FeatureMembership.ownedMemberElement": [ - 8734, + 8736, 882, 0, 0, @@ -33261,13 +33261,13 @@ "FeatureMembership.ownedMemberElementId": [ 0, 0, - 10467, + 10469, 0, 0, 0 ], "FeatureMembership.ownedMemberFeature": [ - 8734, + 8736, 882, 0, 0, @@ -33277,7 +33277,7 @@ "FeatureMembership.ownedMemberName": [ 0, 0, - 8676, + 8678, 0, 0, 0 @@ -33291,7 +33291,7 @@ 0 ], "FeatureMembership.ownedRelatedElement": [ - 8734, + 8736, 882, 0, 0, @@ -33303,19 +33303,19 @@ 0, 0, 0, - 10467, + 10469, 0 ], "FeatureMembership.owner": [ 0, 0, 0, - 10467, + 10469, 0, 0 ], "FeatureMembership.owningRelatedElement": [ - 10467, + 10469, 0, 0, 0, @@ -33323,7 +33323,7 @@ 0 ], "FeatureMembership.owningType": [ - 10399, + 10401, 0, 68, 0, @@ -33333,7 +33333,7 @@ "FeatureMembership.relatedElement": [ 0, 0, - 10467, + 10469, 0, 0, 0 @@ -33341,7 +33341,7 @@ "FeatureMembership.source": [ 0, 0, - 10467, + 10469, 0, 0, 0 @@ -33349,7 +33349,7 @@ "FeatureMembership.target": [ 0, 0, - 10467, + 10469, 0, 0, 0 @@ -33359,13 +33359,13 @@ 0, 0, 0, - 10467, + 10469, 0 ], "FeatureMembership.visibility": [ 63, 1, - 10403, + 10405, 0, 0, 0 @@ -33927,7 +33927,7 @@ 0, 0, 0, - 5646, + 5651, 0 ], "FeatureTyping.declaredName": [ @@ -33943,11 +33943,11 @@ 0, 1, 0, - 5645, + 5650, 0 ], "FeatureTyping.general": [ - 3245, + 3250, 511, 4, 0, @@ -33959,7 +33959,7 @@ 0, 0, 0, - 5646, + 5651, 0 ], "FeatureTyping.isImpliedIncluded": [ @@ -33967,13 +33967,13 @@ 0, 0, 0, - 5646, + 5651, 0 ], "FeatureTyping.isLibraryElement": [ 0, 0, - 5646, + 5651, 0, 0, 0 @@ -33991,7 +33991,7 @@ 0, 1, 0, - 5645, + 5650, 0 ], "FeatureTyping.ownedElement": [ @@ -33999,7 +33999,7 @@ 0, 1, 0, - 5645, + 5650, 0 ], "FeatureTyping.ownedRelatedElement": [ @@ -34007,7 +34007,7 @@ 0, 0, 1, - 5645, + 5650, 0 ], "FeatureTyping.ownedRelationship": [ @@ -34015,7 +34015,7 @@ 1, 0, 3, - 5642, + 5647, 0 ], "FeatureTyping.ownedSpecialization": [ @@ -34038,12 +34038,12 @@ 4, 0, 0, - 5642, + 5647, 0, 0 ], "FeatureTyping.owningFeature": [ - 5642, + 5647, 0, 0, 0, @@ -34067,7 +34067,7 @@ 0 ], "FeatureTyping.owningRelatedElement": [ - 5642, + 5647, 0, 0, 0, @@ -34085,7 +34085,7 @@ "FeatureTyping.owningType": [ 0, 0, - 5642, + 5647, 0, 0, 0 @@ -34099,7 +34099,7 @@ 0 ], "FeatureTyping.relatedElement": [ - 3245, + 3250, 511, 4, 0, @@ -34107,7 +34107,7 @@ 1886 ], "FeatureTyping.source": [ - 5642, + 5647, 0, 4, 0, @@ -34115,7 +34115,7 @@ 0 ], "FeatureTyping.specific": [ - 5642, + 5647, 0, 4, 0, @@ -34123,7 +34123,7 @@ 0 ], "FeatureTyping.target": [ - 3245, + 3250, 511, 4, 0, @@ -34135,11 +34135,11 @@ 0, 0, 0, - 5646, + 5651, 0 ], "FeatureTyping.type": [ - 3247, + 3252, 513, 0, 0, @@ -34147,7 +34147,7 @@ 1886 ], "FeatureTyping.typedFeature": [ - 5644, + 5649, 2, 0, 0, @@ -49999,7 +49999,7 @@ 0, 0, 0, - 384, + 386, 0 ], "MembershipImport.documentation": [ @@ -50007,11 +50007,11 @@ 0, 4, 0, - 380, + 382, 0 ], "MembershipImport.importOwningNamespace": [ - 382, + 384, 0, 2, 0, @@ -50021,13 +50021,13 @@ "MembershipImport.importedElement": [ 0, 0, - 374, + 376, 0, 0, 0 ], "MembershipImport.importedMembership": [ - 107, + 109, 12, 0, 0, @@ -50039,7 +50039,7 @@ 0, 0, 0, - 384, + 386, 0 ], "MembershipImport.isImpliedIncluded": [ @@ -50047,7 +50047,7 @@ 0, 0, 0, - 384, + 386, 0 ], "MembershipImport.isImportAll": [ @@ -50055,23 +50055,23 @@ 0, 0, 0, - 384, + 386, 0 ], "MembershipImport.isLibraryElement": [ 0, 0, - 384, + 386, 0, 0, 0 ], "MembershipImport.isRecursive": [ - 48, + 49, 0, 0, 0, - 336, + 337, 0 ], "MembershipImport.ownedAnnotation": [ @@ -50079,7 +50079,7 @@ 0, 5, 0, - 379, + 381, 0 ], "MembershipImport.ownedElement": [ @@ -50087,7 +50087,7 @@ 0, 5, 0, - 379, + 381, 0 ], "MembershipImport.ownedRelatedElement": [ @@ -50095,7 +50095,7 @@ 0, 0, 4, - 380, + 382, 0 ], "MembershipImport.ownedRelationship": [ @@ -50103,14 +50103,14 @@ 0, 5, 0, - 379, + 381, 0 ], "MembershipImport.owner": [ 0, 0, 0, - 384, + 386, 0, 0 ], @@ -50126,12 +50126,12 @@ 0, 0, 0, - 361, + 362, 0, 0 ], "MembershipImport.owningRelatedElement": [ - 382, + 384, 0, 2, 0, @@ -50150,14 +50150,14 @@ 0, 0, 0, - 361, + 362, 0, 0 ], "MembershipImport.relatedElement": [ 0, 0, - 384, + 386, 0, 0, 0 @@ -50165,7 +50165,7 @@ "MembershipImport.source": [ 0, 0, - 384, + 386, 0, 0, 0 @@ -50173,7 +50173,7 @@ "MembershipImport.target": [ 0, 0, - 384, + 386, 0, 0, 0 @@ -50183,13 +50183,13 @@ 0, 0, 0, - 384, + 386, 0 ], "MembershipImport.visibility": [ - 361, + 362, 0, - 23, + 24, 0, 0, 0 @@ -51927,11 +51927,11 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.declaredName": [ - 36, + 40, 0, 0, 0, @@ -51951,7 +51951,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.directedFeature": [ @@ -51959,7 +51959,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.directedUsage": [ @@ -51967,7 +51967,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.documentation": [ @@ -51975,7 +51975,7 @@ 0, 1, 0, - 35, + 39, 0 ], "MetadataDefinition.endFeature": [ @@ -51983,13 +51983,13 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.feature": [ 0, 0, - 36, + 40, 0, 0, 0 @@ -51997,7 +51997,7 @@ "MetadataDefinition.featureMembership": [ 0, 0, - 36, + 40, 0, 0, 0 @@ -52007,13 +52007,13 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.inheritedFeature": [ 0, 0, - 36, + 40, 0, 0, 0 @@ -52021,7 +52021,7 @@ "MetadataDefinition.inheritedMembership": [ 0, 0, - 36, + 40, 0, 0, 0 @@ -52031,7 +52031,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.intersectingType": [ @@ -52039,7 +52039,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.isAbstract": [ @@ -52047,13 +52047,13 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.isConjugated": [ 0, 0, - 36, + 40, 0, 0, 0 @@ -52063,7 +52063,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.isIndividual": [ @@ -52071,13 +52071,13 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.isLibraryElement": [ 0, 0, - 36, + 40, 0, 0, 0 @@ -52087,13 +52087,13 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.isVariation": [ 0, 0, - 36, + 40, 0, 0, 0 @@ -52101,7 +52101,7 @@ "MetadataDefinition.member": [ 0, 0, - 36, + 40, 0, 0, 0 @@ -52109,7 +52109,7 @@ "MetadataDefinition.membership": [ 0, 0, - 36, + 40, 0, 0, 0 @@ -52117,7 +52117,7 @@ "MetadataDefinition.name": [ 0, 0, - 36, + 40, 0, 0, 0 @@ -52127,7 +52127,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedAction": [ @@ -52135,7 +52135,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedAllocation": [ @@ -52143,7 +52143,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedAnalysisCase": [ @@ -52151,7 +52151,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedAnnotation": [ @@ -52159,7 +52159,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedAttribute": [ @@ -52167,7 +52167,7 @@ 0, 10, 0, - 26, + 30, 0 ], "MetadataDefinition.ownedCalculation": [ @@ -52175,7 +52175,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedCase": [ @@ -52183,7 +52183,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedConcern": [ @@ -52191,7 +52191,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedConnection": [ @@ -52199,7 +52199,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedConstraint": [ @@ -52207,7 +52207,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedDifferencing": [ @@ -52215,7 +52215,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedDisjoining": [ @@ -52223,7 +52223,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedElement": [ @@ -52231,7 +52231,7 @@ 0, 18, 0, - 18, + 22, 0 ], "MetadataDefinition.ownedEndFeature": [ @@ -52239,7 +52239,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedEnumeration": [ @@ -52247,7 +52247,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedFeature": [ @@ -52255,7 +52255,7 @@ 0, 0, 0, - 18, + 22, 0 ], "MetadataDefinition.ownedFeatureMembership": [ @@ -52263,7 +52263,7 @@ 0, 0, 0, - 18, + 22, 0 ], "MetadataDefinition.ownedFlow": [ @@ -52271,7 +52271,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedImport": [ @@ -52279,7 +52279,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedInterface": [ @@ -52287,7 +52287,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedIntersecting": [ @@ -52295,7 +52295,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedItem": [ @@ -52303,7 +52303,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedMember": [ @@ -52311,7 +52311,7 @@ 0, 0, 0, - 18, + 22, 0 ], "MetadataDefinition.ownedMembership": [ @@ -52319,7 +52319,7 @@ 0, 0, 0, - 18, + 22, 0 ], "MetadataDefinition.ownedMetadata": [ @@ -52327,7 +52327,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedOccurrence": [ @@ -52335,7 +52335,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedPart": [ @@ -52343,7 +52343,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedPort": [ @@ -52351,7 +52351,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedReference": [ @@ -52359,7 +52359,7 @@ 0, 9, 0, - 27, + 31, 0 ], "MetadataDefinition.ownedRelationship": [ @@ -52367,7 +52367,7 @@ 6, 0, 0, - 18, + 22, 0 ], "MetadataDefinition.ownedRendering": [ @@ -52375,7 +52375,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedRequirement": [ @@ -52383,7 +52383,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedSpecialization": [ @@ -52391,7 +52391,7 @@ 0, 0, 0, - 30, + 34, 0 ], "MetadataDefinition.ownedState": [ @@ -52399,7 +52399,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedSubclassification": [ @@ -52407,7 +52407,7 @@ 0, 0, 0, - 30, + 34, 0 ], "MetadataDefinition.ownedTransition": [ @@ -52415,7 +52415,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedUnioning": [ @@ -52423,7 +52423,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedUsage": [ @@ -52431,7 +52431,7 @@ 0, 18, 0, - 18, + 22, 0 ], "MetadataDefinition.ownedUseCase": [ @@ -52439,7 +52439,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedVerificationCase": [ @@ -52447,7 +52447,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedView": [ @@ -52455,7 +52455,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.ownedViewpoint": [ @@ -52463,11 +52463,11 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.owner": [ - 36, + 40, 0, 0, 0, @@ -52475,7 +52475,7 @@ 0 ], "MetadataDefinition.owningMembership": [ - 36, + 40, 0, 0, 0, @@ -52483,7 +52483,7 @@ 0 ], "MetadataDefinition.owningNamespace": [ - 36, + 40, 0, 0, 0, @@ -52491,7 +52491,7 @@ 0 ], "MetadataDefinition.owningRelationship": [ - 36, + 40, 0, 0, 0, @@ -52499,7 +52499,7 @@ 0 ], "MetadataDefinition.qualifiedName": [ - 20, + 24, 16, 0, 0, @@ -52527,7 +52527,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.unioningType": [ @@ -52535,13 +52535,13 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.usage": [ 0, 0, - 36, + 40, 0, 0, 0 @@ -52551,7 +52551,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataDefinition.variantMembership": [ @@ -52559,7 +52559,7 @@ 0, 0, 0, - 36, + 40, 0 ], "MetadataFeature.aliasIds": [ @@ -53087,13 +53087,13 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.annotatedElement": [ 8, 4, - 230, + 235, 0, 7, 0 @@ -53103,7 +53103,7 @@ 0, 12, 0, - 237, + 242, 0 ], "MetadataUsage.chainingFeature": [ @@ -53111,7 +53111,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.declaredName": [ @@ -53125,7 +53125,7 @@ "MetadataUsage.definition": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53135,7 +53135,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.directedFeature": [ @@ -53143,7 +53143,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.directedUsage": [ @@ -53151,7 +53151,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.documentation": [ @@ -53159,7 +53159,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.endFeature": [ @@ -53167,13 +53167,13 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.feature": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53181,7 +53181,7 @@ "MetadataUsage.featureMembership": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53189,7 +53189,7 @@ "MetadataUsage.featureTarget": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53199,7 +53199,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.importedMembership": [ @@ -53207,13 +53207,13 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.inheritedFeature": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53221,7 +53221,7 @@ "MetadataUsage.inheritedMembership": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53231,7 +53231,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.intersectingType": [ @@ -53239,7 +53239,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.isAbstract": [ @@ -53247,11 +53247,11 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.isComposite": [ - 249, + 254, 0, 0, 0, @@ -53261,7 +53261,7 @@ "MetadataUsage.isConjugated": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53271,7 +53271,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.isDerived": [ @@ -53279,7 +53279,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.isEnd": [ @@ -53287,7 +53287,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.isImpliedIncluded": [ @@ -53295,7 +53295,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.isIndividual": [ @@ -53303,13 +53303,13 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.isLibraryElement": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53319,7 +53319,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.isPortion": [ @@ -53327,13 +53327,13 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.isReference": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53343,7 +53343,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.isUnique": [ @@ -53351,7 +53351,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.isVariable": [ @@ -53359,13 +53359,13 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.isVariation": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53373,7 +53373,7 @@ "MetadataUsage.itemDefinition": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53381,7 +53381,7 @@ "MetadataUsage.mayTimeVary": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53389,7 +53389,7 @@ "MetadataUsage.member": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53397,7 +53397,7 @@ "MetadataUsage.membership": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53405,7 +53405,7 @@ "MetadataUsage.metaclass": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53413,7 +53413,7 @@ "MetadataUsage.metadataDefinition": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53431,7 +53431,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedAllocation": [ @@ -53439,7 +53439,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedAnalysisCase": [ @@ -53447,7 +53447,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedAttribute": [ @@ -53455,7 +53455,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedCalculation": [ @@ -53463,7 +53463,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedCase": [ @@ -53471,7 +53471,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedConcern": [ @@ -53479,7 +53479,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedConnection": [ @@ -53487,7 +53487,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedConstraint": [ @@ -53495,7 +53495,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedEnumeration": [ @@ -53503,7 +53503,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedFlow": [ @@ -53511,7 +53511,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedInterface": [ @@ -53519,7 +53519,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedItem": [ @@ -53527,7 +53527,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedMetadata": [ @@ -53535,7 +53535,7 @@ 0, 1, 0, - 248, + 253, 0 ], "MetadataUsage.nestedOccurrence": [ @@ -53543,7 +53543,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedPart": [ @@ -53551,7 +53551,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedPort": [ @@ -53559,7 +53559,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedReference": [ @@ -53567,7 +53567,7 @@ 0, 86, 0, - 163, + 168, 0 ], "MetadataUsage.nestedRendering": [ @@ -53575,7 +53575,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedRequirement": [ @@ -53583,7 +53583,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedState": [ @@ -53591,7 +53591,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedTransition": [ @@ -53599,7 +53599,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedUsage": [ @@ -53607,7 +53607,7 @@ 0, 86, 0, - 163, + 168, 0 ], "MetadataUsage.nestedUseCase": [ @@ -53615,7 +53615,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedVerificationCase": [ @@ -53623,7 +53623,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedView": [ @@ -53631,7 +53631,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.nestedViewpoint": [ @@ -53639,13 +53639,13 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.occurrenceDefinition": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53655,7 +53655,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.ownedAnnotatingRelationship": [ @@ -53663,7 +53663,7 @@ 0, 12, 0, - 237, + 242, 0 ], "MetadataUsage.ownedAnnotation": [ @@ -53671,7 +53671,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.ownedDifferencing": [ @@ -53679,7 +53679,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.ownedDisjoining": [ @@ -53687,7 +53687,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.ownedElement": [ @@ -53695,7 +53695,7 @@ 0, 86, 0, - 163, + 168, 0 ], "MetadataUsage.ownedEndFeature": [ @@ -53703,7 +53703,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.ownedFeature": [ @@ -53711,7 +53711,7 @@ 0, 0, 0, - 163, + 168, 0 ], "MetadataUsage.ownedFeatureChaining": [ @@ -53719,7 +53719,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.ownedFeatureInverting": [ @@ -53727,7 +53727,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.ownedFeatureMembership": [ @@ -53735,7 +53735,7 @@ 0, 0, 0, - 163, + 168, 0 ], "MetadataUsage.ownedImport": [ @@ -53743,7 +53743,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.ownedIntersecting": [ @@ -53751,7 +53751,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.ownedMember": [ @@ -53759,7 +53759,7 @@ 0, 0, 0, - 163, + 168, 0 ], "MetadataUsage.ownedMembership": [ @@ -53767,7 +53767,7 @@ 0, 0, 0, - 163, + 168, 0 ], "MetadataUsage.ownedRedefinition": [ @@ -53775,11 +53775,11 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.ownedRelationship": [ - 159, + 164, 90, 0, 0, @@ -53787,7 +53787,7 @@ 0 ], "MetadataUsage.ownedSpecialization": [ - 249, + 254, 0, 0, 0, @@ -53799,7 +53799,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.ownedTypeFeaturing": [ @@ -53807,11 +53807,11 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.ownedTyping": [ - 249, + 254, 0, 0, 0, @@ -53823,11 +53823,11 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.owner": [ - 249, + 254, 0, 0, 0, @@ -53835,7 +53835,7 @@ 0 ], "MetadataUsage.owningMembership": [ - 238, + 243, 4, 0, 0, @@ -53843,7 +53843,7 @@ 0 ], "MetadataUsage.owningNamespace": [ - 242, + 247, 0, 0, 0, @@ -53851,7 +53851,7 @@ 0 ], "MetadataUsage.owningRelationship": [ - 245, + 250, 4, 0, 0, @@ -53862,7 +53862,7 @@ 3, 2, 0, - 244, + 249, 0, 0 ], @@ -53871,11 +53871,11 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.type": [ - 150, + 155, 24, 0, 0, @@ -53887,13 +53887,13 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.usage": [ 0, 0, - 249, + 254, 0, 0, 0 @@ -53903,7 +53903,7 @@ 0, 0, 0, - 249, + 254, 0 ], "MetadataUsage.variantMembership": [ @@ -53911,7 +53911,7 @@ 0, 0, 0, - 249, + 254, 0 ], "Multiplicity.aliasIds": [ @@ -54927,7 +54927,7 @@ 0, 0, 0, - 845, + 849, 0 ], "Namespace.declaredName": [ @@ -54951,7 +54951,7 @@ 0, 3, 0, - 842, + 846, 0 ], "Namespace.importedMembership": [ @@ -54959,7 +54959,7 @@ 0, 11, 0, - 834, + 838, 0 ], "Namespace.isImpliedIncluded": [ @@ -54967,13 +54967,13 @@ 0, 0, 0, - 845, + 849, 0 ], "Namespace.isLibraryElement": [ 0, 0, - 845, + 849, 0, 0, 0 @@ -54981,7 +54981,7 @@ "Namespace.member": [ 0, 0, - 839, + 843, 0, 6, 0 @@ -54989,7 +54989,7 @@ "Namespace.membership": [ 0, 0, - 840, + 844, 0, 5, 0 @@ -55007,13 +55007,13 @@ 0, 0, 0, - 845, + 849, 0 ], "Namespace.ownedElement": [ 0, 0, - 838, + 842, 0, 7, 0 @@ -55023,11 +55023,11 @@ 0, 7, 1, - 831, + 835, 0 ], "Namespace.ownedMember": [ - 804, + 808, 32, 1, 0, @@ -55035,7 +55035,7 @@ 0 ], "Namespace.ownedMembership": [ - 803, + 807, 33, 1, 0, @@ -55043,7 +55043,7 @@ 0 ], "Namespace.ownedRelationship": [ - 808, + 812, 33, 1, 1, @@ -55103,7 +55103,7 @@ 0, 0, 0, - 845, + 849, 0 ], "NamespaceExpose.aliasIds": [ @@ -55111,7 +55111,7 @@ 0, 0, 0, - 19, + 20, 0 ], "NamespaceExpose.documentation": [ @@ -55119,11 +55119,11 @@ 0, 0, 0, - 19, + 20, 0 ], "NamespaceExpose.importOwningNamespace": [ - 19, + 20, 0, 0, 0, @@ -55133,13 +55133,13 @@ "NamespaceExpose.importedElement": [ 0, 0, - 19, + 20, 0, 0, 0 ], "NamespaceExpose.importedNamespace": [ - 19, + 20, 0, 0, 0, @@ -55151,7 +55151,7 @@ 0, 0, 0, - 19, + 20, 0 ], "NamespaceExpose.isImpliedIncluded": [ @@ -55159,11 +55159,11 @@ 0, 0, 0, - 19, + 20, 0 ], "NamespaceExpose.isImportAll": [ - 19, + 20, 0, 0, 0, @@ -55173,7 +55173,7 @@ "NamespaceExpose.isLibraryElement": [ 0, 0, - 19, + 20, 0, 0, 0 @@ -55183,7 +55183,7 @@ 0, 0, 0, - 18, + 19, 0 ], "NamespaceExpose.ownedAnnotation": [ @@ -55191,7 +55191,7 @@ 0, 0, 0, - 19, + 20, 0 ], "NamespaceExpose.ownedElement": [ @@ -55199,11 +55199,11 @@ 0, 0, 0, - 19, + 20, 0 ], "NamespaceExpose.ownedRelatedElement": [ - 16, + 17, 0, 0, 0, @@ -55215,14 +55215,14 @@ 0, 0, 0, - 19, + 20, 0 ], "NamespaceExpose.owner": [ 0, 0, 0, - 19, + 20, 0, 0 ], @@ -55230,12 +55230,12 @@ 0, 0, 0, - 19, + 20, 0, 0 ], "NamespaceExpose.owningRelatedElement": [ - 19, + 20, 0, 0, 0, @@ -55246,14 +55246,14 @@ 0, 0, 0, - 19, + 20, 0, 0 ], "NamespaceExpose.relatedElement": [ 0, 0, - 19, + 20, 0, 0, 0 @@ -55261,7 +55261,7 @@ "NamespaceExpose.source": [ 0, 0, - 19, + 20, 0, 0, 0 @@ -55269,7 +55269,7 @@ "NamespaceExpose.target": [ 0, 0, - 19, + 20, 0, 0, 0 @@ -55279,11 +55279,11 @@ 0, 0, 0, - 19, + 20, 0 ], "NamespaceExpose.visibility": [ - 19, + 20, 0, 0, 0, @@ -55295,7 +55295,7 @@ 0, 0, 0, - 645, + 655, 0 ], "NamespaceImport.documentation": [ @@ -55303,11 +55303,11 @@ 0, 1, 0, - 644, + 654, 0 ], "NamespaceImport.importOwningNamespace": [ - 637, + 647, 0, 8, 0, @@ -55317,14 +55317,14 @@ "NamespaceImport.importedElement": [ 0, 0, - 645, + 655, 0, 0, 0 ], "NamespaceImport.importedNamespace": [ - 298, - 22, + 307, + 23, 0, 0, 0, @@ -55335,7 +55335,7 @@ 0, 0, 0, - 645, + 655, 0 ], "NamespaceImport.isImpliedIncluded": [ @@ -55343,7 +55343,7 @@ 0, 0, 0, - 645, + 655, 0 ], "NamespaceImport.isImportAll": [ @@ -55351,13 +55351,13 @@ 0, 0, 0, - 644, + 654, 0 ], "NamespaceImport.isLibraryElement": [ 0, 0, - 645, + 655, 0, 0, 0 @@ -55367,7 +55367,7 @@ 0, 0, 0, - 642, + 652, 0 ], "NamespaceImport.ownedAnnotation": [ @@ -55375,7 +55375,7 @@ 0, 2, 0, - 643, + 653, 0 ], "NamespaceImport.ownedElement": [ @@ -55383,15 +55383,15 @@ 0, 2, 0, - 643, + 653, 0 ], "NamespaceImport.ownedRelatedElement": [ - 8, + 12, 0, 0, 1, - 636, + 642, 0 ], "NamespaceImport.ownedRelationship": [ @@ -55399,14 +55399,14 @@ 0, 2, 0, - 643, + 653, 0 ], "NamespaceImport.owner": [ 0, 0, 0, - 645, + 655, 0, 0 ], @@ -55422,12 +55422,12 @@ 0, 0, 0, - 642, + 648, 0, 0 ], "NamespaceImport.owningRelatedElement": [ - 637, + 647, 0, 8, 0, @@ -55446,14 +55446,14 @@ 0, 0, 0, - 642, + 648, 0, 0 ], "NamespaceImport.relatedElement": [ 0, 0, - 645, + 655, 0, 0, 0 @@ -55461,7 +55461,7 @@ "NamespaceImport.source": [ 0, 0, - 645, + 655, 0, 0, 0 @@ -55469,7 +55469,7 @@ "NamespaceImport.target": [ 0, 0, - 645, + 655, 0, 0, 0 @@ -55479,13 +55479,13 @@ 0, 0, 0, - 645, + 655, 0 ], "NamespaceImport.visibility": [ - 642, + 648, 0, - 3, + 7, 0, 0, 0 @@ -57751,13 +57751,13 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.argument": [ 1091, 204, - 22, + 27, 1, 1, 0 @@ -57765,7 +57765,7 @@ "OperatorExpression.behavior": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -57775,7 +57775,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.differencingType": [ @@ -57783,13 +57783,13 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.directedFeature": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -57807,7 +57807,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.endFeature": [ @@ -57815,13 +57815,13 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.feature": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -57829,7 +57829,7 @@ "OperatorExpression.featureMembership": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -57837,7 +57837,7 @@ "OperatorExpression.featureTarget": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -57847,13 +57847,13 @@ 0, 874, 0, - 445, + 450, 0 ], "OperatorExpression.function": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -57863,13 +57863,13 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.inheritedFeature": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -57877,14 +57877,14 @@ "OperatorExpression.inheritedMembership": [ 0, 0, - 1319, + 1324, 0, 0, 0 ], "OperatorExpression.input": [ 1167, - 150, + 155, 1, 1, 0, @@ -57893,7 +57893,7 @@ "OperatorExpression.instantiatedType": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -57903,7 +57903,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.isAbstract": [ @@ -57911,11 +57911,11 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.isComposite": [ - 1319, + 1324, 0, 0, 0, @@ -57925,7 +57925,7 @@ "OperatorExpression.isConjugated": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -57935,7 +57935,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.isDerived": [ @@ -57943,7 +57943,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.isEnd": [ @@ -57951,7 +57951,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.isImpliedIncluded": [ @@ -57959,13 +57959,13 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.isLibraryElement": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -57973,7 +57973,7 @@ "OperatorExpression.isModelLevelEvaluable": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -57983,7 +57983,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.isPortion": [ @@ -57991,7 +57991,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.isSufficient": [ @@ -57999,7 +57999,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.isUnique": [ @@ -58007,7 +58007,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.isVariable": [ @@ -58015,13 +58015,13 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.member": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -58029,7 +58029,7 @@ "OperatorExpression.membership": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -58043,7 +58043,7 @@ 0 ], "OperatorExpression.operator": [ - 1307, + 1312, 12, 0, 0, @@ -58053,7 +58053,7 @@ "OperatorExpression.output": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -58063,7 +58063,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedDifferencing": [ @@ -58071,7 +58071,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedDisjoining": [ @@ -58079,13 +58079,13 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedElement": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -58095,12 +58095,12 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedFeature": [ 1190, - 129, + 134, 0, 0, 0, @@ -58111,7 +58111,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedFeatureInverting": [ @@ -58119,12 +58119,12 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedFeatureMembership": [ 1190, - 129, + 134, 0, 0, 0, @@ -58135,7 +58135,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedIntersecting": [ @@ -58143,20 +58143,20 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedMember": [ 0, 0, - 1319, + 1324, 0, 0, 0 ], "OperatorExpression.ownedMembership": [ 1190, - 129, + 134, 0, 0, 0, @@ -58167,12 +58167,12 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedRelationship": [ 1190, - 129, + 134, 0, 0, 0, @@ -58183,7 +58183,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedSubsetting": [ @@ -58191,7 +58191,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedTypeFeaturing": [ @@ -58199,7 +58199,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedTyping": [ @@ -58207,7 +58207,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.ownedUnioning": [ @@ -58215,11 +58215,11 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.owner": [ - 1319, + 1324, 0, 0, 0, @@ -58235,7 +58235,7 @@ 0 ], "OperatorExpression.owningMembership": [ - 1317, + 1322, 2, 0, 0, @@ -58245,13 +58245,13 @@ "OperatorExpression.owningNamespace": [ 232, 0, - 1087, + 1092, 0, 0, 0 ], "OperatorExpression.owningRelationship": [ - 1317, + 1322, 2, 0, 0, @@ -58268,7 +58268,7 @@ ], "OperatorExpression.parameter": [ 1167, - 152, + 157, 0, 0, 0, @@ -58284,7 +58284,7 @@ ], "OperatorExpression.result": [ 1190, - 129, + 134, 0, 0, 0, @@ -58295,13 +58295,13 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OperatorExpression.type": [ 0, 0, - 1319, + 1324, 0, 0, 0 @@ -58311,7 +58311,7 @@ 0, 0, 0, - 1319, + 1324, 0 ], "OwningMembership.aliasIds": [ @@ -58319,7 +58319,7 @@ 0, 0, 0, - 9220, + 9262, 0 ], "OwningMembership.documentation": [ @@ -58327,7 +58327,7 @@ 0, 0, 0, - 9220, + 9262, 0 ], "OwningMembership.isImplied": [ @@ -58335,7 +58335,7 @@ 0, 0, 0, - 9220, + 9262, 0 ], "OwningMembership.isImpliedIncluded": [ @@ -58343,19 +58343,19 @@ 0, 0, 0, - 9220, + 9262, 0 ], "OwningMembership.isLibraryElement": [ 0, 0, - 9220, + 9262, 0, 0, 0 ], "OwningMembership.memberElement": [ - 8600, + 8642, 412, 0, 3, @@ -58365,7 +58365,7 @@ "OwningMembership.memberElementId": [ 0, 0, - 9217, + 9259, 0, 0, 0 @@ -58373,7 +58373,7 @@ "OwningMembership.memberName": [ 0, 0, - 5496, + 5533, 0, 0, 0 @@ -58387,7 +58387,7 @@ 0 ], "OwningMembership.membershipOwningNamespace": [ - 9220, + 9262, 0, 0, 0, @@ -58399,7 +58399,7 @@ 0, 0, 0, - 9220, + 9262, 0 ], "OwningMembership.ownedElement": [ @@ -58407,11 +58407,11 @@ 0, 0, 0, - 9220, + 9262, 0 ], "OwningMembership.ownedMemberElement": [ - 8600, + 8642, 412, 0, 3, @@ -58421,7 +58421,7 @@ "OwningMembership.ownedMemberElementId": [ 0, 0, - 9217, + 9259, 0, 0, 0 @@ -58429,7 +58429,7 @@ "OwningMembership.ownedMemberName": [ 0, 0, - 5496, + 5533, 0, 0, 0 @@ -58443,7 +58443,7 @@ 0 ], "OwningMembership.ownedRelatedElement": [ - 8600, + 8642, 412, 0, 3, @@ -58455,19 +58455,19 @@ 0, 0, 0, - 9220, + 9262, 0 ], "OwningMembership.owner": [ 0, 0, 0, - 9220, + 9262, 0, 0 ], "OwningMembership.owningRelatedElement": [ - 9220, + 9262, 0, 0, 0, @@ -58477,7 +58477,7 @@ "OwningMembership.relatedElement": [ 0, 0, - 9220, + 9262, 0, 0, 0 @@ -58485,7 +58485,7 @@ "OwningMembership.source": [ 0, 0, - 9220, + 9262, 0, 0, 0 @@ -58493,7 +58493,7 @@ "OwningMembership.target": [ 0, 0, - 9217, + 9259, 0, 3, 0 @@ -58503,13 +58503,13 @@ 0, 0, 0, - 9220, + 9262, 0 ], "OwningMembership.visibility": [ 25, 0, - 9195, + 9237, 0, 0, 0 @@ -58519,11 +58519,11 @@ 0, 0, 0, - 1190, + 1209, 0 ], "Package.declaredName": [ - 1166, + 1180, 0, 0, 0, @@ -58535,23 +58535,23 @@ 0, 41, 0, - 1149, + 1168, 0 ], "Package.filterCondition": [ 0, 0, - 37, + 44, 0, - 1153, + 1165, 0 ], "Package.importedMembership": [ 0, 0, - 457, + 468, 0, - 733, + 741, 0 ], "Package.isImpliedIncluded": [ @@ -58559,13 +58559,13 @@ 0, 0, 0, - 1190, + 1209, 0 ], "Package.isLibraryElement": [ 0, 0, - 1190, + 1209, 0, 0, 0 @@ -58573,7 +58573,7 @@ "Package.member": [ 0, 0, - 1154, + 1173, 0, 36, 0 @@ -58581,7 +58581,7 @@ "Package.membership": [ 0, 0, - 1154, + 1173, 0, 36, 0 @@ -58589,7 +58589,7 @@ "Package.name": [ 0, 0, - 1166, + 1180, 0, 0, 0 @@ -58599,51 +58599,51 @@ 0, 0, 0, - 1190, + 1209, 0 ], "Package.ownedElement": [ 0, 0, - 1140, + 1157, 0, - 50, + 52, 0 ], "Package.ownedImport": [ - 462, + 474, 0, 0, 0, - 728, + 735, 0 ], "Package.ownedMember": [ - 977, - 56, - 45, - 0, + 987, + 58, 50, + 0, + 52, 62 ], "Package.ownedMembership": [ - 1057, - 73, + 1074, + 74, 11, 0, - 49, + 50, 0 ], "Package.ownedRelationship": [ - 1072, - 84, + 1090, + 85, 0, 0, 34, 0 ], "Package.owner": [ - 1190, + 1209, 0, 0, 0, @@ -58651,7 +58651,7 @@ 0 ], "Package.owningMembership": [ - 1138, + 1152, 28, 0, 0, @@ -58659,7 +58659,7 @@ 0 ], "Package.owningNamespace": [ - 1166, + 1180, 0, 0, 0, @@ -58667,7 +58667,7 @@ 0 ], "Package.owningRelationship": [ - 1162, + 1181, 28, 0, 0, @@ -58675,7 +58675,7 @@ 0 ], "Package.qualifiedName": [ - 460, + 474, 706, 0, 0, @@ -58687,7 +58687,7 @@ 0, 0, 0, - 1190, + 1209, 0 ], "ParameterMembership.aliasIds": [ @@ -58695,7 +58695,7 @@ 0, 0, 0, - 4362, + 4367, 0 ], "ParameterMembership.documentation": [ @@ -58703,7 +58703,7 @@ 0, 0, 0, - 4362, + 4367, 0 ], "ParameterMembership.isImplied": [ @@ -58711,7 +58711,7 @@ 0, 0, 0, - 4362, + 4367, 0 ], "ParameterMembership.isImpliedIncluded": [ @@ -58719,19 +58719,19 @@ 0, 0, 0, - 4362, + 4367, 0 ], "ParameterMembership.isLibraryElement": [ 0, 0, - 4362, + 4367, 0, 0, 0 ], "ParameterMembership.memberElement": [ - 4153, + 4158, 209, 0, 0, @@ -58741,7 +58741,7 @@ "ParameterMembership.memberElementId": [ 0, 0, - 4362, + 4367, 0, 0, 0 @@ -58749,13 +58749,13 @@ "ParameterMembership.memberName": [ 0, 0, - 3773, + 3778, 0, 0, 0 ], "ParameterMembership.membershipOwningNamespace": [ - 4362, + 4367, 0, 0, 0, @@ -58767,7 +58767,7 @@ 0, 0, 0, - 4362, + 4367, 0 ], "ParameterMembership.ownedElement": [ @@ -58775,11 +58775,11 @@ 0, 0, 0, - 4362, + 4367, 0 ], "ParameterMembership.ownedMemberElement": [ - 4153, + 4158, 209, 0, 0, @@ -58789,13 +58789,13 @@ "ParameterMembership.ownedMemberElementId": [ 0, 0, - 4362, + 4367, 0, 0, 0 ], "ParameterMembership.ownedMemberFeature": [ - 4149, + 4154, 209, 4, 0, @@ -58805,13 +58805,13 @@ "ParameterMembership.ownedMemberName": [ 0, 0, - 3773, + 3778, 0, 0, 0 ], "ParameterMembership.ownedMemberParameter": [ - 4153, + 4158, 209, 0, 0, @@ -58819,7 +58819,7 @@ 0 ], "ParameterMembership.ownedRelatedElement": [ - 4153, + 4158, 209, 0, 0, @@ -58831,19 +58831,19 @@ 0, 0, 0, - 4362, + 4367, 0 ], "ParameterMembership.owner": [ 0, 0, 0, - 4362, + 4367, 0, 0 ], "ParameterMembership.owningRelatedElement": [ - 4362, + 4367, 0, 0, 0, @@ -58853,7 +58853,7 @@ "ParameterMembership.owningType": [ 61, 0, - 4301, + 4306, 0, 0, 0 @@ -58861,7 +58861,7 @@ "ParameterMembership.relatedElement": [ 0, 0, - 4362, + 4367, 0, 0, 0 @@ -58869,7 +58869,7 @@ "ParameterMembership.source": [ 0, 0, - 4362, + 4367, 0, 0, 0 @@ -58877,7 +58877,7 @@ "ParameterMembership.target": [ 0, 0, - 4362, + 4367, 0, 0, 0 @@ -58887,13 +58887,13 @@ 0, 0, 0, - 4362, + 4367, 0 ], "ParameterMembership.visibility": [ 0, 0, - 4362, + 4367, 0, 0, 0 @@ -59583,7 +59583,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.chainingFeature": [ @@ -59591,7 +59591,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.crossFeature": [ @@ -59611,7 +59611,7 @@ 0 ], "PartUsage.declaredName": [ - 1733, + 1750, 0, 0, 0, @@ -59629,7 +59629,7 @@ "PartUsage.definition": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -59639,7 +59639,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.directedFeature": [ @@ -59647,7 +59647,7 @@ 0, 137, 0, - 1774, + 1791, 0 ], "PartUsage.directedUsage": [ @@ -59655,7 +59655,7 @@ 0, 137, 0, - 1774, + 1791, 0 ], "PartUsage.direction": [ @@ -59671,7 +59671,7 @@ 0, 9, 0, - 1902, + 1919, 0 ], "PartUsage.endFeature": [ @@ -59679,7 +59679,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.endOwningType": [ @@ -59693,7 +59693,7 @@ "PartUsage.feature": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -59701,7 +59701,7 @@ "PartUsage.featureMembership": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -59709,7 +59709,7 @@ "PartUsage.featureTarget": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -59717,9 +59717,9 @@ "PartUsage.featuringType": [ 0, 0, - 1481, + 1483, 0, - 430, + 445, 0 ], "PartUsage.importedMembership": [ @@ -59727,7 +59727,7 @@ 0, 3, 0, - 1908, + 1925, 0 ], "PartUsage.individualDefinition": [ @@ -59741,7 +59741,7 @@ "PartUsage.inheritedFeature": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -59749,7 +59749,7 @@ "PartUsage.inheritedMembership": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -59759,7 +59759,7 @@ 0, 56, 0, - 1855, + 1872, 0 ], "PartUsage.intersectingType": [ @@ -59767,7 +59767,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.isAbstract": [ @@ -59775,11 +59775,11 @@ 0, 16, 0, - 1884, + 1901, 0 ], "PartUsage.isComposite": [ - 1911, + 1928, 0, 0, 0, @@ -59789,7 +59789,7 @@ "PartUsage.isConjugated": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -59799,7 +59799,7 @@ 0, 21, 0, - 1888, + 1905, 0 ], "PartUsage.isDefault": [ @@ -59815,7 +59815,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.isEnd": [ @@ -59823,7 +59823,7 @@ 0, 0, 0, - 1890, + 1907, 0 ], "PartUsage.isImpliedIncluded": [ @@ -59831,7 +59831,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.isIndividual": [ @@ -59839,13 +59839,13 @@ 0, 0, 0, - 1904, + 1921, 0 ], "PartUsage.isLibraryElement": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -59855,7 +59855,7 @@ 0, 0, 0, - 1901, + 1918, 0 ], "PartUsage.isPortion": [ @@ -59863,13 +59863,13 @@ 0, 0, 0, - 1903, + 1920, 0 ], "PartUsage.isReference": [ 45, 0, - 1866, + 1883, 0, 0, 0 @@ -59887,7 +59887,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.isUnique": [ @@ -59895,15 +59895,15 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.isVariable": [ 0, 0, - 1449, + 1451, 0, - 462, + 477, 0 ], "PartUsage.isVariant": [ @@ -59917,7 +59917,7 @@ "PartUsage.isVariation": [ 16, 0, - 1895, + 1912, 0, 0, 0 @@ -59925,7 +59925,7 @@ "PartUsage.itemDefinition": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -59941,7 +59941,7 @@ "PartUsage.mayTimeVary": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -59949,7 +59949,7 @@ "PartUsage.member": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -59957,7 +59957,7 @@ "PartUsage.membership": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -59965,7 +59965,7 @@ "PartUsage.multiplicity": [ 272, 0, - 1007, + 1009, 0, 0, 0 @@ -59973,7 +59973,7 @@ "PartUsage.name": [ 178, 0, - 1733, + 1750, 0, 0, 0 @@ -59983,7 +59983,7 @@ 0, 204, 0, - 1707, + 1724, 0 ], "PartUsage.nestedAllocation": [ @@ -59991,7 +59991,7 @@ 0, 2, 0, - 1909, + 1926, 0 ], "PartUsage.nestedAnalysisCase": [ @@ -59999,7 +59999,7 @@ 0, 9, 0, - 1902, + 1919, 0 ], "PartUsage.nestedAttribute": [ @@ -60007,7 +60007,7 @@ 0, 437, 0, - 1474, + 1491, 0 ], "PartUsage.nestedCalculation": [ @@ -60015,7 +60015,7 @@ 0, 65, 0, - 1846, + 1863, 0 ], "PartUsage.nestedCase": [ @@ -60023,7 +60023,7 @@ 0, 12, 0, - 1899, + 1916, 0 ], "PartUsage.nestedConcern": [ @@ -60031,7 +60031,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.nestedConnection": [ @@ -60039,7 +60039,7 @@ 0, 96, 0, - 1815, + 1832, 0 ], "PartUsage.nestedConstraint": [ @@ -60047,7 +60047,7 @@ 0, 63, 0, - 1848, + 1865, 0 ], "PartUsage.nestedEnumeration": [ @@ -60055,7 +60055,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.nestedFlow": [ @@ -60063,7 +60063,7 @@ 0, 23, 0, - 1888, + 1905, 0 ], "PartUsage.nestedInterface": [ @@ -60071,7 +60071,7 @@ 0, 17, 0, - 1894, + 1911, 0 ], "PartUsage.nestedItem": [ @@ -60079,15 +60079,15 @@ 0, 391, 0, - 1520, + 1537, 0 ], "PartUsage.nestedMetadata": [ 0, 0, - 107, + 118, 0, - 1804, + 1810, 0 ], "PartUsage.nestedOccurrence": [ @@ -60095,7 +60095,7 @@ 0, 702, 0, - 1209, + 1226, 0 ], "PartUsage.nestedPart": [ @@ -60103,7 +60103,7 @@ 0, 366, 0, - 1545, + 1562, 0 ], "PartUsage.nestedPort": [ @@ -60111,7 +60111,7 @@ 0, 114, 0, - 1797, + 1814, 0 ], "PartUsage.nestedReference": [ @@ -60119,7 +60119,7 @@ 0, 77, 0, - 1834, + 1851, 0 ], "PartUsage.nestedRendering": [ @@ -60127,7 +60127,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.nestedRequirement": [ @@ -60135,7 +60135,7 @@ 0, 42, 0, - 1869, + 1886, 0 ], "PartUsage.nestedState": [ @@ -60143,7 +60143,7 @@ 0, 18, 0, - 1893, + 1910, 0 ], "PartUsage.nestedTransition": [ @@ -60151,7 +60151,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.nestedUsage": [ @@ -60159,7 +60159,7 @@ 0, 995, 0, - 916, + 933, 0 ], "PartUsage.nestedUseCase": [ @@ -60167,7 +60167,7 @@ 0, 2, 0, - 1909, + 1926, 0 ], "PartUsage.nestedVerificationCase": [ @@ -60175,7 +60175,7 @@ 0, 1, 0, - 1910, + 1927, 0 ], "PartUsage.nestedView": [ @@ -60183,7 +60183,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.nestedViewpoint": [ @@ -60191,13 +60191,13 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.occurrenceDefinition": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -60207,7 +60207,7 @@ 0, 122, 0, - 1789, + 1806, 0 ], "PartUsage.ownedAnnotation": [ @@ -60215,7 +60215,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.ownedCrossSubsetting": [ @@ -60231,7 +60231,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.ownedDisjoining": [ @@ -60239,15 +60239,15 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.ownedElement": [ 0, 0, - 1735, + 1742, 0, - 176, + 186, 0 ], "PartUsage.ownedEndFeature": [ @@ -60255,7 +60255,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.ownedFeature": [ @@ -60263,7 +60263,7 @@ 198, 0, 0, - 916, + 933, 45 ], "PartUsage.ownedFeatureChaining": [ @@ -60271,7 +60271,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.ownedFeatureInverting": [ @@ -60279,7 +60279,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.ownedFeatureMembership": [ @@ -60287,7 +60287,7 @@ 0, 0, 0, - 916, + 933, 0 ], "PartUsage.ownedImport": [ @@ -60295,7 +60295,7 @@ 0, 0, 0, - 1908, + 1925, 0 ], "PartUsage.ownedIntersecting": [ @@ -60303,23 +60303,23 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.ownedMember": [ - 345, + 350, 689, - 672, + 674, 0, - 176, + 186, 29 ], "PartUsage.ownedMembership": [ - 706, + 711, 614, - 415, + 417, 0, - 176, + 186, 0 ], "PartUsage.ownedRedefinition": [ @@ -60327,7 +60327,7 @@ 0, 0, 0, - 1705, + 1722, 0 ], "PartUsage.ownedReferenceSubsetting": [ @@ -60339,27 +60339,27 @@ 0 ], "PartUsage.ownedRelationship": [ - 305, - 1514, + 320, + 1516, 52, 0, 40, 0 ], "PartUsage.ownedSpecialization": [ - 1476, + 1488, 35, 0, 0, - 400, + 405, 0 ], "PartUsage.ownedSubsetting": [ - 355, + 367, 12, 2, 0, - 1542, + 1547, 0 ], "PartUsage.ownedTypeFeaturing": [ @@ -60367,7 +60367,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.ownedTyping": [ @@ -60375,7 +60375,7 @@ 0, 0, 0, - 705, + 722, 0 ], "PartUsage.ownedUnioning": [ @@ -60383,11 +60383,11 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.owner": [ - 1911, + 1928, 0, 0, 0, @@ -60405,13 +60405,13 @@ "PartUsage.owningFeatureMembership": [ 0, 0, - 1461, + 1463, 0, 0, 0 ], "PartUsage.owningMembership": [ - 1898, + 1915, 13, 0, 0, @@ -60419,7 +60419,7 @@ 0 ], "PartUsage.owningNamespace": [ - 1911, + 1928, 0, 0, 0, @@ -60427,7 +60427,7 @@ 0 ], "PartUsage.owningRelationship": [ - 1898, + 1915, 13, 0, 0, @@ -60437,7 +60437,7 @@ "PartUsage.owningType": [ 0, 0, - 1461, + 1463, 0, 0, 0 @@ -60445,7 +60445,7 @@ "PartUsage.owningUsage": [ 0, 0, - 877, + 879, 0, 0, 0 @@ -60453,7 +60453,7 @@ "PartUsage.partDefinition": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -60467,7 +60467,7 @@ 0 ], "PartUsage.qualifiedName": [ - 1119, + 1136, 789, 0, 3, @@ -60494,7 +60494,7 @@ 0, 0, 0, - 167, + 179, 0, 0 ], @@ -60503,13 +60503,13 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.type": [ 979, 227, - 705, + 722, 0, 0, 0 @@ -60519,7 +60519,7 @@ 0, 0, 0, - 1911, + 1928, 0 ], "PartUsage.upperBound": [ @@ -60533,7 +60533,7 @@ "PartUsage.usage": [ 0, 0, - 1911, + 1928, 0, 0, 0 @@ -60551,7 +60551,7 @@ 1, 0, 0, - 1895, + 1912, 0 ], "PartUsage.variantMembership": [ @@ -60559,7 +60559,7 @@ 0, 0, 0, - 1895, + 1912, 0 ], "PayloadFeature.aliasIds": [ @@ -69447,7 +69447,7 @@ 0, 0, 0, - 4649, + 4654, 0 ], "ReturnParameterMembership.documentation": [ @@ -69455,7 +69455,7 @@ 0, 0, 0, - 4649, + 4654, 0 ], "ReturnParameterMembership.isImplied": [ @@ -69463,7 +69463,7 @@ 0, 0, 0, - 4649, + 4654, 0 ], "ReturnParameterMembership.isImpliedIncluded": [ @@ -69471,20 +69471,20 @@ 0, 0, 0, - 4649, + 4654, 0 ], "ReturnParameterMembership.isLibraryElement": [ 0, 0, - 4649, + 4654, 0, 0, 0 ], "ReturnParameterMembership.memberElement": [ 4315, - 334, + 339, 0, 0, 0, @@ -69493,7 +69493,7 @@ "ReturnParameterMembership.memberElementId": [ 0, 0, - 4649, + 4654, 0, 0, 0 @@ -69501,13 +69501,13 @@ "ReturnParameterMembership.memberName": [ 0, 0, - 4649, + 4654, 0, 0, 0 ], "ReturnParameterMembership.membershipOwningNamespace": [ - 4649, + 4654, 0, 0, 0, @@ -69519,7 +69519,7 @@ 0, 0, 0, - 4649, + 4654, 0 ], "ReturnParameterMembership.ownedElement": [ @@ -69527,12 +69527,12 @@ 0, 0, 0, - 4649, + 4654, 0 ], "ReturnParameterMembership.ownedMemberElement": [ 4315, - 334, + 339, 0, 0, 0, @@ -69541,14 +69541,14 @@ "ReturnParameterMembership.ownedMemberElementId": [ 0, 0, - 4649, + 4654, 0, 0, 0 ], "ReturnParameterMembership.ownedMemberFeature": [ 4314, - 334, + 339, 1, 0, 0, @@ -69557,14 +69557,14 @@ "ReturnParameterMembership.ownedMemberName": [ 0, 0, - 4649, + 4654, 0, 0, 0 ], "ReturnParameterMembership.ownedMemberParameter": [ 4315, - 334, + 339, 0, 0, 0, @@ -69572,7 +69572,7 @@ ], "ReturnParameterMembership.ownedRelatedElement": [ 4315, - 334, + 339, 0, 0, 0, @@ -69583,19 +69583,19 @@ 0, 0, 0, - 4649, + 4654, 0 ], "ReturnParameterMembership.owner": [ 0, 0, 0, - 4649, + 4654, 0, 0 ], "ReturnParameterMembership.owningRelatedElement": [ - 4649, + 4654, 0, 0, 0, @@ -69605,7 +69605,7 @@ "ReturnParameterMembership.owningType": [ 171, 0, - 4478, + 4483, 0, 0, 0 @@ -69613,7 +69613,7 @@ "ReturnParameterMembership.relatedElement": [ 0, 0, - 4649, + 4654, 0, 0, 0 @@ -69621,7 +69621,7 @@ "ReturnParameterMembership.source": [ 0, 0, - 4649, + 4654, 0, 0, 0 @@ -69629,7 +69629,7 @@ "ReturnParameterMembership.target": [ 0, 0, - 4649, + 4654, 0, 0, 0 @@ -69639,13 +69639,13 @@ 0, 0, 0, - 4649, + 4654, 0 ], "ReturnParameterMembership.visibility": [ 0, 0, - 4649, + 4654, 0, 0, 0 @@ -75655,7 +75655,7 @@ 0, 0, 0, - 779, + 791, 0 ], "Subsetting.declaredName": [ @@ -75671,12 +75671,12 @@ 0, 0, 0, - 779, + 791, 0 ], "Subsetting.general": [ - 309, - 43, + 315, + 49, 2, 0, 0, @@ -75687,7 +75687,7 @@ 0, 0, 0, - 779, + 791, 0 ], "Subsetting.isImpliedIncluded": [ @@ -75695,13 +75695,13 @@ 0, 0, 0, - 779, + 791, 0 ], "Subsetting.isLibraryElement": [ 0, 0, - 779, + 791, 0, 0, 0 @@ -75719,7 +75719,7 @@ 0, 0, 0, - 779, + 791, 0 ], "Subsetting.ownedElement": [ @@ -75727,7 +75727,7 @@ 0, 0, 0, - 779, + 791, 0 ], "Subsetting.ownedRelatedElement": [ @@ -75735,7 +75735,7 @@ 0, 0, 0, - 765, + 777, 0 ], "Subsetting.ownedRelationship": [ @@ -75743,19 +75743,19 @@ 0, 0, 0, - 779, + 791, 0 ], "Subsetting.owner": [ 2, 0, 0, - 777, + 789, 0, 0 ], "Subsetting.owningFeature": [ - 777, + 789, 0, 0, 0, @@ -75779,7 +75779,7 @@ 0 ], "Subsetting.owningRelatedElement": [ - 777, + 789, 0, 0, 0, @@ -75797,7 +75797,7 @@ "Subsetting.owningType": [ 0, 0, - 777, + 789, 0, 0, 0 @@ -75811,15 +75811,15 @@ 0 ], "Subsetting.relatedElement": [ - 308, - 44, + 314, + 50, 2, 0, 0, 425 ], "Subsetting.source": [ - 777, + 789, 0, 2, 0, @@ -75827,7 +75827,7 @@ 0 ], "Subsetting.specific": [ - 777, + 789, 0, 2, 0, @@ -75835,15 +75835,15 @@ 0 ], "Subsetting.subsettedFeature": [ - 310, - 44, + 316, + 50, 0, 0, 0, 425 ], "Subsetting.subsettingFeature": [ - 778, + 790, 1, 0, 0, @@ -75851,8 +75851,8 @@ 0 ], "Subsetting.target": [ - 309, - 43, + 315, + 49, 2, 0, 0, @@ -75863,7 +75863,7 @@ 0, 0, 0, - 779, + 791, 0 ], "Succession.aliasIds": [ @@ -87495,7 +87495,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.chainingFeature": [ @@ -87503,11 +87503,11 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.declaredName": [ - 80, + 81, 0, 0, 0, @@ -87517,7 +87517,7 @@ "ViewUsage.definition": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87527,7 +87527,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.directedFeature": [ @@ -87535,7 +87535,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.directedUsage": [ @@ -87543,7 +87543,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.documentation": [ @@ -87551,7 +87551,7 @@ 0, 21, 0, - 61, + 62, 0 ], "ViewUsage.endFeature": [ @@ -87559,13 +87559,13 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.exposedElement": [ 0, 0, - 69, + 70, 0, 13, 0 @@ -87573,7 +87573,7 @@ "ViewUsage.feature": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87581,7 +87581,7 @@ "ViewUsage.featureMembership": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87589,7 +87589,7 @@ "ViewUsage.featureTarget": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87599,13 +87599,13 @@ 0, 11, 0, - 71, + 72, 0 ], "ViewUsage.importedMembership": [ 0, 0, - 71, + 72, 0, 11, 0 @@ -87613,7 +87613,7 @@ "ViewUsage.inheritedFeature": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87621,7 +87621,7 @@ "ViewUsage.inheritedMembership": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87631,7 +87631,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.intersectingType": [ @@ -87639,7 +87639,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.isAbstract": [ @@ -87647,11 +87647,11 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.isComposite": [ - 82, + 83, 0, 0, 0, @@ -87661,7 +87661,7 @@ "ViewUsage.isConjugated": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87671,7 +87671,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.isDerived": [ @@ -87679,7 +87679,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.isEnd": [ @@ -87687,7 +87687,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.isImpliedIncluded": [ @@ -87695,7 +87695,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.isIndividual": [ @@ -87703,13 +87703,13 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.isLibraryElement": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87719,7 +87719,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.isPortion": [ @@ -87727,13 +87727,13 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.isReference": [ 1, 0, - 81, + 82, 0, 0, 0 @@ -87743,7 +87743,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.isUnique": [ @@ -87751,7 +87751,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.isVariable": [ @@ -87759,13 +87759,13 @@ 0, 11, 0, - 71, + 72, 0 ], "ViewUsage.isVariation": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87773,7 +87773,7 @@ "ViewUsage.itemDefinition": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87789,7 +87789,7 @@ "ViewUsage.mayTimeVary": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87797,7 +87797,7 @@ "ViewUsage.member": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87805,7 +87805,7 @@ "ViewUsage.membership": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -87821,7 +87821,7 @@ "ViewUsage.name": [ 2, 0, - 80, + 81, 0, 0, 0 @@ -87831,7 +87831,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedAllocation": [ @@ -87839,7 +87839,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedAnalysisCase": [ @@ -87847,7 +87847,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedAttribute": [ @@ -87855,7 +87855,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedCalculation": [ @@ -87863,7 +87863,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedCase": [ @@ -87871,7 +87871,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedConcern": [ @@ -87879,7 +87879,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedConnection": [ @@ -87887,7 +87887,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedConstraint": [ @@ -87895,7 +87895,7 @@ 0, 7, 0, - 75, + 76, 0 ], "ViewUsage.nestedEnumeration": [ @@ -87903,7 +87903,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedFlow": [ @@ -87911,7 +87911,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedInterface": [ @@ -87919,13 +87919,13 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedItem": [ 0, 0, - 33, + 34, 0, 49, 0 @@ -87933,7 +87933,7 @@ "ViewUsage.nestedMetadata": [ 0, 0, - 18, + 19, 0, 64, 0 @@ -87941,7 +87941,7 @@ "ViewUsage.nestedOccurrence": [ 0, 0, - 36, + 37, 0, 46, 0 @@ -87949,7 +87949,7 @@ "ViewUsage.nestedPart": [ 0, 0, - 33, + 34, 0, 49, 0 @@ -87959,7 +87959,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedReference": [ @@ -87967,7 +87967,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedRendering": [ @@ -87975,7 +87975,7 @@ 0, 29, 0, - 53, + 54, 0 ], "ViewUsage.nestedRequirement": [ @@ -87983,7 +87983,7 @@ 0, 7, 0, - 75, + 76, 0 ], "ViewUsage.nestedState": [ @@ -87991,7 +87991,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedTransition": [ @@ -87999,13 +87999,13 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedUsage": [ 0, 0, - 36, + 37, 0, 46, 0 @@ -88015,7 +88015,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedVerificationCase": [ @@ -88023,7 +88023,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.nestedView": [ @@ -88031,7 +88031,7 @@ 0, 4, 0, - 78, + 79, 0 ], "ViewUsage.nestedViewpoint": [ @@ -88039,13 +88039,13 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.occurrenceDefinition": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -88055,7 +88055,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.ownedAnnotation": [ @@ -88063,7 +88063,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.ownedDifferencing": [ @@ -88071,7 +88071,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.ownedDisjoining": [ @@ -88079,13 +88079,13 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.ownedElement": [ 0, 0, - 67, + 68, 0, 15, 0 @@ -88095,11 +88095,11 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.ownedFeature": [ - 32, + 33, 4, 0, 0, @@ -88111,7 +88111,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.ownedFeatureInverting": [ @@ -88119,11 +88119,11 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.ownedFeatureMembership": [ - 36, + 37, 0, 0, 0, @@ -88131,7 +88131,7 @@ 0 ], "ViewUsage.ownedImport": [ - 71, + 72, 0, 0, 0, @@ -88143,11 +88143,11 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.ownedMember": [ - 37, + 38, 11, 9, 0, @@ -88155,7 +88155,7 @@ 0 ], "ViewUsage.ownedMembership": [ - 49, + 50, 3, 5, 0, @@ -88167,11 +88167,11 @@ 0, 0, 0, - 80, + 81, 0 ], "ViewUsage.ownedRelationship": [ - 33, + 34, 49, 0, 0, @@ -88183,7 +88183,7 @@ 0, 0, 0, - 32, + 33, 0 ], "ViewUsage.ownedSubsetting": [ @@ -88191,7 +88191,7 @@ 0, 0, 0, - 73, + 74, 0 ], "ViewUsage.ownedTypeFeaturing": [ @@ -88199,7 +88199,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.ownedTyping": [ @@ -88207,7 +88207,7 @@ 0, 0, 0, - 41, + 42, 0 ], "ViewUsage.ownedUnioning": [ @@ -88215,11 +88215,11 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.owner": [ - 82, + 83, 0, 0, 0, @@ -88243,7 +88243,7 @@ 0 ], "ViewUsage.owningMembership": [ - 81, + 82, 1, 0, 0, @@ -88251,7 +88251,7 @@ 0 ], "ViewUsage.owningNamespace": [ - 82, + 83, 0, 0, 0, @@ -88259,7 +88259,7 @@ 0 ], "ViewUsage.owningRelationship": [ - 81, + 82, 1, 0, 0, @@ -88285,13 +88285,13 @@ "ViewUsage.partDefinition": [ 0, 0, - 82, + 83, 0, 0, 0 ], "ViewUsage.qualifiedName": [ - 66, + 67, 16, 0, 0, @@ -88311,7 +88311,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.subsets": [ @@ -88327,13 +88327,13 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.type": [ 9, 3, - 41, + 42, 0, 0, 29 @@ -88343,7 +88343,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.upperBound": [ @@ -88357,7 +88357,7 @@ "ViewUsage.usage": [ 0, 0, - 82, + 83, 0, 0, 0 @@ -88367,7 +88367,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.variantMembership": [ @@ -88375,7 +88375,7 @@ 0, 0, 0, - 82, + 83, 0 ], "ViewUsage.viewCondition": [ @@ -88383,13 +88383,13 @@ 0, 7, 0, - 75, + 76, 0 ], "ViewUsage.viewDefinition": [ 0, 0, - 82, + 83, 0, 0, 0 diff --git a/docs/project/api-json-differential.md b/docs/project/api-json-differential.md index 85b5877f95..12f0992a61 100644 --- a/docs/project/api-json-differential.md +++ b/docs/project/api-json-differential.md @@ -171,11 +171,11 @@ metaclass when the two sides disagree on the metaclass (`typeMismatch`). The pinned pilot's verdict on the probe (`validate-sysml-batch`): clean. -## Results (pilot `2026-08`, 920 files) +## Results (pilot `2026-08`, 924 files) -**Scorecard:** 920 files; 86974 elements matched (29497 ours-only, 40387 pilot-only, 0 of them implied); properties: 596664 present-equal, 47633 present-different, 1021444 ours-missing, 65920 pilot-missing, 2020649 absent-both, 20867 indeterminate. +**Scorecard:** 924 files; 87130 elements matched (29503 ours-only, 40452 pilot-only, 0 of them implied); properties: 597627 present-equal, 47752 present-different, 1023009 ours-missing, 66058 pilot-missing, 2023975 absent-both, 20867 indeterminate. -The pilot's export failed on 59 files (`pilotFailed`: its own export throws on an element without a resource, 53 of them specification examples; the files are named in the run's text report), ours refused 40 (all of them specification examples the parser could not read whole), left the pilot's 59 failed files out and converted 24 documents alone for declaring an element another document of their root declares (`oursColliding`); no root fell back to per-document conversion. 11311 (metaclass, property) rows carry a comparison; 100645 references compared through the unkeyed sentinel, 140342 of our `sysx:` annotations were left out, and 289/345 elements (ours/pilot) were dropped for ambiguous keys, 8198/32520 for having none. +The pilot's export failed on 59 files (`pilotFailed`: its own export throws on an element without a resource, 53 of them specification examples; the files are named in the run's text report), ours refused 40 (all of them specification examples the parser could not read whole), left the pilot's 59 failed files out and converted 26 documents alone for declaring an element another document of their root declares (`oursColliding`); no root fell back to per-document conversion. 11311 (metaclass, property) rows carry a comparison; 100645 references compared through the unkeyed sentinel, 140342 of our `sysx:` annotations were left out, and 289/345 elements (ours/pilot) were dropped for ambiguous keys, 8198/32520 for having none. | root | files | matched | ours-only | pilot-only | present-equal | present-different | ours-missing | pilot-missing | |---|---:|---:|---:|---:|---:|---:|---:|---:| @@ -265,37 +265,37 @@ The (metaclass, property) rows ranked by the corpus elements on which the pilot | # | metaclass | property | ours-missing | present-different | in-flight overlap | derivation clause | |---:|---|---|---:|---:|---|---| -| 1 | `FeatureMembership` | `isLibraryElement` | 10467 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`; writes `true` on library elements only, never `false`) | `Element::isLibraryElement = libraryNamespace() <> null` (KerML 8.3.2.1, deriveElementIsLibraryElement); the pilot writes `false` on every user element | -| 2 | `FeatureMembership` | `memberElementId` | 10467 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Membership::memberElementId = memberElement.elementId` (KerML 8.3.2.3.5, deriveMembershipMemberElementId) | -| 3 | `FeatureMembership` | `ownedMemberElementId` | 10467 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `OwningMembership::ownedMemberElementId = ownedMemberElement.elementId` (KerML 8.3.2.3.6) | -| 4 | `FeatureMembership` | `relatedElement` | 10467 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::relatedElement = source->union(target)`, ordered (KerML 8.3.2.5.2, deriveRelationshipRelatedElement) | -| 5 | `FeatureMembership` | `source` | 10467 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::source`, which Membership redefines as `[membershipOwningNamespace]` (KerML 8.3.2.3.5) | -| 6 | `FeatureMembership` | `target` | 10467 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::target`, which Membership redefines as `[memberElement]` (KerML 8.3.2.3.5) | -| 7 | `FeatureMembership` | `visibility` | 10403 | 1 | PR #1232 (`feature/api-json-derived-properties-layered`) | owned attribute `Membership::visibility : VisibilityKind`, default `public` (KerML 8.3.2.3.5); not derived | -| 8 | `Feature` | `featureTarget` | 9905 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Feature::featureTarget`: the last `chainingFeature`, else the feature itself (KerML 8.3.3.3, deriveFeatureFeatureTarget; KERML11-1 crossFeature) | -| 9 | `Feature` | `inheritedFeature` | 9905 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Type::inheritedFeature = inheritedMembership.memberElement->selectByKind(Feature)` (KerML 8.3.3.1, deriveTypeInheritedFeature) | -| 10 | `Feature` | `inheritedMembership` | 9905 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Type::inheritedMembership = inheritedMemberships(excluded)` over the supertypes (KerML 8.3.3.1, deriveTypeInheritedMembership) | -| 11 | `Feature` | `isConjugated` | 9905 | 0 | none found | `Type::isConjugated = ownedConjugator <> null` (KerML 8.3.3.1 Type; a derived attribute without a named derive constraint); the pilot writes `false` on every type | -| 12 | `Feature` | `isLibraryElement` | 9905 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`; writes `true` on library elements only, never `false`) | `Element::isLibraryElement = libraryNamespace() <> null` (KerML 8.3.2.1, deriveElementIsLibraryElement); the pilot writes `false` on every user element | -| 13 | `Feature` | `member` | 9905 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Namespace::member = membership.memberElement` (KerML 8.3.2.4, deriveNamespaceMember) | -| 14 | `Feature` | `membership` | 9905 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Namespace::membership = ownedMembership->union(importedMembership)`, and for a Type also `inheritedMembership` (KerML 8.3.2.4, 8.3.3.1) | -| 15 | `Feature` | `feature` | 9899 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Type::feature = featureMembership.ownedMemberFeature` (KerML 8.3.3.1, deriveTypeFeature) | -| 16 | `Feature` | `featureMembership` | 9899 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Type::featureMembership = ownedFeatureMembership->union(inheritedMembership->selectByKind(FeatureMembership))` (KerML 8.3.3.1; KERML11-191 restricts the inherited part to the supertypes) | -| 17 | `Feature` | `featuringType` | 9626 | 2 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Feature::featuringType = typeFeaturing.featuringType`, plus the owning type of an owned feature (KerML 8.3.3.3, deriveFeatureFeaturingType; KERML11-3/4 multiplicity featuring) | -| 18 | `Feature` | `owningFeatureMembership` | 9345 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Feature::owningFeatureMembership = owningMembership->selectByKind(FeatureMembership)` (KerML 8.3.3.3) | -| 19 | `Feature` | `owningType` | 9345 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Feature::owningType = owningFeatureMembership.owningType` (KerML 8.3.3.3, deriveFeatureOwningType) | -| 20 | `Feature` | `type` | 9266 | 120 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Feature::type = typing.type` with the types inherited through chaining and redefinition (KerML 8.3.3.3, deriveFeatureType) | -| 21 | `OwningMembership` | `isLibraryElement` | 9220 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`; writes `true` on library elements only, never `false`) | `Element::isLibraryElement = libraryNamespace() <> null` (KerML 8.3.2.1, deriveElementIsLibraryElement); the pilot writes `false` on every user element | -| 22 | `OwningMembership` | `relatedElement` | 9220 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::relatedElement = source->union(target)`, ordered (KerML 8.3.2.5.2, deriveRelationshipRelatedElement) | -| 23 | `OwningMembership` | `source` | 9220 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::source`, which Membership redefines as `[membershipOwningNamespace]` (KerML 8.3.2.3.5) | -| 24 | `OwningMembership` | `memberElementId` | 9217 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Membership::memberElementId = memberElement.elementId` (KerML 8.3.2.3.5, deriveMembershipMemberElementId) | -| 25 | `OwningMembership` | `ownedMemberElementId` | 9217 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `OwningMembership::ownedMemberElementId = ownedMemberElement.elementId` (KerML 8.3.2.3.6) | -| 26 | `OwningMembership` | `target` | 9217 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::target`, which Membership redefines as `[memberElement]` (KerML 8.3.2.3.5) | -| 27 | `OwningMembership` | `visibility` | 9195 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | owned attribute `Membership::visibility : VisibilityKind`, default `public` (KerML 8.3.2.3.5); not derived | -| 28 | `Feature` | `name` | 8817 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Element::name = effectiveName()`: the declared name, or for a feature the name of the feature it redefines (KerML 8.3.2.1, deriveElementName) | -| 29 | `FeatureMembership` | `memberName` | 8676 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Membership::memberName = memberElement.name` (KerML 8.3.2.3.5, deriveMembershipMemberName) | -| 30 | `FeatureMembership` | `ownedMemberName` | 8676 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `OwningMembership::ownedMemberName = ownedMemberElement.name` (KerML 8.3.2.3.6) | -| 31 | `Feature` | `owningNamespace` | 8586 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Element::owningNamespace = owningMembership.membershipOwningNamespace` (KerML 8.3.2.1, deriveElementOwningNamespace) | +| 1 | `FeatureMembership` | `isLibraryElement` | 10469 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`; writes `true` on library elements only, never `false`) | `Element::isLibraryElement = libraryNamespace() <> null` (KerML 8.3.2.1, deriveElementIsLibraryElement); the pilot writes `false` on every user element | +| 2 | `FeatureMembership` | `memberElementId` | 10469 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Membership::memberElementId = memberElement.elementId` (KerML 8.3.2.3.5, deriveMembershipMemberElementId) | +| 3 | `FeatureMembership` | `ownedMemberElementId` | 10469 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `OwningMembership::ownedMemberElementId = ownedMemberElement.elementId` (KerML 8.3.2.3.6) | +| 4 | `FeatureMembership` | `relatedElement` | 10469 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::relatedElement = source->union(target)`, ordered (KerML 8.3.2.5.2, deriveRelationshipRelatedElement) | +| 5 | `FeatureMembership` | `source` | 10469 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::source`, which Membership redefines as `[membershipOwningNamespace]` (KerML 8.3.2.3.5) | +| 6 | `FeatureMembership` | `target` | 10469 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::target`, which Membership redefines as `[memberElement]` (KerML 8.3.2.3.5) | +| 7 | `FeatureMembership` | `visibility` | 10405 | 1 | PR #1232 (`feature/api-json-derived-properties-layered`) | owned attribute `Membership::visibility : VisibilityKind`, default `public` (KerML 8.3.2.3.5); not derived | +| 8 | `Feature` | `featureTarget` | 9915 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Feature::featureTarget`: the last `chainingFeature`, else the feature itself (KerML 8.3.3.3, deriveFeatureFeatureTarget; KERML11-1 crossFeature) | +| 9 | `Feature` | `inheritedFeature` | 9915 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Type::inheritedFeature = inheritedMembership.memberElement->selectByKind(Feature)` (KerML 8.3.3.1, deriveTypeInheritedFeature) | +| 10 | `Feature` | `inheritedMembership` | 9915 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Type::inheritedMembership = inheritedMemberships(excluded)` over the supertypes (KerML 8.3.3.1, deriveTypeInheritedMembership) | +| 11 | `Feature` | `isConjugated` | 9915 | 0 | none found | `Type::isConjugated = ownedConjugator <> null` (KerML 8.3.3.1 Type; a derived attribute without a named derive constraint); the pilot writes `false` on every type | +| 12 | `Feature` | `isLibraryElement` | 9915 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`; writes `true` on library elements only, never `false`) | `Element::isLibraryElement = libraryNamespace() <> null` (KerML 8.3.2.1, deriveElementIsLibraryElement); the pilot writes `false` on every user element | +| 13 | `Feature` | `member` | 9915 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Namespace::member = membership.memberElement` (KerML 8.3.2.4, deriveNamespaceMember) | +| 14 | `Feature` | `membership` | 9915 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Namespace::membership = ownedMembership->union(importedMembership)`, and for a Type also `inheritedMembership` (KerML 8.3.2.4, 8.3.3.1) | +| 15 | `Feature` | `feature` | 9909 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Type::feature = featureMembership.ownedMemberFeature` (KerML 8.3.3.1, deriveTypeFeature) | +| 16 | `Feature` | `featureMembership` | 9909 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Type::featureMembership = ownedFeatureMembership->union(inheritedMembership->selectByKind(FeatureMembership))` (KerML 8.3.3.1; KERML11-191 restricts the inherited part to the supertypes) | +| 17 | `Feature` | `featuringType` | 9636 | 2 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Feature::featuringType = typeFeaturing.featuringType`, plus the owning type of an owned feature (KerML 8.3.3.3, deriveFeatureFeaturingType; KERML11-3/4 multiplicity featuring) | +| 18 | `Feature` | `owningFeatureMembership` | 9355 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Feature::owningFeatureMembership = owningMembership->selectByKind(FeatureMembership)` (KerML 8.3.3.3) | +| 19 | `Feature` | `owningType` | 9355 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Feature::owningType = owningFeatureMembership.owningType` (KerML 8.3.3.3, deriveFeatureOwningType) | +| 20 | `Feature` | `type` | 9276 | 120 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Feature::type = typing.type` with the types inherited through chaining and redefinition (KerML 8.3.3.3, deriveFeatureType) | +| 21 | `OwningMembership` | `isLibraryElement` | 9262 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`; writes `true` on library elements only, never `false`) | `Element::isLibraryElement = libraryNamespace() <> null` (KerML 8.3.2.1, deriveElementIsLibraryElement); the pilot writes `false` on every user element | +| 22 | `OwningMembership` | `relatedElement` | 9262 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::relatedElement = source->union(target)`, ordered (KerML 8.3.2.5.2, deriveRelationshipRelatedElement) | +| 23 | `OwningMembership` | `source` | 9262 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::source`, which Membership redefines as `[membershipOwningNamespace]` (KerML 8.3.2.3.5) | +| 24 | `OwningMembership` | `memberElementId` | 9259 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Membership::memberElementId = memberElement.elementId` (KerML 8.3.2.3.5, deriveMembershipMemberElementId) | +| 25 | `OwningMembership` | `ownedMemberElementId` | 9259 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `OwningMembership::ownedMemberElementId = ownedMemberElement.elementId` (KerML 8.3.2.3.6) | +| 26 | `OwningMembership` | `target` | 9259 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::target`, which Membership redefines as `[memberElement]` (KerML 8.3.2.3.5) | +| 27 | `OwningMembership` | `visibility` | 9237 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | owned attribute `Membership::visibility : VisibilityKind`, default `public` (KerML 8.3.2.3.5); not derived | +| 28 | `Feature` | `name` | 8827 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Element::name = effectiveName()`: the declared name, or for a feature the name of the feature it redefines (KerML 8.3.2.1, deriveElementName) | +| 29 | `FeatureMembership` | `memberName` | 8678 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Membership::memberName = memberElement.name` (KerML 8.3.2.3.5, deriveMembershipMemberName) | +| 30 | `FeatureMembership` | `ownedMemberName` | 8678 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `OwningMembership::ownedMemberName = ownedMemberElement.name` (KerML 8.3.2.3.6) | +| 31 | `Feature` | `owningNamespace` | 8596 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Element::owningNamespace = owningMembership.membershipOwningNamespace` (KerML 8.3.2.1, deriveElementOwningNamespace) | | 32 | `FeatureValue` | `isLibraryElement` | 6661 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`; writes `true` on library elements only, never `false`) | `Element::isLibraryElement = libraryNamespace() <> null` (KerML 8.3.2.1, deriveElementIsLibraryElement); the pilot writes `false` on every user element | | 33 | `FeatureValue` | `memberElementId` | 6661 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Membership::memberElementId = memberElement.elementId` (KerML 8.3.2.3.5, deriveMembershipMemberElementId) | | 34 | `FeatureValue` | `ownedMemberElementId` | 6661 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `OwningMembership::ownedMemberElementId = ownedMemberElement.elementId` (KerML 8.3.2.3.6) | @@ -303,8 +303,8 @@ The (metaclass, property) rows ranked by the corpus elements on which the pilot | 36 | `FeatureValue` | `source` | 6661 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::source`, which Membership redefines as `[membershipOwningNamespace]` (KerML 8.3.2.3.5) | | 37 | `FeatureValue` | `target` | 6661 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Relationship::target`, which Membership redefines as `[memberElement]` (KerML 8.3.2.3.5) | | 38 | `FeatureValue` | `visibility` | 6661 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | owned attribute `Membership::visibility : VisibilityKind`, default `public` (KerML 8.3.2.3.5); not derived | -| 39 | `FeatureTyping` | `isLibraryElement` | 5646 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`; writes `true` on library elements only, never `false`) | `Element::isLibraryElement = libraryNamespace() <> null` (KerML 8.3.2.1, deriveElementIsLibraryElement); the pilot writes `false` on every user element | -| 40 | `FeatureTyping` | `owningType` | 5642 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Feature::owningType = owningFeatureMembership.owningType` (KerML 8.3.3.3, deriveFeatureOwningType) | +| 39 | `FeatureTyping` | `isLibraryElement` | 5651 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`; writes `true` on library elements only, never `false`) | `Element::isLibraryElement = libraryNamespace() <> null` (KerML 8.3.2.1, deriveElementIsLibraryElement); the pilot writes `false` on every user element | +| 40 | `FeatureTyping` | `owningType` | 5647 | 0 | PR #1232 (`feature/api-json-derived-properties-layered`) | `Feature::owningType = owningFeatureMembership.owningType` (KerML 8.3.3.3, deriveFeatureOwningType) | Rows an evaluator rule in PR #1232 (`internal/semantic/metamodel/rules.go`) already names are marked; that PR adds a lazy metamodel evaluator and layers its derived values into the API-JSON writer, so its merge is expected to move those rows from ours-missing to present-equal or present-different, and this referee is how that movement is measured. From 9011c4f4ffe6b78f98b2adb0d099f02e4164a37a Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 23:08:09 +0000 Subject: [PATCH 6/6] fix(semantics): let only a library element satisfy a library type by name A workspace namesake of a library type no longer conforms to it through the library-copy name fallback, and Base::Anything is the top type only as the library declares it, not as a workspace type of that name. Co-Authored-By: jason.han --- .../filter-conformance-by-element.fixed.md | 2 +- docs/project/spec-compliance.md | 2 +- internal/semantic/semantics/filter.go | 18 +++++-- .../semantics/filter_identity_test.go | 53 +++++++++++++++++++ internal/semantic/semantics/model.go | 8 ++- internal/semantic/semantics/model_test.go | 1 + 6 files changed, 77 insertions(+), 7 deletions(-) diff --git a/changes/unreleased/filter-conformance-by-element.fixed.md b/changes/unreleased/filter-conformance-by-element.fixed.md index ff8df42468..25eebb8d93 100644 --- a/changes/unreleased/filter-conformance-by-element.fixed.md +++ b/changes/unreleased/filter-conformance-by-element.fixed.md @@ -1 +1 @@ -- An element filter (`filter @T;`, `import P::*[@T]`, `expose X::**[@T]`) and a classification (`@T`, `@@T`) now test conformance against the Type element the name resolves to, through its specialization closure, rather than against the qualified name: a type named through an `alias` or a re-exporting import selects what the aliased Type annotates, and a distinct Type that shares the qualified name (the same package opened in another document) selects nothing it does not annotate. The name alone decides only when it resolves to no element, or across copies of a library document. +- An element filter (`filter @T;`, `import P::*[@T]`, `expose X::**[@T]`) and a classification (`@T`, `@@T`) now test conformance against the Type element the name resolves to, through its specialization closure, rather than against the qualified name: a type named through an `alias` or a re-exporting import selects what the aliased Type annotates, and a distinct Type that shares the qualified name (the same package opened in another document) selects nothing it does not annotate. The name alone decides only when it resolves to no element, or between two library copies of one declaration (a workspace namesake of a library type is not that type); likewise `Base::Anything` is the top type every type conforms to only as the library declares it, not as a workspace type of that name. diff --git a/docs/project/spec-compliance.md b/docs/project/spec-compliance.md index a35dbc3d3b..c041bdbfe9 100644 --- a/docs/project/spec-compliance.md +++ b/docs/project/spec-compliance.md @@ -2264,7 +2264,7 @@ semantics layer over the conjugation parity of the typing/specialization chain. | `%render [text\|mermaid\|markdown\|dot\|plantuml\|d2\|csv\|tsv [palette]]` renders a declared or pseudo-view at the prompt; `sysml -render [-render-form ] [-render-palette ] [-o file]` renders one outside it, and `sysml -render-all [-render-form ]` writes every declared view separately. D2 writes only tree, interconnection, state, action, sequence, requirement, definition and package renderings; case and mixed views refuse it with a typed error | `repl/view.go` `Session.ViewRendering`, `renderPseudoView`, `Views`, `renderLines`, `viewRenderer` (a semantic model and resolver of its own over the session's symbol index, so no runtime is built); `model/selection.go` shares declaration-order view enumeration and targetless top-level selection across model and session paths; `repl/meta.go` (the `%render` arm, help entry), `repl/complete.go` (the form completion); `cmd/sysml/render.go` `runRender`, `runRenderAll`, `loadRenderingModel`, `writeArtifactFile` (one artifact on stdout or `-o`, or one file per declared view with render-all reporting on stderr); `cmd/sysml/main.go` (rendering modes are mutually exclusive with conversion and checks) | `repl/view_render_test.go` `TestRenderDefaultsToATree`, `TestRenderWritesMermaidWhenAskedFor`, `TestRenderOfATabularView`, `TestRenderOfAnUnknownNameReports`, `TestPseudoViewsRenderThroughTheSession`, `TestPseudoViewErrorsUseTheSessionLookupAndListAlternatives`, `TestTargetlessPseudoViewSpansLoadedDocuments`, `TestViewsListsSessionViewsInDeclarationOrder`, `TestRenderMisuseShowsUsage`, `TestRenderIsInHelpAndCompletion`, `TestRenderBetweenStepsDisturbsNothing`; `cmd/sysml/render_test.go` `TestRenderWritesTheArtifactOnStdout`, `TestRenderTextFormAndOutputFile`, `TestRenderOfATabularView`, `TestRenderAllWritesOneMachineArtifactPerView`, `TestRenderAllForcedTextUsesTxtAndUnboundedWidth`, `TestRenderAllWithoutViewsIsUnevaluable`, `TestRenderAllMutualExclusions`, `TestRenderOfATableAsDelimitedValues`, `TestRenderAllForcedDelimitedFormWritesTablesOnly`; `view/delimited_test.go` | ✅ Faithful (`%render` is a read: it materializes nothing, adds no object to the session, leaves the submission buffer alone and leaves an `%action`/`%state` debugging session stepping the same graph and objects — pinned by `TestRenderBetweenStepsDisturbsNothing`. A targeted pseudo-view uses the session's normal simple or qualified lookup; a targetless one renders loaded documents in order. `%view`'s report is unchanged) | | Diagram geometry in notation — an OpenSysML extension, not a specification rule: `DiagramLayout::Layout` (`x`, `y`, optional `width`, `height`, `collapsed`) positions the element it annotates, `DiagramLayout::Route` (`points`, a flattened `x0, y0, x1, y1, …` sequence, `ordered nonunique` since a segment repeats a coordinate) steers the edge whose declaring element it annotates, `DiagramLayout::Canvas` (`unit`, `width`, `height`) sizes a view's drawing surface; pixels, y down, origin top-left. For a (view, element) pair an `about` annotation declared in the view's body applies first, the element's own inline annotation second, none third; a view's second `about` annotation of one kind for one element is ignored in favor of the first. The geometry rides the rendering tree as values (`view.Node.Geometry`, `view.Edge.Route`, `view.Rendering.Canvas`) in every graph-shaped rendering — tree, interconnection, state, action, case, mixed — through `Render` and `RenderExposed` (no view, so element fallback only); the sequence diagram and the table carry none. The writers keep it visible: Mermaid as `%% canvas:`, `%% layout:` and `%% route:` comments after the header, text as `at (x, y)`, `size w×h`, `collapsed` and `via (x, y) …` suffixes, `opensysml/render` as optional `x`/`y`/`width`/`height`/`collapsed`/`route`/`canvas`; a model without annotations renders byte-identically | `libs/stdlib/OpenSysML Libraries/DiagramLayout.sysml`; `semantics/layout.go` `Model.LayoutSitesOf`, `LayoutOf`, `RouteOf`, `CanvasOf` (lazy, memoized, over the metadata side table `ElementMetadataOf`/`AnnotationSitesOf`); `semantics/masking.go` `directRedefinedFeatures` → `implicitMetadataBodyRedefinitions` (a metadata body's `points = (…)` is judged by the redefined `nonunique` feature); `ast/metadata.go` `DeclaredMetadata` (transition and succession bodies); `lower/state_graph.go` `StateGraph.DeclOf`, `lower/action_graph.go` (a succession body of annotations only); `view/geometry.go` `Point`, `Geometry`, `Canvas`, `Renderer.geometryOf`/`routeOf`/`canvasOf`, `view/place.go` `Renderer.Draws`/`DrawsAnywhere`, `view/clone.go`, `view/mermaid.go`, `view/text.go`; `lsp/render.go`; `passes/diagram_layout.go` `DiagramLayoutPass` at `LevelConstraint` (`diagram-layout-unplaced` warning for a `Layout`/`Route` on an element the judged rendering draws no node/edge for, `diagram-layout-value` error for odd `points` or a non-constant binding, `diagram-layout-canvas` error outside a view, `diagram-layout-duplicate` warning; source `constraint`) | `parse/view_layout_metadata.golden`; `semantics/layout_test.go` `TestLayoutOfPrefersTheViewBodyOverTheInlineAnnotation`, `TestLayoutOfPlacesAnElementInOneViewOnly`, `TestLayoutOfReadsAnAboutAnnotationNestedInTheViewBody`, `TestLayoutOfFirstViewLocalAnnotationWins`, `TestRouteOfReadsWaypointPairs`, `TestRouteOfReportsAnOddPointCount`, `TestLayoutOfReportsANonConstantBinding`, `TestCanvasOfReadsTheViewsCanvas`; `semantics/uniqueness_test.go` `TestIsUniqueInheritsIntoMetadataBody`; `view/geometry_test.go` (view-local over inline, one view of two, connection/transition/succession routes, canvas, writers, `RenderExposed`, clone, no-annotation byte identity) with `view/testdata/layout.{text,mermaid}.golden`; `lower/action_succession_test.go`; `lsp/render_test.go` `TestRenderCarriesLayoutGeometry`; `passes/diagram_layout_test.go` (one test per diagnostic); `cmd/sysml/check_test.go` `TestCheckReportsDiagramLayoutFindings`; `repl/view_layout_test.go` | ⚠️ Approximate (self-assessed: nothing in the specification to be faithful to — the notation is standard user-defined metadata, the meaning is OpenSysML's, proposed for standardization in `omg-issues.md`. No writer of this build lays a diagram out from the positions: Mermaid and text keep them visible, a layout-honoring form is pending, as is write-back from a graphical editor. Positions are absolute, so a container's children are not repositioned with it) | | A view's conformance to the viewpoints it satisfies is evaluated (SysML v2 7.24 Views and Viewpoints; a concern is a requirement, so its conditions are evaluated by the requirement engine) | `semantics/conformance.go` `Model.ViewConformance` (per satisfy claiming conformance — `IsViewpointSatisfy`, since a satisfy stating a subject asserts its requirement of that subject instead, as the stdlib `View` does: `Model.SatisfyTarget`, then every concern `Model.FramedConcernsOf` reports for the viewpoint, evaluated against the exposed elements the concern's subject admits — the view restates no framing, since `FramedConcernMember` is a requirement, concern and viewpoint body member and no view body one (8.3.20, 8.3.26) through the `ConcernEvaluator` the caller supplies — implemented in `repl/view.go` `concernEvaluator` over `runtime.Context.CheckSatisfactionOn`, so condition evaluation is not reimplemented); `passes/constraint.go` `checkViewSatisfyTarget` (code `view-satisfy-viewpoint`) | `semantics/conformance_test.go` (every concern the viewpoint frames evaluated, those it inherits included, an untyped framing, a framing naming a concern usage; a false condition; an unevaluable one; no admissible subject; an unresolved stakeholder; a satisfy inherited from a view def; a satisfy that is no viewpoint; determinism), `passes/constraint_test.go` `TestConstraintViewSatisfyNonViewpointRequirement`, `TestConstraintViewSatisfyViewpointOK`, `TestConstraintSatisfyOutsideAViewIsNotChecked`, `TestConstraintViewSatisfyRequirementBySubjectOK`, `conformance/viewpoint_framed_concern_conditions.sysml`, `viewpoint_concern_without_condition.sysml` | ⚠️ Approximate (the conditions are evaluated faithfully; the **verdict rules are tool-defined**, since SysML v2 leaves verification verdicts non-normative: a concern must hold of *every* exposed element its subject admits, and what cannot be evaluated — no condition, no admissible subject, an unresolved party, a framing whose concern reference does not resolve, a viewpoint framing no concern at all — is reported as unevaluable with a reason, never as a pass. **Adjudicated: left as found, deliberately.** This row states no name-resolution rule; its verdict rules are non-normative, so no referee can promote it, and its implementation is in `semantics/`, which this change did not own) | -| A filter condition is a model-level predicate over one candidate element, with the candidate as the implicit `self` (`@Safety`, `@@Safety`, `and`/`or`/`xor`/`not`/`implies`, and a comparison of an annotation's feature) | `semantics/filter.go` `Model.CompileElementFilter` / `EvalElementFilter` / `SatisfiesElementFilter` (compiled once per condition, memoized per candidate) over the annotations `semantics/annotations.go` collects — prefix metadata (`#Safety part def P;`), a `metadata` member of the element's body, and `metadata m about X;` or `@M about X;` — with conformance against the Type element the condition's name resolves to (`FilterPredicate.Type`, through `Model.Conforms` over `Model.AllSupertypes`), so `@Safety` matches a metadata type specializing `Safety`, an `alias` of `Safety` or a re-exporting import of it selects the same elements, and a namesake `Safety` declared in another document selects none of them (the name alone decides only when it resolves to no element, or across copies of a library document, whose elements are one normative element); a metaclass classification (`@SysML::PartUsage`) reads the candidate's own kind | `semantics/filter_test.go`, `semantics/filter_identity_test.go`, `model/element_filter_test.go`, `model/filter_conformance_test.go` (`tests/testdata/filters/`: an alias member, a re-exporting import and two documents opening one `Meta::Safety`), `semantics/cached_library_test.go` `TestNamespaceFilterOverALibraryIsTheSameParsedAndRestored` (the condition as parsed and the same condition compiled into an index-cache record classify alike), `TestAnnotationFactsOfALibraryElementSurviveTheCache` | ✅ Faithful (evaluated against a *symbol*, not a value: there is no instance at name-resolution time, which is what a model-level condition is defined over. A KerML declaration keyword implies its metaclass (`struct` → `Structure`, `class` → `Class`, `assoc` → `Association`, `datatype` → `DataType`, and the rest of KerML §8.2: `semantics/annotations.go` `kermlMetaclassNames`), and a metaclass *feature* (`Element::name`, `Type::isAbstract`, `Feature::isComposite`) is answered from the candidate element itself (`reflectiveFeatureValue`), from an annotation only when one binds it. A feature of a metaclass the candidate *is* an instance of but whose value no declaration gives is `ErrFilterUnevaluable` — reported through `filter-not-evaluable`, never decided false, which is the distinction that was dropping candidates and reporting their names unresolved (`kerml-examples` `Simple Tests/Filtering.kerml:38,47,48`, now clean, as the pinned `validate-kerml` is). Refereed: the pinned validators are silent on `testdata/passes/f93_element_filter.{kerml,sysml}` and on `Filtering.kerml`, and so are we (`passes/f93_element_filter_scope_test.go`). `@`/`@@` in the *runtime* value evaluator is the metadata-classification row above — a separate layer, `runtime/`, decided by this same compiled predicate) | +| A filter condition is a model-level predicate over one candidate element, with the candidate as the implicit `self` (`@Safety`, `@@Safety`, `and`/`or`/`xor`/`not`/`implies`, and a comparison of an annotation's feature) | `semantics/filter.go` `Model.CompileElementFilter` / `EvalElementFilter` / `SatisfiesElementFilter` (compiled once per condition, memoized per candidate) over the annotations `semantics/annotations.go` collects — prefix metadata (`#Safety part def P;`), a `metadata` member of the element's body, and `metadata m about X;` or `@M about X;` — with conformance against the Type element the condition's name resolves to (`FilterPredicate.Type`, through `Model.Conforms` over `Model.AllSupertypes`), so `@Safety` matches a metadata type specializing `Safety`, an `alias` of `Safety` or a re-exporting import of it selects the same elements, and a namesake `Safety` declared in another document selects none of them (the name alone decides only when it resolves to no element, or between two library copies of one declaration — `conformsByLibraryName` — so a workspace namesake of a library type is not that type, and `Base::Anything` is the top type only as the library declares it, `Model.isTopType`); a metaclass classification (`@SysML::PartUsage`) reads the candidate's own kind | `semantics/filter_test.go`, `semantics/filter_identity_test.go`, `model/element_filter_test.go`, `model/filter_conformance_test.go` (`tests/testdata/filters/`: an alias member, a re-exporting import and two documents opening one `Meta::Safety`), `semantics/cached_library_test.go` `TestNamespaceFilterOverALibraryIsTheSameParsedAndRestored` (the condition as parsed and the same condition compiled into an index-cache record classify alike), `TestAnnotationFactsOfALibraryElementSurviveTheCache` | ✅ Faithful (evaluated against a *symbol*, not a value: there is no instance at name-resolution time, which is what a model-level condition is defined over. A KerML declaration keyword implies its metaclass (`struct` → `Structure`, `class` → `Class`, `assoc` → `Association`, `datatype` → `DataType`, and the rest of KerML §8.2: `semantics/annotations.go` `kermlMetaclassNames`), and a metaclass *feature* (`Element::name`, `Type::isAbstract`, `Feature::isComposite`) is answered from the candidate element itself (`reflectiveFeatureValue`), from an annotation only when one binds it. A feature of a metaclass the candidate *is* an instance of but whose value no declaration gives is `ErrFilterUnevaluable` — reported through `filter-not-evaluable`, never decided false, which is the distinction that was dropping candidates and reporting their names unresolved (`kerml-examples` `Simple Tests/Filtering.kerml:38,47,48`, now clean, as the pinned `validate-kerml` is). Refereed: the pinned validators are silent on `testdata/passes/f93_element_filter.{kerml,sysml}` and on `Filtering.kerml`, and so are we (`passes/f93_element_filter_scope_test.go`). `@`/`@@` in the *runtime* value evaluator is the metadata-classification row above — a separate layer, `runtime/`, decided by this same compiled predicate) | | A filter condition that is not boolean-valued, or that OpenSysML cannot evaluate | `passes/filter.go` `ElementFilterPass` at `LevelType`, over `semantics/filter.go` `Model.CheckElementFilter`; codes `filter-not-boolean` (error — a condition that is not a predicate can select nothing) and `filter-not-evaluable` (warning). Each fault is reported once, on the membership stating the condition (KerML §8.2.4), however many operands carry it | `passes/filter_test.go` `TestFilterNotBooleanIsReported`, `TestFilterNotEvaluableIsReported`, `TestFilterConditionsInTheSupportedSubsetAreClean` | ✅ Faithful (an unevaluable condition is **reported and not applied**, so the elements it would have selected from all stay visible: a verdict OpenSysML could not reach never silently hides model content — maintainer decision, recorded here because the spec does not say). A feature bound to nothing is *not* that case: reading it yields the empty sequence, which an ordering propagates and `==`/`!=` decide against any value (KerML `DataFunctions`, where an ordering takes `DataValue[1]` and equality `[0..1]`), so `@Safety and Safety::isMandatory == true` does not hold of an element annotated `@Safety` alone and does not surface it — a verdict, not a reported failure. An annotation inherits the values its metadata type declares, so a default the type gives the feature is what the comparison reads (`semantics/annotations.go` `addTypeDefaults`; `semantics/filter_test.go` `TestFilterUnsetAnnotationFeature`, `TestFilterAnnotationFeatureDefault`, `model/element_filter_test.go` `TestFilteredImportRejectsAnUnboundAnnotationFeature`) | | A KerML declaration specializes the library type its keyword implies (`class` → `Occurrences::Occurrence`, `struct` → `Objects::Object`, `assoc`/`association` → `Links::Link`, `behavior` → `Performances::Performance`, `function`/`predicate` → the matching evaluation, `interaction` → `Links::Link` as an association (KerML 1.1 §8.3.5.4; `Links::BinaryLink` with two ends), `metaclass` → `Metaobjects::Metaobject`, `datatype` → `Base::DataValue`, `classifier`/`type` → `Base::Anything`), so the library members it implies are inherited (KerML 1.0 §8.4.2) | `semantics/implicit.go` `implicitKerMLBases`, read by `implicitBase` when `source.KindOf` says the document is KerML (the same file-kind mechanism, no second notion) — a bare `feature` is left with no base rather than being given the SysML `attribute` one; `libs/record.go` (cache format 17) stores the semantic supertype edges so a restored library symbol inherits alike | `semantics/implicit_test.go:TestKerMLImplicitDefinitionBases`, `:TestSysMLImplicitDefinitionBasesRemainKindBased`, `semantics/cached_library_test.go:TestInheritedImplicitBaseIsTheSameParsedAndRestored`, `libs/loader_cache_test.go:TestLoaderCachePreservesRedefinitionMemberEdges` | ✅ Faithful, self-assessed (the keyword table covers the KerML §8.2 declaration kinds, and the implied *feature* bases §8.4.2 also defines are now modelled: `implicitKerMLFeatureBases` maps a feature keyword to the base feature it subsets — `step`/`behavior` → `Performances::performances`, `expr`/`function` → `Performances::evaluations`, `bool`/`predicate` → `booleanEvaluations`, `inv` → `trueEvaluations`, `class` → `Occurrences::occurrences`, `struct` → `Objects::objects`, `datatype` → `Base::dataValues`, `assoc`/`connector` → `Links::links`, `binding` → `Links::selfLinks`, `succession` → `Occurrences::happensBeforeLinks`, `interaction` → `Transfers::transfers`, `flow` → `Transfers::flowTransfers`, `metaclass` → `Metaobjects::metaobjects` — contributed as members, like the base usage, not as conformance. Every name in both tables is checked against what the bundled library declares (`semantics/w7a_library_bases_test.go:TestW7AImplicitBaseTablesNameLibraryElements`) and the member contribution by `implicit_test.go:TestW7AKerMLFeatureBaseContributesMembers`. **Evidence is KerML §8.4.2 plus these tests, not a referee**: an implicit base surfaces in no reference diagnostic — a probe declaring the keyword forms is accepted by `validate-kerml` and by us alike — so no matched run can settle it. The feature table is read for feature declarations only: a keyword that declares a *type* — `class`, `struct`, `assoc`, `behavior`, `predicate`, `interaction` — takes its base from the type table above and nothing from this one) | | A declared generalization suppresses the implicit one only when it already reaches that base, directly or indirectly (KerML 1.0 §8.4.2), so `struct MyWheel specializes Wheel` still specializes `Objects::Object` when `classifier Wheel;` reaches only `Base::Anything` | `semantics/implicit.go` `declaredGeneralizationReaches` (declared generalizations only, and cycle-guarded, so it cannot re-enter the closure the implicit base feeds), consulted for KerML documents; a SysML declaration keeps taking its supertypes from its own declaration | `semantics/implicit_test.go:TestImplicitBaseOfExplicitSupertypeIsTransitive`, `:TestSysMLImplicitBaseOfExplicitSupertypeIsTransitive` | ✅ Faithful, self-assessed (the rule is now the same in both languages and for a usage as for a definition: `implicitBase` consults `declaredGeneralizationReaches` alone, and `Model.DirectSupertypes` no longer skips the implicit base of a SysML usage that declares any generalization, so `part p :> Frames::Frame;` still specializes `Parts::Part` while `part q :> Parts::Part;` takes only what it declares. The implied feature base is suppressed by the same test. A metadata keyword is the one exception: it supplies the kind itself, so its `baseType` stands in for the kind's base (SysML v2 §7.27.4, `model/metadata_test.go:TestSemanticMetadataKeywordSubsetsBaseType`). Tests: `semantics/implicit_test.go:TestW7AKerMLFeatureBaseSuppressedWhenDeclared`, `:TestW7ASysMLSuppressionMatchesKerML`, `:TestImplicitBaseOfExplicitSupertypeIsTransitive`, `:TestSysMLImplicitBaseOfExplicitSupertypeIsTransitive`. **Evidence is KerML §8.4.2 plus these tests, not a referee** — suppression is unobservable in a reference diagnostic; what the move was checked against is the corpus ratchet, which does not change for any file because of it) | diff --git a/internal/semantic/semantics/filter.go b/internal/semantic/semantics/filter.go index eb3dfabe89..37cd53c99f 100644 --- a/internal/semantic/semantics/filter.go +++ b/internal/semantic/semantics/filter.go @@ -940,7 +940,7 @@ func (m *Model) metaclassConformsTo(cand, typ *symbols.Symbol, typeFQN string) b return false } if typ != nil { - return m.Conforms(meta, typ) || m.conformsByName(meta, typeFQN) + return m.Conforms(meta, typ) || (m.isLibraryElement(typ) && m.conformsByLibraryName(meta, typeFQN)) } // The metaclass library is not loaded, so conformance can only be judged on // the name the candidate's metaclass has. @@ -964,7 +964,7 @@ func (m *Model) annotationConforms(a annotation, typ *symbols.Symbol, typeFQN st if typ == nil { return m.conformsByName(a.typ, typeFQN) } - return m.Conforms(a.typ, typ) || (m.isLibraryElement(typ) && m.conformsByName(a.typ, typeFQN)) + return m.Conforms(a.typ, typ) || (m.isLibraryElement(typ) && m.conformsByLibraryName(a.typ, typeFQN)) } // predicateType is the type a compiled condition names: the element it @@ -1011,6 +1011,16 @@ func bodyLocalSymbol(sym *symbols.Symbol) bool { // symbol across generations, and a name identifies one element (symbolByFQN // answers nothing for an ambiguous one), so the name decides what identity cannot. func (m *Model) conformsByName(sym *symbols.Symbol, typeFQN string) bool { + return m.conformsByNameIn(sym, typeFQN, false) +} + +// conformsByLibraryName is conformsByName where only a library element may match: +// copies of one library declaration are one element, a workspace namesake is not. +func (m *Model) conformsByLibraryName(sym *symbols.Symbol, typeFQN string) bool { + return m.conformsByNameIn(sym, typeFQN, true) +} + +func (m *Model) conformsByNameIn(sym *symbols.Symbol, typeFQN string, libraryOnly bool) bool { if sym == nil || typeFQN == "" { return false } @@ -1031,11 +1041,11 @@ func (m *Model) conformsByName(sym *symbols.Symbol, typeFQN string) bool { if i := strings.LastIndex(typeFQN, "::"); i >= 0 { parent, leaf = typeFQN[:i], typeFQN[i+2:] } - if symbols.FQNIs(sym, parent, leaf) { + if symbols.FQNIs(sym, parent, leaf) && (!libraryOnly || m.isLibraryElement(sym)) { return true } for _, sup := range m.AllSupertypes(sym) { - if symbols.FQNIs(sup, parent, leaf) { + if symbols.FQNIs(sup, parent, leaf) && (!libraryOnly || m.isLibraryElement(sup)) { return true } } diff --git a/internal/semantic/semantics/filter_identity_test.go b/internal/semantic/semantics/filter_identity_test.go index 9dfdf8d9dd..de3f27e66e 100644 --- a/internal/semantic/semantics/filter_identity_test.go +++ b/internal/semantic/semantics/filter_identity_test.go @@ -94,3 +94,56 @@ func TestFilterNamingANamesakeTypeSelectsByElement(t *testing.T) { } } } + +// A condition naming a library type is not satisfied by a workspace namesake of +// that type, while a second library copy of the same declaration still is. +func TestFilterNamingALibraryTypeTellsAWorkspaceNamesakeApart(t *testing.T) { + idx := symbols.NewIndex() + addTestDoc(t, idx, "lib.sysml", `package Meta { metadata def Safety; }`) + addTestDoc(t, idx, "lib2.sysml", `package Meta { metadata def Safety; } + package LibB { #Meta::Safety part strap; }`) + addTestDoc(t, idx, "ws.sysml", `package Meta { metadata def Safety; } + package LibA { #Meta::Safety part belt; }`) + idx.MarkLibrary("lib.sysml") + idx.MarkLibrary("lib2.sysml") + idx.ExpandWildcardImports() + r := resolve.New(idx) + m := NewModel(r) + r.SetModel(m) + belt := idx.LookupQualified("LibA::belt")[0] + strap := idx.LookupQualified("LibB::strap")[0] + + f := filterIn(t, m, "lib.sysml", "@Meta::Safety") + if typ := m.CompileElementFilter(f).Type; typ == nil || typ.DocName != "lib.sysml" { + t.Fatalf("the condition must name the library's Safety, got %v", typ) + } + if verdict(t, m, f, belt) { + t.Fatalf("belt, annotated by the workspace's namesake Safety, must not conform to the library's") + } + if !verdict(t, m, f, strap) { + t.Fatalf("strap, annotated by another library copy of Safety, must conform to the library's") + } +} + +// Base::Anything is the top type only as the library declares it; a workspace +// type of that name admits no more than what it annotates (KerML 1.0 §9.2.2.2). +func TestFilterNamingAWorkspaceAnythingIsNotTheTopType(t *testing.T) { + for _, library := range []bool{false, true} { + idx := symbols.NewIndex() + addTestDoc(t, idx, "base.sysml", `package Base { metadata def Anything; }`) + addTestDoc(t, idx, "ws.sysml", `package Meta { metadata def Tag; } + package LibA { #Meta::Tag part radio; }`) + if library { + idx.MarkLibrary("base.sysml") + } + idx.ExpandWildcardImports() + r := resolve.New(idx) + m := NewModel(r) + r.SetModel(m) + radio := idx.LookupQualified("LibA::radio")[0] + f := filterIn(t, m, "ws.sysml", "@Base::Anything") + if got := verdict(t, m, f, radio); got != library { + t.Errorf("library=%v: a part annotated by an unrelated type conforms to Base::Anything: got %v, want %v", library, got, library) + } + } +} diff --git a/internal/semantic/semantics/model.go b/internal/semantic/semantics/model.go index 8e3e786b9b..e8f0a8bc65 100644 --- a/internal/semantic/semantics/model.go +++ b/internal/semantic/semantics/model.go @@ -852,7 +852,7 @@ func (m *Model) conforms(a, b *symbols.Symbol, unioning map[*symbols.Symbol]bool if a == nil || b == nil { return false } - if symbols.SameElement(a, b) || IsAnything(b) { + if symbols.SameElement(a, b) || m.isTopType(b) { return true } for _, s := range m.AllSupertypes(a) { @@ -863,6 +863,12 @@ func (m *Model) conforms(a, b *symbols.Symbol, unioning map[*symbols.Symbol]bool return m.unionConforms(a, b, unioning) } +// isTopType reports whether b is the library's Base::Anything, which every type +// conforms to (KerML 1.0 §9.2.2.2); a workspace namesake of it is an ordinary type. +func (m *Model) isTopType(b *symbols.Symbol) bool { + return IsAnything(b) && (m.resolver == nil || m.resolver.Index() == nil || m.isLibraryElement(b)) +} + // unionConforms reports whether a is declared as the union of types that all // conform to b. A union's instances are exactly those of its unioning types // (KerML 1.0 §8.3.3), so `classifier MyWheel unions MyWheel1, MyWheel2` diff --git a/internal/semantic/semantics/model_test.go b/internal/semantic/semantics/model_test.go index 7df66b7da6..70d08ed629 100644 --- a/internal/semantic/semantics/model_test.go +++ b/internal/semantic/semantics/model_test.go @@ -246,6 +246,7 @@ func TestAllSupertypesSafeOnCycle(t *testing.T) { func TestConformsToAnything(t *testing.T) { m, root := buildModel(t, `package Base { part def Anything; } part def Engine; part def X;`) + m.resolver.Index().MarkLibrary("t.sysml") // Anything is the top type as the library declares it base := sym(t, root, "Base") anything := sym(t, base.Scope, "Anything") engine := sym(t, root, "Engine")