Handle 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 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.flowRate <= 50 }
assert constraint portsMatched { pump.matched }
}
syside solver check -i mixed.sysml
{
"result": {
"subject": "Pump",
"expression": "assertions[2]",
"determination": "unknown",
"outcome": {
"shape": "assertions",
"assertions": [
{
"name": "Pump::flowOk",
"outcome": {
"shape": "attainable_set",
"attainable": {
"values": [
{
"value": "true",
"witness": {
"values": [["Pump::pump.flowRate", "40"]],
"value": "true"
}
}
],
"exhaustive": "true"
},
"unattainable": { "values": ["false"], "exhaustive": "true" }
}
},
{
"name": "Pump::portsMatched",
"outcome": {
"shape": "attainable_set",
"attainable": { "values": [], "exhaustive": "unknown", "reason": "depends on 'Pump::pump.inletDiameter', ..." },
"unattainable": { "values": [], "exhaustive": "unknown", "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 ..." }
],
"fail_when": "false_attainable",
"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 holds (falseis unattainable). Unsupported syntax elsewhere in the model did not block it.portsMatchedcould not be analyzed: neither listing holds a value, and both have anexhaustiveof"unknown". Thereasonsays 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 holds.determinationisunknown: the run as a whole could not decide every assertion.
Changed in version 1.0.0: Before 1.0.0, such an assertion had a status of unanalyzable with a reason.
An assertion the Solver could not analyze is not a violation, so under the default
--fail-when mode the exit code stays 0. If your CI should treat “could not check” as
a failure, use the strict mode:
syside solver check -i mixed.sysml --fail-when not-exactly-true
This exits 1 unless every assertion must hold, so it fails the step when any assertion can be violated or could not be analyzed.
When the whole query is unsupported
If the expression you pass to evaluate --expr or check --predicate itself depends
on an element the Solver could not analyze, the result has no values in either
listing, both with an exhaustive of "unknown" and the same kind of reason, and
result.causes carries an unanalyzable entry with the reasons. The exit code is 0
for evaluate, and for check under the default --fail-when mode:
syside solver evaluate -i mixed.sysml --expr "Pump::pump.matched"
{
"result": {
"subject": "Pump",
"expression": "Pump::pump.matched",
"determination": "unknown",
"outcome": {
"shape": "attainable_set",
"attainable": { "values": [], "exhaustive": "unknown", "reason": "the query depends on 'Pump::pump.inletDiameter', ..." },
"unattainable": { "values": [], "exhaustive": "unknown", "reason": "the query depends on 'Pump::pump.inletDiameter', ..." }
},
"causes": [
{
"unanalyzable": {
"reasons": ["the query depends on 'Pump::pump.inletDiameter', ..."]
}
}
]
},
"warnings": [ "..." ],
"exit_code": 0
}
(The reason strings are shortened and the warnings elided.)
Changed in version 1.0.0: Before 1.0.0, such a query printed an error object instead of a result and exited
with 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 Compare values across units.A package-level part usage without an explicit multiplicity. Write
part rover [1] {...}, or see Add assumptions for thesingular-usagesoverride.A transition with an effect (
transition first Off do assign level := 1 then On;). The Solver does not analyze such a state machine yet. An answer that depends on an attribute the machine writes gets anexhaustiveof"unknown", and thereasonends with “has an effect action (do ...), which is not supported”. Other machines in the model are still analyzed.An assertion inside a state definition or a state. It is reported with the
reason“asserts inside state definitions are not yet supported”, and every other assertion is still checked. Check that requirements hold lists the assertions the Solver checks.The construct’s meaning is open in the specification. Some syntax the Solver refuses by default can be given a stated meaning with an override. Add assumptions lists them.