ArcLang and Capella
Capella is the reference workbench for the Arcadia method. ArcLang implements the same method as text. The two are meant to be used together: a team can keep its Capella model, read and edit it as ArcLang, and write the changes back.
ArcLang is an independent project. It is not affiliated with Thales or the Eclipse Foundation.
Round-trip with a Capella model
The bridge is a pair of Python scripts in tools/capella_bridge, built on capellambse, the library that reads and writes native Capella files. It needs Python 3.10 or later.
python3 -m venv .venv
.venv/bin/pip install capellambse
# Capella to ArcLang: every element keeps its Capella UUID as its id
.venv/bin/python tools/capella_bridge/capella2arc.py path/to/model.aird -o model.arc
arclang check model.arc
# ArcLang back to Capella, matching elements by UUID (--dry-run reports, saves nothing)
arclang export model.arc -f json -o model.json
.venv/bin/python tools/capella_bridge/arc2capella.py model.json path/to/model.aird --dry-runWhat continuous integration proves on every push, on the Capella 7.0 test model of the capellambse project:
- Zero diff. Capella to ArcLang, compile, and back yields a byte-identical Capella model.
- Edits propagate. Changing a description or a requirement text in the
.arcfile changes it in the Capella XML. With--create-missing, a logical component added in ArcLang is created in Capella; with--delete-missing, one removed in ArcLang is deleted. Both flags are explicit, never the default.
What is converted
| Capella | ArcLang |
|---|---|
| Operational actors, entities, activities, processes, communication means | actor, entity, activity, operational_process, communication_means |
| Missions, capabilities, capability realizations | mission, capability, capability_realization |
| Functions of every level, with their ports, sub-functions, realizations and exchanges; functional chains | function inside the component that performs it, `port in |
| System components and actors with ports and component exchanges | system_component, actor, port, component_exchange |
| Logical components, nested, with their functions, ports and component exchanges | component, port, component_exchange |
| Physical nodes, behavior components and their physical functions, links and paths | node, behavior_component, function, link, physical_path |
| Classes, enumerations, data types, exchange items | class, enumeration, data_type, exchange_item |
| State machines with modes, states, regions, pseudo-states and transitions | state_machine, states nested in states, kind: on a pseudo-state |
| Scenarios with messages and combined fragments | scenario, message, fragment |
| Interfaces and their exchange items, provided and required by components | interface, provides, requires |
| Configuration items of the EPBS | epbs, system, subsystem, item |
| Property values and constraints on any element | attributes of the element, constraints: [...] |
| Requirements and their relations to model elements | requirement, trace ... satisfies |
The reverse direction synchronizes names, descriptions and requirements, and creates or deletes logical components on request. Other kinds are synchronized but not created or deleted. Physical components are emitted flat, and a scenario whose participants are not converted is skipped. The bridge's README keeps the exact scope.
Built-in export: a Capella 7 project
arclang export -f capella model.arc -o project.capella writes a Capella 7 project: the .capella, the .aird with its diagrams and the .afm, ready to open in Capella. Capella's identifiers kept by an import are written back, so a model that came from Capella returns to it as the same elements. Measured on 363 real Capella models (Capella's own samples and tests, capellambse's test models, community models): import, export and import again give 98 % of declarations identical, every trace included, and Capella 7.1 validates the exported In-Flight Entertainment System with 1 error where the original has 112; on every model of the sweep the export has no more validation errors than the original.
arclang import -f capella "Model Test 7.0.capella" -o test7.arc
arclang export -f capella test7.arc -o out/test7.capellaArcLang says a few things Capella cannot hold, taken from SysML v2: ports that hold ports, and exchanges of more than two ends. The export flattens them and says so in a note: an exchange on a held port goes to its outer port, an exchange of n ends becomes n−1 exchanges from its first end.
Built-in import, diagrams included
arclang import -f capella reads a Capella 6 or 7 project without Python: every level (operational analysis, system analysis, logical and physical architectures, EPBS), the requirements of the Requirements add-on with their attributes and relations, the data model (types, enumerations, classes and their fields, exchange items and their elements), the interfaces, the state machines with their regions and pseudo-states, the scenarios with their messages and combined fragments, the functional chains, operational processes and physical paths, the capabilities with what they involve, extend and include, the property values of the PVMT add-on and the constraints, and the realizations between levels. Capella's identifiers become the ids, so importing twice gives the same text. The result compiles, or the import fails and the refused text is kept beside the output for the reader; what is left out is counted and named.
Measured on Capella's own In-Flight Entertainment System sample (5 473 elements, 118 diagrams) and on the capellambse test model (1 449 elements, 33 diagrams), the import keeps 99 % and 96 % of the model elements: declared with their id, or carried inside a declaration (a field, a port, an involves list, a trace). Since each level has its own functions, ports and exchanges, as Arcadia has them, every function, function port and functional exchange of both samples comes through, their realizations across levels become traces (ports, exchanges, states, transitions and classes included), the allocations of functional exchanges to component exchanges become allocates traces, classes keep their inheritance and their associations, functional chains keep their control nodes, sequence links and the chains they reference, scenarios keep the states and functions asserted on their lifelines, and 116 of the 118 diagrams of the sample find their elements. What the language still has no place for is under 1 % of either sample, said as such in the report:
| Capella | Why it is left out today |
|---|---|
| Timers, duration constraints and references to other scenarios | a scenario holds messages, fragments and state fragments |
| Ports of the root physical component | the root is the physical system itself |
| Allocations of component exchanges to physical links, generic traces | no trace kind for them yet |
| Units outside the unit table | kept as a name on the type |
Roles, the tooling of Capella (transition links, REC/RPL catalogs, key values) and the packages have no counterpart and are not model content.
The diagrams of the .aird beside the file become diagram declarations: what a Capella diagram shows is what the ArcLang diagram shows, under the same name. A Capella user finds their diagrams back, laid out by ArcLang.
$ arclang import -f capella "tests/fixtures/capella/test7_0/Model Test 7.0.capella" -o imported.arc
Importing from Capella: tests/fixtures/capella/test7_0/Model Test 7.0.capella...
56 allocation traces
3 associations
14 behavior components
2 capabilities
21 capability involvements
3 capability realizations
1 chains owned by a capability, a threat or a function
29 class fields
8 class generalizations
19 classes
3 collections (as classes)
3 combined fragments
1 combined fragments of an operator ArcLang has no frame for (written as seq)
1 communication means
12 component exchanges
49 component ports
1 configuration item realizations
1 configuration items
9 constraints
15 control nodes of chains
17 data types
25 diagrams
4 diagrams of chains and processes (a chain is listed, not drawn)
3 diagrams of scenarios (each scenario is a view of its own)
2 diagrams of state machines (each machine is a view of its own)
7 enumerations
1 exchange item elements
17 exchange items
41 function ports
3 functional chains
19 functional exchanges
1 functional exchanges whose end is not an imported function (left out)
1 functions available in states
11 interactions
10 interface uses
3 interfaces
2 interfaces of the system level (declared in the logical architecture)
2 lifelines of elements not written (left out)
17 logical components
20 logical functions
1 logical functions (performed by no component)
18 messages
7 messages carrying an exchange
2 missions
6 modes
14 operational activities
2 operational actors
6 operational capabilities
4 operational entities
2 operational processes
12 physical exchanges
4 physical functions
3 physical functions (performed by no component)
10 physical links
19 physical nodes
4 physical paths
18 physical ports
23 property values
26 realization traces
11 requirement attributes
3 requirement relations
3 requirement relations to elements not written (left out)
8 requirements
1 roles (left out: ArcLang has no operational role)
7 scenarios
4 scenarios without a message
7 sequence links of chains
1 state fragments (functions on lifelines)
2 state fragments (states on lifelines)
8 state machines
3 state machines without a state
25 states
4 system actors
1 system components
4 system function allocations
4 system functions
25 transitions
4 unions (as classes)
✓ Import successful
Input: tests/fixtures/capella/test7_0/Model Test 7.0.capella
Output: imported.arc$ arclang check imported.arc
Checking imported.arc...
✓ No compilation errors
⚠ Compilation warnings:
duplicate element id '3bdd4fa2-5646-44a1-9fa6-80c68433ddb7_R. Weasley vs. Whomping Willow': InterfaceIn 'R. Weasley vs. Whomping Willow IN' and InterfaceOut 'R. Weasley vs. Whomping Willow OUT' share the same identity — give one an explicit unique id
duplicate element id '3bdd4fa2-5646-44a1-9fa6-80c68433ddb7_Whomping Willow_to_Whomping Willow': InterfaceIn 'Whomping Willow_to_Whomping Willow IN' and InterfaceOut 'Whomping Willow_to_Whomping Willow OUT' share the same identity — give one an explicit unique id
duplicate element id '3bdd4fa2-5646-44a1-9fa6-80c68433ddb7_Prof. S. Snape <3 Whomping Willow': InterfaceIn 'Prof. S. Snape <3 Whomping Willow IN' and InterfaceOut 'Prof. S. Snape <3 Whomping Willow OUT' share the same identity — give one an explicit unique id
duplicate element id '6f463eed-c77b-4568-8078-beec0536f243_Prof. S. Snape <3 Whomping Willow': InterfaceIn 'Prof. S. Snape <3 Whomping Willow IN' and InterfaceOut 'Prof. S. Snape <3 Whomping Willow OUT' share the same identity — give one an explicit unique id
duplicate element id 'ff7b8672-84db-4b93-9fea-22a410907fb1_R. Weasley vs. Whomping Willow': InterfaceIn 'R. Weasley vs. Whomping Willow IN' and InterfaceOut 'R. Weasley vs. Whomping Willow OUT' share the same identity — give one an explicit unique id
⚠ Traceability warnings:
Requirement 0a9a68b1-ba9a-4793-b2cf-4448f0b4b8cc has no trace
Requirement 79291c33-5147-4543-9398-9077d582576d has no trace
Requirement 1092f69a-5f3a-4fe6-a8fd-b2dffde90650 has no trace
Requirement 32d66740-e428-4600-be68-8410d9d568cc has no trace
Requirement 7e8d0edf-67f0-48c5-82f6-ec9cdb809eee has no trace
Requirement db4d4c74-b913-4d9a-8905-7d93d3360560 has no trace
Component 6583b560-6d2f-4190-baa2-94eef179c8ea has no trace
Component 3bdd4fa2-5646-44a1-9fa6-80c68433ddb7 has no trace
Component a58821df-c5b4-4958-9455-0d30755be6b1 has no trace
Component 20a83ab5-be44-4271-a7c5-b41142fc1f18 has no trace
Component c853900f-0b55-4499-8662-280eb9c3b71d has no trace
Component d461d616-c8a1-444b-8043-864e7c6a350a has no trace
Component a02f741f-c619-422c-bda9-f43f8dba0d7e has no trace
Component ba88f7c7-96c9-44dd-a71d-3b25a567da25 has no trace
Component 881b99aa-50ff-4c1c-a0aa-11fb376ebe1a has no trace
Component 1788c8b1-dda2-44ac-bc08-e6ee8eea9d7a has no trace
Component 08e02248-504d-4ed8-a295-c7682a614f66 has no trace
Component 6f463eed-c77b-4568-8078-beec0536f243 has no trace
Component a8c46457-a702-41c4-a971-c815c4c5a674 has no trace
Component ff7b8672-84db-4b93-9fea-22a410907fb1 has no trace
Component 3e0ee19f-0e3f-49d4-ae99-29bd4a3260c5 has no trace
Component b3888dad-a870-4b8b-97d4-0ddb83ef9251 has no traceThe bridge above remains the way back to Capella, and the way to keep both in step.
How the two compare
| Capella | ArcLang | |
|---|---|---|
| Method | Arcadia | Arcadia |
| Model storage | XML files written by the workbench | Plain text files written by people |
| Editing | Graphical editors | Any text editor, with a language server for diagnostics |
| Diagrams | Drawn and arranged by hand, stored with the model | Compiled from the model, laid out automatically, optional arrangement saved next to the model |
| Review of a change | Model comparison tools inside the workbench | Pull request on text, plus a semantic diff by element identity |
| Merge | Model merge tools | Git merge of text |
| Checks | Validation rules run in the workbench | Compiler errors, and a production gate with an exit code for continuous integration |
| Typed quantities and constraints | Property values, add-ons | In the language: units, dimensions, evaluated assertions |
| Ecosystem | Mature, with many add-ons and viewpoints | Young, with exports to SysML v2, ReqIF, Simulink, FMI |
| License | Eclipse Public License | MIT |
Capella is the better choice when engineers work mainly in diagrams, when the organization already runs on its add-ons, or when a customer requires it. ArcLang fits when the model must live in Git next to the code, be reviewed in pull requests and be checked on every commit. The round-trip exists so that the choice does not have to be exclusive.
Diagrams
Capella users will recognize the views: operational, system, logical and physical architecture blank diagrams, capabilities, class diagrams, the product breakdown, mode and state machines, and scenarios. In ArcLang they are generated, not drawn. That removes a class of errors, a diagram that no longer matches the model. What Capella users put on a diagram by hand, ArcLang writes down: a diagram declaration names the elements a diagram shows, and "Arrange" in the viewer moves boxes where the reader wants them, kept in a layout file next to the model.