Handling unsupported syntax
The Solver covers a growing subset of SysML v2. When a model uses something outside that subset, the Solver does not fail the whole run: it analyzes what it can, skips what it cannot, and tells you exactly what was skipped and why. Nothing is silently guessed.
A partly analyzable model
Create mixed.sysml. The flow-rate check is fully supported; the diameter-match check
relies on attributes whose type nothing in the model decides:
package Pump {
private import ScalarValues::Integer;
part pump [1] {
attribute flowRate : Integer = 40;
attribute inletDiameter;
attribute outletDiameter;
attribute matched = inletDiameter == outletDiameter;
}
assert constraint flowOk { Pump::pump::flowRate <= 50 }
assert constraint portsMatched { Pump::pump::matched }
}
syside solver check -i mixed.sysml
{
"result": {
"subject": "Pump",
"expression": "assertions[2]",
"determination": "unknown",
"outcome": {
"shape": "assertions",
"assertions": [
{ "name": "Pump::flowOk", "status": "satisfied",
"counterexample": null },
{
"name": "Pump::portsMatched",
"status": "unanalyzable",
"counterexample": null,
"reason": "depends on 'Pump::pump::inletDiameter', ..."
}
]
},
"causes": []
},
"warnings": [
{ "code": "Unimplemented", "span": null,
"message": "'Pump::pump::inletDiameter' excluded from analysis ..." },
{ "code": "Unimplemented", "span": null,
"message": "'Pump::pump::outletDiameter' excluded from analysis ..." }
],
"exit_code": 0
}
(The reason and message strings are shortened here; the real output carries them
in full.)
How to read this:
flowOkwas checked normally and is satisfied. Unsupported syntax elsewhere in the model did not block it.portsMatchedis unanalyzable – neither satisfied nor violated. Itsreasonsays which element caused it and, where the Solver can tell, what to change (here: declare a type for the two diameters).Each skipped element also appears in
warnings, so skipped parts of the model are visible even when every remaining assertion passes.determinationisunknown: the run as a whole could not decide every assertion.
An unanalyzable assertion is not a violation, so the exit code stays 0. If your CI should treat “could not check” as a failure, test for it explicitly – for example:
syside solver check -i mixed.sysml | jq -e \
'.result.outcome.assertions | all(.status == "satisfied")'
jq -e sets the exit code to 1 unless the expression is true, failing the step when
any assertion is violated or unanalyzable.
When the whole query is unsupported
If the expression you pass to evaluate --expr or check --predicate itself
depends on an unanalyzable element, there is no partial answer to give. The Solver
prints an error object with the same kind of reason and exits with code 2:
{
"error": {
"code": "Unimplemented",
"span": null,
"message": "the query depends on 'Battery::Cell::voltage', ..."
},
"exit_code": 2
}
Common causes and fixes
Attribute has no declared type, and its uses do not decide one (as in the example above). Declare one:
attribute inletDiameter : Real;.A quantity attribute is missing its quantity type. Values with units need a declaration like
: MassValue; see Comparing values across units.A package-level part usage without an explicit multiplicity. Write
part rover [1] {...}, or see Adding assumptions for thesingular-usagesoverride.The construct’s meaning is genuinely open in the specification. Some syntax the Solver refuses by default can be given a stated meaning with an override; Adding assumptions lists them.