This reference covers the +opensysml package. See client libraries to compare
language surfaces, the MATLAB client guide, and
client/matlab/README.md for local test and conformance commands.
The package uses Connect-JSON over HTTP, with no generated protobuf code, and runs in MATLAB
R2019b+ and GNU Octave 7+. MATLAB uses matlab.net.http; Octave uses curl. Add
client/matlab/ to the path:
addpath('client/matlab')conn = opensysml.connect(); % OPENSYSML_SERVICE, otherwise a private child
conn = opensysml.external('localhost:50051');
conn = opensysml.private('binary', '/path/to/sysml-grpc');
conn = opensysml.connect('version', 'v0.0.0', ...
'capabilities', {'query', 'convert'});connect selects external when OPENSYSML_SERVICE is set and private otherwise. private
accepts binary, timeout, version, and capabilities; external accepts version and
capabilities. When no binary is given, private checks $OPENSYSML_GRPC_BINARY,
~/.opensysml/bin/sysml-grpc, and PATH. It starts the process with
-port 0 -health-port 0 -report-address -exit-with-parent through Java's ProcessBuilder.
Octave built without Java cannot spawn a private service. conn.close() stops a private child
but does not stop an external service.
[version, names] = conn.serverInfo() asks GetServerInfo once and caches the result.
conn.hasCapability(name) tests the advertised names; conn.describe() returns a service
description; conn.require(name) and conn.requireAll(names) enforce support. The expected
version and capabilities options are checked against the service before use.
opensysml.capabilities() returns the known capability names as MATLAB camelCase struct fields
whose values are the wire's snake_case strings.
model = opensysml.parseFile(conn, 'model.sysml', ...
'language', 'sysml', 'strict', true);
model = opensysml.parseSource(conn, ...
'package P { part def B; }', 'name', 'p.sysml');
docs = {opensysml.SourceDocument.file('base.sysml'), ...
opensysml.SourceDocument.inline('more.sysml', moreSource, 'sysml')};
model = opensysml.parseSources(conn, docs);SourceDocument.file(path) represents a file read by the service. SourceDocument.inline(name, content, language) represents inline SysML or KerML source and supplies the diagnostic document
name. parseSources accepts a cell array mixing these forms and parses the documents as one
model. parseFile, parseSource, and parseSources accept language, strict,
strictConformance, and raiseForErrors name-value options as applicable. strict is an alias
for strictConformance; specifying both requires the same logical value. The strict-conformance
option requires the strict_conformance capability. raiseForErrors returns a usable model or
raises a typed model diagnostic.
A Model carries connection, hash, diagnostics, roots, root, documents, and
sourcePath. Its errors() method returns error-severity diagnostics, ok() indicates whether
there are any, and raiseForErrors() raises with the diagnostics and model in the error details.
model.edit() opens an editor. Model operations are also exposed as methods:
| Area | Methods |
|---|---|
| Symbols | symbol, get, find, walk |
| Values and instances | evaluate, instantiate |
| Behaviors | executeAction, exploreAction, executeState, exploreState |
| Verification | verifyConstraint, verifyRequirement, verifySatisfaction, satisfied, validateInstance |
| Analysis | calc, runAnalysis, exploreAnalysis, runSweep |
| Query and documents | query, runDocumentQuery, renderDocument |
| Notation | convert, toSysml, toTurtle, toApiJson, save |
| Migration | opensysml.migrate, Migration.write, Migration.byVerdict |
get(fqn) resolves a qualified id. find(name) accepts a short name and returns an empty value
when it finds no result. walk(depth) traverses child symbols to the requested depth; its default
is unlimited. opensysml.getSymbol(model, id) returns the GetSymbol answer as a plain record;
model.symbol(id) wraps it in a Symbol, which exposes id, name, kind, typeFacts,
multiplicity, specializations, and the decoded record. Its methods include children(),
attributes(), parts(), getAttr(name), facts(), and attributeFacts(). Symbol collections
use cells. The function is getSymbol, not symbol: MATLAB names a class file after the class,
so a symbol.m beside Symbol.m cannot coexist on a case-insensitive file system.
opensysml.diagnostics(model) returns diagnostic records with severity, message, file, line,
column and code.
opensysml.call(conn, method, request) sends a decoded request to
/sysml.SysMLService/<method>; opensysml.callRaw(conn, method, requestJsonText) returns
[status, contentType, bodyText] without parsing. The conformance runner uses callRaw to send
scenario requests exactly as written.
opensysml.decodeValue reads all twenty-two Connect-JSON Value arms and opensysml.encodeValue
writes supported request values. intValue uses decimal JSON strings and exact int64
accumulation, including -9223372036854775808; an Integer beyond int64
arrives as bigIntValue and decodes to struct('bigInteger', digits), its decimal digits kept as
char because no MATLAB number holds it, and is sent back as written; realValue supports "NaN", "Infinity", and
"-Infinity". Other primitive mappings include boolValue to logical, stringValue to
char, complex to a complex scalar, and sequence to a cell array. null becomes [].
Structured arms use MATLAB structs: instanceId uses instanceRef; quantity values use
magnitude, unit, and unitTerm; enums include literalId, enumerationId, name, and
value; arrays include dimensions and an elements cell; vectors include components;
measurement references retain unit fields; functions include calcId and self; sets contain
an elements cell; metaobjects retain elementId and metaclassId; unset, infinity, and
undetermined values have their named struct wrappers. An unset value, undetermined value, or
function with a self reference cannot be sent back as an input.
Public constructors and utilities include quantity, infinity, enumLiteral, instanceRef,
objectRef, elementRef, functionRef, metaobject, parseUint64, and isExperimental.
Format constants are FORMAT_SYSML, FORMAT_TURTLE, and FORMAT_API_JSON. Use cells for
repeated values and request lists: MATLAB's jsonencode emits a scalar struct array as one JSON
object, while an empty cell encodes as an empty list.
The package functions and corresponding Model methods cover expression evaluation,
instantiation, single-run action and state execution, behavior exploration, constraint and
requirement verification, satisfaction verification, instance validation, calculations,
analyses, and parameter sweeps. Options are name-value pairs; supported options vary by method
and include inputs, events, schedule, performer, trace, subject, arguments,
namedArguments, engine, and question. Explore schedules return an Exploration; a normal
executeAction, executeState, or runAnalysis request answers one run. Exploration entry
points are opensysml.exploreAction, opensysml.exploreState, and
opensysml.exploreAnalysis.
executeState(..., 'trace', true) returns typed DocumentEvent entries in
trace and the discarded-record count in traceDropped; it checks the
state_trace capability before sending the request.
A failed traced run keeps its existing error identifier; lastError().details
includes its partial trace and traceDropped.
opensysml.listEngines(conn) returns EngineInfo records. Engine selection is available with
the engine option on supported calculation, verification, analysis, and sweep methods; a named
engine requires the engines capability. Standing records the engine, evidence strength and
bounds associated with an answer.
| Result class | Contents and helpers |
|---|---|
Verdict |
Outcome fields including holds, condition, witness, error, engine and diagnostics; explain(), raiseForError(), and logical conversion. |
Validation |
Verdicts, summary, ordered instance cells in service order, diagnostics and verifications; valid(), violated(), undecided(), raiseForError(), and explain(). |
CalcResult |
value, outputs, diagnostics and Standing; character conversion formats the computed result. |
AnalysisResult |
Outputs, verdicts, instances, verifications, evaluations and standing; selected(), satisfied(), and explain(). |
SweepTable |
Rows, parameters, sampling metadata, instances, diagnostics and standing; failures() selects failed rows. |
Exploration |
Outcome cells, complete, run and budget counts; status(), ok(), explain(), and raiseForIncomplete(). |
EngineInfo |
Engine identity, answers, bounds, readiness and protocol details; explain() describes it. |
Standing |
Engine, strength and bounds, with reported(), reached(), and explain(). |
The result's diagnostics and repeated records are cells of decoded records/objects, not MATLAB
object arrays.
conversion = opensysml.convert(conn, 'sysml', ...
'content', sourceText, 'fromFormat', 'sysml');
conversion.write('out.sysml');
turtle = model.toTurtle();
saved = model.save('model.ttl');opensysml.convert(conn, toFormat, ...) requires exactly one source:
filePath, content, or modelHash. Optional fields are fromFormat and
tolerateSyntaxErrors. Model.convert(format, 'tolerateSyntaxErrors', true) uses the parsed
model; toSysml, toTurtle, and toApiJson select common output formats. Model.save(path, ...) infers format from the path unless format is supplied and writes the returned content.
Conversion has content, fromFormat, toFormat, diagnostics, experimental,
experimentalNotice, char, length, and write(path). Experimental RDF conversions can
issue the opensysml:experimental warning. A SysML v1 model — fromFormat xmi, uml or
mdzip, or a filePath with that extension — is refused with opensysml:argument: it is
migrated, not converted.
migrated = opensysml.migrate(conn, 'sysml', 'filePath', 'Vehicle.mdzip', 'report', true);
migrated.report.summary
cellfun(@(e) e.name, migrated.byVerdict('unmapped'), 'UniformOutput', false)
migrated.write('Vehicle.sysml'); % images beside it, under images/opensysml.migrate(conn, toFormat, ...) takes exactly one of filePath or content (the
file's bytes as uint8, with fromFormat naming xmi, uml or mdzip), and the options
sysml -migrate has: fromFormat, report, results, layoutPath or layoutContent,
imageBaseUrl, strict. The returned Migration has content, fromFormat, toFormat,
report (a struct with source, exporter, summary, the mapped, approximated,
unmapped and skipped counts, entries and text), results, files (a map from each
image's relative path to its bytes), sourcePath, experimental and experimentalNotice;
byVerdict(verdict) selects entries and write(path) writes the model with its images beside
it, refusing to overwrite the v1 model — under any spelling or link to it — or to write outside
the model's directory, through .., an absolute path or a symbolic link. Migration is
experimental and issues the opensysml:experimental warning; a model the service cannot read
raises opensysml:diagnostics:migration.
model.query('oslc.where=...') preserves the OSLC text-query interface. The structured SysML v2
API query is built from scope, select, and where:
q = opensysml.buildQuery([], ...
'scope', {'Demo::Car'}, ...
'select', {'name', '@type'}, ...
'where', struct('@type', 'PrimitiveConstraint', ...
'property', 'name', 'operator', '=', 'value', 'Car'));
elements = model.query(q);scope accepts qualified names or id-reference records. select contains property names.
Constraints may be PrimitiveConstraint (=, >, <) or a non-empty
CompositeConstraint (and, or) containing constraints. buildQuery validates unknown
fields and malformed operators before sending. Query results are cells of element records with
id, type, and a containers.Map of properties.
model.runDocumentQuery(queryId, 'bindings', bindings) sends named parameter bindings and
returns a DocumentQueryResult with columns and rows; both are cell collections.
bindings may be a scalar struct or containers.Map. Primitive values, quantity structs,
elementRef(id), and objectRef(id, path) are supported. model.renderDocument(documentId, 'form', 'markdown') returns Markdown; 'html' requests HTML and requires both
render_document and render_document_html.
model.edit() and opensysml.Editor(model) create a chainable handle editor. Each builder
returns the editor so operations can be composed. Positional arguments keep Python's order;
optional arguments use lowerCamel MATLAB name-value pairs. The public surface includes:
- Core operations:
setValue,rename,addMember,addMetadata,addMetadataPrefix,addObjective,addVerify,addSatisfy,addRequirementConstraint,addRequireConstraint,addAssumeConstraint,addDocumentation,addComment,addNote,addImport,move,deleteElement, andapply. - Connection and behavior declarations:
addTransition,addEntryTransition,addFirst,addThen,addAccept,addSend,addAssign,addIf,addWhile,addLoop,addFor,addTerminate,addGuardedThen,addElse,addConnection,addAllocation,addFlow, andaddSuccession. - Declaration helpers include package, part, attribute, item, port, class, struct, datatype, classifier, feature, association, behavior, function, predicate, interaction, metaclass, calculation, action, parameter, return, state, constraint, requirement, and assertion forms.
deleteElement is the deletion builder name so the handle object's destructor remains
available as delete. opensysml.Body is another chainable handle for nested action bodies;
it supports sequence items, actions, accept/send, assignment, if, while, loop, for,
termination, guarded transitions and else. Recursive bodies are limited to 128 levels.
Editor.operations() is hidden from normal help but returns the wire operation cell for
inspection. opensysml.applyEdits(model, operations) exposes the low-level request wrapper and
accepts a cell of oneof operation structs.
Editor.apply() and applyEdits require apply_edits and operation-specific capabilities such
as authoring, connection_authoring, satisfy_authoring, transition_authoring,
action_body_statement_authoring, member_modifiers, and edit_documents. Missing
capabilities are checked before the RPC. A successful call returns EditResult, a Conversion
subclass with edited content, applied edit records, documents records, and save(path).
Applying an empty editor raises the typed noOperations edit failure; applying the same editor
twice raises opensysml:argument.
Errors use public opensysml:* identifiers. MATLAB raises MException; Octave raises ordinary
errors with the same identifiers. opensysml.lastError() returns a struct with identifier,
message, diagnostics, and details for the most recently raised client error.
| Identifier | Raised for |
|---|---|
opensysml:argument |
Invalid arguments or unsupported name-value options. |
opensysml:transport |
Connection errors, timeouts, or non-JSON responses where JSON was required. |
opensysml:connect:modelNotFound, symbolNotFound, modelFileNotFound |
Missing model, symbol, or source file from a Connect status. |
opensysml:connect:invalidRequest, unavailable, serviceTimeout, unsupportedOperation, service |
Other typed Connect status failures. |
opensysml:missingCapability |
The service does not advertise a required capability; details include capability and service. |
opensysml:staleService |
Requested version or required capability set does not match the service. |
opensysml:diagnostics:model, conversion, wrongKind, execution |
Model, conversion, kind, execution, or verification errors reported by a successful RPC. |
opensysml:diagnostics:edit:<failure> |
Typed edit failure. Failure names use lowerCamel, for example unknownTarget, renameReferenced, and deleteReferenced; lastError().details retains the wire enum and structured referrers. |
opensysml:encode, decode, unknownArm |
Value encoding/decoding contract violations or unknown wire values. |
opensysml:experimental |
Warning for experimental RDF conversion. |
The Connect status and service origin, missing capability, edit failure enum, referring elements,
and diagnostics are exposed in lastError().details or lastError().diagnostics. Content-Type
is checked before decoding; proxy HTML or plain-text errors are transport errors rather than
malformed JSON errors.
- Release download, pinned digests and signature verification. The client never downloads a service binary.
- Typed-module generation.
- The separate FMI runner.
- Dataframe and HTML display helpers.
- Process-wide sharing of a private child service.
model[fqn]indexing; usegetorfind.
octave --no-gui --eval "addpath('client/matlab'); addpath('client/matlab/conformance'); addpath('client/matlab/conformance/private'); run_conformance('--address','localhost:50051')"
make conformance-matlabFlags: --binary/--address, --scenarios/--fixtures, --run substring, --report file
(- is stdout), --allow-skips, -v. --binary needs Java to start a private child; Octave
without Java uses --address. The report follows the shared JSON schema, and the exit status is
non-zero on fail or error, or on a skip without --allow-skips.