sysml 0.1.0__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sysml/__init__.py +5 -0
- sysml/_native/RUST-STANDARD-LIBRARY-NOTICES.html +29357 -0
- sysml/_native/THIRD-PARTY-NOTICES.txt +1102 -0
- sysml/_native/sysmlv2_abi.dll +0 -0
- sysml/base.py +358 -0
- sysml/classes.py +14291 -0
- sysml/classes.pyi +13769 -0
- sysml/library.py +151 -0
- sysml/stdlib/Domain Libraries/Analysis/.meta.json +10 -0
- sysml/stdlib/Domain Libraries/Analysis/.project.json +27 -0
- sysml/stdlib/Domain Libraries/Analysis/AnalysisTooling.sysml +34 -0
- sysml/stdlib/Domain Libraries/Analysis/SampledFunctions.sysml +119 -0
- sysml/stdlib/Domain Libraries/Analysis/StateSpaceRepresentation.sysml +143 -0
- sysml/stdlib/Domain Libraries/Analysis/TradeStudies.sysml +171 -0
- sysml/stdlib/Domain Libraries/Cause and Effect/.meta.json +8 -0
- sysml/stdlib/Domain Libraries/Cause and Effect/.project.json +23 -0
- sysml/stdlib/Domain Libraries/Cause and Effect/CausationConnections.sysml +83 -0
- sysml/stdlib/Domain Libraries/Cause and Effect/CauseAndEffect.sysml +81 -0
- sysml/stdlib/Domain Libraries/Geometry/.meta.json +8 -0
- sysml/stdlib/Domain Libraries/Geometry/.project.json +27 -0
- sysml/stdlib/Domain Libraries/Geometry/ShapeItems.sysml +899 -0
- sysml/stdlib/Domain Libraries/Geometry/SpatialItems.sysml +168 -0
- sysml/stdlib/Domain Libraries/Metadata/.meta.json +10 -0
- sysml/stdlib/Domain Libraries/Metadata/.project.json +19 -0
- sysml/stdlib/Domain Libraries/Metadata/ImageMetadata.sysml +78 -0
- sysml/stdlib/Domain Libraries/Metadata/ModelingMetadata.sysml +143 -0
- sysml/stdlib/Domain Libraries/Metadata/ParametersOfInterestMetadata.sysml +39 -0
- sysml/stdlib/Domain Libraries/Metadata/RiskMetadata.sysml +100 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/.meta.json +30 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/.project.json +23 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQ.sysml +42 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQAcoustics.sysml +439 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQAtomicNuclear.sysml +2726 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQBase.sysml +206 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQCharacteristicNumbers.sysml +1991 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQChemistryMolecular.sysml +1353 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQCondensedMatter.sysml +1223 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQElectromagnetism.sysml +2333 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQInformation.sysml +958 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQLight.sysml +1537 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQMechanics.sysml +1564 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQSpaceTime.sysml +1169 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/ISQThermodynamics.sysml +1256 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/MeasurementRefCalculations.sysml +30 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/MeasurementReferences.sysml +526 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/Quantities.sysml +107 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/QuantityCalculations.sysml +70 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/SI.sysml +378 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/SIPrefixes.sysml +48 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/TensorCalculations.sysml +50 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/Time.sysml +274 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/USCustomaryUnits.sysml +260 -0
- sysml/stdlib/Domain Libraries/Quantities and Units/VectorCalculations.sysml +62 -0
- sysml/stdlib/Domain Libraries/Requirement Derivation/.meta.json +8 -0
- sysml/stdlib/Domain Libraries/Requirement Derivation/.project.json +19 -0
- sysml/stdlib/Domain Libraries/Requirement Derivation/DerivationConnections.sysml +63 -0
- sysml/stdlib/Domain Libraries/Requirement Derivation/RequirementDerivation.sysml +39 -0
- sysml/stdlib/Kernel Libraries/Kernel Data Type Library/.meta.json +9 -0
- sysml/stdlib/Kernel Libraries/Kernel Data Type Library/.project.json +11 -0
- sysml/stdlib/Kernel Libraries/Kernel Data Type Library/Collections.kerml +177 -0
- sysml/stdlib/Kernel Libraries/Kernel Data Type Library/ScalarValues.kerml +23 -0
- sysml/stdlib/Kernel Libraries/Kernel Data Type Library/VectorValues.kerml +64 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/.meta.json +23 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/.project.json +15 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/BaseFunctions.kerml +80 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/BooleanFunctions.kerml +22 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/CollectionFunctions.kerml +68 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/ComplexFunctions.kerml +47 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/ControlFunctions.kerml +117 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/DataFunctions.kerml +43 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/IntegerFunctions.kerml +43 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/NaturalFunctions.kerml +27 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/NumericalFunctions.kerml +43 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/OccurrenceFunctions.kerml +154 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/RationalFunctions.kerml +49 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/RealFunctions.kerml +56 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/ScalarFunctions.kerml +33 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/SequenceFunctions.kerml +111 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/StringFunctions.kerml +25 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/TrigFunctions.kerml +35 -0
- sysml/stdlib/Kernel Libraries/Kernel Function Library/VectorFunctions.kerml +273 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/.meta.json +22 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/.project.json +15 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/Base.kerml +95 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/Clocks.kerml +156 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/ControlPerformances.kerml +135 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/FeatureReferencingPerformances.kerml +190 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/KerML.kerml +483 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/Links.kerml +67 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/Metaobjects.kerml +58 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/Objects.kerml +212 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/Observation.kerml +161 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/Occurrences.kerml +992 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/Performances.kerml +293 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/SpatialFrames.kerml +197 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/StatePerformances.kerml +145 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/Transfers.kerml +281 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/TransitionPerformances.kerml +66 -0
- sysml/stdlib/Kernel Libraries/Kernel Semantic Library/Triggers.kerml +188 -0
- sysml/stdlib/LICENSE +277 -0
- sysml/stdlib/NOTICE +27 -0
- sysml/stdlib/Systems Library/.meta.json +27 -0
- sysml/stdlib/Systems Library/.project.json +19 -0
- sysml/stdlib/Systems Library/Actions.sysml +557 -0
- sysml/stdlib/Systems Library/Allocations.sysml +29 -0
- sysml/stdlib/Systems Library/AnalysisCases.sysml +38 -0
- sysml/stdlib/Systems Library/Attributes.sysml +25 -0
- sysml/stdlib/Systems Library/Calculations.sysml +37 -0
- sysml/stdlib/Systems Library/Cases.sysml +71 -0
- sysml/stdlib/Systems Library/Connections.sysml +60 -0
- sysml/stdlib/Systems Library/Constraints.sysml +44 -0
- sysml/stdlib/Systems Library/Flows.sysml +126 -0
- sysml/stdlib/Systems Library/Interfaces.sysml +89 -0
- sysml/stdlib/Systems Library/Items.sysml +153 -0
- sysml/stdlib/Systems Library/Metadata.sysml +32 -0
- sysml/stdlib/Systems Library/Parts.sysml +81 -0
- sysml/stdlib/Systems Library/Ports.sysml +54 -0
- sysml/stdlib/Systems Library/Requirements.sysml +194 -0
- sysml/stdlib/Systems Library/StandardViewDefinitions.sysml +123 -0
- sysml/stdlib/Systems Library/States.sysml +103 -0
- sysml/stdlib/Systems Library/SysML.sysml +539 -0
- sysml/stdlib/Systems Library/UseCases.sysml +57 -0
- sysml/stdlib/Systems Library/VerificationCases.sysml +103 -0
- sysml/stdlib/Systems Library/Views.sysml +164 -0
- sysml/toolkit.py +373 -0
- sysml/toolkit_table.py +665 -0
- sysml-0.1.0.dist-info/METADATA +87 -0
- sysml-0.1.0.dist-info/RECORD +134 -0
- sysml-0.1.0.dist-info/WHEEL +5 -0
- sysml-0.1.0.dist-info/licenses/LICENSE +202 -0
- sysml-0.1.0.dist-info/licenses/NOTICE +7 -0
- sysml-0.1.0.dist-info/licenses/stdlib/LICENSE +277 -0
- sysml-0.1.0.dist-info/licenses/stdlib/NOTICE +27 -0
- sysml-0.1.0.dist-info/top_level.txt +1 -0
sysml/library.py
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"""The KerML and SysML standard library, in the two forms the backends read.
|
|
2
|
+
|
|
3
|
+
`standard_library()` is the directory of the library's models that a platform wheel carries, for the
|
|
4
|
+
SysML Toolkit backend: ``Model.from_toolkit("model.sysml", library_dir=standard_library())``.
|
|
5
|
+
|
|
6
|
+
`standard_library_json()` is the same library as full-form interchange JSON, for the payload backend
|
|
7
|
+
(`PayloadLibrary`). It is too large for a wheel: the first call downloads ``sysml_library-<version>.zip``
|
|
8
|
+
from this version's GitHub release, checks it against the SHA-256 that GitHub states for that file,
|
|
9
|
+
and keeps the JSON in the user's cache, where later calls find it. Nothing is downloaded unless the
|
|
10
|
+
function is called. ``SYSML_LIBRARY_JSON`` names a copy of the JSON to use instead, for machines
|
|
11
|
+
without access to GitHub.
|
|
12
|
+
|
|
13
|
+
Both are the library of the SysML v2 release the SDK was built with, licensed under the Eclipse
|
|
14
|
+
Public License 2.0, not the SDK's Apache-2.0: see the LICENSE and NOTICE beside them.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import hashlib
|
|
20
|
+
import json
|
|
21
|
+
import os
|
|
22
|
+
import re
|
|
23
|
+
import shutil
|
|
24
|
+
import sys
|
|
25
|
+
import tempfile
|
|
26
|
+
import urllib.request
|
|
27
|
+
import zipfile
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
|
|
30
|
+
from .base import SdkError
|
|
31
|
+
|
|
32
|
+
REPOSITORY = "Open-MBEE/sysml-sdk"
|
|
33
|
+
JSON_VARIABLE = "SYSML_LIBRARY_JSON"
|
|
34
|
+
CACHE_VARIABLE = "SYSML_CACHE_DIR"
|
|
35
|
+
_PACKAGE = Path(__file__).resolve().parent
|
|
36
|
+
_TIMEOUT = 60
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class LibraryUnavailable(SdkError):
|
|
40
|
+
"""The standard library is not at hand: this installation does not carry it, or it could not be
|
|
41
|
+
downloaded and checked."""
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def standard_library() -> Path:
|
|
45
|
+
"""The directory of the standard library models a platform wheel carries, to pass as
|
|
46
|
+
`library_dir`. The source distribution and a repository checkout carry none."""
|
|
47
|
+
directory = _PACKAGE / "stdlib"
|
|
48
|
+
if not directory.is_dir() or next((p for p in directory.rglob("*") if p.suffix in (".kerml", ".sysml")),
|
|
49
|
+
None) is None:
|
|
50
|
+
raise LibraryUnavailable(
|
|
51
|
+
"this installation of the SDK carries no standard library models (only the platform "
|
|
52
|
+
"wheels do); pass the sysml.library directory of sysml_library-<version>.zip from "
|
|
53
|
+
f"https://github.com/{REPOSITORY}/releases as library_dir")
|
|
54
|
+
return directory
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def standard_library_json(*, version: str | None = None, cache_dir: str | os.PathLike | None = None) -> Path:
|
|
58
|
+
"""The standard library as full-form JSON, for `PayloadLibrary`: the file ``SYSML_LIBRARY_JSON``
|
|
59
|
+
names, else the copy in the cache (``cache_dir``, else ``SYSML_CACHE_DIR``, else the user's cache
|
|
60
|
+
directory), downloaded from the GitHub release of ``version`` (default: this SDK's) on the first
|
|
61
|
+
call and checked against the SHA-256 GitHub states for it."""
|
|
62
|
+
named = os.environ.get(JSON_VARIABLE)
|
|
63
|
+
if named:
|
|
64
|
+
if not Path(named).is_file():
|
|
65
|
+
raise LibraryUnavailable(f"{JSON_VARIABLE} names {named}, which is not a file")
|
|
66
|
+
return Path(named)
|
|
67
|
+
version = version or _version()
|
|
68
|
+
stem = f"sysml_library-{version}"
|
|
69
|
+
target = Path(cache_dir) if cache_dir is not None else _cache_root()
|
|
70
|
+
target = target / stem
|
|
71
|
+
found = target / "sysml.library.full.json"
|
|
72
|
+
if found.is_file():
|
|
73
|
+
return found
|
|
74
|
+
|
|
75
|
+
page = f"https://github.com/{REPOSITORY}/releases/tag/v{version}"
|
|
76
|
+
by_hand = (f"download {stem}.zip from {page}, unpack it, and set {JSON_VARIABLE} to the "
|
|
77
|
+
"sysml.library.full.json it holds")
|
|
78
|
+
try:
|
|
79
|
+
release = _get_json(f"https://api.github.com/repos/{REPOSITORY}/releases/tags/v{version}")
|
|
80
|
+
except (OSError, ValueError) as e:
|
|
81
|
+
raise LibraryUnavailable(f"cannot read the release v{version} of {REPOSITORY} ({e}); {by_hand}") from e
|
|
82
|
+
asset = next((a for a in release.get("assets", []) if a.get("name") == f"{stem}.zip"), None)
|
|
83
|
+
if asset is None:
|
|
84
|
+
raise LibraryUnavailable(f"the release v{version} of {REPOSITORY} has no {stem}.zip ({page})")
|
|
85
|
+
digest = asset.get("digest") or ""
|
|
86
|
+
if not digest.startswith("sha256:"):
|
|
87
|
+
raise LibraryUnavailable(f"GitHub states no SHA-256 for {stem}.zip, so it is not downloaded; {by_hand}")
|
|
88
|
+
|
|
89
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
90
|
+
with tempfile.TemporaryDirectory(dir=target.parent) as work:
|
|
91
|
+
archive = Path(work) / f"{stem}.zip"
|
|
92
|
+
try:
|
|
93
|
+
sha256 = _download(asset["browser_download_url"], archive)
|
|
94
|
+
except OSError as e:
|
|
95
|
+
raise LibraryUnavailable(f"cannot download {asset['browser_download_url']} ({e}); {by_hand}") from e
|
|
96
|
+
if sha256 != digest.removeprefix("sha256:"):
|
|
97
|
+
raise LibraryUnavailable(f"{stem}.zip does not match the SHA-256 GitHub states for it "
|
|
98
|
+
f"({sha256}, not {digest.removeprefix('sha256:')}); nothing was kept")
|
|
99
|
+
try:
|
|
100
|
+
with zipfile.ZipFile(archive) as z:
|
|
101
|
+
for name in ("sysml.library.full.json", "LICENSE", "NOTICE", "README.txt"):
|
|
102
|
+
z.extract(f"{stem}/{name}", work)
|
|
103
|
+
except (KeyError, zipfile.BadZipFile) as e:
|
|
104
|
+
raise LibraryUnavailable(f"{stem}.zip is not the archive the SDK expects ({e}); {by_hand}") from e
|
|
105
|
+
if target.exists():
|
|
106
|
+
shutil.rmtree(target) # a copy left incomplete by an earlier call
|
|
107
|
+
os.replace(Path(work) / stem, target)
|
|
108
|
+
return found
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _version() -> str:
|
|
112
|
+
"""This SDK's version: its installed metadata, else (in a repository checkout) pyproject.toml's."""
|
|
113
|
+
from importlib import metadata
|
|
114
|
+
try:
|
|
115
|
+
return metadata.version(__package__)
|
|
116
|
+
except metadata.PackageNotFoundError:
|
|
117
|
+
pyproject = _PACKAGE.parent.parent / "pyproject.toml"
|
|
118
|
+
m = re.search(r'^version = "([^"]+)"', pyproject.read_text(encoding="utf-8"), re.M)
|
|
119
|
+
if m is None:
|
|
120
|
+
raise LibraryUnavailable("cannot tell this SDK's version; pass version=")
|
|
121
|
+
return m.group(1)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _cache_root() -> Path:
|
|
125
|
+
if os.environ.get(CACHE_VARIABLE):
|
|
126
|
+
return Path(os.environ[CACHE_VARIABLE])
|
|
127
|
+
if sys.platform == "win32":
|
|
128
|
+
return Path(os.environ.get("LOCALAPPDATA") or Path.home() / "AppData" / "Local") / "sysml" / "Cache"
|
|
129
|
+
if sys.platform == "darwin":
|
|
130
|
+
return Path.home() / "Library" / "Caches" / "sysml"
|
|
131
|
+
return Path(os.environ.get("XDG_CACHE_HOME") or Path.home() / ".cache") / "sysml"
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _request(url: str, accept: str) -> urllib.request.Request:
|
|
135
|
+
return urllib.request.Request(url, headers={"User-Agent": f"{__package__}-sdk", "Accept": accept})
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _get_json(url: str) -> dict:
|
|
139
|
+
with urllib.request.urlopen(_request(url, "application/vnd.github+json"), timeout=_TIMEOUT) as response:
|
|
140
|
+
return json.load(response)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _download(url: str, path: Path) -> str:
|
|
144
|
+
"""Write the file at `url` to `path`; its SHA-256, as hex."""
|
|
145
|
+
h = hashlib.sha256()
|
|
146
|
+
with urllib.request.urlopen(_request(url, "application/octet-stream"), timeout=_TIMEOUT) as response, \
|
|
147
|
+
open(path, "wb") as out:
|
|
148
|
+
while chunk := response.read(1 << 20):
|
|
149
|
+
h.update(chunk)
|
|
150
|
+
out.write(chunk)
|
|
151
|
+
return h.hexdigest()
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"index": {
|
|
3
|
+
"AnalysisTooling": "AnalysisTooling.sysml",
|
|
4
|
+
"SampledFunctions": "SampledFunctions.sysml",
|
|
5
|
+
"StateSpaceRepresentation": "StateSpaceRepresentation.sysml",
|
|
6
|
+
"TradeStudies": "TradeStudies.sysml"
|
|
7
|
+
},
|
|
8
|
+
"created": "2025-03-13T00:00:00Z",
|
|
9
|
+
"metamodel": "https://www.omg.org/spec/SysML/20250201"
|
|
10
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "SysML Analysis Library",
|
|
3
|
+
"description": "Standard analysis domain library for the Systems Modeling Language (SysML)",
|
|
4
|
+
"version": "2.1.0-dev.20260501",
|
|
5
|
+
"usage": [
|
|
6
|
+
{
|
|
7
|
+
"resource": "https://www.omg.org/spec/KerML/20250201/Semantic-Library.kpar",
|
|
8
|
+
"versionConstraint": "1.1.0-dev.20260501"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"resource": "https://www.omg.org/spec/KerML/20250201/Data-Type-Library.kpar",
|
|
12
|
+
"versionConstraint": "1.1.0-dev.20260501"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"resource": "https://www.omg.org/spec/KerML/20250201/Function-Library.kpar",
|
|
16
|
+
"versionConstraint": "1.1.0-dev.20260501"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"resource": "https://www.omg.org/spec/SysML/20250201/Systems-Library.kpar",
|
|
20
|
+
"versionConstraint": "2.1.0-dev.20260501"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"resource": "https://www.omg.org/spec/SysML/20250201/Quantities-and-Units-Domain-Library.kpar",
|
|
24
|
+
"versionConstraint": "2.1.0-dev.20260501"
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
standard library package AnalysisTooling {
|
|
2
|
+
doc
|
|
3
|
+
/*
|
|
4
|
+
* This package contains definitions for metadata annotations related
|
|
5
|
+
* to analysis tool integration.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
private import ScalarValues::*;
|
|
9
|
+
|
|
10
|
+
metadata def ToolExecution {
|
|
11
|
+
doc
|
|
12
|
+
/*
|
|
13
|
+
* ToolExecution metadata identifies an external analysis tool to be
|
|
14
|
+
* used to implement the annotated action.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
attribute toolName : String;
|
|
18
|
+
attribute uri : String;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
metadata def ToolVariable {
|
|
22
|
+
doc
|
|
23
|
+
/*
|
|
24
|
+
* ToolVariable metadata is used in the context of an action that has
|
|
25
|
+
* been annotated with ToolExecution metadata. It is used to annotate
|
|
26
|
+
* a parameter or other feature of the action with the name of the
|
|
27
|
+
* variable in the tool that is to correspond to the annotated
|
|
28
|
+
* feature.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
attribute name : String;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
standard library package SampledFunctions {
|
|
2
|
+
doc
|
|
3
|
+
/*
|
|
4
|
+
* This package provides a library model of discretely sampled mathematical functions.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
private import Base::Anything;
|
|
8
|
+
private import ScalarValues::Positive;
|
|
9
|
+
private import Collections::KeyValuePair;
|
|
10
|
+
private import Collections::OrderedMap;
|
|
11
|
+
private import SequenceFunctions::size;
|
|
12
|
+
private import ControlFunctions::forAll;
|
|
13
|
+
private import ControlFunctions::collect;
|
|
14
|
+
private import ControlFunctions::select;
|
|
15
|
+
|
|
16
|
+
attribute def SamplePair :> KeyValuePair {
|
|
17
|
+
doc
|
|
18
|
+
/*
|
|
19
|
+
* SamplePair is a key-value pair of a domain-value and a range-value, used as a sample element in SampledFunction.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
attribute domainValue :>> key;
|
|
23
|
+
attribute rangeValue :>> val;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
attribute def SampledFunction :> OrderedMap {
|
|
27
|
+
doc
|
|
28
|
+
/*
|
|
29
|
+
* SampledFunction is a variable-size, ordered collection of 'SamplePair' elements that represents a generic, discretely sampled,
|
|
30
|
+
* uni-variate or multi-variate mathematical function. The function must be montonic, either strictly increasing or strictly
|
|
31
|
+
* decreasing.
|
|
32
|
+
*
|
|
33
|
+
* It maps discrete domain values to discrete range values.
|
|
34
|
+
* The domain of the function is represented by the sequence of 'domainValue' of each 'SamplePair' in 'samples', and
|
|
35
|
+
* the range of the function is represented by the sequence of 'rangeValue' of each 'SamplePair' in 'samples'.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
attribute samples: SamplePair[0..*] ordered :>> elements;
|
|
39
|
+
|
|
40
|
+
assert constraint {
|
|
41
|
+
// Note: Assumes the functions '<' and '>' are defined for the domain type.
|
|
42
|
+
(1..size(samples)-1)->forAll { in i; (samples.domainValue#(i) < samples.domainValue#(i+1)) } or // Strictly increasing
|
|
43
|
+
(1..size(samples)-1)->forAll { in i; (samples.domainValue#(i) > samples.domainValue#(i+1)) } // Strictly decreasing
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
calc def Domain {
|
|
48
|
+
doc
|
|
49
|
+
/*
|
|
50
|
+
* Domain returns the sequence of the domainValues of all samples in a SampledFunction.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
in fn : SampledFunction;
|
|
54
|
+
return : Anything[0..*] = fn.samples.domainValue;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
calc def Range {
|
|
58
|
+
doc
|
|
59
|
+
/*
|
|
60
|
+
* Range returns the sequence of the rangeValues of all samples in a SampledFunction.
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
in fn : SampledFunction;
|
|
64
|
+
return : Anything[0..*] = fn.samples.rangeValue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
calc def Sample {
|
|
68
|
+
doc
|
|
69
|
+
/*
|
|
70
|
+
* Sample returns a SampledFunction that samples a given calculation over a sequence of domainValues.
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
in calc calculation { in x; }
|
|
74
|
+
in attribute domainValues [0..*];
|
|
75
|
+
return sampling = new SampledFunction (
|
|
76
|
+
samples = domainValues->collect { in x; new SamplePair(x, calculation(x)) }
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
calc def Interpolate {
|
|
81
|
+
doc
|
|
82
|
+
/*
|
|
83
|
+
* An Interpolate calculation returns an interpolated range value from a given SampledFunction for a given domain value.
|
|
84
|
+
* If the input domain value is outside the bounds of the domainValues of the SampleFunction, null is returned.
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
in attribute fn : SampledFunction;
|
|
88
|
+
in attribute value;
|
|
89
|
+
return attribute result;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
calc interpolateLinear : Interpolate {
|
|
93
|
+
doc
|
|
94
|
+
/*
|
|
95
|
+
* interpolateLinear is an Interpolate calculation assuming a linear functional form between SamplePairs.
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
in attribute fn : SampledFunction;
|
|
99
|
+
in attribute value;
|
|
100
|
+
|
|
101
|
+
private attribute domainValues = Domain(fn);
|
|
102
|
+
private attribute index : Positive[0..1] =
|
|
103
|
+
(1..size(domainValues))->select { in i : Positive; domainValues#(i) <= value }#(1);
|
|
104
|
+
|
|
105
|
+
private calc def Linear {
|
|
106
|
+
in attribute lowerSample : SamplePair;
|
|
107
|
+
in attribute upperSample : SamplePair;
|
|
108
|
+
in attribute value;
|
|
109
|
+
private attribute f = (value - lowerSample.domainValue) / (lowerSample.domainValue - upperSample.domainValue);
|
|
110
|
+
return result = upperSample.rangeValue + f * (lowerSample.rangeValue - upperSample.rangeValue);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return result [0..1] =
|
|
114
|
+
if index == null or index == size(domainValues)? null
|
|
115
|
+
else if domainValues#(index) < domainValues#(index+1)? Linear(fn.samples#(index), fn.samples#(index+1), value)
|
|
116
|
+
else Linear(fn.samples#(index+1), fn.samples#(index), value);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
standard library package StateSpaceRepresentation {
|
|
2
|
+
doc
|
|
3
|
+
/*
|
|
4
|
+
* This package provides a model of the foundational state-space system representation,
|
|
5
|
+
* commonly used in control systems.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
private import ISQ::DurationValue;
|
|
9
|
+
private import Quantities::VectorQuantityValue;
|
|
10
|
+
private import VectorCalculations::*;
|
|
11
|
+
|
|
12
|
+
abstract attribute def StateSpace :> VectorQuantityValue;
|
|
13
|
+
abstract attribute def Input :> VectorQuantityValue;
|
|
14
|
+
abstract attribute def Output :> VectorQuantityValue;
|
|
15
|
+
|
|
16
|
+
abstract calc def GetNextState {
|
|
17
|
+
in input: Input;
|
|
18
|
+
in stateSpace: StateSpace;
|
|
19
|
+
in timeStep: DurationValue;
|
|
20
|
+
return : StateSpace;
|
|
21
|
+
}
|
|
22
|
+
abstract calc def GetOutput {
|
|
23
|
+
in input: Input;
|
|
24
|
+
in stateSpace: StateSpace;
|
|
25
|
+
return : Output;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
abstract action def StateSpaceEventDef {
|
|
29
|
+
doc
|
|
30
|
+
/*
|
|
31
|
+
* Events to be received.
|
|
32
|
+
*/
|
|
33
|
+
}
|
|
34
|
+
action def ZeroCrossingEventDef :> StateSpaceEventDef;
|
|
35
|
+
|
|
36
|
+
item def StateSpaceItem {
|
|
37
|
+
doc
|
|
38
|
+
/*
|
|
39
|
+
* Item for SSR connection
|
|
40
|
+
*/
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
abstract action def StateSpaceDynamics {
|
|
44
|
+
doc
|
|
45
|
+
/*
|
|
46
|
+
* StateSpaceDynamics is the simplest form of State Space Representation,
|
|
47
|
+
* and nextState directly computes the stateSpace of the next timestep.
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
in attribute input: Input;
|
|
51
|
+
|
|
52
|
+
abstract calc getNextState: GetNextState;
|
|
53
|
+
abstract calc getOutput: GetOutput;
|
|
54
|
+
attribute stateSpace: StateSpace;
|
|
55
|
+
|
|
56
|
+
out attribute output: Output = getOutput(input, stateSpace);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
abstract attribute def StateDerivative :> VectorQuantityValue {
|
|
60
|
+
doc
|
|
61
|
+
/*
|
|
62
|
+
* The definition of the time derivative of StateSpace, which means dx/dt, where x is StateSpace
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
ref stateSpace: StateSpace;
|
|
66
|
+
constraint { stateSpace.order == order }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
abstract calc def GetDerivative {
|
|
70
|
+
doc
|
|
71
|
+
/*
|
|
72
|
+
* Computes the time derivative of stateSpace, which corresponds dx/dt = f(u, x), where u is input and x is stateSpace.
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
in input: Input;
|
|
76
|
+
in stateSpace: StateSpace;
|
|
77
|
+
return : StateDerivative;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
abstract calc def Integrate {
|
|
81
|
+
doc
|
|
82
|
+
/*
|
|
83
|
+
* Integrates stateSpace to compute the next stateSpace, which corresponds to x + int dx/dt dt.
|
|
84
|
+
* Its actual implementation should be given by a solver.
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
in getDerivative: GetDerivative;
|
|
88
|
+
in input: Input;
|
|
89
|
+
in initialState: StateSpace;
|
|
90
|
+
in timeInterval: DurationValue;
|
|
91
|
+
return result: StateSpace;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
abstract action def ContinuousStateSpaceDynamics :> StateSpaceDynamics {
|
|
95
|
+
doc
|
|
96
|
+
/*
|
|
97
|
+
* ContinuousStateSpaceDynamics represents continuous behavior.
|
|
98
|
+
* derivative needs to return a time derivative of stateSpace, i.e. dx/dt.
|
|
99
|
+
*/
|
|
100
|
+
|
|
101
|
+
abstract calc getDerivative: GetDerivative;
|
|
102
|
+
calc :>> getNextState: GetNextState {
|
|
103
|
+
/* We compute nextState by Integrate defined above by giving derivative calc. */
|
|
104
|
+
calc integrate: Integrate {
|
|
105
|
+
in getDerivative = ContinuousStateSpaceDynamics::getDerivative;
|
|
106
|
+
in input = GetNextState::input;
|
|
107
|
+
in initialState = GetNextState::stateSpace;
|
|
108
|
+
in timeInterval = GetNextState::timeStep;
|
|
109
|
+
}
|
|
110
|
+
return result = integrate.result;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
event occurrence zeroCrossingEvents[0..*] : ZeroCrossingEventDef {
|
|
114
|
+
/* ContinuousStateSpaceDynamics may cause zero crossings anomaly. */
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
abstract calc def GetDifference {
|
|
119
|
+
doc
|
|
120
|
+
/*
|
|
121
|
+
* Computes difference of stateSpace by one timestep, that is x(k+1) - x(k),
|
|
122
|
+
* where k is the timestep number.
|
|
123
|
+
*/
|
|
124
|
+
|
|
125
|
+
in input: Input;
|
|
126
|
+
in stateSpace: StateSpace;
|
|
127
|
+
return : StateSpace;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
abstract action def DiscreteStateSpaceDynamics :> StateSpaceDynamics {
|
|
131
|
+
doc
|
|
132
|
+
/*
|
|
133
|
+
* DiscreteStateSpaceDynamics represents discrete behavior.
|
|
134
|
+
* differences needs to return difference of the stateSpace for each timestep.
|
|
135
|
+
*/
|
|
136
|
+
|
|
137
|
+
abstract calc getDifference: GetDifference;
|
|
138
|
+
calc :>> getNextState: GetNextState {
|
|
139
|
+
attribute diff: StateSpace = getDifference(input, stateSpace);
|
|
140
|
+
return result = stateSpace + diff;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
standard library package TradeStudies {
|
|
2
|
+
doc
|
|
3
|
+
/*
|
|
4
|
+
* This package provides a simple framework for defining trade-off study analysis cases.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
private import Base::Anything;
|
|
8
|
+
private import ScalarValues::*;
|
|
9
|
+
private import ScalarFunctions::*;
|
|
10
|
+
private import ControlFunctions::*;
|
|
11
|
+
|
|
12
|
+
abstract calc def EvaluationFunction {
|
|
13
|
+
doc
|
|
14
|
+
/*
|
|
15
|
+
* An EvaluationFunction is a calculation that evaluates a TradeStudy alternative,
|
|
16
|
+
* producing a ScalarValue that can be comparted with the evaluation of other
|
|
17
|
+
* alternatives.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
in ref alternative : Anything {
|
|
21
|
+
doc
|
|
22
|
+
/*
|
|
23
|
+
* The alternative to be evaluated.
|
|
24
|
+
*/
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return attribute result : ScalarValue[1] {
|
|
28
|
+
doc
|
|
29
|
+
/*
|
|
30
|
+
* A ScalarValue representing the evaluation of the given alternative.
|
|
31
|
+
*/
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
abstract requirement def TradeStudyObjective {
|
|
36
|
+
doc
|
|
37
|
+
/*
|
|
38
|
+
* A TradeStudyObjective is the base definition for the objective of a TradeStudy.
|
|
39
|
+
* The requirement is to choose from a given set of alternatives the selectedAlternative
|
|
40
|
+
* for that has the best evaluation according to a given EvaluationFunction. What
|
|
41
|
+
* value is considered "best" is not defined in the abstract base definition but must be
|
|
42
|
+
* computed in any concrete specialization.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
subject selectedAlternative : Anything {
|
|
46
|
+
doc
|
|
47
|
+
/*
|
|
48
|
+
* The alternative that should be selected, as evaluated using the given
|
|
49
|
+
* ObjectiveFunction.
|
|
50
|
+
*/
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
in ref alternatives : Anything[1..*] {
|
|
54
|
+
doc
|
|
55
|
+
/*
|
|
56
|
+
* The alternatives being considered in the TradeStudy for which this TradeStudyObjective
|
|
57
|
+
* is the objective.
|
|
58
|
+
*/
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
in calc eval : EvaluationFunction {
|
|
62
|
+
doc
|
|
63
|
+
/*
|
|
64
|
+
* The EvaluationFunction to be used in evaluating the given alternatives.
|
|
65
|
+
*/
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
attribute best : ScalarValue {
|
|
69
|
+
doc
|
|
70
|
+
/*
|
|
71
|
+
* Out of the evaluation results of all the given alternatives, the one that is considered
|
|
72
|
+
* "best", in the sense that it is the value the selectedAlternative should have. This
|
|
73
|
+
* value must be computed in any concrete specialization of TradeStudyObjective.
|
|
74
|
+
*/
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
require constraint { eval(selectedAlternative) == best }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
requirement def MinimizeObjective :> TradeStudyObjective {
|
|
81
|
+
doc
|
|
82
|
+
/*
|
|
83
|
+
* A MinimizeObjective is a TradeStudyObjective that requires that the
|
|
84
|
+
* selectedAlternative have the minimum ObjectiveFunction value of all the
|
|
85
|
+
* given alternatives.
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
attribute :>> best = alternatives->minimize {
|
|
89
|
+
doc
|
|
90
|
+
/*
|
|
91
|
+
* For a MinimizeObjective, the best value is the minimum one.
|
|
92
|
+
*/
|
|
93
|
+
|
|
94
|
+
in x; eval(x)
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
requirement def MaximizeObjective :> TradeStudyObjective {
|
|
99
|
+
doc
|
|
100
|
+
/*
|
|
101
|
+
* A MaximizeObjective is a TradeStudyObjective that requires that the
|
|
102
|
+
* selectedAlternative have the maximum ObjectiveFunction value of all the
|
|
103
|
+
* given alternatives.
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
attribute :>> best = alternatives->maximize {
|
|
107
|
+
doc
|
|
108
|
+
/*
|
|
109
|
+
* For a MinimizeObjective, the best value is the maximum one.
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
in x; eval(x)
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
abstract analysis def TradeStudy {
|
|
117
|
+
doc
|
|
118
|
+
/*
|
|
119
|
+
* A TradeStudy is an analysis case whose subject is a set of alternatives
|
|
120
|
+
* (at least one) and whose result is a selection of one of those alternatives.
|
|
121
|
+
* The alternatives are evaluated based on a given ObjectiveFunction and the
|
|
122
|
+
* selection is made such that it satisfies the objective of the TradeStudy
|
|
123
|
+
* (which must be a TradeStudyObjective).
|
|
124
|
+
*/
|
|
125
|
+
|
|
126
|
+
subject studyAlternatives : Anything[1..*] {
|
|
127
|
+
doc
|
|
128
|
+
/*
|
|
129
|
+
* The set of alternatives being considered in this TradeStudy.
|
|
130
|
+
*
|
|
131
|
+
* In a TradeStudy usage, bind this feature to the actual collection of
|
|
132
|
+
* alternatives to be considered.
|
|
133
|
+
*/
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
abstract calc evaluationFunction : EvaluationFunction {
|
|
137
|
+
doc
|
|
138
|
+
/*
|
|
139
|
+
* The EvaluationFunction to be used to evaluate the alternatives.
|
|
140
|
+
*
|
|
141
|
+
* In a TradeStudy usage, redefine this feature to provide the desired
|
|
142
|
+
* calculation (or bind it to a calculation usage that does so).
|
|
143
|
+
*/
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
objective tradeStudyObjective : TradeStudyObjective {
|
|
147
|
+
doc
|
|
148
|
+
/*
|
|
149
|
+
* The objective of this TradeStudy.
|
|
150
|
+
*
|
|
151
|
+
* Redefine this feature to give it a definition that is a concrete
|
|
152
|
+
* specialization of TradeStudyObjective. That can either be one of the
|
|
153
|
+
* specializations provided in this package, or a more specific user-
|
|
154
|
+
* defined one.
|
|
155
|
+
*/
|
|
156
|
+
|
|
157
|
+
subject :>> selectedAlternative;
|
|
158
|
+
in ref :>> alternatives = studyAlternatives;
|
|
159
|
+
in calc :>> eval = evaluationFunction;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return selectedAlternative : Anything = studyAlternatives->selectOne {in ref a {
|
|
163
|
+
doc
|
|
164
|
+
/*
|
|
165
|
+
* The alternative selected by this TradeStudy, which is the one that meets the
|
|
166
|
+
* requirement of the tradeStudyObjective.
|
|
167
|
+
*/
|
|
168
|
+
} tradeStudyObjective(selectedAlternative = a)};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "SysML Cause and Effect Library",
|
|
3
|
+
"description": "Standard cause-and-effect domain library for the Systems Modeling Language (SysML)",
|
|
4
|
+
"version": "2.1.0-dev.20260501",
|
|
5
|
+
"usage": [
|
|
6
|
+
{
|
|
7
|
+
"resource": "https://www.omg.org/spec/KerML/20250201/Semantic-Library.kpar",
|
|
8
|
+
"versionConstraint": "1.1.0-dev.20260501"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"resource": "https://www.omg.org/spec/KerML/20250201/Data-Type-Library.kpar",
|
|
12
|
+
"versionConstraint": "1.1.0-dev.20260501"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"resource": "https://www.omg.org/spec/KerML/20250201/Function-Library.kpar",
|
|
16
|
+
"versionConstraint": "1.1.0-dev.20260501"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"resource": "https://www.omg.org/spec/SysML/20250201/Systems-Library.kpar",
|
|
20
|
+
"versionConstraint": "2.1.0-dev.20260501"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|