Advanced Technical Guide
This section covers advanced technical aspects of SysIDE Automator for power users who need deeper understanding when building custom applications or scripting heavily using the library.
It details key implementation aspects including multithreading considerations, expression evaluation, formatting options, and JSON serialization features.
Learn more:
Multithreading: Considerations for multithreading
Expression Evaluation: Capabilities of implemented expression evaluation
Formatting: Formatting options
JSON Exports and Imports: JSON serialization features
Multithreading
On modern computers, multithreading is necessary to achieve high performance and SysIDE here is no exception. SysIDE supports internal and external multithreading:
Internal multithreading: SysIDE uses multithreading internally when loading and validating models, which is not visible to the user except for the CPU usage.
External multithreading: SysIDE was designed to be used in multithreaded environments. While Python still uses a global interpreter lock (GIL), there is an ongoing effort to remove it. Therefore, the SysIDE API already exposes necessary locks for building multithreaded applications based on SysIDE once Python removes the GIL.
When using SysIDE in a multithreaded environment, the following guidelines should be followed:
Access to
Documents
andTextDocuments
should be synchronizedLinked elements allow unsynchronized access to their owning documents for performance
Users who want to modify model
Documents
should do so in a single-thread, or manually lock all dependentDocuments
including transitive dependants.
Expression Evaluation
As part of semantic resolution, minimal expression evaluation is implemented. It covers most arithmetic expressions and some standard library functions, enough to parse the standard library and accompanying examples. Currently, the following are not yet supported:
arbitrary user defined functions and expressions,
quantities and units.
Evaluation is implemented to work on a read-only model so it is not allowed to construct new elements. As a side effect, this reduces the memory usage as models parsed from syntactically valid source files cannot have orphan elements. Rather than constructing orphan literal expression elements, evaluation returns the values directly.
Most SysML operators are supported, however a few are not:
[
, undefined by KerML specification, quantity declaration in SysMLall
, type extent~
, undefined by KerML specification
Constructor expressions are returned as-is because they implicitly conform to the
constructed object. This means that its arguments are not evaluated eagerly. Given an
owning_type
with a feature
that evaluates to a constructor expression value
,
its arguments can be evaluated as:
compiler = syside.Compiler()
for parameter in value.owned_parameters.collect():
expr = parameter.feature_value_expression
if not expr:
# should not be executed in a valid model
print(f"{parameter} has no feature value")
else:
result, report = compiler.evaluate(expr, scope=owning_type)
if not report:
print(f"{parameter} failed to evaluate: {report.diagnostics}")
elif isinstance(result, str):
print(f'{parameter} = "{result}"')
else:
print(f"{parameter} = {result}")
For now, constructor expressions can only be inferred as InvocationExpressions
that
invoke a Type
that is neither a subtype of Expression
nor Function
, e.g.
not isinstance(value, (*syside.Expression.STD, *syside.Function.STD))
. Next SysML
update is adding an explicit ConstructorExpression
type for constructor expressions
which will simplify this.
In addition, currently supported standard library functions include:
NumericalFunctions::product
NumericalFunctions::sum
SequenceFunctions::notEmpty
SequenceFunctions::isEmpty
SequenceFunctions::size
SequenceFunctions::includes
SequenceFunctions::excludes
StringFunctions::Length
StringFunctions::Substring
Support for more standard library functions will be added in future updates.
Formatting
SysIDE provides an AST-based formatter that ensures consistent code style across source files. The formatter:
Enforces consistent indentation and token usage (e.g.,
:>>
vsredefines
)Converts in-memory models to textual syntax, even without original source text
Supports format ignore pragmas to preserve specific formatting
Note
The formatter verifies that models contain all required elements but does not validate the generated syntax.
Example of format ignore pragma usage:
package P {
part def PartDef;
// syside-format ignore
part 'my unformatted AST' : PartDef {
}
}
The pragma preserves the formatting of the AST it is attached to, while maintaining consistent indentation for the rest of the file.
JSON Exports and Imports
SysIDE also supports bi-directional JSON serialization. Serialization produces a mostly specification compliant JSON with a few minor differences:
not all implicit elements are constructed which will fail for attributes that are defined as non-null in the standard JSON schema, e.g.
Function::result
;references can be serialized with relative
@uri
field for references to elements from other documents. This brings JSON exports in-line with corresponding XMI exports used by the Pilot implementation where references are always exported as<relative URI>#<element id>
. Additionally, such exports enable much faster deserialization because cross references are transparent and do not require searching the world for their resolution.
Warning
JSON export and import implementations in SysIDE and Pilot implementation target different use cases and, therefore, JSONs exported by one cannot be imported by another without additional processing. More specifically:
SysIDE JSON support is primarily intended for use in project interchange files (.kpar) as described in clause 10 of KerML specification.
Pilot implementation JSON support targets the model server API described in “Systems Modeling Application Programming Interface (API) and Services” specification.
We are working on bringing support of API-specific JSONs to SysIDE. Also, it is likely that Pilot implementation will support project interchange files in the near future.
JSON deserialization (import) works on the same JSON files as were exported. However, in the interest of keeping the initial implementation simple there are a few limitations:
the first element in the array is treated as the root node, not necessarily the root namespace
references to elements from other
Documents
must contain a@uri
field. The URI of theDocument
model is deserialized into will be used to resolve relative URI referencesdeserialization may be lossy because the specification dumps all owned elements into
ownedRelationships
andownedRelatedElements
attributes which lose the more fine grained information stored in the model by SysIDE. For example,SendActionUsage
receiver
,payload
andsender
are all parameters toReferenceUsage
, only disambiguated by their relative position, so if one is missing the others may be deserialized into different members.
Note that deserialization ignores majority of fields present in the JSON schema,
including all derived fields with the exception of name
and shortName
. Therefore
users may wish to export JSONs with minimal export options to reduce memory usage and
improve performance.
Warning
JSONs typically take 100-1000 times more space than the original textual notation and are opaque to human readers. Therefore, we recommend using textual notation instead of JSON whenever possible.