Documentation menu

Getting started with ArcLang

This page takes about ten minutes. You install the compiler, write a small braking-assistance model, and take it from "compiles" to "passes the production gate".

If you only want to try the language, the playground runs the same compiler in your browser, with nothing to install and nothing uploaded.

If model-based systems engineering is new to you, start with MBSE in 15 minutes and the tutorial, which builds a model from a blank page in the playground.

Install the compiler

Download the binary for your platform from the releases page. Each release ships Linux (x86-64) and macOS (Apple silicon and Intel) binaries, a SHA256SUMS file and build provenance attestations.

curl -LO https://github.com/Mbaroudi/arclang/releases/download/v4.12.0/arclang-linux-x86_64.tar.gz
curl -LO https://github.com/Mbaroudi/arclang/releases/download/v4.12.0/SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing
tar xzf arclang-linux-x86_64.tar.gz
sudo install arclang-linux-x86_64 /usr/local/bin/arclang

On macOS, replace arclang-linux-x86_64 with arclang-macos-aarch64 or arclang-macos-x86_64, and sha256sum with shasum -a 256. To check where a binary was built, run gh attestation verify arclang-linux-x86_64.tar.gz -R Mbaroudi/arclang.

You can also build from source with a Rust toolchain:

git clone https://github.com/Mbaroudi/arclang
cd arclang
cargo build --release      # the binary is target/release/arclang
$ arclang --version
arclang 4.12.0

Write a first model

Create brake.arc. It declares two safety requirements, a logical architecture of two components that exchange data through ports, and two traces that say which component satisfies which requirement.

brake.arc
model BrakeAssist {
    version: "1.0.0"

    requirements safety {
        req "REQ-001" "Obstacle detection" {
            description: "The system shall detect an obstacle at 150 m or more"
            safety_level: "ASIL-D"
        }
        req "REQ-002" "Braking reaction" {
            description: "The system shall command braking within 100 ms of detection"
            safety_level: "ASIL-D"
        }
    }

    architecture logical {
        component "Radar" {
            id: "LC-RADAR"
            safety_level: "ASIL-D"
            function "Detect obstacle" { latency: 40 ms }
            port out objects
        }
        component "Brake controller" {
            id: "LC-BRAKE"
            safety_level: "ASIL-D"
            function "Command braking" { latency: 25 ms }
            port in objects
        }
        component_exchange "Detected objects" {
            from_port: "LC-RADAR.objects"
            to_port: "LC-BRAKE.objects"
        }
    }
}

trace "LC-RADAR" satisfies "REQ-001" { rationale: "Long-range radar" }
trace "LC-BRAKE" satisfies "REQ-002" { rationale: "Commands the actuator" }

A few things to notice:

  • Names are identifiers (BrakeAssist) or strings ("Brake controller"). An identifier that contains a hyphen, such as "REQ-001", must be quoted.
  • id gives an element a stable identity. Traces, exports and the semantic diff rely on it, so a rename does not break anything.
  • latency: 40 ms is a typed quantity, not text. The compiler knows it is a duration.

Compile it

arclang check compiles the model and reports what it finds.

$ arclang check brake.arc
Checking brake.arc...
✓ No compilation errors

The model compiles, and every requirement and component is touched by a trace: check would name the ones that are not. Whether the model is complete enough to release is a different question, answered by the production gate below.

To get the compiled model as JSON, for a script or another tool, run arclang build brake.arc: it writes brake.json next to the model.

The compiler is strict. A construct it does not know, a unit that does not exist or a trace to an element that is not declared stops the build with a located message. Change the second trace so that it targets a requirement that does not exist:

broken.arc
model Broken {
    requirements safety {
        req "REQ-001" "Obstacle detection" { description: "Detect an obstacle at 150 m or more" }
    }
    architecture logical {
        component "Radar" { id: "LC-RADAR" }
    }
}

trace "LC-RADAR" satisfies "REQ-099"
$ arclang check broken.arc
Checking broken.arc...
✗ Check failed: Semantic error: 1 unresolved trace reference(s):
  trace 'LC-RADAR satisfies REQ-099': unknown element 'REQ-099' (to) — declare it or fix the reference
Error: Compilation error: Semantic error: 1 unresolved trace reference(s):
  trace 'LC-RADAR satisfies REQ-099': unknown element 'REQ-099' (to) — declare it or fix the reference

Draw the diagrams

arclang diagram writes a self-contained HTML viewer. It embeds its layout engine and makes no network request, so you can open it from a file or attach it to a review.

$ arclang diagram brake.arc -f html -o brake.html
✓ lab — 4 nodes, 1 edges
✓ req — 4 nodes, 2 edges
✓ gv — 4 nodes, 0 edges
✓ iv:Logical Architecture — 2 nodes, 1 edges
  Output: brake.html

Open brake.html in a browser. The logical architecture view shows each component with the function allocated to it and the exchange bound to its ports. See Diagrams for the other views.

Run the production gate

Compiling is not the same as being ready for a design review. arclang gate gives a PASS or FAIL verdict against what such a review requires. Our model fails it:

$ arclang gate brake.arc
Production-readiness gate (ISO26262) — brake.arc
  Requirements: 2 total, 2 satisfied, 0 verified

✗ 3 blocker(s):
  [requirements.verification] requirement 'REQ-001' has no verification case (test_case verifies: [...])
  [requirements.verification] requirement 'REQ-002' has no verification case (test_case verifies: [...])
  [safety.hara] elements declare ASIL/DAL levels but the model contains no hazard analysis (safety_analysis { hazard ... })

⚠ 1 warning(s):
  [methodology] system analysis without an operational analysis: no operational need is captured

PRODUCTION GATE: FAIL ✗ (3 blockers)
Error: Compilation error: production gate failed with 3 blocker(s)

The gate found three blockers. Both requirements are satisfied by a component, but nothing verifies them, and the model assigns ASIL-D to its elements without a hazard analysis that justifies it. It also warns that no operational need is captured.

Complete the model: an operational actor, one test case per requirement, and the hazard that the braking requirement mitigates.

brake_ready.arc
model BrakeAssist {
    version: "1.0.0"

    operational_analysis "Driving" {
        actor "Driver" { id: "ACT-DRIVER" description: "Drives the vehicle" }
    }

    requirements safety {
        req "REQ-001" "Obstacle detection" {
            description: "The system shall detect an obstacle at 150 m or more"
            safety_level: "ASIL-D"
        }
        req "REQ-002" "Braking reaction" {
            description: "The system shall command braking within 100 ms of detection"
            safety_level: "ASIL-D"
        }
    }

    architecture logical {
        component "Radar" {
            id: "LC-RADAR"
            safety_level: "ASIL-D"
            function "Detect obstacle" { latency: 40 ms }
            port out objects
        }
        component "Brake controller" {
            id: "LC-BRAKE"
            safety_level: "ASIL-D"
            function "Command braking" { latency: 25 ms }
            port in objects
        }
        component_exchange "Detected objects" {
            from_port: "LC-RADAR.objects"
            to_port: "LC-BRAKE.objects"
        }
    }
}

trace "LC-RADAR" satisfies "REQ-001" { rationale: "Long-range radar" }
trace "LC-BRAKE" satisfies "REQ-002" { rationale: "Commands the actuator" }

test_case "TC-001" {
    verifies: ["REQ-001"]
    method: "test"
    description: "Track test with a target at 150 m"
}
test_case "TC-002" {
    verifies: ["REQ-002"]
    method: "test"
    description: "HIL measurement of detection-to-command latency"
}

safety_analysis {
    hazard "Late braking" {
        description: "Braking is commanded too late to avoid the obstacle"
        severity: "S3"
        exposure: "E4"
        controllability: "C3"
        asil: "ASIL-D"
        mitigated_by: ["REQ-002"]
    }
}
$ arclang gate brake_ready.arc
Production-readiness gate (ISO26262) — brake_ready.arc
  Requirements: 2 total, 2 satisfied, 2 verified

PRODUCTION GATE: PASS ✓

The gate recomputes the ASIL of each hazard from its severity, exposure and controllability with the ISO 26262 table, and compares it with the level the model declares. Declare asil: "ASIL-B" for the hazard above and the gate fails, because S3, E4 and C3 give ASIL-D.

Put it in continuous integration

Every command returns a non-zero exit code on failure, so a pipeline needs no wrapper:

arclang fmt models/ --check     # the sources are formatted
arclang check model.arc --lint  # the model compiles, with methodology advisories
arclang gate model.arc          # the dossier is ready for review

Since 4.6, arclang ci init writes the whole pipeline for GitHub Actions, GitLab CI, Azure DevOps or Jenkins, with the gate as a required check, SARIF for code scanning and a report on each pull request: see CI/CD.

Next steps

Every ArcLang sample on this page is compiled, and every command is run, with the released compiler when the site is built.