Repository navigation
fix(check): withdraw part-usage-part-definition; a part usage's derived partDefinition is never empty - #1484
Open
devin-ai-integration[bot] wants to merge 6 commits into
Open
devin-ai-integration[bot] wants to merge 6 commits into
devin-ai-integration[bot] wants to merge 6 commits into
Conversation
…artDefinition A part usage's derived partDefinition includes Parts::Part through the implied Parts::parts subsetting (SysML 8.3.11.3, KerML 8.3.3.3.4, 8.4.2), so the constraint cannot fail for a part typed only by an item definition; the gap register's section 19 states the derivation and cites the pilot's own derived properties on the model. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Contributor
Author
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
…ed partDefinition is never empty SysML v2 validatePartUsagePartDefinition reads partDefinition->notEmpty() over the derived partDefinition, a filter of KerML Feature::type (8.3.3.3.4), which unions the types of every subsetted feature, the implied Parts::parts subsetting of checkPartUsageSpecialization included; validation constraints presume the semantic constraints hold (8.3.1), so every part usage is typed by Parts::Part (7.10) and a report on a part typed only by an item definition was stricter than the specification. The pass, its code, probe and tests go; Model.FeatureTypeSetWithImplied carries the derivation, which reflective type and partDefinition read for every usage kind in place of a Parts::parts special case. The pilot corpus and spec-example ratchets, the pilot differential, Xpect and rejection baselines, the census (the row is now deliberate, derivePartUsagePartDefinition faithful) and the records that called these diagnostics ours are re-recorded. Co-Authored-By: jason.han <hanhuijun@gmail.com>
… for reflection A subject is indexed as a part usage, so its reflective type and partDefinition keep Parts::Part through the base of the symbol's kind; the join is confined to SysML usages so KerML end features keep their declared types. The self-model's pass registry drops the withdrawn pass. Co-Authored-By: jason.han <hanhuijun@gmail.com>
5 of 6 tasks
…odel edit The self-model's pipeline.sysml lost the withdrawn pass's row, which moved the examples root digest both differential baselines record and the API JSON element counts the self-model contributes; the pilot differential figures themselves did not move. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…t-definition-reading Co-Authored-By: jason.han <hanhuijun@gmail.com>
This was referenced Oct 25, 2026
Draft
…t references A bare variant that references a feature is a ReferenceUsage whatever placeholder kind the parser indexes it under, so FeatureTypeSetWithImplied no longer joins the part kind's base to it. Comments trimmed to the repository's two-line limit. Co-Authored-By: jason.han <hanhuijun@gmail.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
On
develop,part-usage-part-definition("A part must be typed by at least one part definition.") is reported on a part usage typed only by an item definition —package P { item def I; part p : I; }— and so on four lines of the OMG pilot example corpus (Geometry Examples/SimpleQuadcopter.sysml:14 and :114,Simple Tests/IndividualTest.sysml:12,Simple Tests/ItemTest.sysml:11). The pinned pilot reports nothing there, but its silence is not the argument: the pilot never evaluates the constraint (checkPartUsageis commented out), so the question is what the specification's own derivation says. This PR settles the reading first (below) and then brings the check and every record that cites it into line with that reading.Closes nothing by itself; it revisits the behaviour #647 asked for.
Spec decision
Verdict:
partDefinition->notEmpty()cannot fail for a part usage typed only by an item definition. The check ondevelopis stricter than the specification.Clauses (SysML v2.1 Beta 2 and KerML 1.1 Beta 2 at the pin of
scripts/pilot-pin.sh, rendered byscripts/download-spec-examples.shintobuild/spec-docs/):PartUsage:/partDefinition : PartDefinition [0..*] {subsets itemDefinition};derivePartUsagePartDefinition—partDefinition = itemDefinition->selectByKind(PartDefinition);validatePartUsagePartDefinition—partDefinition->notEmpty();checkPartUsageSpecialization—specializesFromLibrary('Parts::parts').ItemUsage,deriveItemUsageItemDefinition—itemDefinition = occurrenceDefinition->selectByKind(Structure); §8.3.9.3/occurrenceDefinition : Class {redefines definition}; §8.3.8.3Usage/definition : Classifier {redefines type}. §8.3.1 (derivation constraints, note): a derived property that redefines a derived property takes the redefined property's derivation — sodefinition,occurrenceDefinition,itemDefinitionandpartDefinitionare all filters over KerMLFeature::type.deriveFeatureType:type = closure(typingFeatures()).typing.typewith redundant supertypes removed;typingFeatures()(§8.3.3.3.4) is all subsetted features exceptCrossSubsetting(plus the last chaining feature). Nothing in it distinguishes an impliedSubsettingfrom an owned one.checkPartUsageSpecializationis satisfied by an impliedSubsettingofParts::parts, whose type isParts::Part(§9.2.4). KerML §8.4.2 omits an implied specialization only when an owned specialization has the same general or a subtype of it; aFeatureTypingby an item definition is neither, so the implied subsetting stays.checkPartUsageSpecializationsatisfied,type(p) ⊇ {Parts::Part},itemDefinition(p) ⊇ {Parts::Part}(aPartDefinitionis aStructure),partDefinition(p) ⊇ {Parts::Part}. §8.3.1 also notes that derived values "may depend on whether implied relationships are included in the model or not", which is exactly why the validation constraints are read under the presumption above rather than against a model missing its implied relationships.partsdefined by the base part definitionPart, every part usage is always directly or indirectly defined by at least one part definition, implicitly if not explicitly, in addition to any other item definitions." This is the authors stating the consequence of the derivation in prose.So the constraint is not self-contradictory and admits one reading: it is satisfied for every part usage once the semantic constraints are, and the only part usage it can ever report is one whose derived
partDefinitionis empty — i.e. one for which the impliedParts::partssubsetting cannot be formed (noPartslibrary in scope). The reading indocs/project/spec-pilot-gap-register.md§19 (27 Sep) was right; the issue's reading, which counted only the owned typings, was not.Corroboration, not grounds:
scripts/pilot-json-exporter,isImpliedIncluded = false) ofpackage P { item def I; part p : I; }givestype = [P::I, Parts::Part],occurrenceDefinition = [P::I, Parts::Part],itemDefinition = [P::I, Parts::Part],partDefinition = [Parts::Part].validation/valid/PartUsage.sysml.xt:41 annotatespart f :> i;underitem i : I;with// also typed by part def Part.What the code did on
develop:internal/check/passes/part_usage_definition.goreadsemantics.Model.FeatureTypeSet, which excludes the implied generals whenever the feature states any typing of its own, so onpart p : Iit saw{I}and reported. The tree's own reflective layer already disagreed with it:Model.reflectiveFeatureTypesaddedParts::parts' type for aPartUsage(pinned since 2 Oct byTestReflectivePartUsageIncludesImplicitPartDefinition:type = [ItemType, Parts::Part],partDefinition = [Parts::Part]). Our API JSON export writestype = [I]for the part usage (isImpliedIncluded = false) and nopartDefinitionat all, so it neither agreed nor disagreed with the check; that export gap (the pilot writespartDefinition = [Parts::Part]) is noted, not changed here.The specification's own example drew the rule too:
examples/spec-examples/sysml/7.6.5/1.sysml(part cylinders : Cylinder[2..*];withCylinderan item definition fromShapeItems) carried three only-ourskind-mismatchrows in the differential baseline.Behaviour changes
part-usage-part-definitionis withdrawn. A part usage typed only by an item definition (or by any non-part definition) is no longer reported, and the diagnostic code leaves the catalogue. Spec-compliance note: SysML v2.1 Beta 2 §8.3.11.3validatePartUsagePartDefinitionholds for every part usage whose semantic constraints hold, through the impliedParts::partssubsetting (§7.10, §8.3.1, §8.4.7.2; KerML §8.3.3.3.4, §8.4.2), so no textual model violates it. The pass could not be kept as a vacuous check: the census (tools/census/validation) requires every faithfulvalidate*row to be backed by a probe that draws its diagnostic, and no library-loaded model can, so the row moves to deliberate on the precedent ofvalidateDefinitionVariationIsAbstractandvalidateEnumerationDefinitionIsVariation(unobservable in text, held as derived truth).typejoins the implied generals' types for every usage kind. Newsemantics.Model.FeatureTypeSetWithImplied=FeatureTypeSet∪ the types of the kind's implied generals and base feature, most-specific only;Model.reflectiveFeatureTypesreads it in place of thePartUsage-onlyParts::partslookup. For a typed usage whose declared type conforms to its kind's base (attribute a : Real,part r : PD) nothing changes; for a part typed by an item definition reflectivetypeis[I, Parts::Part]andpartDefinitionis[Parts::Part], as the pilot derives them. Asubject s : T;is indexed as a part usage here, so the join also takes the base feature of the symbol's kind (Parts::parts) andTestReflectivePartUsageIncludesImplicitPartDefinitionkeepstype = [ItemType, Parts::Part]for it; the join is confined to SysML usages so KerML end features keep their declared types (TestSelfCheckReflectiveRelationshipConstraints).derivePartUsagePartDefinitionmoves from unknown to faithful in the census, citing the reflective derivation.Records moved
tests/corpus/testdata/pilot_corpora_expected.txtSimpleQuadcopter.sysml2,IndividualTest.sysml1,ItemTest.sysml1tests/corpus/testdata/spec_examples_expected.txtsysml/7.6.5/1.sysml3docs/project/pilot-differential-baseline.jsonpilot-examples88 / 261,spec-examples150 / 50pilot-examples91 / 257,spec-examples151 / 47 (the 4 OMG lines and the 3 spec-example lines; nothing else moved)docs/project/pilot-xpect-baseline.jsonnoErrors262 / 276noErrors265 / 276 (IndividualTest.sysml.xt,ItemTest.sysml.xt,validation/valid/PartUsage.sysml.xt)docs/project/pilot-rejection-baseline.jsonsemantic/variant-kind-inconsistent-with-variation.sysmloursErrors 6docs/project/constraint-manifest.json/validation-constraints.mdvalidatePartUsagePartDefinitionfaithful (164 reported, 4 deliberate);derivePartUsagePartDefinitionunknowndocs/reference/diagnostics.mdpart-usage-part-definitionentrymake diagnostics-catalogue)examples/self-model/pipeline.sysmlpassCount = 67, aPartUsageDefinitionPassrowexamplesroot digest inpilot-differential-baseline.json(digest only, no figure) and inapi-json-differential-baseline.json(one self-model element fewer: matched 91774 → 91766, pilot-only 37351 → 37349, with theapi-json-differential.mdfigures re-typed to match)pilot-differential.mdS10 row (Ours, pilot-following reason),pilot-xpect.mdrow + open reading,pilot-rejection.mdrows,constraint-census-triage.mdobservation + row 127 (#1232 is merged),spec-compliance.mdrow, the fourtesting-pilot-*skills' headline figuresmake docs-countsandmake docs-checkpassThe differential baseline rows for the four OMG lines are gone rather than kept: the pilot still lacks the check, but there is no longer a diagnostic on our side to record against it — both tools are clean on those lines, which is the spec-over-pilot outcome.
Specification basis
SysML v2.1 Beta 2 §8.3.11.3
validatePartUsagePartDefinition/derivePartUsagePartDefinition, §8.3.10.3deriveItemUsageItemDefinition, §8.4.7.2, §7.10; KerML 1.1 Beta 2 §8.3.3.3.4deriveFeatureType, §8.4.2, §8.3.1. ThevalidatePartUsagePartDefinitionrow indocs/project/spec-compliance.mdis rewritten (census deliberate, ✅ faithful: the derivation is held, no diagnostic).How it was verified
Re-run on the head with
bin/sysml:Geometry Examples/SimpleQuadcopter.sysml,Simple Tests/IndividualTest.sysml,Simple Tests/ItemTest.sysmlandpackage P { item def I; part p : I; }all analyse clean (no diagnostic of any severity).New tests:
semantics/feature_type_implied_test.go(part p : I→FeatureTypeSet = [I],FeatureTypeSetWithImplied = [I, Parts::Part]; a part owned by an item def, a part typed by a part def, an untyped part and a typed attribute),passes/item_typed_part_test.go(the issue's model, the OMG shapes andpart f :> i;draw no error).TestReflectivePartUsageIncludesImplicitPartDefinitionkeeps pinningtype/partDefinitionfor the part usage.Gate (local):
go build ./...clean;go vet ./...clean;gofmt -l .empty;make lint✓ (staticcheck + gosec, main module and tools);make docs-counts✓;make docs-check✓;go run -C tools ./cmd/validation-census -check✓;pilot-diff/pilot-xpect/pilot-rejectre-recorded and reproducing;go test ./...withOPENSYSML_REQUIRE_TRAINING_CORPUS=1 OPENSYSML_REQUIRE_PILOT_CORPORA=1 OPENSYSML_REQUIRE_SPEC_EXAMPLES=1 OPENSYSML_REQUIRE_PILOT_LIBRARY_XMI=1 OPENSYSML_REQUIRE_PSSM_SUITE=1: first run 120 packages ok, 2 failing —examples(TestSelfModelPassRegistryMatchesImplementation: the self-model still listed the withdrawn pass) andinternal/frontend/repl(TestSelfCheckPartUsageDefinitionForObjectivesAndVariants: asubjectis indexed as a part usage and lostParts::Partwhen the special case went). Both fixed in the second commit (the kind's base joins a SysML usage's implied types; confined to SysML so KerML end features keep their declared types), theninternal/semantic/...,internal/check/...,internal/frontend/repl,examples,internal/doc/...,internal/exec/runtime,internal/translate/export,tests/corpus,tests/export,tests/resolve,internal/workspace/...re-run with the require variables: 36 packages ok, 0 failing.Review round on the merged head: a bare
variant a;referencing an action (placeholder kind part usage, metaclass ReferenceUsage) had gainedParts::Partin its reflectivetype;FeatureTypeSetWithImpliednow returns the plainFeatureTypeSetfor a variant reference, pinned byTestReflectiveVariantReferenceTakesNoKindBaseType. Probed and unchanged:attribute x : I(item def) derives[I, Base::DataValue]on both the parsed and recorded paths (the impliedattributeValuesedge exists when the declared type does not conform);part :> Parts::parts,part : PD :> Parts::parts,part :> explicitTyped,port : ~PortD,item : PDkeep their declared type only, so a suppressed implied edge changes nothing. After the fixpilot-apijson-diff -updatere-recorded byte-identical, the four provenance tests pass,make docs-countsis current, and the four OMG files plus the minimal model validate with zero diagnostics.Follow-ups
Parts::Partamong a recorded variant reference's own types (FeatureTypeSetreturns[P::AD Parts::Part]for the recorded fixture before any implied join), so the recorded path of a variant reference still shows the part base; the regression test pins the parsed path only.Checklist
make lintpasses locally;go test ./...with the require variables set: see abovechanges/unreleased/<slug>.<section>.md, not as an edit toCHANGELOG.mdmake docs-countsrun if a gate count moved (compliance rows need nothing: the census is counted at docs build)F4,K5) in the body, docs, or changelogRequested by: @HuiJun