| description | The sysml command line — validator, analysis runner, interactive REPL, behavior engine, RDF exporter and document generator. Run the real REPL, with guided walkthroughs, in your browser. |
|---|
One binary is the whole toolchain: validator, analysis runner, interactive REPL,
behavior engine, RDF exporter and document generator. The same runtime sits behind
sysml-lsp for editors and sysml-grpc for programs. Pick a tab to see it work.
The runtime showcase, with this model$ sysml -quiet -analysis DeltaVBudget::saturnIBAscent delta-v-budget.sysml ✓ package DeltaVBudget ✓ DeltaVBudget::saturnIBAscent stage1DeltaV = 3037.6966629706967 [SI::'m/s'] stage2DeltaV = 6432.955324716369 [SI::'m/s'] margin = 70.65198768706614 [SI::'m/s'] objective reachesOrbit: satisfied standing: value (observed: 1 run under reverse)
$ sysml -quiet -analysis "DeltaVBudget::saturnIBAscent(required = 9800 ['m/s'])" delta-v-budget.sysml ✓ package DeltaVBudget ✗ DeltaVBudget::saturnIBAscent(required = 9800 ['m/s']) … margin = -329.34801231293386 [SI::'m/s'] objective reachesOrbit: not satisfied: margin > 0 ['m/s'] standing: value (observed: 1 run under reverse)
Every one of these, reproduced$ sysml -quiet -validate mass-rollup.sysml ✓ package MassRollup ✓ mass-rollup.sysml: no errors$ sysml -quiet -e MassRollup::saturnVWithIU.totalMass mass-rollup.sysml ✓ package MassRollup sysml: evaluation failed: feature value saturnVWithIU.totalMass: feature value InstrumentUnit.totalMass: no value for feature mass
$ sysml -quiet -calc "DeltaVBudget::InjectionDeltaV(3.986E14 [SI::N], 6563000 [SI::m], 384400000 [SI::m])" delta-v-budget.sysml ✓ package DeltaVBudget sysml: calc invocation failed: calc DeltaVBudget::InjectionDeltaV: result: type mismatch: cannot write 3135.1638390999387 [kg**0.5/s] (dimension M^0.5·T^-1) to a feature typed by SpeedValue (dimension L·T^-1) standing: not covered (…)
The REPL, in the guidesysml> part def Wheel { attribute diameter = 16.0; } ✓ part def Wheelsysml> %instantiate Wheel ✓ Created instance of Wheel ID: 1
sysml> %features Wheel Instance: Wheel (ID: 1) Features: diameter = 16.0 …
sysml> calc add { in x; in y; x + y } ✓ calc add
sysml> %calc add 10 20 ✓ add(10, 20) = 30 standing: value (observed: 1 run under reverse)
The document generation manual$ sysml rover.sysml -render-document Hello::RoverReport ✓ package Hello # Rover PartsThe rover's top-level parts, from the model:
<!-- caption --> Top-level parts
name arm chassis mast
$ sysml rover.sysml -render-document Hello::RoverReport -doc-form html -o rover.html ✓ package Hello wrote rover.html (html, 4983 bytes) # or -doc-form pdf
Checking a model, in the guide$ sysml -validate vehicles.sysml vehicles.sysml:6:16: error: unresolved reference: Whel — did you mean Wheel? part spare : Whel; ^~~~ sysml: vehicles.sysml did not analyse cleanly; no check was made$ echo $? 2
$ sed -i 's/Whel/Wheel/' vehicles.sysml && sysml -validate vehicles.sysml ✓ package Vehicles ✓ vehicles.sysml: no errors
Executing behavior, in the guidesysml> state def TrafficLight { ...> entry; then green; ...> state green; accept after 25 [SI::s] then yellow; ...> state yellow; accept after 5 [SI::s] then red; ...> state red; accept after 30 [SI::s] then done; ...> } ✓ state def TrafficLightsysml> %state TrafficLight ✓ Started state machine executor for "TrafficLight" Current state: green
sysml> %advance 25 ✓ Advanced to 25.0 (1 event(s) processed) Current state: yellow
sysml> %advance 35 ✓ Advanced to 60.0 (2 event(s) processed) ✓ State machine completed (a transition reacheddone)
Saving and RDF, in the guide$ sysml vehicles.sysml -convert ttl -o vehicles.ttl note: RDF conversion is experimental: the mapping covers model structure and the behavior its bodies state, refuses what it cannot write back, … wrote vehicles.ttl (ttl, 5562 bytes) $ grep -A5 '^elmt:Vehicles__Wheel$' vehicles.ttl elmt:Vehicles__Wheel a sysml:PartDefinition ; sysml:qualifiedName "Vehicles::Wheel" ; sysml:elementId "Vehicles__Wheel" ; sysx:memberIndex "1"^^xsd:integer ; sysml:owningNamespace elmt:Vehicles ;$ sysml vehicles.ttl -convert sysml # and back again note: RDF conversion is experimental: … package Vehicles { part def Wheel; …
$ sysml -query 'oslc.where=sysml:name="wheels"' vehicles.sysml ✓ package Vehicles Vehicles::Car::wheels PartUsage
$ pip install opensysml
$ python
>>> import opensysml
>>> model = opensysml.load("vehicle.sysml")
>>> model.ok
True
>>> model.eval("mass", subject="Demo::sedan")
1800.0
>>> vehicle = model.get("Demo::Vehicle")
>>> vehicle.kind, vehicle.id
('partDef', 'Demo::Vehicle')
>>> built = model.instantiate("Demo::Vehicle")
>>> built.mass
1500.0
</div>
- analysis
- found
- repl
- docs
- check
- run
- rdf
- python
// Refills the pane's text nodes in place: commands typed per character, output per line; // the
follows the tail until the reader scrolls it.
function printer(pane) {
var pre = pane.querySelector("pre");
var code = pane.querySelector("pre > code");
var nodes = [];
var timer = null;
var follow = true;
if (code) {
var walker = document.createTreeWalker(code, NodeFilter.SHOW_TEXT, null, false);
var node;
while ((node = walker.nextNode())) {
nodes.push({ node: node, text: node.data, prompt: !!node.parentNode.closest(".osml-prompt") });
}
}
function unfollow() { follow = false; }
if (pre) {
pre.addEventListener("wheel", unfollow, { passive: true });
pre.addEventListener("touchmove", unfollow, { passive: true });
}
function restore() {
nodes.forEach(function (n) { n.node.data = n.text; });
}
function cancel() {
if (timer) { clearTimeout(timer); timer = null; }
pane.classList.remove("is-printing");
restore();
}
function run(done) {
cancel();
if (reduceMotion.matches || !nodes.length) { done(); return; }
nodes.forEach(function (n) { n.node.data = ""; });
pre.scrollTop = 0;
pre.scrollLeft = 0;
follow = true;
pane.classList.add("is-printing");
var i = 0, pos = 0, typing = false;
function step() {
if (i >= nodes.length) {
timer = null;
pane.classList.remove("is-printing");
done();
return;
}
var n = nodes[i], delay;
if (n.prompt) {
n.node.data = n.text;
pos = n.text.length;
typing = true;
delay = TYPE_MS * 6;
} else if (typing) {
var ch = n.text.charAt(pos++);
n.node.data += ch;
if (ch === "\n") typing = false;
delay = TYPE_MS + Math.random() * TYPE_MS;
} else {
var end = n.text.indexOf("\n", pos);
end = end < 0 ? n.text.length : end + 1;
n.node.data += n.text.slice(pos, end);
pos = end;
delay = LINE_MS;
}
if (pos >= n.text.length) { i++; pos = 0; }
if (follow) pre.scrollTop = pre.scrollHeight;
timer = setTimeout(step, delay);
}
step();
}
return { run: run, cancel: cancel };
}
function setUp(root) {
var tabs = Array.prototype.slice.call(root.querySelectorAll("[role=tab]"));
var panes = Array.prototype.slice.call(root.querySelectorAll("[role=tabpanel]"));
var printers = panes.map(printer);
var title = root.querySelector("[data-osml-title]");
var current = 0;
var timer = null;
var autoplay = false;
function show(index, focus) {
printers[current].cancel();
current = (index + panes.length) % panes.length;
panes.forEach(function (pane, i) {
pane.classList.toggle("is-active", i === current);
});
tabs.forEach(function (tab, i) {
var active = i === current;
tab.setAttribute("aria-selected", active ? "true" : "false");
tab.tabIndex = active ? 0 : -1;
if (active && focus) tab.focus();
});
if (title) title.textContent = panes[current].dataset.title || "";
printers[current].run(function () { schedule(DWELL); });
}
function stop() {
autoplay = false;
if (timer) { clearTimeout(timer); timer = null; }
}
function schedule(delay) {
if (timer) clearTimeout(timer);
timer = null;
if (!autoplay || reduceMotion.matches) return;
timer = setTimeout(advance, delay);
}
function advance() {
timer = null;
if (!root.isConnected) { stop(); return; }
if (root.matches(":hover") || root.contains(document.activeElement)) { schedule(1000); return; }
show(current + 1, false);
}
tabs.forEach(function (tab, i) {
tab.addEventListener("click", function () { stop(); show(i, false); });
tab.addEventListener("keydown", function (event) {
var targets = { ArrowRight: i + 1, ArrowLeft: i - 1, Home: 0, End: panes.length - 1 };
if (typeof targets[event.key] !== "number") return;
event.preventDefault();
stop();
show(targets[event.key], true);
});
});
autoplay = !reduceMotion.matches;
show(0, false);
}
Array.prototype.forEach.call(document.querySelectorAll("[data-osml-cli-showcase]"), setUp);
})();
</script>
This is the real sysml REPL, the same cmd/sysml you run in a
terminal, built for WebAssembly with the production build tags and running entirely in this
page. Nothing is sent to a server. Pick a walkthrough and press Run this step to type
each command into the prompt, or type your own. Arrow keys bring back earlier lines, including
those from your last visit, and Tab completes commands and names.
Loading the walkthroughs…
sysml — WebAssembly, in this page
$ sysml # the full REPL, about 12 MB, downloaded once when you start it
Start the REPL
sysml> <textarea data-repl-in rows="1" aria-label="REPL input" placeholder="start the REPL, or run a walkthrough step" disabled autocomplete="off" autocapitalize="off" spellcheck="false"></textarea>
Running a walkthrough step starts the REPL too.
<script>
(function () {
function mountAll() {
document.querySelectorAll("[data-osml-repl]:not([data-mounted])").forEach(function (el) {
el.dataset.mounted = "";
window.osmlRepl.mount(el);
});
}
if (window.osmlRepl) { mountAll(); return; }
var s = document.createElement("script");
s.src = "../assets/sysml-repl.js";
s.onload = mountAll;
document.head.appendChild(s);
})();
</script>
What the browser can't do: there is no disk, so %load and %save
work on an in-memory filesystem that holds the showcase models under
examples/runtime-showcase/ and is lost when the session ends. A page can't start
other programs either, so %check, %solve, %configure,
%optimize and %explain, which run an external SMT solver, report that
the solver is unavailable. The production build also leaves out code generation, Flexo
synchronization, SysML v1 migration, FMI and PDF rendering. Everything else in the
REPL command reference runs here as it does in a terminal.
-analysis
Execute a model's analysis cases — evaluated features with units carried and
checked, objectives decided against what the run finds. The delta-v budget above
is the runtime showcase.
sysml>
Parse, instantiate, evaluate and inspect a live session — every % command and
its arguments, plus what keeps your model across restarts.
-check
Name resolution, typing and constraint tiers — and what a validator alone cannot
reach, which the runtime modes below do.
-run
Actions, state machines, calculations, analyses and requirements, run on a clock —
with a step budget if a model does not finish on its own.
-convert
Write a model out as Turtle for graph stores — the mapping, what is not mapped,
and why the experimental flag is honest.
-render-document
Markdown, HTML and PDF documents driven by the model's own document queries —
the full manual is a chapter of its own.
- CLI — every flag, the modes, and the exit codes
- REPL commands — every
%command and its arguments - Environment variables — resource limits for a single run